ActivityManagerService.java revision ff17024e583b170312d82089fd358d278ce16c9a
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.os.BackgroundThread; 65import com.android.internal.os.BatteryStatsImpl; 66import com.android.internal.os.ProcessCpuTracker; 67import com.android.internal.os.TransferPipe; 68import com.android.internal.os.Zygote; 69import com.android.internal.util.FastPrintWriter; 70import com.android.internal.util.FastXmlSerializer; 71import com.android.internal.util.MemInfoReader; 72import com.android.internal.util.Preconditions; 73import com.android.server.AppOpsService; 74import com.android.server.AttributeCache; 75import com.android.server.IntentResolver; 76import com.android.server.LocalServices; 77import com.android.server.ServiceThread; 78import com.android.server.SystemService; 79import com.android.server.SystemServiceManager; 80import com.android.server.Watchdog; 81import com.android.server.am.ActivityStack.ActivityState; 82import com.android.server.firewall.IntentFirewall; 83import com.android.server.pm.Installer; 84import com.android.server.pm.UserManagerService; 85import com.android.server.statusbar.StatusBarManagerInternal; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.Process; 177import android.os.RemoteCallbackList; 178import android.os.RemoteException; 179import android.os.SELinux; 180import android.os.ServiceManager; 181import android.os.StrictMode; 182import android.os.SystemClock; 183import android.os.SystemProperties; 184import android.os.UpdateLock; 185import android.os.UserHandle; 186import android.os.UserManager; 187import android.provider.Settings; 188import android.text.format.DateUtils; 189import android.text.format.Time; 190import android.util.AtomicFile; 191import android.util.EventLog; 192import android.util.Log; 193import android.util.Pair; 194import android.util.PrintWriterPrinter; 195import android.util.Slog; 196import android.util.SparseArray; 197import android.util.TimeUtils; 198import android.util.Xml; 199import android.view.Gravity; 200import android.view.LayoutInflater; 201import android.view.View; 202import android.view.WindowManager; 203 204import dalvik.system.VMRuntime; 205 206import java.io.BufferedInputStream; 207import java.io.BufferedOutputStream; 208import java.io.DataInputStream; 209import java.io.DataOutputStream; 210import java.io.File; 211import java.io.FileDescriptor; 212import java.io.FileInputStream; 213import java.io.FileNotFoundException; 214import java.io.FileOutputStream; 215import java.io.IOException; 216import java.io.InputStreamReader; 217import java.io.PrintWriter; 218import java.io.StringWriter; 219import java.lang.ref.WeakReference; 220import java.util.ArrayList; 221import java.util.Arrays; 222import java.util.Collections; 223import java.util.Comparator; 224import java.util.HashMap; 225import java.util.HashSet; 226import java.util.Iterator; 227import java.util.List; 228import java.util.Locale; 229import java.util.Map; 230import java.util.Set; 231import java.util.concurrent.atomic.AtomicBoolean; 232import java.util.concurrent.atomic.AtomicLong; 233 234public final class ActivityManagerService extends ActivityManagerNative 235 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 236 237 private static final String USER_DATA_DIR = "/data/user/"; 238 // File that stores last updated system version and called preboot receivers 239 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 240 241 static final String TAG = "ActivityManager"; 242 static final String TAG_MU = "ActivityManagerServiceMU"; 243 static final boolean DEBUG = false; 244 static final boolean localLOGV = DEBUG; 245 static final boolean DEBUG_BACKUP = localLOGV || false; 246 static final boolean DEBUG_BROADCAST = localLOGV || false; 247 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 248 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 249 static final boolean DEBUG_CLEANUP = localLOGV || false; 250 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 251 static final boolean DEBUG_FOCUS = false; 252 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 253 static final boolean DEBUG_MU = localLOGV || false; 254 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 255 static final boolean DEBUG_LRU = localLOGV || false; 256 static final boolean DEBUG_PAUSE = localLOGV || false; 257 static final boolean DEBUG_POWER = localLOGV || false; 258 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 259 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 260 static final boolean DEBUG_PROCESSES = localLOGV || false; 261 static final boolean DEBUG_PROVIDER = localLOGV || false; 262 static final boolean DEBUG_RESULTS = localLOGV || false; 263 static final boolean DEBUG_SERVICE = localLOGV || false; 264 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 265 static final boolean DEBUG_STACK = localLOGV || false; 266 static final boolean DEBUG_SWITCH = localLOGV || false; 267 static final boolean DEBUG_TASKS = localLOGV || false; 268 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 269 static final boolean DEBUG_TRANSITION = localLOGV || false; 270 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 271 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 272 static final boolean DEBUG_VISBILITY = localLOGV || false; 273 static final boolean DEBUG_PSS = localLOGV || false; 274 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 275 static final boolean DEBUG_RECENTS = localLOGV || false; 276 static final boolean VALIDATE_TOKENS = false; 277 static final boolean SHOW_ACTIVITY_START_TIME = true; 278 279 // Control over CPU and battery monitoring. 280 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 281 static final boolean MONITOR_CPU_USAGE = true; 282 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 283 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 284 static final boolean MONITOR_THREAD_CPU_USAGE = false; 285 286 // The flags that are set for all calls we make to the package manager. 287 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 288 289 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 290 291 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 292 293 // Maximum number recent bitmaps to keep in memory. 294 static final int MAX_RECENT_BITMAPS = 5; 295 296 // Amount of time after a call to stopAppSwitches() during which we will 297 // prevent further untrusted switches from happening. 298 static final long APP_SWITCH_DELAY_TIME = 5*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real. 302 static final int PROC_START_TIMEOUT = 10*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real, when the process was 306 // started with a wrapper for instrumentation (such as Valgrind) because it 307 // could take much longer than usual. 308 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 309 310 // How long to wait after going idle before forcing apps to GC. 311 static final int GC_TIMEOUT = 5*1000; 312 313 // The minimum amount of time between successive GC requests for a process. 314 static final int GC_MIN_INTERVAL = 60*1000; 315 316 // The minimum amount of time between successive PSS requests for a process. 317 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process 320 // when the request is due to the memory state being lowered. 321 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 322 323 // The rate at which we check for apps using excessive power -- 15 mins. 324 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on wake locks to start killing things. 328 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on CPU usage to start killing things. 332 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // How long we allow a receiver to run before giving up on it. 335 static final int BROADCAST_FG_TIMEOUT = 10*1000; 336 static final int BROADCAST_BG_TIMEOUT = 60*1000; 337 338 // How long we wait until we timeout on key dispatching. 339 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 340 341 // How long we wait until we timeout on key dispatching during instrumentation. 342 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 343 344 // Amount of time we wait for observers to handle a user switch before 345 // giving up on them and unfreezing the screen. 346 static final int USER_SWITCH_TIMEOUT = 2*1000; 347 348 // Maximum number of users we allow to be running at a time. 349 static final int MAX_RUNNING_USERS = 3; 350 351 // How long to wait in getAssistContextExtras for the activity and foreground services 352 // to respond with the result. 353 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 354 355 // Maximum number of persisted Uri grants a package is allowed 356 static final int MAX_PERSISTED_URI_GRANTS = 128; 357 358 static final int MY_PID = Process.myPid(); 359 360 static final String[] EMPTY_STRING_ARRAY = new String[0]; 361 362 // How many bytes to write into the dropbox log before truncating 363 static final int DROPBOX_MAX_SIZE = 256 * 1024; 364 365 // Access modes for handleIncomingUser. 366 static final int ALLOW_NON_FULL = 0; 367 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 368 static final int ALLOW_FULL_ONLY = 2; 369 370 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 371 372 /** All system services */ 373 SystemServiceManager mSystemServiceManager; 374 375 private Installer mInstaller; 376 377 /** Run all ActivityStacks through this */ 378 ActivityStackSupervisor mStackSupervisor; 379 380 public IntentFirewall mIntentFirewall; 381 382 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 383 // default actuion automatically. Important for devices without direct input 384 // devices. 385 private boolean mShowDialogs = true; 386 387 BroadcastQueue mFgBroadcastQueue; 388 BroadcastQueue mBgBroadcastQueue; 389 // Convenient for easy iteration over the queues. Foreground is first 390 // so that dispatch of foreground broadcasts gets precedence. 391 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 392 393 BroadcastQueue broadcastQueueForIntent(Intent intent) { 394 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 395 if (DEBUG_BACKGROUND_BROADCAST) { 396 Slog.i(TAG, "Broadcast intent " + intent + " on " 397 + (isFg ? "foreground" : "background") 398 + " queue"); 399 } 400 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 401 } 402 403 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 404 for (BroadcastQueue queue : mBroadcastQueues) { 405 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 406 if (r != null) { 407 return r; 408 } 409 } 410 return null; 411 } 412 413 /** 414 * Activity we have told the window manager to have key focus. 415 */ 416 ActivityRecord mFocusedActivity = null; 417 418 /** 419 * List of intents that were used to start the most recent tasks. 420 */ 421 ArrayList<TaskRecord> mRecentTasks; 422 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 423 424 /** 425 * For addAppTask: cached of the last activity component that was added. 426 */ 427 ComponentName mLastAddedTaskComponent; 428 429 /** 430 * For addAppTask: cached of the last activity uid that was added. 431 */ 432 int mLastAddedTaskUid; 433 434 /** 435 * For addAppTask: cached of the last ActivityInfo that was added. 436 */ 437 ActivityInfo mLastAddedTaskActivity; 438 439 public class PendingAssistExtras extends Binder implements Runnable { 440 public final ActivityRecord activity; 441 public final Bundle extras; 442 public final Intent intent; 443 public final String hint; 444 public final int userHandle; 445 public boolean haveResult = false; 446 public Bundle result = null; 447 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 448 String _hint, int _userHandle) { 449 activity = _activity; 450 extras = _extras; 451 intent = _intent; 452 hint = _hint; 453 userHandle = _userHandle; 454 } 455 @Override 456 public void run() { 457 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 458 synchronized (this) { 459 haveResult = true; 460 notifyAll(); 461 } 462 } 463 } 464 465 final ArrayList<PendingAssistExtras> mPendingAssistExtras 466 = new ArrayList<PendingAssistExtras>(); 467 468 /** 469 * Process management. 470 */ 471 final ProcessList mProcessList = new ProcessList(); 472 473 /** 474 * All of the applications we currently have running organized by name. 475 * The keys are strings of the application package name (as 476 * returned by the package manager), and the keys are ApplicationRecord 477 * objects. 478 */ 479 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 480 481 /** 482 * Tracking long-term execution of processes to look for abuse and other 483 * bad app behavior. 484 */ 485 final ProcessStatsService mProcessStats; 486 487 /** 488 * The currently running isolated processes. 489 */ 490 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 491 492 /** 493 * Counter for assigning isolated process uids, to avoid frequently reusing the 494 * same ones. 495 */ 496 int mNextIsolatedProcessUid = 0; 497 498 /** 499 * The currently running heavy-weight process, if any. 500 */ 501 ProcessRecord mHeavyWeightProcess = null; 502 503 /** 504 * The last time that various processes have crashed. 505 */ 506 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 507 508 /** 509 * Information about a process that is currently marked as bad. 510 */ 511 static final class BadProcessInfo { 512 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 513 this.time = time; 514 this.shortMsg = shortMsg; 515 this.longMsg = longMsg; 516 this.stack = stack; 517 } 518 519 final long time; 520 final String shortMsg; 521 final String longMsg; 522 final String stack; 523 } 524 525 /** 526 * Set of applications that we consider to be bad, and will reject 527 * incoming broadcasts from (which the user has no control over). 528 * Processes are added to this set when they have crashed twice within 529 * a minimum amount of time; they are removed from it when they are 530 * later restarted (hopefully due to some user action). The value is the 531 * time it was added to the list. 532 */ 533 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 534 535 /** 536 * All of the processes we currently have running organized by pid. 537 * The keys are the pid running the application. 538 * 539 * <p>NOTE: This object is protected by its own lock, NOT the global 540 * activity manager lock! 541 */ 542 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 543 544 /** 545 * All of the processes that have been forced to be foreground. The key 546 * is the pid of the caller who requested it (we hold a death 547 * link on it). 548 */ 549 abstract class ForegroundToken implements IBinder.DeathRecipient { 550 int pid; 551 IBinder token; 552 } 553 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 554 555 /** 556 * List of records for processes that someone had tried to start before the 557 * system was ready. We don't start them at that point, but ensure they 558 * are started by the time booting is complete. 559 */ 560 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 561 562 /** 563 * List of persistent applications that are in the process 564 * of being started. 565 */ 566 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 567 568 /** 569 * Processes that are being forcibly torn down. 570 */ 571 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 572 573 /** 574 * List of running applications, sorted by recent usage. 575 * The first entry in the list is the least recently used. 576 */ 577 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Where in mLruProcesses that the processes hosting activities start. 581 */ 582 int mLruProcessActivityStart = 0; 583 584 /** 585 * Where in mLruProcesses that the processes hosting services start. 586 * This is after (lower index) than mLruProcessesActivityStart. 587 */ 588 int mLruProcessServiceStart = 0; 589 590 /** 591 * List of processes that should gc as soon as things are idle. 592 */ 593 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 594 595 /** 596 * Processes we want to collect PSS data from. 597 */ 598 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 599 600 /** 601 * Last time we requested PSS data of all processes. 602 */ 603 long mLastFullPssTime = SystemClock.uptimeMillis(); 604 605 /** 606 * If set, the next time we collect PSS data we should do a full collection 607 * with data from native processes and the kernel. 608 */ 609 boolean mFullPssPending = false; 610 611 /** 612 * This is the process holding what we currently consider to be 613 * the "home" activity. 614 */ 615 ProcessRecord mHomeProcess; 616 617 /** 618 * This is the process holding the activity the user last visited that 619 * is in a different process from the one they are currently in. 620 */ 621 ProcessRecord mPreviousProcess; 622 623 /** 624 * The time at which the previous process was last visible. 625 */ 626 long mPreviousProcessVisibleTime; 627 628 /** 629 * Which uses have been started, so are allowed to run code. 630 */ 631 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 632 633 /** 634 * LRU list of history of current users. Most recently current is at the end. 635 */ 636 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 637 638 /** 639 * Constant array of the users that are currently started. 640 */ 641 int[] mStartedUserArray = new int[] { 0 }; 642 643 /** 644 * Registered observers of the user switching mechanics. 645 */ 646 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 647 = new RemoteCallbackList<IUserSwitchObserver>(); 648 649 /** 650 * Currently active user switch. 651 */ 652 Object mCurUserSwitchCallback; 653 654 /** 655 * Packages that the user has asked to have run in screen size 656 * compatibility mode instead of filling the screen. 657 */ 658 final CompatModePackages mCompatModePackages; 659 660 /** 661 * Set of IntentSenderRecord objects that are currently active. 662 */ 663 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 664 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 665 666 /** 667 * Fingerprints (hashCode()) of stack traces that we've 668 * already logged DropBox entries for. Guarded by itself. If 669 * something (rogue user app) forces this over 670 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 671 */ 672 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 673 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 674 675 /** 676 * Strict Mode background batched logging state. 677 * 678 * The string buffer is guarded by itself, and its lock is also 679 * used to determine if another batched write is already 680 * in-flight. 681 */ 682 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 683 684 /** 685 * Keeps track of all IIntentReceivers that have been registered for 686 * broadcasts. Hash keys are the receiver IBinder, hash value is 687 * a ReceiverList. 688 */ 689 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 690 new HashMap<IBinder, ReceiverList>(); 691 692 /** 693 * Resolver for broadcast intents to registered receivers. 694 * Holds BroadcastFilter (subclass of IntentFilter). 695 */ 696 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 697 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 698 @Override 699 protected boolean allowFilterResult( 700 BroadcastFilter filter, List<BroadcastFilter> dest) { 701 IBinder target = filter.receiverList.receiver.asBinder(); 702 for (int i=dest.size()-1; i>=0; i--) { 703 if (dest.get(i).receiverList.receiver.asBinder() == target) { 704 return false; 705 } 706 } 707 return true; 708 } 709 710 @Override 711 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 712 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 713 || userId == filter.owningUserId) { 714 return super.newResult(filter, match, userId); 715 } 716 return null; 717 } 718 719 @Override 720 protected BroadcastFilter[] newArray(int size) { 721 return new BroadcastFilter[size]; 722 } 723 724 @Override 725 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 726 return packageName.equals(filter.packageName); 727 } 728 }; 729 730 /** 731 * State of all active sticky broadcasts per user. Keys are the action of the 732 * sticky Intent, values are an ArrayList of all broadcasted intents with 733 * that action (which should usually be one). The SparseArray is keyed 734 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 735 * for stickies that are sent to all users. 736 */ 737 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 738 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 739 740 final ActiveServices mServices; 741 742 /** 743 * Backup/restore process management 744 */ 745 String mBackupAppName = null; 746 BackupRecord mBackupTarget = null; 747 748 final ProviderMap mProviderMap; 749 750 /** 751 * List of content providers who have clients waiting for them. The 752 * application is currently being launched and the provider will be 753 * removed from this list once it is published. 754 */ 755 final ArrayList<ContentProviderRecord> mLaunchingProviders 756 = new ArrayList<ContentProviderRecord>(); 757 758 /** 759 * File storing persisted {@link #mGrantedUriPermissions}. 760 */ 761 private final AtomicFile mGrantFile; 762 763 /** XML constants used in {@link #mGrantFile} */ 764 private static final String TAG_URI_GRANTS = "uri-grants"; 765 private static final String TAG_URI_GRANT = "uri-grant"; 766 private static final String ATTR_USER_HANDLE = "userHandle"; 767 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 768 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 769 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 770 private static final String ATTR_TARGET_PKG = "targetPkg"; 771 private static final String ATTR_URI = "uri"; 772 private static final String ATTR_MODE_FLAGS = "modeFlags"; 773 private static final String ATTR_CREATED_TIME = "createdTime"; 774 private static final String ATTR_PREFIX = "prefix"; 775 776 /** 777 * Global set of specific {@link Uri} permissions that have been granted. 778 * This optimized lookup structure maps from {@link UriPermission#targetUid} 779 * to {@link UriPermission#uri} to {@link UriPermission}. 780 */ 781 @GuardedBy("this") 782 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 783 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 784 785 public static class GrantUri { 786 public final int sourceUserId; 787 public final Uri uri; 788 public boolean prefix; 789 790 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 791 this.sourceUserId = sourceUserId; 792 this.uri = uri; 793 this.prefix = prefix; 794 } 795 796 @Override 797 public int hashCode() { 798 return toString().hashCode(); 799 } 800 801 @Override 802 public boolean equals(Object o) { 803 if (o instanceof GrantUri) { 804 GrantUri other = (GrantUri) o; 805 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 806 && prefix == other.prefix; 807 } 808 return false; 809 } 810 811 @Override 812 public String toString() { 813 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 814 if (prefix) result += " [prefix]"; 815 return result; 816 } 817 818 public String toSafeString() { 819 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 820 if (prefix) result += " [prefix]"; 821 return result; 822 } 823 824 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 825 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 826 ContentProvider.getUriWithoutUserId(uri), false); 827 } 828 } 829 830 CoreSettingsObserver mCoreSettingsObserver; 831 832 /** 833 * Thread-local storage used to carry caller permissions over through 834 * indirect content-provider access. 835 */ 836 private class Identity { 837 public final IBinder token; 838 public final int pid; 839 public final int uid; 840 841 Identity(IBinder _token, int _pid, int _uid) { 842 token = _token; 843 pid = _pid; 844 uid = _uid; 845 } 846 } 847 848 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 849 850 /** 851 * All information we have collected about the runtime performance of 852 * any user id that can impact battery performance. 853 */ 854 final BatteryStatsService mBatteryStatsService; 855 856 /** 857 * Information about component usage 858 */ 859 UsageStatsManagerInternal mUsageStatsService; 860 861 /** 862 * Information about and control over application operations 863 */ 864 final AppOpsService mAppOpsService; 865 866 /** 867 * Save recent tasks information across reboots. 868 */ 869 final TaskPersister mTaskPersister; 870 871 /** 872 * Current configuration information. HistoryRecord objects are given 873 * a reference to this object to indicate which configuration they are 874 * currently running in, so this object must be kept immutable. 875 */ 876 Configuration mConfiguration = new Configuration(); 877 878 /** 879 * Current sequencing integer of the configuration, for skipping old 880 * configurations. 881 */ 882 int mConfigurationSeq = 0; 883 884 /** 885 * Hardware-reported OpenGLES version. 886 */ 887 final int GL_ES_VERSION; 888 889 /** 890 * List of initialization arguments to pass to all processes when binding applications to them. 891 * For example, references to the commonly used services. 892 */ 893 HashMap<String, IBinder> mAppBindArgs; 894 895 /** 896 * Temporary to avoid allocations. Protected by main lock. 897 */ 898 final StringBuilder mStringBuilder = new StringBuilder(256); 899 900 /** 901 * Used to control how we initialize the service. 902 */ 903 ComponentName mTopComponent; 904 String mTopAction = Intent.ACTION_MAIN; 905 String mTopData; 906 boolean mProcessesReady = false; 907 boolean mSystemReady = false; 908 boolean mBooting = false; 909 boolean mCallFinishBooting = false; 910 boolean mBootAnimationComplete = false; 911 boolean mWaitingUpdate = false; 912 boolean mDidUpdate = false; 913 boolean mOnBattery = false; 914 boolean mLaunchWarningShown = false; 915 916 Context mContext; 917 918 int mFactoryTest; 919 920 boolean mCheckedForSetup; 921 922 /** 923 * The time at which we will allow normal application switches again, 924 * after a call to {@link #stopAppSwitches()}. 925 */ 926 long mAppSwitchesAllowedTime; 927 928 /** 929 * This is set to true after the first switch after mAppSwitchesAllowedTime 930 * is set; any switches after that will clear the time. 931 */ 932 boolean mDidAppSwitch; 933 934 /** 935 * Last time (in realtime) at which we checked for power usage. 936 */ 937 long mLastPowerCheckRealtime; 938 939 /** 940 * Last time (in uptime) at which we checked for power usage. 941 */ 942 long mLastPowerCheckUptime; 943 944 /** 945 * Set while we are wanting to sleep, to prevent any 946 * activities from being started/resumed. 947 */ 948 private boolean mSleeping = false; 949 950 /** 951 * Set while we are running a voice interaction. This overrides 952 * sleeping while it is active. 953 */ 954 private boolean mRunningVoice = false; 955 956 /** 957 * State of external calls telling us if the device is asleep. 958 */ 959 private boolean mWentToSleep = false; 960 961 static final int LOCK_SCREEN_HIDDEN = 0; 962 static final int LOCK_SCREEN_LEAVING = 1; 963 static final int LOCK_SCREEN_SHOWN = 2; 964 /** 965 * State of external call telling us if the lock screen is shown. 966 */ 967 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 968 969 /** 970 * Set if we are shutting down the system, similar to sleeping. 971 */ 972 boolean mShuttingDown = false; 973 974 /** 975 * Current sequence id for oom_adj computation traversal. 976 */ 977 int mAdjSeq = 0; 978 979 /** 980 * Current sequence id for process LRU updating. 981 */ 982 int mLruSeq = 0; 983 984 /** 985 * Keep track of the non-cached/empty process we last found, to help 986 * determine how to distribute cached/empty processes next time. 987 */ 988 int mNumNonCachedProcs = 0; 989 990 /** 991 * Keep track of the number of cached hidden procs, to balance oom adj 992 * distribution between those and empty procs. 993 */ 994 int mNumCachedHiddenProcs = 0; 995 996 /** 997 * Keep track of the number of service processes we last found, to 998 * determine on the next iteration which should be B services. 999 */ 1000 int mNumServiceProcs = 0; 1001 int mNewNumAServiceProcs = 0; 1002 int mNewNumServiceProcs = 0; 1003 1004 /** 1005 * Allow the current computed overall memory level of the system to go down? 1006 * This is set to false when we are killing processes for reasons other than 1007 * memory management, so that the now smaller process list will not be taken as 1008 * an indication that memory is tighter. 1009 */ 1010 boolean mAllowLowerMemLevel = false; 1011 1012 /** 1013 * The last computed memory level, for holding when we are in a state that 1014 * processes are going away for other reasons. 1015 */ 1016 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1017 1018 /** 1019 * The last total number of process we have, to determine if changes actually look 1020 * like a shrinking number of process due to lower RAM. 1021 */ 1022 int mLastNumProcesses; 1023 1024 /** 1025 * The uptime of the last time we performed idle maintenance. 1026 */ 1027 long mLastIdleTime = SystemClock.uptimeMillis(); 1028 1029 /** 1030 * Total time spent with RAM that has been added in the past since the last idle time. 1031 */ 1032 long mLowRamTimeSinceLastIdle = 0; 1033 1034 /** 1035 * If RAM is currently low, when that horrible situation started. 1036 */ 1037 long mLowRamStartTime = 0; 1038 1039 /** 1040 * For reporting to battery stats the current top application. 1041 */ 1042 private String mCurResumedPackage = null; 1043 private int mCurResumedUid = -1; 1044 1045 /** 1046 * For reporting to battery stats the apps currently running foreground 1047 * service. The ProcessMap is package/uid tuples; each of these contain 1048 * an array of the currently foreground processes. 1049 */ 1050 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1051 = new ProcessMap<ArrayList<ProcessRecord>>(); 1052 1053 /** 1054 * This is set if we had to do a delayed dexopt of an app before launching 1055 * it, to increase the ANR timeouts in that case. 1056 */ 1057 boolean mDidDexOpt; 1058 1059 /** 1060 * Set if the systemServer made a call to enterSafeMode. 1061 */ 1062 boolean mSafeMode; 1063 1064 String mDebugApp = null; 1065 boolean mWaitForDebugger = false; 1066 boolean mDebugTransient = false; 1067 String mOrigDebugApp = null; 1068 boolean mOrigWaitForDebugger = false; 1069 boolean mAlwaysFinishActivities = false; 1070 IActivityController mController = null; 1071 String mProfileApp = null; 1072 ProcessRecord mProfileProc = null; 1073 String mProfileFile; 1074 ParcelFileDescriptor mProfileFd; 1075 int mSamplingInterval = 0; 1076 boolean mAutoStopProfiler = false; 1077 int mProfileType = 0; 1078 String mOpenGlTraceApp = null; 1079 1080 static class ProcessChangeItem { 1081 static final int CHANGE_ACTIVITIES = 1<<0; 1082 static final int CHANGE_PROCESS_STATE = 1<<1; 1083 int changes; 1084 int uid; 1085 int pid; 1086 int processState; 1087 boolean foregroundActivities; 1088 } 1089 1090 final RemoteCallbackList<IProcessObserver> mProcessObservers 1091 = new RemoteCallbackList<IProcessObserver>(); 1092 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1093 1094 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1095 = new ArrayList<ProcessChangeItem>(); 1096 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1097 = new ArrayList<ProcessChangeItem>(); 1098 1099 /** 1100 * Runtime CPU use collection thread. This object's lock is used to 1101 * perform synchronization with the thread (notifying it to run). 1102 */ 1103 final Thread mProcessCpuThread; 1104 1105 /** 1106 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1107 * Must acquire this object's lock when accessing it. 1108 * NOTE: this lock will be held while doing long operations (trawling 1109 * through all processes in /proc), so it should never be acquired by 1110 * any critical paths such as when holding the main activity manager lock. 1111 */ 1112 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1113 MONITOR_THREAD_CPU_USAGE); 1114 final AtomicLong mLastCpuTime = new AtomicLong(0); 1115 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1116 1117 long mLastWriteTime = 0; 1118 1119 /** 1120 * Used to retain an update lock when the foreground activity is in 1121 * immersive mode. 1122 */ 1123 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1124 1125 /** 1126 * Set to true after the system has finished booting. 1127 */ 1128 boolean mBooted = false; 1129 1130 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1131 int mProcessLimitOverride = -1; 1132 1133 WindowManagerService mWindowManager; 1134 1135 final ActivityThread mSystemThread; 1136 1137 // Holds the current foreground user's id 1138 int mCurrentUserId = 0; 1139 // Holds the target user's id during a user switch 1140 int mTargetUserId = UserHandle.USER_NULL; 1141 // If there are multiple profiles for the current user, their ids are here 1142 // Currently only the primary user can have managed profiles 1143 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1144 1145 /** 1146 * Mapping from each known user ID to the profile group ID it is associated with. 1147 */ 1148 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1149 1150 private UserManagerService mUserManager; 1151 1152 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1153 final ProcessRecord mApp; 1154 final int mPid; 1155 final IApplicationThread mAppThread; 1156 1157 AppDeathRecipient(ProcessRecord app, int pid, 1158 IApplicationThread thread) { 1159 if (localLOGV) Slog.v( 1160 TAG, "New death recipient " + this 1161 + " for thread " + thread.asBinder()); 1162 mApp = app; 1163 mPid = pid; 1164 mAppThread = thread; 1165 } 1166 1167 @Override 1168 public void binderDied() { 1169 if (localLOGV) Slog.v( 1170 TAG, "Death received in " + this 1171 + " for thread " + mAppThread.asBinder()); 1172 synchronized(ActivityManagerService.this) { 1173 appDiedLocked(mApp, mPid, mAppThread); 1174 } 1175 } 1176 } 1177 1178 static final int SHOW_ERROR_MSG = 1; 1179 static final int SHOW_NOT_RESPONDING_MSG = 2; 1180 static final int SHOW_FACTORY_ERROR_MSG = 3; 1181 static final int UPDATE_CONFIGURATION_MSG = 4; 1182 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1183 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1184 static final int SERVICE_TIMEOUT_MSG = 12; 1185 static final int UPDATE_TIME_ZONE = 13; 1186 static final int SHOW_UID_ERROR_MSG = 14; 1187 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1188 static final int PROC_START_TIMEOUT_MSG = 20; 1189 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1190 static final int KILL_APPLICATION_MSG = 22; 1191 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1192 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1193 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1194 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1195 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1196 static final int CLEAR_DNS_CACHE_MSG = 28; 1197 static final int UPDATE_HTTP_PROXY_MSG = 29; 1198 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1199 static final int DISPATCH_PROCESSES_CHANGED = 31; 1200 static final int DISPATCH_PROCESS_DIED = 32; 1201 static final int REPORT_MEM_USAGE_MSG = 33; 1202 static final int REPORT_USER_SWITCH_MSG = 34; 1203 static final int CONTINUE_USER_SWITCH_MSG = 35; 1204 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1205 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1206 static final int PERSIST_URI_GRANTS_MSG = 38; 1207 static final int REQUEST_ALL_PSS_MSG = 39; 1208 static final int START_PROFILES_MSG = 40; 1209 static final int UPDATE_TIME = 41; 1210 static final int SYSTEM_USER_START_MSG = 42; 1211 static final int SYSTEM_USER_CURRENT_MSG = 43; 1212 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1213 static final int FINISH_BOOTING_MSG = 45; 1214 static final int START_USER_SWITCH_MSG = 46; 1215 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1216 static final int DISMISS_DIALOG_MSG = 48; 1217 1218 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1219 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1220 static final int FIRST_COMPAT_MODE_MSG = 300; 1221 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1222 1223 CompatModeDialog mCompatModeDialog; 1224 long mLastMemUsageReportTime = 0; 1225 1226 /** 1227 * Flag whether the current user is a "monkey", i.e. whether 1228 * the UI is driven by a UI automation tool. 1229 */ 1230 private boolean mUserIsMonkey; 1231 1232 /** Flag whether the device has a Recents UI */ 1233 boolean mHasRecents; 1234 1235 /** The dimensions of the thumbnails in the Recents UI. */ 1236 int mThumbnailWidth; 1237 int mThumbnailHeight; 1238 1239 final ServiceThread mHandlerThread; 1240 final MainHandler mHandler; 1241 1242 final class MainHandler extends Handler { 1243 public MainHandler(Looper looper) { 1244 super(looper, null, true); 1245 } 1246 1247 @Override 1248 public void handleMessage(Message msg) { 1249 switch (msg.what) { 1250 case SHOW_ERROR_MSG: { 1251 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1252 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1253 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1254 synchronized (ActivityManagerService.this) { 1255 ProcessRecord proc = (ProcessRecord)data.get("app"); 1256 AppErrorResult res = (AppErrorResult) data.get("result"); 1257 if (proc != null && proc.crashDialog != null) { 1258 Slog.e(TAG, "App already has crash dialog: " + proc); 1259 if (res != null) { 1260 res.set(0); 1261 } 1262 return; 1263 } 1264 boolean isBackground = (UserHandle.getAppId(proc.uid) 1265 >= Process.FIRST_APPLICATION_UID 1266 && proc.pid != MY_PID); 1267 for (int userId : mCurrentProfileIds) { 1268 isBackground &= (proc.userId != userId); 1269 } 1270 if (isBackground && !showBackground) { 1271 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1272 if (res != null) { 1273 res.set(0); 1274 } 1275 return; 1276 } 1277 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1278 Dialog d = new AppErrorDialog(mContext, 1279 ActivityManagerService.this, res, proc); 1280 d.show(); 1281 proc.crashDialog = d; 1282 } else { 1283 // The device is asleep, so just pretend that the user 1284 // saw a crash dialog and hit "force quit". 1285 if (res != null) { 1286 res.set(0); 1287 } 1288 } 1289 } 1290 1291 ensureBootCompleted(); 1292 } break; 1293 case SHOW_NOT_RESPONDING_MSG: { 1294 synchronized (ActivityManagerService.this) { 1295 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1296 ProcessRecord proc = (ProcessRecord)data.get("app"); 1297 if (proc != null && proc.anrDialog != null) { 1298 Slog.e(TAG, "App already has anr dialog: " + proc); 1299 return; 1300 } 1301 1302 Intent intent = new Intent("android.intent.action.ANR"); 1303 if (!mProcessesReady) { 1304 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1305 | Intent.FLAG_RECEIVER_FOREGROUND); 1306 } 1307 broadcastIntentLocked(null, null, intent, 1308 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1309 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1310 1311 if (mShowDialogs) { 1312 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1313 mContext, proc, (ActivityRecord)data.get("activity"), 1314 msg.arg1 != 0); 1315 d.show(); 1316 proc.anrDialog = d; 1317 } else { 1318 // Just kill the app if there is no dialog to be shown. 1319 killAppAtUsersRequest(proc, null); 1320 } 1321 } 1322 1323 ensureBootCompleted(); 1324 } break; 1325 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1326 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1327 synchronized (ActivityManagerService.this) { 1328 ProcessRecord proc = (ProcessRecord) data.get("app"); 1329 if (proc == null) { 1330 Slog.e(TAG, "App not found when showing strict mode dialog."); 1331 break; 1332 } 1333 if (proc.crashDialog != null) { 1334 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1335 return; 1336 } 1337 AppErrorResult res = (AppErrorResult) data.get("result"); 1338 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1339 Dialog d = new StrictModeViolationDialog(mContext, 1340 ActivityManagerService.this, res, proc); 1341 d.show(); 1342 proc.crashDialog = d; 1343 } else { 1344 // The device is asleep, so just pretend that the user 1345 // saw a crash dialog and hit "force quit". 1346 res.set(0); 1347 } 1348 } 1349 ensureBootCompleted(); 1350 } break; 1351 case SHOW_FACTORY_ERROR_MSG: { 1352 Dialog d = new FactoryErrorDialog( 1353 mContext, msg.getData().getCharSequence("msg")); 1354 d.show(); 1355 ensureBootCompleted(); 1356 } break; 1357 case UPDATE_CONFIGURATION_MSG: { 1358 final ContentResolver resolver = mContext.getContentResolver(); 1359 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1360 } break; 1361 case GC_BACKGROUND_PROCESSES_MSG: { 1362 synchronized (ActivityManagerService.this) { 1363 performAppGcsIfAppropriateLocked(); 1364 } 1365 } break; 1366 case WAIT_FOR_DEBUGGER_MSG: { 1367 synchronized (ActivityManagerService.this) { 1368 ProcessRecord app = (ProcessRecord)msg.obj; 1369 if (msg.arg1 != 0) { 1370 if (!app.waitedForDebugger) { 1371 Dialog d = new AppWaitingForDebuggerDialog( 1372 ActivityManagerService.this, 1373 mContext, app); 1374 app.waitDialog = d; 1375 app.waitedForDebugger = true; 1376 d.show(); 1377 } 1378 } else { 1379 if (app.waitDialog != null) { 1380 app.waitDialog.dismiss(); 1381 app.waitDialog = null; 1382 } 1383 } 1384 } 1385 } break; 1386 case SERVICE_TIMEOUT_MSG: { 1387 if (mDidDexOpt) { 1388 mDidDexOpt = false; 1389 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1390 nmsg.obj = msg.obj; 1391 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1392 return; 1393 } 1394 mServices.serviceTimeout((ProcessRecord)msg.obj); 1395 } break; 1396 case UPDATE_TIME_ZONE: { 1397 synchronized (ActivityManagerService.this) { 1398 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1399 ProcessRecord r = mLruProcesses.get(i); 1400 if (r.thread != null) { 1401 try { 1402 r.thread.updateTimeZone(); 1403 } catch (RemoteException ex) { 1404 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1405 } 1406 } 1407 } 1408 } 1409 } break; 1410 case CLEAR_DNS_CACHE_MSG: { 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.clearDnsCache(); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case UPDATE_HTTP_PROXY_MSG: { 1425 ProxyInfo proxy = (ProxyInfo)msg.obj; 1426 String host = ""; 1427 String port = ""; 1428 String exclList = ""; 1429 Uri pacFileUrl = Uri.EMPTY; 1430 if (proxy != null) { 1431 host = proxy.getHost(); 1432 port = Integer.toString(proxy.getPort()); 1433 exclList = proxy.getExclusionListAsString(); 1434 pacFileUrl = proxy.getPacFileUrl(); 1435 } 1436 synchronized (ActivityManagerService.this) { 1437 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1438 ProcessRecord r = mLruProcesses.get(i); 1439 if (r.thread != null) { 1440 try { 1441 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1442 } catch (RemoteException ex) { 1443 Slog.w(TAG, "Failed to update http proxy for: " + 1444 r.info.processName); 1445 } 1446 } 1447 } 1448 } 1449 } break; 1450 case SHOW_UID_ERROR_MSG: { 1451 if (mShowDialogs) { 1452 AlertDialog d = new BaseErrorDialog(mContext); 1453 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1454 d.setCancelable(false); 1455 d.setTitle(mContext.getText(R.string.android_system_label)); 1456 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1457 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1458 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1459 d.show(); 1460 } 1461 } break; 1462 case SHOW_FINGERPRINT_ERROR_MSG: { 1463 if (mShowDialogs) { 1464 AlertDialog d = new BaseErrorDialog(mContext); 1465 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1466 d.setCancelable(false); 1467 d.setTitle(mContext.getText(R.string.android_system_label)); 1468 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1469 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1470 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1471 d.show(); 1472 } 1473 } break; 1474 case PROC_START_TIMEOUT_MSG: { 1475 if (mDidDexOpt) { 1476 mDidDexOpt = false; 1477 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1478 nmsg.obj = msg.obj; 1479 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1480 return; 1481 } 1482 ProcessRecord app = (ProcessRecord)msg.obj; 1483 synchronized (ActivityManagerService.this) { 1484 processStartTimedOutLocked(app); 1485 } 1486 } break; 1487 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1488 synchronized (ActivityManagerService.this) { 1489 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1490 } 1491 } break; 1492 case KILL_APPLICATION_MSG: { 1493 synchronized (ActivityManagerService.this) { 1494 int appid = msg.arg1; 1495 boolean restart = (msg.arg2 == 1); 1496 Bundle bundle = (Bundle)msg.obj; 1497 String pkg = bundle.getString("pkg"); 1498 String reason = bundle.getString("reason"); 1499 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1500 false, UserHandle.USER_ALL, reason); 1501 } 1502 } break; 1503 case FINALIZE_PENDING_INTENT_MSG: { 1504 ((PendingIntentRecord)msg.obj).completeFinalize(); 1505 } break; 1506 case POST_HEAVY_NOTIFICATION_MSG: { 1507 INotificationManager inm = NotificationManager.getService(); 1508 if (inm == null) { 1509 return; 1510 } 1511 1512 ActivityRecord root = (ActivityRecord)msg.obj; 1513 ProcessRecord process = root.app; 1514 if (process == null) { 1515 return; 1516 } 1517 1518 try { 1519 Context context = mContext.createPackageContext(process.info.packageName, 0); 1520 String text = mContext.getString(R.string.heavy_weight_notification, 1521 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1522 Notification notification = new Notification(); 1523 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1524 notification.when = 0; 1525 notification.flags = Notification.FLAG_ONGOING_EVENT; 1526 notification.tickerText = text; 1527 notification.defaults = 0; // please be quiet 1528 notification.sound = null; 1529 notification.vibrate = null; 1530 notification.color = mContext.getResources().getColor( 1531 com.android.internal.R.color.system_notification_accent_color); 1532 notification.setLatestEventInfo(context, text, 1533 mContext.getText(R.string.heavy_weight_notification_detail), 1534 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1535 PendingIntent.FLAG_CANCEL_CURRENT, null, 1536 new UserHandle(root.userId))); 1537 1538 try { 1539 int[] outId = new int[1]; 1540 inm.enqueueNotificationWithTag("android", "android", null, 1541 R.string.heavy_weight_notification, 1542 notification, outId, root.userId); 1543 } catch (RuntimeException e) { 1544 Slog.w(ActivityManagerService.TAG, 1545 "Error showing notification for heavy-weight app", e); 1546 } catch (RemoteException e) { 1547 } 1548 } catch (NameNotFoundException e) { 1549 Slog.w(TAG, "Unable to create context for heavy notification", e); 1550 } 1551 } break; 1552 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1553 INotificationManager inm = NotificationManager.getService(); 1554 if (inm == null) { 1555 return; 1556 } 1557 try { 1558 inm.cancelNotificationWithTag("android", null, 1559 R.string.heavy_weight_notification, msg.arg1); 1560 } catch (RuntimeException e) { 1561 Slog.w(ActivityManagerService.TAG, 1562 "Error canceling notification for service", e); 1563 } catch (RemoteException e) { 1564 } 1565 } break; 1566 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1567 synchronized (ActivityManagerService.this) { 1568 checkExcessivePowerUsageLocked(true); 1569 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1570 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1571 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1572 } 1573 } break; 1574 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1575 synchronized (ActivityManagerService.this) { 1576 ActivityRecord ar = (ActivityRecord)msg.obj; 1577 if (mCompatModeDialog != null) { 1578 if (mCompatModeDialog.mAppInfo.packageName.equals( 1579 ar.info.applicationInfo.packageName)) { 1580 return; 1581 } 1582 mCompatModeDialog.dismiss(); 1583 mCompatModeDialog = null; 1584 } 1585 if (ar != null && false) { 1586 if (mCompatModePackages.getPackageAskCompatModeLocked( 1587 ar.packageName)) { 1588 int mode = mCompatModePackages.computeCompatModeLocked( 1589 ar.info.applicationInfo); 1590 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1591 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1592 mCompatModeDialog = new CompatModeDialog( 1593 ActivityManagerService.this, mContext, 1594 ar.info.applicationInfo); 1595 mCompatModeDialog.show(); 1596 } 1597 } 1598 } 1599 } 1600 break; 1601 } 1602 case DISPATCH_PROCESSES_CHANGED: { 1603 dispatchProcessesChanged(); 1604 break; 1605 } 1606 case DISPATCH_PROCESS_DIED: { 1607 final int pid = msg.arg1; 1608 final int uid = msg.arg2; 1609 dispatchProcessDied(pid, uid); 1610 break; 1611 } 1612 case REPORT_MEM_USAGE_MSG: { 1613 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1614 Thread thread = new Thread() { 1615 @Override public void run() { 1616 reportMemUsage(memInfos); 1617 } 1618 }; 1619 thread.start(); 1620 break; 1621 } 1622 case START_USER_SWITCH_MSG: { 1623 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1624 break; 1625 } 1626 case REPORT_USER_SWITCH_MSG: { 1627 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1628 break; 1629 } 1630 case CONTINUE_USER_SWITCH_MSG: { 1631 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1632 break; 1633 } 1634 case USER_SWITCH_TIMEOUT_MSG: { 1635 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1636 break; 1637 } 1638 case IMMERSIVE_MODE_LOCK_MSG: { 1639 final boolean nextState = (msg.arg1 != 0); 1640 if (mUpdateLock.isHeld() != nextState) { 1641 if (DEBUG_IMMERSIVE) { 1642 final ActivityRecord r = (ActivityRecord) msg.obj; 1643 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1644 } 1645 if (nextState) { 1646 mUpdateLock.acquire(); 1647 } else { 1648 mUpdateLock.release(); 1649 } 1650 } 1651 break; 1652 } 1653 case PERSIST_URI_GRANTS_MSG: { 1654 writeGrantedUriPermissions(); 1655 break; 1656 } 1657 case REQUEST_ALL_PSS_MSG: { 1658 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1659 break; 1660 } 1661 case START_PROFILES_MSG: { 1662 synchronized (ActivityManagerService.this) { 1663 startProfilesLocked(); 1664 } 1665 break; 1666 } 1667 case UPDATE_TIME: { 1668 synchronized (ActivityManagerService.this) { 1669 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1670 ProcessRecord r = mLruProcesses.get(i); 1671 if (r.thread != null) { 1672 try { 1673 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1674 } catch (RemoteException ex) { 1675 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1676 } 1677 } 1678 } 1679 } 1680 break; 1681 } 1682 case SYSTEM_USER_START_MSG: { 1683 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1684 Integer.toString(msg.arg1), msg.arg1); 1685 mSystemServiceManager.startUser(msg.arg1); 1686 break; 1687 } 1688 case SYSTEM_USER_CURRENT_MSG: { 1689 mBatteryStatsService.noteEvent( 1690 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1691 Integer.toString(msg.arg2), msg.arg2); 1692 mBatteryStatsService.noteEvent( 1693 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1694 Integer.toString(msg.arg1), msg.arg1); 1695 mSystemServiceManager.switchUser(msg.arg1); 1696 break; 1697 } 1698 case ENTER_ANIMATION_COMPLETE_MSG: { 1699 synchronized (ActivityManagerService.this) { 1700 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1701 if (r != null && r.app != null && r.app.thread != null) { 1702 try { 1703 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1704 } catch (RemoteException e) { 1705 } 1706 } 1707 } 1708 break; 1709 } 1710 case FINISH_BOOTING_MSG: { 1711 if (msg.arg1 != 0) { 1712 finishBooting(); 1713 } 1714 if (msg.arg2 != 0) { 1715 enableScreenAfterBoot(); 1716 } 1717 break; 1718 } 1719 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1720 try { 1721 Locale l = (Locale) msg.obj; 1722 IBinder service = ServiceManager.getService("mount"); 1723 IMountService mountService = IMountService.Stub.asInterface(service); 1724 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1725 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1726 } catch (RemoteException e) { 1727 Log.e(TAG, "Error storing locale for decryption UI", e); 1728 } 1729 break; 1730 } 1731 case DISMISS_DIALOG_MSG: { 1732 final Dialog d = (Dialog) msg.obj; 1733 d.dismiss(); 1734 break; 1735 } 1736 } 1737 } 1738 }; 1739 1740 static final int COLLECT_PSS_BG_MSG = 1; 1741 1742 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1743 @Override 1744 public void handleMessage(Message msg) { 1745 switch (msg.what) { 1746 case COLLECT_PSS_BG_MSG: { 1747 long start = SystemClock.uptimeMillis(); 1748 MemInfoReader memInfo = null; 1749 synchronized (ActivityManagerService.this) { 1750 if (mFullPssPending) { 1751 mFullPssPending = false; 1752 memInfo = new MemInfoReader(); 1753 } 1754 } 1755 if (memInfo != null) { 1756 updateCpuStatsNow(); 1757 long nativeTotalPss = 0; 1758 synchronized (mProcessCpuTracker) { 1759 final int N = mProcessCpuTracker.countStats(); 1760 for (int j=0; j<N; j++) { 1761 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1762 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1763 // This is definitely an application process; skip it. 1764 continue; 1765 } 1766 synchronized (mPidsSelfLocked) { 1767 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1768 // This is one of our own processes; skip it. 1769 continue; 1770 } 1771 } 1772 nativeTotalPss += Debug.getPss(st.pid, null); 1773 } 1774 } 1775 memInfo.readMemInfo(); 1776 synchronized (ActivityManagerService.this) { 1777 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1778 + (SystemClock.uptimeMillis()-start) + "ms"); 1779 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1780 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1781 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1782 } 1783 } 1784 1785 int i = 0; 1786 int num = 0; 1787 long[] tmp = new long[1]; 1788 do { 1789 ProcessRecord proc; 1790 int procState; 1791 int pid; 1792 synchronized (ActivityManagerService.this) { 1793 if (i >= mPendingPssProcesses.size()) { 1794 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1795 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1796 mPendingPssProcesses.clear(); 1797 return; 1798 } 1799 proc = mPendingPssProcesses.get(i); 1800 procState = proc.pssProcState; 1801 if (proc.thread != null && procState == proc.setProcState) { 1802 pid = proc.pid; 1803 } else { 1804 proc = null; 1805 pid = 0; 1806 } 1807 i++; 1808 } 1809 if (proc != null) { 1810 long pss = Debug.getPss(pid, tmp); 1811 synchronized (ActivityManagerService.this) { 1812 if (proc.thread != null && proc.setProcState == procState 1813 && proc.pid == pid) { 1814 num++; 1815 proc.lastPssTime = SystemClock.uptimeMillis(); 1816 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1817 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1818 + ": " + pss + " lastPss=" + proc.lastPss 1819 + " state=" + ProcessList.makeProcStateString(procState)); 1820 if (proc.initialIdlePss == 0) { 1821 proc.initialIdlePss = pss; 1822 } 1823 proc.lastPss = pss; 1824 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1825 proc.lastCachedPss = pss; 1826 } 1827 } 1828 } 1829 } 1830 } while (true); 1831 } 1832 } 1833 } 1834 }; 1835 1836 public void setSystemProcess() { 1837 try { 1838 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1839 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1840 ServiceManager.addService("meminfo", new MemBinder(this)); 1841 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1842 ServiceManager.addService("dbinfo", new DbBinder(this)); 1843 if (MONITOR_CPU_USAGE) { 1844 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1845 } 1846 ServiceManager.addService("permission", new PermissionController(this)); 1847 1848 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1849 "android", STOCK_PM_FLAGS); 1850 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1851 1852 synchronized (this) { 1853 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1854 app.persistent = true; 1855 app.pid = MY_PID; 1856 app.maxAdj = ProcessList.SYSTEM_ADJ; 1857 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1858 mProcessNames.put(app.processName, app.uid, app); 1859 synchronized (mPidsSelfLocked) { 1860 mPidsSelfLocked.put(app.pid, app); 1861 } 1862 updateLruProcessLocked(app, false, null); 1863 updateOomAdjLocked(); 1864 } 1865 } catch (PackageManager.NameNotFoundException e) { 1866 throw new RuntimeException( 1867 "Unable to find android system package", e); 1868 } 1869 } 1870 1871 public void setWindowManager(WindowManagerService wm) { 1872 mWindowManager = wm; 1873 mStackSupervisor.setWindowManager(wm); 1874 } 1875 1876 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1877 mUsageStatsService = usageStatsManager; 1878 } 1879 1880 public void startObservingNativeCrashes() { 1881 final NativeCrashListener ncl = new NativeCrashListener(this); 1882 ncl.start(); 1883 } 1884 1885 public IAppOpsService getAppOpsService() { 1886 return mAppOpsService; 1887 } 1888 1889 static class MemBinder extends Binder { 1890 ActivityManagerService mActivityManagerService; 1891 MemBinder(ActivityManagerService activityManagerService) { 1892 mActivityManagerService = activityManagerService; 1893 } 1894 1895 @Override 1896 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1897 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1898 != PackageManager.PERMISSION_GRANTED) { 1899 pw.println("Permission Denial: can't dump meminfo from from pid=" 1900 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1901 + " without permission " + android.Manifest.permission.DUMP); 1902 return; 1903 } 1904 1905 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1906 } 1907 } 1908 1909 static class GraphicsBinder extends Binder { 1910 ActivityManagerService mActivityManagerService; 1911 GraphicsBinder(ActivityManagerService activityManagerService) { 1912 mActivityManagerService = activityManagerService; 1913 } 1914 1915 @Override 1916 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1917 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1918 != PackageManager.PERMISSION_GRANTED) { 1919 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1920 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1921 + " without permission " + android.Manifest.permission.DUMP); 1922 return; 1923 } 1924 1925 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1926 } 1927 } 1928 1929 static class DbBinder extends Binder { 1930 ActivityManagerService mActivityManagerService; 1931 DbBinder(ActivityManagerService activityManagerService) { 1932 mActivityManagerService = activityManagerService; 1933 } 1934 1935 @Override 1936 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1937 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1938 != PackageManager.PERMISSION_GRANTED) { 1939 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1940 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1941 + " without permission " + android.Manifest.permission.DUMP); 1942 return; 1943 } 1944 1945 mActivityManagerService.dumpDbInfo(fd, pw, args); 1946 } 1947 } 1948 1949 static class CpuBinder extends Binder { 1950 ActivityManagerService mActivityManagerService; 1951 CpuBinder(ActivityManagerService activityManagerService) { 1952 mActivityManagerService = activityManagerService; 1953 } 1954 1955 @Override 1956 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1957 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1958 != PackageManager.PERMISSION_GRANTED) { 1959 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1960 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1961 + " without permission " + android.Manifest.permission.DUMP); 1962 return; 1963 } 1964 1965 synchronized (mActivityManagerService.mProcessCpuTracker) { 1966 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1967 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1968 SystemClock.uptimeMillis())); 1969 } 1970 } 1971 } 1972 1973 public static final class Lifecycle extends SystemService { 1974 private final ActivityManagerService mService; 1975 1976 public Lifecycle(Context context) { 1977 super(context); 1978 mService = new ActivityManagerService(context); 1979 } 1980 1981 @Override 1982 public void onStart() { 1983 mService.start(); 1984 } 1985 1986 public ActivityManagerService getService() { 1987 return mService; 1988 } 1989 } 1990 1991 // Note: This method is invoked on the main thread but may need to attach various 1992 // handlers to other threads. So take care to be explicit about the looper. 1993 public ActivityManagerService(Context systemContext) { 1994 mContext = systemContext; 1995 mFactoryTest = FactoryTest.getMode(); 1996 mSystemThread = ActivityThread.currentActivityThread(); 1997 1998 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1999 2000 mHandlerThread = new ServiceThread(TAG, 2001 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2002 mHandlerThread.start(); 2003 mHandler = new MainHandler(mHandlerThread.getLooper()); 2004 2005 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2006 "foreground", BROADCAST_FG_TIMEOUT, false); 2007 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2008 "background", BROADCAST_BG_TIMEOUT, true); 2009 mBroadcastQueues[0] = mFgBroadcastQueue; 2010 mBroadcastQueues[1] = mBgBroadcastQueue; 2011 2012 mServices = new ActiveServices(this); 2013 mProviderMap = new ProviderMap(this); 2014 2015 // TODO: Move creation of battery stats service outside of activity manager service. 2016 File dataDir = Environment.getDataDirectory(); 2017 File systemDir = new File(dataDir, "system"); 2018 systemDir.mkdirs(); 2019 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2020 mBatteryStatsService.getActiveStatistics().readLocked(); 2021 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2022 mOnBattery = DEBUG_POWER ? true 2023 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2024 mBatteryStatsService.getActiveStatistics().setCallback(this); 2025 2026 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2027 2028 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2029 2030 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2031 2032 // User 0 is the first and only user that runs at boot. 2033 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2034 mUserLru.add(Integer.valueOf(0)); 2035 updateStartedUserArrayLocked(); 2036 2037 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2038 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2039 2040 mConfiguration.setToDefaults(); 2041 mConfiguration.setLocale(Locale.getDefault()); 2042 2043 mConfigurationSeq = mConfiguration.seq = 1; 2044 mProcessCpuTracker.init(); 2045 2046 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2047 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2048 mStackSupervisor = new ActivityStackSupervisor(this); 2049 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2050 2051 mProcessCpuThread = new Thread("CpuTracker") { 2052 @Override 2053 public void run() { 2054 while (true) { 2055 try { 2056 try { 2057 synchronized(this) { 2058 final long now = SystemClock.uptimeMillis(); 2059 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2060 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2061 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2062 // + ", write delay=" + nextWriteDelay); 2063 if (nextWriteDelay < nextCpuDelay) { 2064 nextCpuDelay = nextWriteDelay; 2065 } 2066 if (nextCpuDelay > 0) { 2067 mProcessCpuMutexFree.set(true); 2068 this.wait(nextCpuDelay); 2069 } 2070 } 2071 } catch (InterruptedException e) { 2072 } 2073 updateCpuStatsNow(); 2074 } catch (Exception e) { 2075 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2076 } 2077 } 2078 } 2079 }; 2080 2081 Watchdog.getInstance().addMonitor(this); 2082 Watchdog.getInstance().addThread(mHandler); 2083 } 2084 2085 public void setSystemServiceManager(SystemServiceManager mgr) { 2086 mSystemServiceManager = mgr; 2087 } 2088 2089 public void setInstaller(Installer installer) { 2090 mInstaller = installer; 2091 } 2092 2093 private void start() { 2094 Process.removeAllProcessGroups(); 2095 mProcessCpuThread.start(); 2096 2097 mBatteryStatsService.publish(mContext); 2098 mAppOpsService.publish(mContext); 2099 Slog.d("AppOps", "AppOpsService published"); 2100 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2101 } 2102 2103 public void initPowerManagement() { 2104 mStackSupervisor.initPowerManagement(); 2105 mBatteryStatsService.initPowerManagement(); 2106 } 2107 2108 @Override 2109 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2110 throws RemoteException { 2111 if (code == SYSPROPS_TRANSACTION) { 2112 // We need to tell all apps about the system property change. 2113 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2114 synchronized(this) { 2115 final int NP = mProcessNames.getMap().size(); 2116 for (int ip=0; ip<NP; ip++) { 2117 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2118 final int NA = apps.size(); 2119 for (int ia=0; ia<NA; ia++) { 2120 ProcessRecord app = apps.valueAt(ia); 2121 if (app.thread != null) { 2122 procs.add(app.thread.asBinder()); 2123 } 2124 } 2125 } 2126 } 2127 2128 int N = procs.size(); 2129 for (int i=0; i<N; i++) { 2130 Parcel data2 = Parcel.obtain(); 2131 try { 2132 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2133 } catch (RemoteException e) { 2134 } 2135 data2.recycle(); 2136 } 2137 } 2138 try { 2139 return super.onTransact(code, data, reply, flags); 2140 } catch (RuntimeException e) { 2141 // The activity manager only throws security exceptions, so let's 2142 // log all others. 2143 if (!(e instanceof SecurityException)) { 2144 Slog.wtf(TAG, "Activity Manager Crash", e); 2145 } 2146 throw e; 2147 } 2148 } 2149 2150 void updateCpuStats() { 2151 final long now = SystemClock.uptimeMillis(); 2152 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2153 return; 2154 } 2155 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2156 synchronized (mProcessCpuThread) { 2157 mProcessCpuThread.notify(); 2158 } 2159 } 2160 } 2161 2162 void updateCpuStatsNow() { 2163 synchronized (mProcessCpuTracker) { 2164 mProcessCpuMutexFree.set(false); 2165 final long now = SystemClock.uptimeMillis(); 2166 boolean haveNewCpuStats = false; 2167 2168 if (MONITOR_CPU_USAGE && 2169 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2170 mLastCpuTime.set(now); 2171 haveNewCpuStats = true; 2172 mProcessCpuTracker.update(); 2173 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2174 //Slog.i(TAG, "Total CPU usage: " 2175 // + mProcessCpu.getTotalCpuPercent() + "%"); 2176 2177 // Slog the cpu usage if the property is set. 2178 if ("true".equals(SystemProperties.get("events.cpu"))) { 2179 int user = mProcessCpuTracker.getLastUserTime(); 2180 int system = mProcessCpuTracker.getLastSystemTime(); 2181 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2182 int irq = mProcessCpuTracker.getLastIrqTime(); 2183 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2184 int idle = mProcessCpuTracker.getLastIdleTime(); 2185 2186 int total = user + system + iowait + irq + softIrq + idle; 2187 if (total == 0) total = 1; 2188 2189 EventLog.writeEvent(EventLogTags.CPU, 2190 ((user+system+iowait+irq+softIrq) * 100) / total, 2191 (user * 100) / total, 2192 (system * 100) / total, 2193 (iowait * 100) / total, 2194 (irq * 100) / total, 2195 (softIrq * 100) / total); 2196 } 2197 } 2198 2199 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2200 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2201 synchronized(bstats) { 2202 synchronized(mPidsSelfLocked) { 2203 if (haveNewCpuStats) { 2204 if (mOnBattery) { 2205 int perc = bstats.startAddingCpuLocked(); 2206 int totalUTime = 0; 2207 int totalSTime = 0; 2208 final int N = mProcessCpuTracker.countStats(); 2209 for (int i=0; i<N; i++) { 2210 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2211 if (!st.working) { 2212 continue; 2213 } 2214 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2215 int otherUTime = (st.rel_utime*perc)/100; 2216 int otherSTime = (st.rel_stime*perc)/100; 2217 totalUTime += otherUTime; 2218 totalSTime += otherSTime; 2219 if (pr != null) { 2220 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2221 if (ps == null || !ps.isActive()) { 2222 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2223 pr.info.uid, pr.processName); 2224 } 2225 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2226 st.rel_stime-otherSTime); 2227 ps.addSpeedStepTimes(cpuSpeedTimes); 2228 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2229 } else { 2230 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2231 if (ps == null || !ps.isActive()) { 2232 st.batteryStats = ps = bstats.getProcessStatsLocked( 2233 bstats.mapUid(st.uid), st.name); 2234 } 2235 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2236 st.rel_stime-otherSTime); 2237 ps.addSpeedStepTimes(cpuSpeedTimes); 2238 } 2239 } 2240 bstats.finishAddingCpuLocked(perc, totalUTime, 2241 totalSTime, cpuSpeedTimes); 2242 } 2243 } 2244 } 2245 2246 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2247 mLastWriteTime = now; 2248 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2249 } 2250 } 2251 } 2252 } 2253 2254 @Override 2255 public void batteryNeedsCpuUpdate() { 2256 updateCpuStatsNow(); 2257 } 2258 2259 @Override 2260 public void batteryPowerChanged(boolean onBattery) { 2261 // When plugging in, update the CPU stats first before changing 2262 // the plug state. 2263 updateCpuStatsNow(); 2264 synchronized (this) { 2265 synchronized(mPidsSelfLocked) { 2266 mOnBattery = DEBUG_POWER ? true : onBattery; 2267 } 2268 } 2269 } 2270 2271 /** 2272 * Initialize the application bind args. These are passed to each 2273 * process when the bindApplication() IPC is sent to the process. They're 2274 * lazily setup to make sure the services are running when they're asked for. 2275 */ 2276 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2277 if (mAppBindArgs == null) { 2278 mAppBindArgs = new HashMap<>(); 2279 2280 // Isolated processes won't get this optimization, so that we don't 2281 // violate the rules about which services they have access to. 2282 if (!isolated) { 2283 // Setup the application init args 2284 mAppBindArgs.put("package", ServiceManager.getService("package")); 2285 mAppBindArgs.put("window", ServiceManager.getService("window")); 2286 mAppBindArgs.put(Context.ALARM_SERVICE, 2287 ServiceManager.getService(Context.ALARM_SERVICE)); 2288 } 2289 } 2290 return mAppBindArgs; 2291 } 2292 2293 final void setFocusedActivityLocked(ActivityRecord r) { 2294 if (mFocusedActivity != r) { 2295 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2296 mFocusedActivity = r; 2297 if (r.task != null && r.task.voiceInteractor != null) { 2298 startRunningVoiceLocked(); 2299 } else { 2300 finishRunningVoiceLocked(); 2301 } 2302 mStackSupervisor.setFocusedStack(r); 2303 if (r != null) { 2304 mWindowManager.setFocusedApp(r.appToken, true); 2305 } 2306 applyUpdateLockStateLocked(r); 2307 } 2308 } 2309 2310 final void clearFocusedActivity(ActivityRecord r) { 2311 if (mFocusedActivity == r) { 2312 mFocusedActivity = null; 2313 } 2314 } 2315 2316 @Override 2317 public void setFocusedStack(int stackId) { 2318 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2319 synchronized (ActivityManagerService.this) { 2320 ActivityStack stack = mStackSupervisor.getStack(stackId); 2321 if (stack != null) { 2322 ActivityRecord r = stack.topRunningActivityLocked(null); 2323 if (r != null) { 2324 setFocusedActivityLocked(r); 2325 } 2326 } 2327 } 2328 } 2329 2330 @Override 2331 public void notifyActivityDrawn(IBinder token) { 2332 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2333 synchronized (this) { 2334 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2335 if (r != null) { 2336 r.task.stack.notifyActivityDrawnLocked(r); 2337 } 2338 } 2339 } 2340 2341 final void applyUpdateLockStateLocked(ActivityRecord r) { 2342 // Modifications to the UpdateLock state are done on our handler, outside 2343 // the activity manager's locks. The new state is determined based on the 2344 // state *now* of the relevant activity record. The object is passed to 2345 // the handler solely for logging detail, not to be consulted/modified. 2346 final boolean nextState = r != null && r.immersive; 2347 mHandler.sendMessage( 2348 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2349 } 2350 2351 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2352 Message msg = Message.obtain(); 2353 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2354 msg.obj = r.task.askedCompatMode ? null : r; 2355 mHandler.sendMessage(msg); 2356 } 2357 2358 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2359 String what, Object obj, ProcessRecord srcApp) { 2360 app.lastActivityTime = now; 2361 2362 if (app.activities.size() > 0) { 2363 // Don't want to touch dependent processes that are hosting activities. 2364 return index; 2365 } 2366 2367 int lrui = mLruProcesses.lastIndexOf(app); 2368 if (lrui < 0) { 2369 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2370 + what + " " + obj + " from " + srcApp); 2371 return index; 2372 } 2373 2374 if (lrui >= index) { 2375 // Don't want to cause this to move dependent processes *back* in the 2376 // list as if they were less frequently used. 2377 return index; 2378 } 2379 2380 if (lrui >= mLruProcessActivityStart) { 2381 // Don't want to touch dependent processes that are hosting activities. 2382 return index; 2383 } 2384 2385 mLruProcesses.remove(lrui); 2386 if (index > 0) { 2387 index--; 2388 } 2389 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2390 + " in LRU list: " + app); 2391 mLruProcesses.add(index, app); 2392 return index; 2393 } 2394 2395 final void removeLruProcessLocked(ProcessRecord app) { 2396 int lrui = mLruProcesses.lastIndexOf(app); 2397 if (lrui >= 0) { 2398 if (!app.killed) { 2399 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2400 Process.killProcessQuiet(app.pid); 2401 Process.killProcessGroup(app.info.uid, app.pid); 2402 } 2403 if (lrui <= mLruProcessActivityStart) { 2404 mLruProcessActivityStart--; 2405 } 2406 if (lrui <= mLruProcessServiceStart) { 2407 mLruProcessServiceStart--; 2408 } 2409 mLruProcesses.remove(lrui); 2410 } 2411 } 2412 2413 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2414 ProcessRecord client) { 2415 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2416 || app.treatLikeActivity; 2417 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2418 if (!activityChange && hasActivity) { 2419 // The process has activities, so we are only allowing activity-based adjustments 2420 // to move it. It should be kept in the front of the list with other 2421 // processes that have activities, and we don't want those to change their 2422 // order except due to activity operations. 2423 return; 2424 } 2425 2426 mLruSeq++; 2427 final long now = SystemClock.uptimeMillis(); 2428 app.lastActivityTime = now; 2429 2430 // First a quick reject: if the app is already at the position we will 2431 // put it, then there is nothing to do. 2432 if (hasActivity) { 2433 final int N = mLruProcesses.size(); 2434 if (N > 0 && mLruProcesses.get(N-1) == app) { 2435 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2436 return; 2437 } 2438 } else { 2439 if (mLruProcessServiceStart > 0 2440 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2441 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2442 return; 2443 } 2444 } 2445 2446 int lrui = mLruProcesses.lastIndexOf(app); 2447 2448 if (app.persistent && lrui >= 0) { 2449 // We don't care about the position of persistent processes, as long as 2450 // they are in the list. 2451 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2452 return; 2453 } 2454 2455 /* In progress: compute new position first, so we can avoid doing work 2456 if the process is not actually going to move. Not yet working. 2457 int addIndex; 2458 int nextIndex; 2459 boolean inActivity = false, inService = false; 2460 if (hasActivity) { 2461 // Process has activities, put it at the very tipsy-top. 2462 addIndex = mLruProcesses.size(); 2463 nextIndex = mLruProcessServiceStart; 2464 inActivity = true; 2465 } else if (hasService) { 2466 // Process has services, put it at the top of the service list. 2467 addIndex = mLruProcessActivityStart; 2468 nextIndex = mLruProcessServiceStart; 2469 inActivity = true; 2470 inService = true; 2471 } else { 2472 // Process not otherwise of interest, it goes to the top of the non-service area. 2473 addIndex = mLruProcessServiceStart; 2474 if (client != null) { 2475 int clientIndex = mLruProcesses.lastIndexOf(client); 2476 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2477 + app); 2478 if (clientIndex >= 0 && addIndex > clientIndex) { 2479 addIndex = clientIndex; 2480 } 2481 } 2482 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2483 } 2484 2485 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2486 + mLruProcessActivityStart + "): " + app); 2487 */ 2488 2489 if (lrui >= 0) { 2490 if (lrui < mLruProcessActivityStart) { 2491 mLruProcessActivityStart--; 2492 } 2493 if (lrui < mLruProcessServiceStart) { 2494 mLruProcessServiceStart--; 2495 } 2496 /* 2497 if (addIndex > lrui) { 2498 addIndex--; 2499 } 2500 if (nextIndex > lrui) { 2501 nextIndex--; 2502 } 2503 */ 2504 mLruProcesses.remove(lrui); 2505 } 2506 2507 /* 2508 mLruProcesses.add(addIndex, app); 2509 if (inActivity) { 2510 mLruProcessActivityStart++; 2511 } 2512 if (inService) { 2513 mLruProcessActivityStart++; 2514 } 2515 */ 2516 2517 int nextIndex; 2518 if (hasActivity) { 2519 final int N = mLruProcesses.size(); 2520 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2521 // Process doesn't have activities, but has clients with 2522 // activities... move it up, but one below the top (the top 2523 // should always have a real activity). 2524 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2525 mLruProcesses.add(N-1, app); 2526 // To keep it from spamming the LRU list (by making a bunch of clients), 2527 // we will push down any other entries owned by the app. 2528 final int uid = app.info.uid; 2529 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2530 ProcessRecord subProc = mLruProcesses.get(i); 2531 if (subProc.info.uid == uid) { 2532 // We want to push this one down the list. If the process after 2533 // it is for the same uid, however, don't do so, because we don't 2534 // want them internally to be re-ordered. 2535 if (mLruProcesses.get(i-1).info.uid != uid) { 2536 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2537 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2538 ProcessRecord tmp = mLruProcesses.get(i); 2539 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2540 mLruProcesses.set(i-1, tmp); 2541 i--; 2542 } 2543 } else { 2544 // A gap, we can stop here. 2545 break; 2546 } 2547 } 2548 } else { 2549 // Process has activities, put it at the very tipsy-top. 2550 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2551 mLruProcesses.add(app); 2552 } 2553 nextIndex = mLruProcessServiceStart; 2554 } else if (hasService) { 2555 // Process has services, put it at the top of the service list. 2556 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2557 mLruProcesses.add(mLruProcessActivityStart, app); 2558 nextIndex = mLruProcessServiceStart; 2559 mLruProcessActivityStart++; 2560 } else { 2561 // Process not otherwise of interest, it goes to the top of the non-service area. 2562 int index = mLruProcessServiceStart; 2563 if (client != null) { 2564 // If there is a client, don't allow the process to be moved up higher 2565 // in the list than that client. 2566 int clientIndex = mLruProcesses.lastIndexOf(client); 2567 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2568 + " when updating " + app); 2569 if (clientIndex <= lrui) { 2570 // Don't allow the client index restriction to push it down farther in the 2571 // list than it already is. 2572 clientIndex = lrui; 2573 } 2574 if (clientIndex >= 0 && index > clientIndex) { 2575 index = clientIndex; 2576 } 2577 } 2578 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2579 mLruProcesses.add(index, app); 2580 nextIndex = index-1; 2581 mLruProcessActivityStart++; 2582 mLruProcessServiceStart++; 2583 } 2584 2585 // If the app is currently using a content provider or service, 2586 // bump those processes as well. 2587 for (int j=app.connections.size()-1; j>=0; j--) { 2588 ConnectionRecord cr = app.connections.valueAt(j); 2589 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2590 && cr.binding.service.app != null 2591 && cr.binding.service.app.lruSeq != mLruSeq 2592 && !cr.binding.service.app.persistent) { 2593 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2594 "service connection", cr, app); 2595 } 2596 } 2597 for (int j=app.conProviders.size()-1; j>=0; j--) { 2598 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2599 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2600 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2601 "provider reference", cpr, app); 2602 } 2603 } 2604 } 2605 2606 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2607 if (uid == Process.SYSTEM_UID) { 2608 // The system gets to run in any process. If there are multiple 2609 // processes with the same uid, just pick the first (this 2610 // should never happen). 2611 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2612 if (procs == null) return null; 2613 final int N = procs.size(); 2614 for (int i = 0; i < N; i++) { 2615 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2616 } 2617 } 2618 ProcessRecord proc = mProcessNames.get(processName, uid); 2619 if (false && proc != null && !keepIfLarge 2620 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2621 && proc.lastCachedPss >= 4000) { 2622 // Turn this condition on to cause killing to happen regularly, for testing. 2623 if (proc.baseProcessTracker != null) { 2624 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2625 } 2626 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2627 } else if (proc != null && !keepIfLarge 2628 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2629 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2630 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2631 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2632 if (proc.baseProcessTracker != null) { 2633 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2634 } 2635 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2636 } 2637 } 2638 return proc; 2639 } 2640 2641 void ensurePackageDexOpt(String packageName) { 2642 IPackageManager pm = AppGlobals.getPackageManager(); 2643 try { 2644 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2645 mDidDexOpt = true; 2646 } 2647 } catch (RemoteException e) { 2648 } 2649 } 2650 2651 boolean isNextTransitionForward() { 2652 int transit = mWindowManager.getPendingAppTransition(); 2653 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2654 || transit == AppTransition.TRANSIT_TASK_OPEN 2655 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2656 } 2657 2658 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2659 String processName, String abiOverride, int uid, Runnable crashHandler) { 2660 synchronized(this) { 2661 ApplicationInfo info = new ApplicationInfo(); 2662 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2663 // For isolated processes, the former contains the parent's uid and the latter the 2664 // actual uid of the isolated process. 2665 // In the special case introduced by this method (which is, starting an isolated 2666 // process directly from the SystemServer without an actual parent app process) the 2667 // closest thing to a parent's uid is SYSTEM_UID. 2668 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2669 // the |isolated| logic in the ProcessRecord constructor. 2670 info.uid = Process.SYSTEM_UID; 2671 info.processName = processName; 2672 info.className = entryPoint; 2673 info.packageName = "android"; 2674 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2675 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2676 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2677 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2678 crashHandler); 2679 return proc != null ? proc.pid : 0; 2680 } 2681 } 2682 2683 final ProcessRecord startProcessLocked(String processName, 2684 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2685 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2686 boolean isolated, boolean keepIfLarge) { 2687 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2688 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2689 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2690 null /* crashHandler */); 2691 } 2692 2693 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2694 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2695 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2696 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2697 long startTime = SystemClock.elapsedRealtime(); 2698 ProcessRecord app; 2699 if (!isolated) { 2700 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2701 checkTime(startTime, "startProcess: after getProcessRecord"); 2702 } else { 2703 // If this is an isolated process, it can't re-use an existing process. 2704 app = null; 2705 } 2706 // We don't have to do anything more if: 2707 // (1) There is an existing application record; and 2708 // (2) The caller doesn't think it is dead, OR there is no thread 2709 // object attached to it so we know it couldn't have crashed; and 2710 // (3) There is a pid assigned to it, so it is either starting or 2711 // already running. 2712 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2713 + " app=" + app + " knownToBeDead=" + knownToBeDead 2714 + " thread=" + (app != null ? app.thread : null) 2715 + " pid=" + (app != null ? app.pid : -1)); 2716 if (app != null && app.pid > 0) { 2717 if (!knownToBeDead || app.thread == null) { 2718 // We already have the app running, or are waiting for it to 2719 // come up (we have a pid but not yet its thread), so keep it. 2720 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2721 // If this is a new package in the process, add the package to the list 2722 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2723 checkTime(startTime, "startProcess: done, added package to proc"); 2724 return app; 2725 } 2726 2727 // An application record is attached to a previous process, 2728 // clean it up now. 2729 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2730 checkTime(startTime, "startProcess: bad proc running, killing"); 2731 Process.killProcessGroup(app.info.uid, app.pid); 2732 handleAppDiedLocked(app, true, true); 2733 checkTime(startTime, "startProcess: done killing old proc"); 2734 } 2735 2736 String hostingNameStr = hostingName != null 2737 ? hostingName.flattenToShortString() : null; 2738 2739 if (!isolated) { 2740 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2741 // If we are in the background, then check to see if this process 2742 // is bad. If so, we will just silently fail. 2743 if (mBadProcesses.get(info.processName, info.uid) != null) { 2744 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2745 + "/" + info.processName); 2746 return null; 2747 } 2748 } else { 2749 // When the user is explicitly starting a process, then clear its 2750 // crash count so that we won't make it bad until they see at 2751 // least one crash dialog again, and make the process good again 2752 // if it had been bad. 2753 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2754 + "/" + info.processName); 2755 mProcessCrashTimes.remove(info.processName, info.uid); 2756 if (mBadProcesses.get(info.processName, info.uid) != null) { 2757 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2758 UserHandle.getUserId(info.uid), info.uid, 2759 info.processName); 2760 mBadProcesses.remove(info.processName, info.uid); 2761 if (app != null) { 2762 app.bad = false; 2763 } 2764 } 2765 } 2766 } 2767 2768 if (app == null) { 2769 checkTime(startTime, "startProcess: creating new process record"); 2770 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2771 app.crashHandler = crashHandler; 2772 if (app == null) { 2773 Slog.w(TAG, "Failed making new process record for " 2774 + processName + "/" + info.uid + " isolated=" + isolated); 2775 return null; 2776 } 2777 mProcessNames.put(processName, app.uid, app); 2778 if (isolated) { 2779 mIsolatedProcesses.put(app.uid, app); 2780 } 2781 checkTime(startTime, "startProcess: done creating new process record"); 2782 } else { 2783 // If this is a new package in the process, add the package to the list 2784 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2785 checkTime(startTime, "startProcess: added package to existing proc"); 2786 } 2787 2788 // If the system is not ready yet, then hold off on starting this 2789 // process until it is. 2790 if (!mProcessesReady 2791 && !isAllowedWhileBooting(info) 2792 && !allowWhileBooting) { 2793 if (!mProcessesOnHold.contains(app)) { 2794 mProcessesOnHold.add(app); 2795 } 2796 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2797 checkTime(startTime, "startProcess: returning with proc on hold"); 2798 return app; 2799 } 2800 2801 checkTime(startTime, "startProcess: stepping in to startProcess"); 2802 startProcessLocked( 2803 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2804 checkTime(startTime, "startProcess: done starting proc!"); 2805 return (app.pid != 0) ? app : null; 2806 } 2807 2808 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2809 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2810 } 2811 2812 private final void startProcessLocked(ProcessRecord app, 2813 String hostingType, String hostingNameStr) { 2814 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2815 null /* entryPoint */, null /* entryPointArgs */); 2816 } 2817 2818 private final void startProcessLocked(ProcessRecord app, String hostingType, 2819 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2820 long startTime = SystemClock.elapsedRealtime(); 2821 if (app.pid > 0 && app.pid != MY_PID) { 2822 checkTime(startTime, "startProcess: removing from pids map"); 2823 synchronized (mPidsSelfLocked) { 2824 mPidsSelfLocked.remove(app.pid); 2825 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2826 } 2827 checkTime(startTime, "startProcess: done removing from pids map"); 2828 app.setPid(0); 2829 } 2830 2831 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2832 "startProcessLocked removing on hold: " + app); 2833 mProcessesOnHold.remove(app); 2834 2835 checkTime(startTime, "startProcess: starting to update cpu stats"); 2836 updateCpuStats(); 2837 checkTime(startTime, "startProcess: done updating cpu stats"); 2838 2839 try { 2840 int uid = app.uid; 2841 2842 int[] gids = null; 2843 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2844 if (!app.isolated) { 2845 int[] permGids = null; 2846 try { 2847 checkTime(startTime, "startProcess: getting gids from package manager"); 2848 final PackageManager pm = mContext.getPackageManager(); 2849 permGids = pm.getPackageGids(app.info.packageName); 2850 2851 if (Environment.isExternalStorageEmulated()) { 2852 checkTime(startTime, "startProcess: checking external storage perm"); 2853 if (pm.checkPermission( 2854 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2855 app.info.packageName) == PERMISSION_GRANTED) { 2856 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2857 } else { 2858 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2859 } 2860 } 2861 } catch (PackageManager.NameNotFoundException e) { 2862 Slog.w(TAG, "Unable to retrieve gids", e); 2863 } 2864 2865 /* 2866 * Add shared application and profile GIDs so applications can share some 2867 * resources like shared libraries and access user-wide resources 2868 */ 2869 if (permGids == null) { 2870 gids = new int[2]; 2871 } else { 2872 gids = new int[permGids.length + 2]; 2873 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2874 } 2875 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2876 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2877 } 2878 checkTime(startTime, "startProcess: building args"); 2879 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2880 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2881 && mTopComponent != null 2882 && app.processName.equals(mTopComponent.getPackageName())) { 2883 uid = 0; 2884 } 2885 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2886 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2887 uid = 0; 2888 } 2889 } 2890 int debugFlags = 0; 2891 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2892 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2893 // Also turn on CheckJNI for debuggable apps. It's quite 2894 // awkward to turn on otherwise. 2895 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2896 } 2897 // Run the app in safe mode if its manifest requests so or the 2898 // system is booted in safe mode. 2899 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2900 mSafeMode == true) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2905 } 2906 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2907 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2908 } 2909 if ("1".equals(SystemProperties.get("debug.assert"))) { 2910 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2911 } 2912 2913 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2914 if (requiredAbi == null) { 2915 requiredAbi = Build.SUPPORTED_ABIS[0]; 2916 } 2917 2918 String instructionSet = null; 2919 if (app.info.primaryCpuAbi != null) { 2920 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2921 } 2922 2923 // Start the process. It will either succeed and return a result containing 2924 // the PID of the new process, or else throw a RuntimeException. 2925 boolean isActivityProcess = (entryPoint == null); 2926 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2927 checkTime(startTime, "startProcess: asking zygote to start proc"); 2928 Process.ProcessStartResult startResult = Process.start(entryPoint, 2929 app.processName, uid, uid, gids, debugFlags, mountExternal, 2930 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2931 app.info.dataDir, entryPointArgs); 2932 checkTime(startTime, "startProcess: returned from zygote!"); 2933 2934 if (app.isolated) { 2935 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2936 } 2937 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2938 checkTime(startTime, "startProcess: done updating battery stats"); 2939 2940 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2941 UserHandle.getUserId(uid), startResult.pid, uid, 2942 app.processName, hostingType, 2943 hostingNameStr != null ? hostingNameStr : ""); 2944 2945 if (app.persistent) { 2946 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2947 } 2948 2949 checkTime(startTime, "startProcess: building log message"); 2950 StringBuilder buf = mStringBuilder; 2951 buf.setLength(0); 2952 buf.append("Start proc "); 2953 buf.append(app.processName); 2954 if (!isActivityProcess) { 2955 buf.append(" ["); 2956 buf.append(entryPoint); 2957 buf.append("]"); 2958 } 2959 buf.append(" for "); 2960 buf.append(hostingType); 2961 if (hostingNameStr != null) { 2962 buf.append(" "); 2963 buf.append(hostingNameStr); 2964 } 2965 buf.append(": pid="); 2966 buf.append(startResult.pid); 2967 buf.append(" uid="); 2968 buf.append(uid); 2969 buf.append(" gids={"); 2970 if (gids != null) { 2971 for (int gi=0; gi<gids.length; gi++) { 2972 if (gi != 0) buf.append(", "); 2973 buf.append(gids[gi]); 2974 2975 } 2976 } 2977 buf.append("}"); 2978 if (requiredAbi != null) { 2979 buf.append(" abi="); 2980 buf.append(requiredAbi); 2981 } 2982 Slog.i(TAG, buf.toString()); 2983 app.setPid(startResult.pid); 2984 app.usingWrapper = startResult.usingWrapper; 2985 app.removed = false; 2986 app.killed = false; 2987 app.killedByAm = false; 2988 checkTime(startTime, "startProcess: starting to update pids map"); 2989 synchronized (mPidsSelfLocked) { 2990 this.mPidsSelfLocked.put(startResult.pid, app); 2991 if (isActivityProcess) { 2992 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2993 msg.obj = app; 2994 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2995 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2996 } 2997 } 2998 checkTime(startTime, "startProcess: done updating pids map"); 2999 } catch (RuntimeException e) { 3000 // XXX do better error recovery. 3001 app.setPid(0); 3002 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3003 if (app.isolated) { 3004 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3005 } 3006 Slog.e(TAG, "Failure starting process " + app.processName, e); 3007 } 3008 } 3009 3010 void updateUsageStats(ActivityRecord component, boolean resumed) { 3011 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3012 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3013 if (resumed) { 3014 if (mUsageStatsService != null) { 3015 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3016 UsageEvents.Event.MOVE_TO_FOREGROUND); 3017 } 3018 synchronized (stats) { 3019 stats.noteActivityResumedLocked(component.app.uid); 3020 } 3021 } else { 3022 if (mUsageStatsService != null) { 3023 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3024 UsageEvents.Event.MOVE_TO_BACKGROUND); 3025 } 3026 synchronized (stats) { 3027 stats.noteActivityPausedLocked(component.app.uid); 3028 } 3029 } 3030 } 3031 3032 Intent getHomeIntent() { 3033 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3034 intent.setComponent(mTopComponent); 3035 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3036 intent.addCategory(Intent.CATEGORY_HOME); 3037 } 3038 return intent; 3039 } 3040 3041 boolean startHomeActivityLocked(int userId) { 3042 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3043 && mTopAction == null) { 3044 // We are running in factory test mode, but unable to find 3045 // the factory test app, so just sit around displaying the 3046 // error message and don't try to start anything. 3047 return false; 3048 } 3049 Intent intent = getHomeIntent(); 3050 ActivityInfo aInfo = 3051 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3052 if (aInfo != null) { 3053 intent.setComponent(new ComponentName( 3054 aInfo.applicationInfo.packageName, aInfo.name)); 3055 // Don't do this if the home app is currently being 3056 // instrumented. 3057 aInfo = new ActivityInfo(aInfo); 3058 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3059 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3060 aInfo.applicationInfo.uid, true); 3061 if (app == null || app.instrumentationClass == null) { 3062 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3063 mStackSupervisor.startHomeActivity(intent, aInfo); 3064 } 3065 } 3066 3067 return true; 3068 } 3069 3070 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3071 ActivityInfo ai = null; 3072 ComponentName comp = intent.getComponent(); 3073 try { 3074 if (comp != null) { 3075 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3076 } else { 3077 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3078 intent, 3079 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3080 flags, userId); 3081 3082 if (info != null) { 3083 ai = info.activityInfo; 3084 } 3085 } 3086 } catch (RemoteException e) { 3087 // ignore 3088 } 3089 3090 return ai; 3091 } 3092 3093 /** 3094 * Starts the "new version setup screen" if appropriate. 3095 */ 3096 void startSetupActivityLocked() { 3097 // Only do this once per boot. 3098 if (mCheckedForSetup) { 3099 return; 3100 } 3101 3102 // We will show this screen if the current one is a different 3103 // version than the last one shown, and we are not running in 3104 // low-level factory test mode. 3105 final ContentResolver resolver = mContext.getContentResolver(); 3106 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3107 Settings.Global.getInt(resolver, 3108 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3109 mCheckedForSetup = true; 3110 3111 // See if we should be showing the platform update setup UI. 3112 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3113 List<ResolveInfo> ris = mContext.getPackageManager() 3114 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3115 3116 // We don't allow third party apps to replace this. 3117 ResolveInfo ri = null; 3118 for (int i=0; ris != null && i<ris.size(); i++) { 3119 if ((ris.get(i).activityInfo.applicationInfo.flags 3120 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3121 ri = ris.get(i); 3122 break; 3123 } 3124 } 3125 3126 if (ri != null) { 3127 String vers = ri.activityInfo.metaData != null 3128 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3129 : null; 3130 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3131 vers = ri.activityInfo.applicationInfo.metaData.getString( 3132 Intent.METADATA_SETUP_VERSION); 3133 } 3134 String lastVers = Settings.Secure.getString( 3135 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3136 if (vers != null && !vers.equals(lastVers)) { 3137 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3138 intent.setComponent(new ComponentName( 3139 ri.activityInfo.packageName, ri.activityInfo.name)); 3140 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3141 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3142 null); 3143 } 3144 } 3145 } 3146 } 3147 3148 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3149 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3150 } 3151 3152 void enforceNotIsolatedCaller(String caller) { 3153 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3154 throw new SecurityException("Isolated process not allowed to call " + caller); 3155 } 3156 } 3157 3158 void enforceShellRestriction(String restriction, int userHandle) { 3159 if (Binder.getCallingUid() == Process.SHELL_UID) { 3160 if (userHandle < 0 3161 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3162 throw new SecurityException("Shell does not have permission to access user " 3163 + userHandle); 3164 } 3165 } 3166 } 3167 3168 @Override 3169 public int getFrontActivityScreenCompatMode() { 3170 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3171 synchronized (this) { 3172 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3173 } 3174 } 3175 3176 @Override 3177 public void setFrontActivityScreenCompatMode(int mode) { 3178 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3179 "setFrontActivityScreenCompatMode"); 3180 synchronized (this) { 3181 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3182 } 3183 } 3184 3185 @Override 3186 public int getPackageScreenCompatMode(String packageName) { 3187 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3188 synchronized (this) { 3189 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3190 } 3191 } 3192 3193 @Override 3194 public void setPackageScreenCompatMode(String packageName, int mode) { 3195 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3196 "setPackageScreenCompatMode"); 3197 synchronized (this) { 3198 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3199 } 3200 } 3201 3202 @Override 3203 public boolean getPackageAskScreenCompat(String packageName) { 3204 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3205 synchronized (this) { 3206 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3207 } 3208 } 3209 3210 @Override 3211 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3212 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3213 "setPackageAskScreenCompat"); 3214 synchronized (this) { 3215 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3216 } 3217 } 3218 3219 private void dispatchProcessesChanged() { 3220 int N; 3221 synchronized (this) { 3222 N = mPendingProcessChanges.size(); 3223 if (mActiveProcessChanges.length < N) { 3224 mActiveProcessChanges = new ProcessChangeItem[N]; 3225 } 3226 mPendingProcessChanges.toArray(mActiveProcessChanges); 3227 mAvailProcessChanges.addAll(mPendingProcessChanges); 3228 mPendingProcessChanges.clear(); 3229 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3230 } 3231 3232 int i = mProcessObservers.beginBroadcast(); 3233 while (i > 0) { 3234 i--; 3235 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3236 if (observer != null) { 3237 try { 3238 for (int j=0; j<N; j++) { 3239 ProcessChangeItem item = mActiveProcessChanges[j]; 3240 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3241 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3242 + item.pid + " uid=" + item.uid + ": " 3243 + item.foregroundActivities); 3244 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3245 item.foregroundActivities); 3246 } 3247 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3248 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3249 + item.pid + " uid=" + item.uid + ": " + item.processState); 3250 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3251 } 3252 } 3253 } catch (RemoteException e) { 3254 } 3255 } 3256 } 3257 mProcessObservers.finishBroadcast(); 3258 } 3259 3260 private void dispatchProcessDied(int pid, int uid) { 3261 int i = mProcessObservers.beginBroadcast(); 3262 while (i > 0) { 3263 i--; 3264 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3265 if (observer != null) { 3266 try { 3267 observer.onProcessDied(pid, uid); 3268 } catch (RemoteException e) { 3269 } 3270 } 3271 } 3272 mProcessObservers.finishBroadcast(); 3273 } 3274 3275 @Override 3276 public final int startActivity(IApplicationThread caller, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3278 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3279 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3280 resultWho, requestCode, startFlags, profilerInfo, options, 3281 UserHandle.getCallingUserId()); 3282 } 3283 3284 @Override 3285 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3286 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3287 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3288 enforceNotIsolatedCaller("startActivity"); 3289 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3290 false, ALLOW_FULL_ONLY, "startActivity", null); 3291 // TODO: Switch to user app stacks here. 3292 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3293 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3294 profilerInfo, null, null, options, userId, null, null); 3295 } 3296 3297 @Override 3298 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3299 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3300 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3301 3302 // This is very dangerous -- it allows you to perform a start activity (including 3303 // permission grants) as any app that may launch one of your own activities. So 3304 // we will only allow this to be done from activities that are part of the core framework, 3305 // and then only when they are running as the system. 3306 final ActivityRecord sourceRecord; 3307 final int targetUid; 3308 final String targetPackage; 3309 synchronized (this) { 3310 if (resultTo == null) { 3311 throw new SecurityException("Must be called from an activity"); 3312 } 3313 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3314 if (sourceRecord == null) { 3315 throw new SecurityException("Called with bad activity token: " + resultTo); 3316 } 3317 if (!sourceRecord.info.packageName.equals("android")) { 3318 throw new SecurityException( 3319 "Must be called from an activity that is declared in the android package"); 3320 } 3321 if (sourceRecord.app == null) { 3322 throw new SecurityException("Called without a process attached to activity"); 3323 } 3324 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3325 // This is still okay, as long as this activity is running under the 3326 // uid of the original calling activity. 3327 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3328 throw new SecurityException( 3329 "Calling activity in uid " + sourceRecord.app.uid 3330 + " must be system uid or original calling uid " 3331 + sourceRecord.launchedFromUid); 3332 } 3333 } 3334 targetUid = sourceRecord.launchedFromUid; 3335 targetPackage = sourceRecord.launchedFromPackage; 3336 } 3337 3338 if (userId == UserHandle.USER_NULL) { 3339 userId = UserHandle.getUserId(sourceRecord.app.uid); 3340 } 3341 3342 // TODO: Switch to user app stacks here. 3343 try { 3344 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3345 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3346 null, null, options, userId, null, null); 3347 return ret; 3348 } catch (SecurityException e) { 3349 // XXX need to figure out how to propagate to original app. 3350 // A SecurityException here is generally actually a fault of the original 3351 // calling activity (such as a fairly granting permissions), so propagate it 3352 // back to them. 3353 /* 3354 StringBuilder msg = new StringBuilder(); 3355 msg.append("While launching"); 3356 msg.append(intent.toString()); 3357 msg.append(": "); 3358 msg.append(e.getMessage()); 3359 */ 3360 throw e; 3361 } 3362 } 3363 3364 @Override 3365 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3366 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3367 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3368 enforceNotIsolatedCaller("startActivityAndWait"); 3369 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3370 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3371 WaitResult res = new WaitResult(); 3372 // TODO: Switch to user app stacks here. 3373 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3374 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3375 options, userId, null, null); 3376 return res; 3377 } 3378 3379 @Override 3380 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3381 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3382 int startFlags, Configuration config, Bundle options, int userId) { 3383 enforceNotIsolatedCaller("startActivityWithConfig"); 3384 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3385 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3386 // TODO: Switch to user app stacks here. 3387 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3388 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3389 null, null, config, options, userId, null, null); 3390 return ret; 3391 } 3392 3393 @Override 3394 public int startActivityIntentSender(IApplicationThread caller, 3395 IntentSender intent, Intent fillInIntent, String resolvedType, 3396 IBinder resultTo, String resultWho, int requestCode, 3397 int flagsMask, int flagsValues, Bundle options) { 3398 enforceNotIsolatedCaller("startActivityIntentSender"); 3399 // Refuse possible leaked file descriptors 3400 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3401 throw new IllegalArgumentException("File descriptors passed in Intent"); 3402 } 3403 3404 IIntentSender sender = intent.getTarget(); 3405 if (!(sender instanceof PendingIntentRecord)) { 3406 throw new IllegalArgumentException("Bad PendingIntent object"); 3407 } 3408 3409 PendingIntentRecord pir = (PendingIntentRecord)sender; 3410 3411 synchronized (this) { 3412 // If this is coming from the currently resumed activity, it is 3413 // effectively saying that app switches are allowed at this point. 3414 final ActivityStack stack = getFocusedStack(); 3415 if (stack.mResumedActivity != null && 3416 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3417 mAppSwitchesAllowedTime = 0; 3418 } 3419 } 3420 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3421 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3422 return ret; 3423 } 3424 3425 @Override 3426 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3427 Intent intent, String resolvedType, IVoiceInteractionSession session, 3428 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3429 Bundle options, int userId) { 3430 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3431 != PackageManager.PERMISSION_GRANTED) { 3432 String msg = "Permission Denial: startVoiceActivity() from pid=" 3433 + Binder.getCallingPid() 3434 + ", uid=" + Binder.getCallingUid() 3435 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3436 Slog.w(TAG, msg); 3437 throw new SecurityException(msg); 3438 } 3439 if (session == null || interactor == null) { 3440 throw new NullPointerException("null session or interactor"); 3441 } 3442 userId = handleIncomingUser(callingPid, callingUid, userId, 3443 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3444 // TODO: Switch to user app stacks here. 3445 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3446 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3447 null, options, userId, null, null); 3448 } 3449 3450 @Override 3451 public boolean startNextMatchingActivity(IBinder callingActivity, 3452 Intent intent, Bundle options) { 3453 // Refuse possible leaked file descriptors 3454 if (intent != null && intent.hasFileDescriptors() == true) { 3455 throw new IllegalArgumentException("File descriptors passed in Intent"); 3456 } 3457 3458 synchronized (this) { 3459 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3460 if (r == null) { 3461 ActivityOptions.abort(options); 3462 return false; 3463 } 3464 if (r.app == null || r.app.thread == null) { 3465 // The caller is not running... d'oh! 3466 ActivityOptions.abort(options); 3467 return false; 3468 } 3469 intent = new Intent(intent); 3470 // The caller is not allowed to change the data. 3471 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3472 // And we are resetting to find the next component... 3473 intent.setComponent(null); 3474 3475 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3476 3477 ActivityInfo aInfo = null; 3478 try { 3479 List<ResolveInfo> resolves = 3480 AppGlobals.getPackageManager().queryIntentActivities( 3481 intent, r.resolvedType, 3482 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3483 UserHandle.getCallingUserId()); 3484 3485 // Look for the original activity in the list... 3486 final int N = resolves != null ? resolves.size() : 0; 3487 for (int i=0; i<N; i++) { 3488 ResolveInfo rInfo = resolves.get(i); 3489 if (rInfo.activityInfo.packageName.equals(r.packageName) 3490 && rInfo.activityInfo.name.equals(r.info.name)) { 3491 // We found the current one... the next matching is 3492 // after it. 3493 i++; 3494 if (i<N) { 3495 aInfo = resolves.get(i).activityInfo; 3496 } 3497 if (debug) { 3498 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3499 + "/" + r.info.name); 3500 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3501 + "/" + aInfo.name); 3502 } 3503 break; 3504 } 3505 } 3506 } catch (RemoteException e) { 3507 } 3508 3509 if (aInfo == null) { 3510 // Nobody who is next! 3511 ActivityOptions.abort(options); 3512 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3513 return false; 3514 } 3515 3516 intent.setComponent(new ComponentName( 3517 aInfo.applicationInfo.packageName, aInfo.name)); 3518 intent.setFlags(intent.getFlags()&~( 3519 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3520 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3521 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3522 Intent.FLAG_ACTIVITY_NEW_TASK)); 3523 3524 // Okay now we need to start the new activity, replacing the 3525 // currently running activity. This is a little tricky because 3526 // we want to start the new one as if the current one is finished, 3527 // but not finish the current one first so that there is no flicker. 3528 // And thus... 3529 final boolean wasFinishing = r.finishing; 3530 r.finishing = true; 3531 3532 // Propagate reply information over to the new activity. 3533 final ActivityRecord resultTo = r.resultTo; 3534 final String resultWho = r.resultWho; 3535 final int requestCode = r.requestCode; 3536 r.resultTo = null; 3537 if (resultTo != null) { 3538 resultTo.removeResultsLocked(r, resultWho, requestCode); 3539 } 3540 3541 final long origId = Binder.clearCallingIdentity(); 3542 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3543 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3544 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3545 -1, r.launchedFromUid, 0, options, false, null, null, null); 3546 Binder.restoreCallingIdentity(origId); 3547 3548 r.finishing = wasFinishing; 3549 if (res != ActivityManager.START_SUCCESS) { 3550 return false; 3551 } 3552 return true; 3553 } 3554 } 3555 3556 @Override 3557 public final int startActivityFromRecents(int taskId, Bundle options) { 3558 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3559 String msg = "Permission Denial: startActivityFromRecents called without " + 3560 START_TASKS_FROM_RECENTS; 3561 Slog.w(TAG, msg); 3562 throw new SecurityException(msg); 3563 } 3564 return startActivityFromRecentsInner(taskId, options); 3565 } 3566 3567 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3568 final TaskRecord task; 3569 final int callingUid; 3570 final String callingPackage; 3571 final Intent intent; 3572 final int userId; 3573 synchronized (this) { 3574 task = recentTaskForIdLocked(taskId); 3575 if (task == null) { 3576 throw new IllegalArgumentException("Task " + taskId + " not found."); 3577 } 3578 callingUid = task.mCallingUid; 3579 callingPackage = task.mCallingPackage; 3580 intent = task.intent; 3581 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3582 userId = task.userId; 3583 } 3584 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3585 options, userId, null, task); 3586 } 3587 3588 final int startActivityInPackage(int uid, String callingPackage, 3589 Intent intent, String resolvedType, IBinder resultTo, 3590 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3591 IActivityContainer container, TaskRecord inTask) { 3592 3593 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3594 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3595 3596 // TODO: Switch to user app stacks here. 3597 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3598 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3599 null, null, null, options, userId, container, inTask); 3600 return ret; 3601 } 3602 3603 @Override 3604 public final int startActivities(IApplicationThread caller, String callingPackage, 3605 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3606 int userId) { 3607 enforceNotIsolatedCaller("startActivities"); 3608 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3609 false, ALLOW_FULL_ONLY, "startActivity", null); 3610 // TODO: Switch to user app stacks here. 3611 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3612 resolvedTypes, resultTo, options, userId); 3613 return ret; 3614 } 3615 3616 final int startActivitiesInPackage(int uid, String callingPackage, 3617 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3618 Bundle options, int userId) { 3619 3620 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3621 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3622 // TODO: Switch to user app stacks here. 3623 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3624 resultTo, options, userId); 3625 return ret; 3626 } 3627 3628 //explicitly remove thd old information in mRecentTasks when removing existing user. 3629 private void removeRecentTasksForUserLocked(int userId) { 3630 if(userId <= 0) { 3631 Slog.i(TAG, "Can't remove recent task on user " + userId); 3632 return; 3633 } 3634 3635 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3636 TaskRecord tr = mRecentTasks.get(i); 3637 if (tr.userId == userId) { 3638 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3639 + " when finishing user" + userId); 3640 mRecentTasks.remove(i); 3641 tr.removedFromRecents(mTaskPersister); 3642 } 3643 } 3644 3645 // Remove tasks from persistent storage. 3646 mTaskPersister.wakeup(null, true); 3647 } 3648 3649 // Sort by taskId 3650 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3651 @Override 3652 public int compare(TaskRecord lhs, TaskRecord rhs) { 3653 return rhs.taskId - lhs.taskId; 3654 } 3655 }; 3656 3657 // Extract the affiliates of the chain containing mRecentTasks[start]. 3658 private int processNextAffiliateChain(int start) { 3659 final TaskRecord startTask = mRecentTasks.get(start); 3660 final int affiliateId = startTask.mAffiliatedTaskId; 3661 3662 // Quick identification of isolated tasks. I.e. those not launched behind. 3663 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3664 startTask.mNextAffiliate == null) { 3665 // There is still a slim chance that there are other tasks that point to this task 3666 // and that the chain is so messed up that this task no longer points to them but 3667 // the gain of this optimization outweighs the risk. 3668 startTask.inRecents = true; 3669 return start + 1; 3670 } 3671 3672 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3673 mTmpRecents.clear(); 3674 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3675 final TaskRecord task = mRecentTasks.get(i); 3676 if (task.mAffiliatedTaskId == affiliateId) { 3677 mRecentTasks.remove(i); 3678 mTmpRecents.add(task); 3679 } 3680 } 3681 3682 // Sort them all by taskId. That is the order they were create in and that order will 3683 // always be correct. 3684 Collections.sort(mTmpRecents, mTaskRecordComparator); 3685 3686 // Go through and fix up the linked list. 3687 // The first one is the end of the chain and has no next. 3688 final TaskRecord first = mTmpRecents.get(0); 3689 first.inRecents = true; 3690 if (first.mNextAffiliate != null) { 3691 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3692 first.setNextAffiliate(null); 3693 mTaskPersister.wakeup(first, false); 3694 } 3695 // Everything in the middle is doubly linked from next to prev. 3696 final int tmpSize = mTmpRecents.size(); 3697 for (int i = 0; i < tmpSize - 1; ++i) { 3698 final TaskRecord next = mTmpRecents.get(i); 3699 final TaskRecord prev = mTmpRecents.get(i + 1); 3700 if (next.mPrevAffiliate != prev) { 3701 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3702 " setting prev=" + prev); 3703 next.setPrevAffiliate(prev); 3704 mTaskPersister.wakeup(next, false); 3705 } 3706 if (prev.mNextAffiliate != next) { 3707 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3708 " setting next=" + next); 3709 prev.setNextAffiliate(next); 3710 mTaskPersister.wakeup(prev, false); 3711 } 3712 prev.inRecents = true; 3713 } 3714 // The last one is the beginning of the list and has no prev. 3715 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3716 if (last.mPrevAffiliate != null) { 3717 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3718 last.setPrevAffiliate(null); 3719 mTaskPersister.wakeup(last, false); 3720 } 3721 3722 // Insert the group back into mRecentTasks at start. 3723 mRecentTasks.addAll(start, mTmpRecents); 3724 3725 // Let the caller know where we left off. 3726 return start + tmpSize; 3727 } 3728 3729 /** 3730 * Update the recent tasks lists: make sure tasks should still be here (their 3731 * applications / activities still exist), update their availability, fixup ordering 3732 * of affiliations. 3733 */ 3734 void cleanupRecentTasksLocked(int userId) { 3735 if (mRecentTasks == null) { 3736 // Happens when called from the packagemanager broadcast before boot. 3737 return; 3738 } 3739 3740 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3741 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3742 final IPackageManager pm = AppGlobals.getPackageManager(); 3743 final ActivityInfo dummyAct = new ActivityInfo(); 3744 final ApplicationInfo dummyApp = new ApplicationInfo(); 3745 3746 int N = mRecentTasks.size(); 3747 3748 int[] users = userId == UserHandle.USER_ALL 3749 ? getUsersLocked() : new int[] { userId }; 3750 for (int user : users) { 3751 for (int i = 0; i < N; i++) { 3752 TaskRecord task = mRecentTasks.get(i); 3753 if (task.userId != user) { 3754 // Only look at tasks for the user ID of interest. 3755 continue; 3756 } 3757 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3758 // This situation is broken, and we should just get rid of it now. 3759 mRecentTasks.remove(i); 3760 task.removedFromRecents(mTaskPersister); 3761 i--; 3762 N--; 3763 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3764 continue; 3765 } 3766 // Check whether this activity is currently available. 3767 if (task.realActivity != null) { 3768 ActivityInfo ai = availActCache.get(task.realActivity); 3769 if (ai == null) { 3770 try { 3771 ai = pm.getActivityInfo(task.realActivity, 3772 PackageManager.GET_UNINSTALLED_PACKAGES 3773 | PackageManager.GET_DISABLED_COMPONENTS, user); 3774 } catch (RemoteException e) { 3775 // Will never happen. 3776 continue; 3777 } 3778 if (ai == null) { 3779 ai = dummyAct; 3780 } 3781 availActCache.put(task.realActivity, ai); 3782 } 3783 if (ai == dummyAct) { 3784 // This could be either because the activity no longer exists, or the 3785 // app is temporarily gone. For the former we want to remove the recents 3786 // entry; for the latter we want to mark it as unavailable. 3787 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3788 if (app == null) { 3789 try { 3790 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3791 PackageManager.GET_UNINSTALLED_PACKAGES 3792 | PackageManager.GET_DISABLED_COMPONENTS, user); 3793 } catch (RemoteException e) { 3794 // Will never happen. 3795 continue; 3796 } 3797 if (app == null) { 3798 app = dummyApp; 3799 } 3800 availAppCache.put(task.realActivity.getPackageName(), app); 3801 } 3802 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3803 // Doesn't exist any more! Good-bye. 3804 mRecentTasks.remove(i); 3805 task.removedFromRecents(mTaskPersister); 3806 i--; 3807 N--; 3808 Slog.w(TAG, "Removing no longer valid recent: " + task); 3809 continue; 3810 } else { 3811 // Otherwise just not available for now. 3812 if (task.isAvailable) { 3813 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3814 + task); 3815 } 3816 task.isAvailable = false; 3817 } 3818 } else { 3819 if (!ai.enabled || !ai.applicationInfo.enabled 3820 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3821 if (task.isAvailable) { 3822 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3823 + task + " (enabled=" + ai.enabled + "/" 3824 + ai.applicationInfo.enabled + " flags=" 3825 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3826 } 3827 task.isAvailable = false; 3828 } else { 3829 if (!task.isAvailable) { 3830 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3831 + task); 3832 } 3833 task.isAvailable = true; 3834 } 3835 } 3836 } 3837 } 3838 } 3839 3840 // Verify the affiliate chain for each task. 3841 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3842 } 3843 3844 mTmpRecents.clear(); 3845 // mRecentTasks is now in sorted, affiliated order. 3846 } 3847 3848 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3849 int N = mRecentTasks.size(); 3850 TaskRecord top = task; 3851 int topIndex = taskIndex; 3852 while (top.mNextAffiliate != null && topIndex > 0) { 3853 top = top.mNextAffiliate; 3854 topIndex--; 3855 } 3856 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3857 + topIndex + " from intial " + taskIndex); 3858 // Find the end of the chain, doing a sanity check along the way. 3859 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3860 int endIndex = topIndex; 3861 TaskRecord prev = top; 3862 while (endIndex < N) { 3863 TaskRecord cur = mRecentTasks.get(endIndex); 3864 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3865 + endIndex + " " + cur); 3866 if (cur == top) { 3867 // Verify start of the chain. 3868 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3869 Slog.wtf(TAG, "Bad chain @" + endIndex 3870 + ": first task has next affiliate: " + prev); 3871 sane = false; 3872 break; 3873 } 3874 } else { 3875 // Verify middle of the chain's next points back to the one before. 3876 if (cur.mNextAffiliate != prev 3877 || cur.mNextAffiliateTaskId != prev.taskId) { 3878 Slog.wtf(TAG, "Bad chain @" + endIndex 3879 + ": middle task " + cur + " @" + endIndex 3880 + " has bad next affiliate " 3881 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3882 + ", expected " + prev); 3883 sane = false; 3884 break; 3885 } 3886 } 3887 if (cur.mPrevAffiliateTaskId == -1) { 3888 // Chain ends here. 3889 if (cur.mPrevAffiliate != null) { 3890 Slog.wtf(TAG, "Bad chain @" + endIndex 3891 + ": last task " + cur + " has previous affiliate " 3892 + cur.mPrevAffiliate); 3893 sane = false; 3894 } 3895 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3896 break; 3897 } else { 3898 // Verify middle of the chain's prev points to a valid item. 3899 if (cur.mPrevAffiliate == null) { 3900 Slog.wtf(TAG, "Bad chain @" + endIndex 3901 + ": task " + cur + " has previous affiliate " 3902 + cur.mPrevAffiliate + " but should be id " 3903 + cur.mPrevAffiliate); 3904 sane = false; 3905 break; 3906 } 3907 } 3908 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3909 Slog.wtf(TAG, "Bad chain @" + endIndex 3910 + ": task " + cur + " has affiliated id " 3911 + cur.mAffiliatedTaskId + " but should be " 3912 + task.mAffiliatedTaskId); 3913 sane = false; 3914 break; 3915 } 3916 prev = cur; 3917 endIndex++; 3918 if (endIndex >= N) { 3919 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3920 + ": last task " + prev); 3921 sane = false; 3922 break; 3923 } 3924 } 3925 if (sane) { 3926 if (endIndex < taskIndex) { 3927 Slog.wtf(TAG, "Bad chain @" + endIndex 3928 + ": did not extend to task " + task + " @" + taskIndex); 3929 sane = false; 3930 } 3931 } 3932 if (sane) { 3933 // All looks good, we can just move all of the affiliated tasks 3934 // to the top. 3935 for (int i=topIndex; i<=endIndex; i++) { 3936 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3937 + " from " + i + " to " + (i-topIndex)); 3938 TaskRecord cur = mRecentTasks.remove(i); 3939 mRecentTasks.add(i-topIndex, cur); 3940 } 3941 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3942 + " to " + endIndex); 3943 return true; 3944 } 3945 3946 // Whoops, couldn't do it. 3947 return false; 3948 } 3949 3950 final void addRecentTaskLocked(TaskRecord task) { 3951 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3952 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3953 3954 int N = mRecentTasks.size(); 3955 // Quick case: check if the top-most recent task is the same. 3956 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3957 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3958 return; 3959 } 3960 // Another quick case: check if this is part of a set of affiliated 3961 // tasks that are at the top. 3962 if (isAffiliated && N > 0 && task.inRecents 3963 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3964 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3965 + " at top when adding " + task); 3966 return; 3967 } 3968 // Another quick case: never add voice sessions. 3969 if (task.voiceSession != null) { 3970 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3971 return; 3972 } 3973 3974 boolean needAffiliationFix = false; 3975 3976 // Slightly less quick case: the task is already in recents, so all we need 3977 // to do is move it. 3978 if (task.inRecents) { 3979 int taskIndex = mRecentTasks.indexOf(task); 3980 if (taskIndex >= 0) { 3981 if (!isAffiliated) { 3982 // Simple case: this is not an affiliated task, so we just move it to the front. 3983 mRecentTasks.remove(taskIndex); 3984 mRecentTasks.add(0, task); 3985 notifyTaskPersisterLocked(task, false); 3986 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3987 + " from " + taskIndex); 3988 return; 3989 } else { 3990 // More complicated: need to keep all affiliated tasks together. 3991 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3992 // All went well. 3993 return; 3994 } 3995 3996 // Uh oh... something bad in the affiliation chain, try to rebuild 3997 // everything and then go through our general path of adding a new task. 3998 needAffiliationFix = true; 3999 } 4000 } else { 4001 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4002 needAffiliationFix = true; 4003 } 4004 } 4005 4006 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4007 trimRecentsForTask(task, true); 4008 4009 N = mRecentTasks.size(); 4010 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4011 final TaskRecord tr = mRecentTasks.remove(N - 1); 4012 tr.removedFromRecents(mTaskPersister); 4013 N--; 4014 } 4015 task.inRecents = true; 4016 if (!isAffiliated || needAffiliationFix) { 4017 // If this is a simple non-affiliated task, or we had some failure trying to 4018 // handle it as part of an affilated task, then just place it at the top. 4019 mRecentTasks.add(0, task); 4020 } else if (isAffiliated) { 4021 // If this is a new affiliated task, then move all of the affiliated tasks 4022 // to the front and insert this new one. 4023 TaskRecord other = task.mNextAffiliate; 4024 if (other == null) { 4025 other = task.mPrevAffiliate; 4026 } 4027 if (other != null) { 4028 int otherIndex = mRecentTasks.indexOf(other); 4029 if (otherIndex >= 0) { 4030 // Insert new task at appropriate location. 4031 int taskIndex; 4032 if (other == task.mNextAffiliate) { 4033 // We found the index of our next affiliation, which is who is 4034 // before us in the list, so add after that point. 4035 taskIndex = otherIndex+1; 4036 } else { 4037 // We found the index of our previous affiliation, which is who is 4038 // after us in the list, so add at their position. 4039 taskIndex = otherIndex; 4040 } 4041 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4042 + taskIndex + ": " + task); 4043 mRecentTasks.add(taskIndex, task); 4044 4045 // Now move everything to the front. 4046 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4047 // All went well. 4048 return; 4049 } 4050 4051 // Uh oh... something bad in the affiliation chain, try to rebuild 4052 // everything and then go through our general path of adding a new task. 4053 needAffiliationFix = true; 4054 } else { 4055 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4056 + other); 4057 needAffiliationFix = true; 4058 } 4059 } else { 4060 if (DEBUG_RECENTS) Slog.d(TAG, 4061 "addRecent: adding affiliated task without next/prev:" + task); 4062 needAffiliationFix = true; 4063 } 4064 } 4065 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4066 4067 if (needAffiliationFix) { 4068 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4069 cleanupRecentTasksLocked(task.userId); 4070 } 4071 } 4072 4073 /** 4074 * If needed, remove oldest existing entries in recents that are for the same kind 4075 * of task as the given one. 4076 */ 4077 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4078 int N = mRecentTasks.size(); 4079 final Intent intent = task.intent; 4080 final boolean document = intent != null && intent.isDocument(); 4081 4082 int maxRecents = task.maxRecents - 1; 4083 for (int i=0; i<N; i++) { 4084 final TaskRecord tr = mRecentTasks.get(i); 4085 if (task != tr) { 4086 if (task.userId != tr.userId) { 4087 continue; 4088 } 4089 if (i > MAX_RECENT_BITMAPS) { 4090 tr.freeLastThumbnail(); 4091 } 4092 final Intent trIntent = tr.intent; 4093 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4094 (intent == null || !intent.filterEquals(trIntent))) { 4095 continue; 4096 } 4097 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4098 if (document && trIsDocument) { 4099 // These are the same document activity (not necessarily the same doc). 4100 if (maxRecents > 0) { 4101 --maxRecents; 4102 continue; 4103 } 4104 // Hit the maximum number of documents for this task. Fall through 4105 // and remove this document from recents. 4106 } else if (document || trIsDocument) { 4107 // Only one of these is a document. Not the droid we're looking for. 4108 continue; 4109 } 4110 } 4111 4112 if (!doTrim) { 4113 // If the caller is not actually asking for a trim, just tell them we reached 4114 // a point where the trim would happen. 4115 return i; 4116 } 4117 4118 // Either task and tr are the same or, their affinities match or their intents match 4119 // and neither of them is a document, or they are documents using the same activity 4120 // and their maxRecents has been reached. 4121 tr.disposeThumbnail(); 4122 mRecentTasks.remove(i); 4123 if (task != tr) { 4124 tr.removedFromRecents(mTaskPersister); 4125 } 4126 i--; 4127 N--; 4128 if (task.intent == null) { 4129 // If the new recent task we are adding is not fully 4130 // specified, then replace it with the existing recent task. 4131 task = tr; 4132 } 4133 notifyTaskPersisterLocked(tr, false); 4134 } 4135 4136 return -1; 4137 } 4138 4139 @Override 4140 public void reportActivityFullyDrawn(IBinder token) { 4141 synchronized (this) { 4142 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4143 if (r == null) { 4144 return; 4145 } 4146 r.reportFullyDrawnLocked(); 4147 } 4148 } 4149 4150 @Override 4151 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4152 synchronized (this) { 4153 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4154 if (r == null) { 4155 return; 4156 } 4157 final long origId = Binder.clearCallingIdentity(); 4158 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4159 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4160 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4161 if (config != null) { 4162 r.frozenBeforeDestroy = true; 4163 if (!updateConfigurationLocked(config, r, false, false)) { 4164 mStackSupervisor.resumeTopActivitiesLocked(); 4165 } 4166 } 4167 Binder.restoreCallingIdentity(origId); 4168 } 4169 } 4170 4171 @Override 4172 public int getRequestedOrientation(IBinder token) { 4173 synchronized (this) { 4174 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4175 if (r == null) { 4176 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4177 } 4178 return mWindowManager.getAppOrientation(r.appToken); 4179 } 4180 } 4181 4182 /** 4183 * This is the internal entry point for handling Activity.finish(). 4184 * 4185 * @param token The Binder token referencing the Activity we want to finish. 4186 * @param resultCode Result code, if any, from this Activity. 4187 * @param resultData Result data (Intent), if any, from this Activity. 4188 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4189 * the root Activity in the task. 4190 * 4191 * @return Returns true if the activity successfully finished, or false if it is still running. 4192 */ 4193 @Override 4194 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4195 boolean finishTask) { 4196 // Refuse possible leaked file descriptors 4197 if (resultData != null && resultData.hasFileDescriptors() == true) { 4198 throw new IllegalArgumentException("File descriptors passed in Intent"); 4199 } 4200 4201 synchronized(this) { 4202 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4203 if (r == null) { 4204 return true; 4205 } 4206 // Keep track of the root activity of the task before we finish it 4207 TaskRecord tr = r.task; 4208 ActivityRecord rootR = tr.getRootActivity(); 4209 if (rootR == null) { 4210 Slog.w(TAG, "Finishing task with all activities already finished"); 4211 } 4212 // Do not allow task to finish in Lock Task mode. 4213 if (tr == mStackSupervisor.mLockTaskModeTask) { 4214 if (rootR == r) { 4215 Slog.i(TAG, "Not finishing task in lock task mode"); 4216 mStackSupervisor.showLockTaskToast(); 4217 return false; 4218 } 4219 } 4220 if (mController != null) { 4221 // Find the first activity that is not finishing. 4222 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4223 if (next != null) { 4224 // ask watcher if this is allowed 4225 boolean resumeOK = true; 4226 try { 4227 resumeOK = mController.activityResuming(next.packageName); 4228 } catch (RemoteException e) { 4229 mController = null; 4230 Watchdog.getInstance().setActivityController(null); 4231 } 4232 4233 if (!resumeOK) { 4234 Slog.i(TAG, "Not finishing activity because controller resumed"); 4235 return false; 4236 } 4237 } 4238 } 4239 final long origId = Binder.clearCallingIdentity(); 4240 try { 4241 boolean res; 4242 if (finishTask && r == rootR) { 4243 // If requested, remove the task that is associated to this activity only if it 4244 // was the root activity in the task. The result code and data is ignored 4245 // because we don't support returning them across task boundaries. 4246 res = removeTaskByIdLocked(tr.taskId, false); 4247 if (!res) { 4248 Slog.i(TAG, "Removing task failed to finish activity"); 4249 } 4250 } else { 4251 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4252 resultData, "app-request", true); 4253 if (!res) { 4254 Slog.i(TAG, "Failed to finish by app-request"); 4255 } 4256 } 4257 return res; 4258 } finally { 4259 Binder.restoreCallingIdentity(origId); 4260 } 4261 } 4262 } 4263 4264 @Override 4265 public final void finishHeavyWeightApp() { 4266 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4267 != PackageManager.PERMISSION_GRANTED) { 4268 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4269 + Binder.getCallingPid() 4270 + ", uid=" + Binder.getCallingUid() 4271 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4272 Slog.w(TAG, msg); 4273 throw new SecurityException(msg); 4274 } 4275 4276 synchronized(this) { 4277 if (mHeavyWeightProcess == null) { 4278 return; 4279 } 4280 4281 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4282 mHeavyWeightProcess.activities); 4283 for (int i=0; i<activities.size(); i++) { 4284 ActivityRecord r = activities.get(i); 4285 if (!r.finishing) { 4286 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4287 null, "finish-heavy", true); 4288 } 4289 } 4290 4291 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4292 mHeavyWeightProcess.userId, 0)); 4293 mHeavyWeightProcess = null; 4294 } 4295 } 4296 4297 @Override 4298 public void crashApplication(int uid, int initialPid, String packageName, 4299 String message) { 4300 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4301 != PackageManager.PERMISSION_GRANTED) { 4302 String msg = "Permission Denial: crashApplication() from pid=" 4303 + Binder.getCallingPid() 4304 + ", uid=" + Binder.getCallingUid() 4305 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4306 Slog.w(TAG, msg); 4307 throw new SecurityException(msg); 4308 } 4309 4310 synchronized(this) { 4311 ProcessRecord proc = null; 4312 4313 // Figure out which process to kill. We don't trust that initialPid 4314 // still has any relation to current pids, so must scan through the 4315 // list. 4316 synchronized (mPidsSelfLocked) { 4317 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4318 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4319 if (p.uid != uid) { 4320 continue; 4321 } 4322 if (p.pid == initialPid) { 4323 proc = p; 4324 break; 4325 } 4326 if (p.pkgList.containsKey(packageName)) { 4327 proc = p; 4328 } 4329 } 4330 } 4331 4332 if (proc == null) { 4333 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4334 + " initialPid=" + initialPid 4335 + " packageName=" + packageName); 4336 return; 4337 } 4338 4339 if (proc.thread != null) { 4340 if (proc.pid == Process.myPid()) { 4341 Log.w(TAG, "crashApplication: trying to crash self!"); 4342 return; 4343 } 4344 long ident = Binder.clearCallingIdentity(); 4345 try { 4346 proc.thread.scheduleCrash(message); 4347 } catch (RemoteException e) { 4348 } 4349 Binder.restoreCallingIdentity(ident); 4350 } 4351 } 4352 } 4353 4354 @Override 4355 public final void finishSubActivity(IBinder token, String resultWho, 4356 int requestCode) { 4357 synchronized(this) { 4358 final long origId = Binder.clearCallingIdentity(); 4359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4360 if (r != null) { 4361 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4362 } 4363 Binder.restoreCallingIdentity(origId); 4364 } 4365 } 4366 4367 @Override 4368 public boolean finishActivityAffinity(IBinder token) { 4369 synchronized(this) { 4370 final long origId = Binder.clearCallingIdentity(); 4371 try { 4372 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4373 4374 ActivityRecord rootR = r.task.getRootActivity(); 4375 // Do not allow task to finish in Lock Task mode. 4376 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4377 if (rootR == r) { 4378 mStackSupervisor.showLockTaskToast(); 4379 return false; 4380 } 4381 } 4382 boolean res = false; 4383 if (r != null) { 4384 res = r.task.stack.finishActivityAffinityLocked(r); 4385 } 4386 return res; 4387 } finally { 4388 Binder.restoreCallingIdentity(origId); 4389 } 4390 } 4391 } 4392 4393 @Override 4394 public void finishVoiceTask(IVoiceInteractionSession session) { 4395 synchronized(this) { 4396 final long origId = Binder.clearCallingIdentity(); 4397 try { 4398 mStackSupervisor.finishVoiceTask(session); 4399 } finally { 4400 Binder.restoreCallingIdentity(origId); 4401 } 4402 } 4403 4404 } 4405 4406 @Override 4407 public boolean releaseActivityInstance(IBinder token) { 4408 synchronized(this) { 4409 final long origId = Binder.clearCallingIdentity(); 4410 try { 4411 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4412 if (r.task == null || r.task.stack == null) { 4413 return false; 4414 } 4415 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4416 } finally { 4417 Binder.restoreCallingIdentity(origId); 4418 } 4419 } 4420 } 4421 4422 @Override 4423 public void releaseSomeActivities(IApplicationThread appInt) { 4424 synchronized(this) { 4425 final long origId = Binder.clearCallingIdentity(); 4426 try { 4427 ProcessRecord app = getRecordForAppLocked(appInt); 4428 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4429 } finally { 4430 Binder.restoreCallingIdentity(origId); 4431 } 4432 } 4433 } 4434 4435 @Override 4436 public boolean willActivityBeVisible(IBinder token) { 4437 synchronized(this) { 4438 ActivityStack stack = ActivityRecord.getStackLocked(token); 4439 if (stack != null) { 4440 return stack.willActivityBeVisibleLocked(token); 4441 } 4442 return false; 4443 } 4444 } 4445 4446 @Override 4447 public void overridePendingTransition(IBinder token, String packageName, 4448 int enterAnim, int exitAnim) { 4449 synchronized(this) { 4450 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4451 if (self == null) { 4452 return; 4453 } 4454 4455 final long origId = Binder.clearCallingIdentity(); 4456 4457 if (self.state == ActivityState.RESUMED 4458 || self.state == ActivityState.PAUSING) { 4459 mWindowManager.overridePendingAppTransition(packageName, 4460 enterAnim, exitAnim, null); 4461 } 4462 4463 Binder.restoreCallingIdentity(origId); 4464 } 4465 } 4466 4467 /** 4468 * Main function for removing an existing process from the activity manager 4469 * as a result of that process going away. Clears out all connections 4470 * to the process. 4471 */ 4472 private final void handleAppDiedLocked(ProcessRecord app, 4473 boolean restarting, boolean allowRestart) { 4474 int pid = app.pid; 4475 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4476 if (!kept && !restarting) { 4477 removeLruProcessLocked(app); 4478 if (pid > 0) { 4479 ProcessList.remove(pid); 4480 } 4481 } 4482 4483 if (mProfileProc == app) { 4484 clearProfilerLocked(); 4485 } 4486 4487 // Remove this application's activities from active lists. 4488 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4489 4490 app.activities.clear(); 4491 4492 if (app.instrumentationClass != null) { 4493 Slog.w(TAG, "Crash of app " + app.processName 4494 + " running instrumentation " + app.instrumentationClass); 4495 Bundle info = new Bundle(); 4496 info.putString("shortMsg", "Process crashed."); 4497 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4498 } 4499 4500 if (!restarting) { 4501 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4502 // If there was nothing to resume, and we are not already 4503 // restarting this process, but there is a visible activity that 4504 // is hosted by the process... then make sure all visible 4505 // activities are running, taking care of restarting this 4506 // process. 4507 if (hasVisibleActivities) { 4508 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4509 } 4510 } 4511 } 4512 } 4513 4514 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4515 IBinder threadBinder = thread.asBinder(); 4516 // Find the application record. 4517 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4518 ProcessRecord rec = mLruProcesses.get(i); 4519 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4520 return i; 4521 } 4522 } 4523 return -1; 4524 } 4525 4526 final ProcessRecord getRecordForAppLocked( 4527 IApplicationThread thread) { 4528 if (thread == null) { 4529 return null; 4530 } 4531 4532 int appIndex = getLRURecordIndexForAppLocked(thread); 4533 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4534 } 4535 4536 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4537 // If there are no longer any background processes running, 4538 // and the app that died was not running instrumentation, 4539 // then tell everyone we are now low on memory. 4540 boolean haveBg = false; 4541 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4542 ProcessRecord rec = mLruProcesses.get(i); 4543 if (rec.thread != null 4544 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4545 haveBg = true; 4546 break; 4547 } 4548 } 4549 4550 if (!haveBg) { 4551 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4552 if (doReport) { 4553 long now = SystemClock.uptimeMillis(); 4554 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4555 doReport = false; 4556 } else { 4557 mLastMemUsageReportTime = now; 4558 } 4559 } 4560 final ArrayList<ProcessMemInfo> memInfos 4561 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4562 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4563 long now = SystemClock.uptimeMillis(); 4564 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4565 ProcessRecord rec = mLruProcesses.get(i); 4566 if (rec == dyingProc || rec.thread == null) { 4567 continue; 4568 } 4569 if (doReport) { 4570 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4571 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4572 } 4573 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4574 // The low memory report is overriding any current 4575 // state for a GC request. Make sure to do 4576 // heavy/important/visible/foreground processes first. 4577 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4578 rec.lastRequestedGc = 0; 4579 } else { 4580 rec.lastRequestedGc = rec.lastLowMemory; 4581 } 4582 rec.reportLowMemory = true; 4583 rec.lastLowMemory = now; 4584 mProcessesToGc.remove(rec); 4585 addProcessToGcListLocked(rec); 4586 } 4587 } 4588 if (doReport) { 4589 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4590 mHandler.sendMessage(msg); 4591 } 4592 scheduleAppGcsLocked(); 4593 } 4594 } 4595 4596 final void appDiedLocked(ProcessRecord app) { 4597 appDiedLocked(app, app.pid, app.thread); 4598 } 4599 4600 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4601 // First check if this ProcessRecord is actually active for the pid. 4602 synchronized (mPidsSelfLocked) { 4603 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4604 if (curProc != app) { 4605 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4606 return; 4607 } 4608 } 4609 4610 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4611 synchronized (stats) { 4612 stats.noteProcessDiedLocked(app.info.uid, pid); 4613 } 4614 4615 Process.killProcessQuiet(pid); 4616 Process.killProcessGroup(app.info.uid, pid); 4617 app.killed = true; 4618 4619 // Clean up already done if the process has been re-started. 4620 if (app.pid == pid && app.thread != null && 4621 app.thread.asBinder() == thread.asBinder()) { 4622 boolean doLowMem = app.instrumentationClass == null; 4623 boolean doOomAdj = doLowMem; 4624 if (!app.killedByAm) { 4625 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4626 + ") has died"); 4627 mAllowLowerMemLevel = true; 4628 } else { 4629 // Note that we always want to do oom adj to update our state with the 4630 // new number of procs. 4631 mAllowLowerMemLevel = false; 4632 doLowMem = false; 4633 } 4634 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4635 if (DEBUG_CLEANUP) Slog.v( 4636 TAG, "Dying app: " + app + ", pid: " + pid 4637 + ", thread: " + thread.asBinder()); 4638 handleAppDiedLocked(app, false, true); 4639 4640 if (doOomAdj) { 4641 updateOomAdjLocked(); 4642 } 4643 if (doLowMem) { 4644 doLowMemReportIfNeededLocked(app); 4645 } 4646 } else if (app.pid != pid) { 4647 // A new process has already been started. 4648 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4649 + ") has died and restarted (pid " + app.pid + ")."); 4650 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4651 } else if (DEBUG_PROCESSES) { 4652 Slog.d(TAG, "Received spurious death notification for thread " 4653 + thread.asBinder()); 4654 } 4655 } 4656 4657 /** 4658 * If a stack trace dump file is configured, dump process stack traces. 4659 * @param clearTraces causes the dump file to be erased prior to the new 4660 * traces being written, if true; when false, the new traces will be 4661 * appended to any existing file content. 4662 * @param firstPids of dalvik VM processes to dump stack traces for first 4663 * @param lastPids of dalvik VM processes to dump stack traces for last 4664 * @param nativeProcs optional list of native process names to dump stack crawls 4665 * @return file containing stack traces, or null if no dump file is configured 4666 */ 4667 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4668 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4669 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4670 if (tracesPath == null || tracesPath.length() == 0) { 4671 return null; 4672 } 4673 4674 File tracesFile = new File(tracesPath); 4675 try { 4676 File tracesDir = tracesFile.getParentFile(); 4677 if (!tracesDir.exists()) { 4678 tracesDir.mkdirs(); 4679 if (!SELinux.restorecon(tracesDir)) { 4680 return null; 4681 } 4682 } 4683 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4684 4685 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4686 tracesFile.createNewFile(); 4687 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4688 } catch (IOException e) { 4689 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4690 return null; 4691 } 4692 4693 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4694 return tracesFile; 4695 } 4696 4697 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4698 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4699 // Use a FileObserver to detect when traces finish writing. 4700 // The order of traces is considered important to maintain for legibility. 4701 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4702 @Override 4703 public synchronized void onEvent(int event, String path) { notify(); } 4704 }; 4705 4706 try { 4707 observer.startWatching(); 4708 4709 // First collect all of the stacks of the most important pids. 4710 if (firstPids != null) { 4711 try { 4712 int num = firstPids.size(); 4713 for (int i = 0; i < num; i++) { 4714 synchronized (observer) { 4715 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4716 observer.wait(200); // Wait for write-close, give up after 200msec 4717 } 4718 } 4719 } catch (InterruptedException e) { 4720 Slog.wtf(TAG, e); 4721 } 4722 } 4723 4724 // Next collect the stacks of the native pids 4725 if (nativeProcs != null) { 4726 int[] pids = Process.getPidsForCommands(nativeProcs); 4727 if (pids != null) { 4728 for (int pid : pids) { 4729 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4730 } 4731 } 4732 } 4733 4734 // Lastly, measure CPU usage. 4735 if (processCpuTracker != null) { 4736 processCpuTracker.init(); 4737 System.gc(); 4738 processCpuTracker.update(); 4739 try { 4740 synchronized (processCpuTracker) { 4741 processCpuTracker.wait(500); // measure over 1/2 second. 4742 } 4743 } catch (InterruptedException e) { 4744 } 4745 processCpuTracker.update(); 4746 4747 // We'll take the stack crawls of just the top apps using CPU. 4748 final int N = processCpuTracker.countWorkingStats(); 4749 int numProcs = 0; 4750 for (int i=0; i<N && numProcs<5; i++) { 4751 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4752 if (lastPids.indexOfKey(stats.pid) >= 0) { 4753 numProcs++; 4754 try { 4755 synchronized (observer) { 4756 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4757 observer.wait(200); // Wait for write-close, give up after 200msec 4758 } 4759 } catch (InterruptedException e) { 4760 Slog.wtf(TAG, e); 4761 } 4762 4763 } 4764 } 4765 } 4766 } finally { 4767 observer.stopWatching(); 4768 } 4769 } 4770 4771 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4772 if (true || IS_USER_BUILD) { 4773 return; 4774 } 4775 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4776 if (tracesPath == null || tracesPath.length() == 0) { 4777 return; 4778 } 4779 4780 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4781 StrictMode.allowThreadDiskWrites(); 4782 try { 4783 final File tracesFile = new File(tracesPath); 4784 final File tracesDir = tracesFile.getParentFile(); 4785 final File tracesTmp = new File(tracesDir, "__tmp__"); 4786 try { 4787 if (!tracesDir.exists()) { 4788 tracesDir.mkdirs(); 4789 if (!SELinux.restorecon(tracesDir.getPath())) { 4790 return; 4791 } 4792 } 4793 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4794 4795 if (tracesFile.exists()) { 4796 tracesTmp.delete(); 4797 tracesFile.renameTo(tracesTmp); 4798 } 4799 StringBuilder sb = new StringBuilder(); 4800 Time tobj = new Time(); 4801 tobj.set(System.currentTimeMillis()); 4802 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4803 sb.append(": "); 4804 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4805 sb.append(" since "); 4806 sb.append(msg); 4807 FileOutputStream fos = new FileOutputStream(tracesFile); 4808 fos.write(sb.toString().getBytes()); 4809 if (app == null) { 4810 fos.write("\n*** No application process!".getBytes()); 4811 } 4812 fos.close(); 4813 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4814 } catch (IOException e) { 4815 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4816 return; 4817 } 4818 4819 if (app != null) { 4820 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4821 firstPids.add(app.pid); 4822 dumpStackTraces(tracesPath, firstPids, null, null, null); 4823 } 4824 4825 File lastTracesFile = null; 4826 File curTracesFile = null; 4827 for (int i=9; i>=0; i--) { 4828 String name = String.format(Locale.US, "slow%02d.txt", i); 4829 curTracesFile = new File(tracesDir, name); 4830 if (curTracesFile.exists()) { 4831 if (lastTracesFile != null) { 4832 curTracesFile.renameTo(lastTracesFile); 4833 } else { 4834 curTracesFile.delete(); 4835 } 4836 } 4837 lastTracesFile = curTracesFile; 4838 } 4839 tracesFile.renameTo(curTracesFile); 4840 if (tracesTmp.exists()) { 4841 tracesTmp.renameTo(tracesFile); 4842 } 4843 } finally { 4844 StrictMode.setThreadPolicy(oldPolicy); 4845 } 4846 } 4847 4848 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4849 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4850 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4851 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4852 4853 if (mController != null) { 4854 try { 4855 // 0 == continue, -1 = kill process immediately 4856 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4857 if (res < 0 && app.pid != MY_PID) { 4858 app.kill("anr", true); 4859 } 4860 } catch (RemoteException e) { 4861 mController = null; 4862 Watchdog.getInstance().setActivityController(null); 4863 } 4864 } 4865 4866 long anrTime = SystemClock.uptimeMillis(); 4867 if (MONITOR_CPU_USAGE) { 4868 updateCpuStatsNow(); 4869 } 4870 4871 synchronized (this) { 4872 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4873 if (mShuttingDown) { 4874 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4875 return; 4876 } else if (app.notResponding) { 4877 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4878 return; 4879 } else if (app.crashing) { 4880 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4881 return; 4882 } 4883 4884 // In case we come through here for the same app before completing 4885 // this one, mark as anring now so we will bail out. 4886 app.notResponding = true; 4887 4888 // Log the ANR to the event log. 4889 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4890 app.processName, app.info.flags, annotation); 4891 4892 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4893 firstPids.add(app.pid); 4894 4895 int parentPid = app.pid; 4896 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4897 if (parentPid != app.pid) firstPids.add(parentPid); 4898 4899 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4900 4901 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4902 ProcessRecord r = mLruProcesses.get(i); 4903 if (r != null && r.thread != null) { 4904 int pid = r.pid; 4905 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4906 if (r.persistent) { 4907 firstPids.add(pid); 4908 } else { 4909 lastPids.put(pid, Boolean.TRUE); 4910 } 4911 } 4912 } 4913 } 4914 } 4915 4916 // Log the ANR to the main log. 4917 StringBuilder info = new StringBuilder(); 4918 info.setLength(0); 4919 info.append("ANR in ").append(app.processName); 4920 if (activity != null && activity.shortComponentName != null) { 4921 info.append(" (").append(activity.shortComponentName).append(")"); 4922 } 4923 info.append("\n"); 4924 info.append("PID: ").append(app.pid).append("\n"); 4925 if (annotation != null) { 4926 info.append("Reason: ").append(annotation).append("\n"); 4927 } 4928 if (parent != null && parent != activity) { 4929 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4930 } 4931 4932 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4933 4934 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4935 NATIVE_STACKS_OF_INTEREST); 4936 4937 String cpuInfo = null; 4938 if (MONITOR_CPU_USAGE) { 4939 updateCpuStatsNow(); 4940 synchronized (mProcessCpuTracker) { 4941 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4942 } 4943 info.append(processCpuTracker.printCurrentLoad()); 4944 info.append(cpuInfo); 4945 } 4946 4947 info.append(processCpuTracker.printCurrentState(anrTime)); 4948 4949 Slog.e(TAG, info.toString()); 4950 if (tracesFile == null) { 4951 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4952 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4953 } 4954 4955 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4956 cpuInfo, tracesFile, null); 4957 4958 if (mController != null) { 4959 try { 4960 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4961 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4962 if (res != 0) { 4963 if (res < 0 && app.pid != MY_PID) { 4964 app.kill("anr", true); 4965 } else { 4966 synchronized (this) { 4967 mServices.scheduleServiceTimeoutLocked(app); 4968 } 4969 } 4970 return; 4971 } 4972 } catch (RemoteException e) { 4973 mController = null; 4974 Watchdog.getInstance().setActivityController(null); 4975 } 4976 } 4977 4978 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4979 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4980 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4981 4982 synchronized (this) { 4983 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4984 app.kill("bg anr", true); 4985 return; 4986 } 4987 4988 // Set the app's notResponding state, and look up the errorReportReceiver 4989 makeAppNotRespondingLocked(app, 4990 activity != null ? activity.shortComponentName : null, 4991 annotation != null ? "ANR " + annotation : "ANR", 4992 info.toString()); 4993 4994 // Bring up the infamous App Not Responding dialog 4995 Message msg = Message.obtain(); 4996 HashMap<String, Object> map = new HashMap<String, Object>(); 4997 msg.what = SHOW_NOT_RESPONDING_MSG; 4998 msg.obj = map; 4999 msg.arg1 = aboveSystem ? 1 : 0; 5000 map.put("app", app); 5001 if (activity != null) { 5002 map.put("activity", activity); 5003 } 5004 5005 mHandler.sendMessage(msg); 5006 } 5007 } 5008 5009 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5010 if (!mLaunchWarningShown) { 5011 mLaunchWarningShown = true; 5012 mHandler.post(new Runnable() { 5013 @Override 5014 public void run() { 5015 synchronized (ActivityManagerService.this) { 5016 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5017 d.show(); 5018 mHandler.postDelayed(new Runnable() { 5019 @Override 5020 public void run() { 5021 synchronized (ActivityManagerService.this) { 5022 d.dismiss(); 5023 mLaunchWarningShown = false; 5024 } 5025 } 5026 }, 4000); 5027 } 5028 } 5029 }); 5030 } 5031 } 5032 5033 @Override 5034 public boolean clearApplicationUserData(final String packageName, 5035 final IPackageDataObserver observer, int userId) { 5036 enforceNotIsolatedCaller("clearApplicationUserData"); 5037 int uid = Binder.getCallingUid(); 5038 int pid = Binder.getCallingPid(); 5039 userId = handleIncomingUser(pid, uid, 5040 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5041 long callingId = Binder.clearCallingIdentity(); 5042 try { 5043 IPackageManager pm = AppGlobals.getPackageManager(); 5044 int pkgUid = -1; 5045 synchronized(this) { 5046 try { 5047 pkgUid = pm.getPackageUid(packageName, userId); 5048 } catch (RemoteException e) { 5049 } 5050 if (pkgUid == -1) { 5051 Slog.w(TAG, "Invalid packageName: " + packageName); 5052 if (observer != null) { 5053 try { 5054 observer.onRemoveCompleted(packageName, false); 5055 } catch (RemoteException e) { 5056 Slog.i(TAG, "Observer no longer exists."); 5057 } 5058 } 5059 return false; 5060 } 5061 if (uid == pkgUid || checkComponentPermission( 5062 android.Manifest.permission.CLEAR_APP_USER_DATA, 5063 pid, uid, -1, true) 5064 == PackageManager.PERMISSION_GRANTED) { 5065 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5066 } else { 5067 throw new SecurityException("PID " + pid + " does not have permission " 5068 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5069 + " of package " + packageName); 5070 } 5071 5072 // Remove all tasks match the cleared application package and user 5073 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5074 final TaskRecord tr = mRecentTasks.get(i); 5075 final String taskPackageName = 5076 tr.getBaseIntent().getComponent().getPackageName(); 5077 if (tr.userId != userId) continue; 5078 if (!taskPackageName.equals(packageName)) continue; 5079 removeTaskByIdLocked(tr.taskId, false); 5080 } 5081 } 5082 5083 try { 5084 // Clear application user data 5085 pm.clearApplicationUserData(packageName, observer, userId); 5086 5087 synchronized(this) { 5088 // Remove all permissions granted from/to this package 5089 removeUriPermissionsForPackageLocked(packageName, userId, true); 5090 } 5091 5092 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5093 Uri.fromParts("package", packageName, null)); 5094 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5095 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5096 null, null, 0, null, null, null, false, false, userId); 5097 } catch (RemoteException e) { 5098 } 5099 } finally { 5100 Binder.restoreCallingIdentity(callingId); 5101 } 5102 return true; 5103 } 5104 5105 @Override 5106 public void killBackgroundProcesses(final String packageName, int userId) { 5107 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5108 != PackageManager.PERMISSION_GRANTED && 5109 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5110 != PackageManager.PERMISSION_GRANTED) { 5111 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5112 + Binder.getCallingPid() 5113 + ", uid=" + Binder.getCallingUid() 5114 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5115 Slog.w(TAG, msg); 5116 throw new SecurityException(msg); 5117 } 5118 5119 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5120 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5121 long callingId = Binder.clearCallingIdentity(); 5122 try { 5123 IPackageManager pm = AppGlobals.getPackageManager(); 5124 synchronized(this) { 5125 int appId = -1; 5126 try { 5127 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5128 } catch (RemoteException e) { 5129 } 5130 if (appId == -1) { 5131 Slog.w(TAG, "Invalid packageName: " + packageName); 5132 return; 5133 } 5134 killPackageProcessesLocked(packageName, appId, userId, 5135 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5136 } 5137 } finally { 5138 Binder.restoreCallingIdentity(callingId); 5139 } 5140 } 5141 5142 @Override 5143 public void killAllBackgroundProcesses() { 5144 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5145 != PackageManager.PERMISSION_GRANTED) { 5146 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5147 + Binder.getCallingPid() 5148 + ", uid=" + Binder.getCallingUid() 5149 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5150 Slog.w(TAG, msg); 5151 throw new SecurityException(msg); 5152 } 5153 5154 long callingId = Binder.clearCallingIdentity(); 5155 try { 5156 synchronized(this) { 5157 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5158 final int NP = mProcessNames.getMap().size(); 5159 for (int ip=0; ip<NP; ip++) { 5160 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5161 final int NA = apps.size(); 5162 for (int ia=0; ia<NA; ia++) { 5163 ProcessRecord app = apps.valueAt(ia); 5164 if (app.persistent) { 5165 // we don't kill persistent processes 5166 continue; 5167 } 5168 if (app.removed) { 5169 procs.add(app); 5170 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5171 app.removed = true; 5172 procs.add(app); 5173 } 5174 } 5175 } 5176 5177 int N = procs.size(); 5178 for (int i=0; i<N; i++) { 5179 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5180 } 5181 mAllowLowerMemLevel = true; 5182 updateOomAdjLocked(); 5183 doLowMemReportIfNeededLocked(null); 5184 } 5185 } finally { 5186 Binder.restoreCallingIdentity(callingId); 5187 } 5188 } 5189 5190 @Override 5191 public void forceStopPackage(final String packageName, int userId) { 5192 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5193 != PackageManager.PERMISSION_GRANTED) { 5194 String msg = "Permission Denial: forceStopPackage() from pid=" 5195 + Binder.getCallingPid() 5196 + ", uid=" + Binder.getCallingUid() 5197 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5198 Slog.w(TAG, msg); 5199 throw new SecurityException(msg); 5200 } 5201 final int callingPid = Binder.getCallingPid(); 5202 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5203 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5204 long callingId = Binder.clearCallingIdentity(); 5205 try { 5206 IPackageManager pm = AppGlobals.getPackageManager(); 5207 synchronized(this) { 5208 int[] users = userId == UserHandle.USER_ALL 5209 ? getUsersLocked() : new int[] { userId }; 5210 for (int user : users) { 5211 int pkgUid = -1; 5212 try { 5213 pkgUid = pm.getPackageUid(packageName, user); 5214 } catch (RemoteException e) { 5215 } 5216 if (pkgUid == -1) { 5217 Slog.w(TAG, "Invalid packageName: " + packageName); 5218 continue; 5219 } 5220 try { 5221 pm.setPackageStoppedState(packageName, true, user); 5222 } catch (RemoteException e) { 5223 } catch (IllegalArgumentException e) { 5224 Slog.w(TAG, "Failed trying to unstop package " 5225 + packageName + ": " + e); 5226 } 5227 if (isUserRunningLocked(user, false)) { 5228 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5229 } 5230 } 5231 } 5232 } finally { 5233 Binder.restoreCallingIdentity(callingId); 5234 } 5235 } 5236 5237 @Override 5238 public void addPackageDependency(String packageName) { 5239 synchronized (this) { 5240 int callingPid = Binder.getCallingPid(); 5241 if (callingPid == Process.myPid()) { 5242 // Yeah, um, no. 5243 Slog.w(TAG, "Can't addPackageDependency on system process"); 5244 return; 5245 } 5246 ProcessRecord proc; 5247 synchronized (mPidsSelfLocked) { 5248 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5249 } 5250 if (proc != null) { 5251 if (proc.pkgDeps == null) { 5252 proc.pkgDeps = new ArraySet<String>(1); 5253 } 5254 proc.pkgDeps.add(packageName); 5255 } 5256 } 5257 } 5258 5259 /* 5260 * The pkg name and app id have to be specified. 5261 */ 5262 @Override 5263 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5264 if (pkg == null) { 5265 return; 5266 } 5267 // Make sure the uid is valid. 5268 if (appid < 0) { 5269 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5270 return; 5271 } 5272 int callerUid = Binder.getCallingUid(); 5273 // Only the system server can kill an application 5274 if (callerUid == Process.SYSTEM_UID) { 5275 // Post an aysnc message to kill the application 5276 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5277 msg.arg1 = appid; 5278 msg.arg2 = 0; 5279 Bundle bundle = new Bundle(); 5280 bundle.putString("pkg", pkg); 5281 bundle.putString("reason", reason); 5282 msg.obj = bundle; 5283 mHandler.sendMessage(msg); 5284 } else { 5285 throw new SecurityException(callerUid + " cannot kill pkg: " + 5286 pkg); 5287 } 5288 } 5289 5290 @Override 5291 public void closeSystemDialogs(String reason) { 5292 enforceNotIsolatedCaller("closeSystemDialogs"); 5293 5294 final int pid = Binder.getCallingPid(); 5295 final int uid = Binder.getCallingUid(); 5296 final long origId = Binder.clearCallingIdentity(); 5297 try { 5298 synchronized (this) { 5299 // Only allow this from foreground processes, so that background 5300 // applications can't abuse it to prevent system UI from being shown. 5301 if (uid >= Process.FIRST_APPLICATION_UID) { 5302 ProcessRecord proc; 5303 synchronized (mPidsSelfLocked) { 5304 proc = mPidsSelfLocked.get(pid); 5305 } 5306 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5307 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5308 + " from background process " + proc); 5309 return; 5310 } 5311 } 5312 closeSystemDialogsLocked(reason); 5313 } 5314 } finally { 5315 Binder.restoreCallingIdentity(origId); 5316 } 5317 } 5318 5319 void closeSystemDialogsLocked(String reason) { 5320 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5321 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5322 | Intent.FLAG_RECEIVER_FOREGROUND); 5323 if (reason != null) { 5324 intent.putExtra("reason", reason); 5325 } 5326 mWindowManager.closeSystemDialogs(reason); 5327 5328 mStackSupervisor.closeSystemDialogsLocked(); 5329 5330 broadcastIntentLocked(null, null, intent, null, 5331 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5332 Process.SYSTEM_UID, UserHandle.USER_ALL); 5333 } 5334 5335 @Override 5336 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5337 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5338 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5339 for (int i=pids.length-1; i>=0; i--) { 5340 ProcessRecord proc; 5341 int oomAdj; 5342 synchronized (this) { 5343 synchronized (mPidsSelfLocked) { 5344 proc = mPidsSelfLocked.get(pids[i]); 5345 oomAdj = proc != null ? proc.setAdj : 0; 5346 } 5347 } 5348 infos[i] = new Debug.MemoryInfo(); 5349 Debug.getMemoryInfo(pids[i], infos[i]); 5350 if (proc != null) { 5351 synchronized (this) { 5352 if (proc.thread != null && proc.setAdj == oomAdj) { 5353 // Record this for posterity if the process has been stable. 5354 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5355 infos[i].getTotalUss(), false, proc.pkgList); 5356 } 5357 } 5358 } 5359 } 5360 return infos; 5361 } 5362 5363 @Override 5364 public long[] getProcessPss(int[] pids) { 5365 enforceNotIsolatedCaller("getProcessPss"); 5366 long[] pss = new long[pids.length]; 5367 for (int i=pids.length-1; i>=0; i--) { 5368 ProcessRecord proc; 5369 int oomAdj; 5370 synchronized (this) { 5371 synchronized (mPidsSelfLocked) { 5372 proc = mPidsSelfLocked.get(pids[i]); 5373 oomAdj = proc != null ? proc.setAdj : 0; 5374 } 5375 } 5376 long[] tmpUss = new long[1]; 5377 pss[i] = Debug.getPss(pids[i], tmpUss); 5378 if (proc != null) { 5379 synchronized (this) { 5380 if (proc.thread != null && proc.setAdj == oomAdj) { 5381 // Record this for posterity if the process has been stable. 5382 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5383 } 5384 } 5385 } 5386 } 5387 return pss; 5388 } 5389 5390 @Override 5391 public void killApplicationProcess(String processName, int uid) { 5392 if (processName == null) { 5393 return; 5394 } 5395 5396 int callerUid = Binder.getCallingUid(); 5397 // Only the system server can kill an application 5398 if (callerUid == Process.SYSTEM_UID) { 5399 synchronized (this) { 5400 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5401 if (app != null && app.thread != null) { 5402 try { 5403 app.thread.scheduleSuicide(); 5404 } catch (RemoteException e) { 5405 // If the other end already died, then our work here is done. 5406 } 5407 } else { 5408 Slog.w(TAG, "Process/uid not found attempting kill of " 5409 + processName + " / " + uid); 5410 } 5411 } 5412 } else { 5413 throw new SecurityException(callerUid + " cannot kill app process: " + 5414 processName); 5415 } 5416 } 5417 5418 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5419 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5420 false, true, false, false, UserHandle.getUserId(uid), reason); 5421 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5422 Uri.fromParts("package", packageName, null)); 5423 if (!mProcessesReady) { 5424 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5425 | Intent.FLAG_RECEIVER_FOREGROUND); 5426 } 5427 intent.putExtra(Intent.EXTRA_UID, uid); 5428 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5429 broadcastIntentLocked(null, null, intent, 5430 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5431 false, false, 5432 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5433 } 5434 5435 private void forceStopUserLocked(int userId, String reason) { 5436 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5437 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5438 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5439 | Intent.FLAG_RECEIVER_FOREGROUND); 5440 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5441 broadcastIntentLocked(null, null, intent, 5442 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5443 false, false, 5444 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5445 } 5446 5447 private final boolean killPackageProcessesLocked(String packageName, int appId, 5448 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5449 boolean doit, boolean evenPersistent, String reason) { 5450 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5451 5452 // Remove all processes this package may have touched: all with the 5453 // same UID (except for the system or root user), and all whose name 5454 // matches the package name. 5455 final int NP = mProcessNames.getMap().size(); 5456 for (int ip=0; ip<NP; ip++) { 5457 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5458 final int NA = apps.size(); 5459 for (int ia=0; ia<NA; ia++) { 5460 ProcessRecord app = apps.valueAt(ia); 5461 if (app.persistent && !evenPersistent) { 5462 // we don't kill persistent processes 5463 continue; 5464 } 5465 if (app.removed) { 5466 if (doit) { 5467 procs.add(app); 5468 } 5469 continue; 5470 } 5471 5472 // Skip process if it doesn't meet our oom adj requirement. 5473 if (app.setAdj < minOomAdj) { 5474 continue; 5475 } 5476 5477 // If no package is specified, we call all processes under the 5478 // give user id. 5479 if (packageName == null) { 5480 if (app.userId != userId) { 5481 continue; 5482 } 5483 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5484 continue; 5485 } 5486 // Package has been specified, we want to hit all processes 5487 // that match it. We need to qualify this by the processes 5488 // that are running under the specified app and user ID. 5489 } else { 5490 final boolean isDep = app.pkgDeps != null 5491 && app.pkgDeps.contains(packageName); 5492 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5493 continue; 5494 } 5495 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5496 continue; 5497 } 5498 if (!app.pkgList.containsKey(packageName) && !isDep) { 5499 continue; 5500 } 5501 } 5502 5503 // Process has passed all conditions, kill it! 5504 if (!doit) { 5505 return true; 5506 } 5507 app.removed = true; 5508 procs.add(app); 5509 } 5510 } 5511 5512 int N = procs.size(); 5513 for (int i=0; i<N; i++) { 5514 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5515 } 5516 updateOomAdjLocked(); 5517 return N > 0; 5518 } 5519 5520 private final boolean forceStopPackageLocked(String name, int appId, 5521 boolean callerWillRestart, boolean purgeCache, boolean doit, 5522 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5523 int i; 5524 int N; 5525 5526 if (userId == UserHandle.USER_ALL && name == null) { 5527 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5528 } 5529 5530 if (appId < 0 && name != null) { 5531 try { 5532 appId = UserHandle.getAppId( 5533 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5534 } catch (RemoteException e) { 5535 } 5536 } 5537 5538 if (doit) { 5539 if (name != null) { 5540 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5541 + " user=" + userId + ": " + reason); 5542 } else { 5543 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5544 } 5545 5546 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5547 for (int ip=pmap.size()-1; ip>=0; ip--) { 5548 SparseArray<Long> ba = pmap.valueAt(ip); 5549 for (i=ba.size()-1; i>=0; i--) { 5550 boolean remove = false; 5551 final int entUid = ba.keyAt(i); 5552 if (name != null) { 5553 if (userId == UserHandle.USER_ALL) { 5554 if (UserHandle.getAppId(entUid) == appId) { 5555 remove = true; 5556 } 5557 } else { 5558 if (entUid == UserHandle.getUid(userId, appId)) { 5559 remove = true; 5560 } 5561 } 5562 } else if (UserHandle.getUserId(entUid) == userId) { 5563 remove = true; 5564 } 5565 if (remove) { 5566 ba.removeAt(i); 5567 } 5568 } 5569 if (ba.size() == 0) { 5570 pmap.removeAt(ip); 5571 } 5572 } 5573 } 5574 5575 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5576 -100, callerWillRestart, true, doit, evenPersistent, 5577 name == null ? ("stop user " + userId) : ("stop " + name)); 5578 5579 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5580 if (!doit) { 5581 return true; 5582 } 5583 didSomething = true; 5584 } 5585 5586 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5587 if (!doit) { 5588 return true; 5589 } 5590 didSomething = true; 5591 } 5592 5593 if (name == null) { 5594 // Remove all sticky broadcasts from this user. 5595 mStickyBroadcasts.remove(userId); 5596 } 5597 5598 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5599 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5600 userId, providers)) { 5601 if (!doit) { 5602 return true; 5603 } 5604 didSomething = true; 5605 } 5606 N = providers.size(); 5607 for (i=0; i<N; i++) { 5608 removeDyingProviderLocked(null, providers.get(i), true); 5609 } 5610 5611 // Remove transient permissions granted from/to this package/user 5612 removeUriPermissionsForPackageLocked(name, userId, false); 5613 5614 if (name == null || uninstalling) { 5615 // Remove pending intents. For now we only do this when force 5616 // stopping users, because we have some problems when doing this 5617 // for packages -- app widgets are not currently cleaned up for 5618 // such packages, so they can be left with bad pending intents. 5619 if (mIntentSenderRecords.size() > 0) { 5620 Iterator<WeakReference<PendingIntentRecord>> it 5621 = mIntentSenderRecords.values().iterator(); 5622 while (it.hasNext()) { 5623 WeakReference<PendingIntentRecord> wpir = it.next(); 5624 if (wpir == null) { 5625 it.remove(); 5626 continue; 5627 } 5628 PendingIntentRecord pir = wpir.get(); 5629 if (pir == null) { 5630 it.remove(); 5631 continue; 5632 } 5633 if (name == null) { 5634 // Stopping user, remove all objects for the user. 5635 if (pir.key.userId != userId) { 5636 // Not the same user, skip it. 5637 continue; 5638 } 5639 } else { 5640 if (UserHandle.getAppId(pir.uid) != appId) { 5641 // Different app id, skip it. 5642 continue; 5643 } 5644 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5645 // Different user, skip it. 5646 continue; 5647 } 5648 if (!pir.key.packageName.equals(name)) { 5649 // Different package, skip it. 5650 continue; 5651 } 5652 } 5653 if (!doit) { 5654 return true; 5655 } 5656 didSomething = true; 5657 it.remove(); 5658 pir.canceled = true; 5659 if (pir.key.activity != null) { 5660 pir.key.activity.pendingResults.remove(pir.ref); 5661 } 5662 } 5663 } 5664 } 5665 5666 if (doit) { 5667 if (purgeCache && name != null) { 5668 AttributeCache ac = AttributeCache.instance(); 5669 if (ac != null) { 5670 ac.removePackage(name); 5671 } 5672 } 5673 if (mBooted) { 5674 mStackSupervisor.resumeTopActivitiesLocked(); 5675 mStackSupervisor.scheduleIdleLocked(); 5676 } 5677 } 5678 5679 return didSomething; 5680 } 5681 5682 private final boolean removeProcessLocked(ProcessRecord app, 5683 boolean callerWillRestart, boolean allowRestart, String reason) { 5684 final String name = app.processName; 5685 final int uid = app.uid; 5686 if (DEBUG_PROCESSES) Slog.d( 5687 TAG, "Force removing proc " + app.toShortString() + " (" + name 5688 + "/" + uid + ")"); 5689 5690 mProcessNames.remove(name, uid); 5691 mIsolatedProcesses.remove(app.uid); 5692 if (mHeavyWeightProcess == app) { 5693 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5694 mHeavyWeightProcess.userId, 0)); 5695 mHeavyWeightProcess = null; 5696 } 5697 boolean needRestart = false; 5698 if (app.pid > 0 && app.pid != MY_PID) { 5699 int pid = app.pid; 5700 synchronized (mPidsSelfLocked) { 5701 mPidsSelfLocked.remove(pid); 5702 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5703 } 5704 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5705 if (app.isolated) { 5706 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5707 } 5708 app.kill(reason, true); 5709 handleAppDiedLocked(app, true, allowRestart); 5710 removeLruProcessLocked(app); 5711 5712 if (app.persistent && !app.isolated) { 5713 if (!callerWillRestart) { 5714 addAppLocked(app.info, false, null /* ABI override */); 5715 } else { 5716 needRestart = true; 5717 } 5718 } 5719 } else { 5720 mRemovedProcesses.add(app); 5721 } 5722 5723 return needRestart; 5724 } 5725 5726 private final void processStartTimedOutLocked(ProcessRecord app) { 5727 final int pid = app.pid; 5728 boolean gone = false; 5729 synchronized (mPidsSelfLocked) { 5730 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5731 if (knownApp != null && knownApp.thread == null) { 5732 mPidsSelfLocked.remove(pid); 5733 gone = true; 5734 } 5735 } 5736 5737 if (gone) { 5738 Slog.w(TAG, "Process " + app + " failed to attach"); 5739 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5740 pid, app.uid, app.processName); 5741 mProcessNames.remove(app.processName, app.uid); 5742 mIsolatedProcesses.remove(app.uid); 5743 if (mHeavyWeightProcess == app) { 5744 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5745 mHeavyWeightProcess.userId, 0)); 5746 mHeavyWeightProcess = null; 5747 } 5748 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5749 if (app.isolated) { 5750 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5751 } 5752 // Take care of any launching providers waiting for this process. 5753 checkAppInLaunchingProvidersLocked(app, true); 5754 // Take care of any services that are waiting for the process. 5755 mServices.processStartTimedOutLocked(app); 5756 app.kill("start timeout", true); 5757 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5758 Slog.w(TAG, "Unattached app died before backup, skipping"); 5759 try { 5760 IBackupManager bm = IBackupManager.Stub.asInterface( 5761 ServiceManager.getService(Context.BACKUP_SERVICE)); 5762 bm.agentDisconnected(app.info.packageName); 5763 } catch (RemoteException e) { 5764 // Can't happen; the backup manager is local 5765 } 5766 } 5767 if (isPendingBroadcastProcessLocked(pid)) { 5768 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5769 skipPendingBroadcastLocked(pid); 5770 } 5771 } else { 5772 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5773 } 5774 } 5775 5776 private final boolean attachApplicationLocked(IApplicationThread thread, 5777 int pid) { 5778 5779 // Find the application record that is being attached... either via 5780 // the pid if we are running in multiple processes, or just pull the 5781 // next app record if we are emulating process with anonymous threads. 5782 ProcessRecord app; 5783 if (pid != MY_PID && pid >= 0) { 5784 synchronized (mPidsSelfLocked) { 5785 app = mPidsSelfLocked.get(pid); 5786 } 5787 } else { 5788 app = null; 5789 } 5790 5791 if (app == null) { 5792 Slog.w(TAG, "No pending application record for pid " + pid 5793 + " (IApplicationThread " + thread + "); dropping process"); 5794 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5795 if (pid > 0 && pid != MY_PID) { 5796 Process.killProcessQuiet(pid); 5797 //TODO: Process.killProcessGroup(app.info.uid, pid); 5798 } else { 5799 try { 5800 thread.scheduleExit(); 5801 } catch (Exception e) { 5802 // Ignore exceptions. 5803 } 5804 } 5805 return false; 5806 } 5807 5808 // If this application record is still attached to a previous 5809 // process, clean it up now. 5810 if (app.thread != null) { 5811 handleAppDiedLocked(app, true, true); 5812 } 5813 5814 // Tell the process all about itself. 5815 5816 if (localLOGV) Slog.v( 5817 TAG, "Binding process pid " + pid + " to record " + app); 5818 5819 final String processName = app.processName; 5820 try { 5821 AppDeathRecipient adr = new AppDeathRecipient( 5822 app, pid, thread); 5823 thread.asBinder().linkToDeath(adr, 0); 5824 app.deathRecipient = adr; 5825 } catch (RemoteException e) { 5826 app.resetPackageList(mProcessStats); 5827 startProcessLocked(app, "link fail", processName); 5828 return false; 5829 } 5830 5831 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5832 5833 app.makeActive(thread, mProcessStats); 5834 app.curAdj = app.setAdj = -100; 5835 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5836 app.forcingToForeground = null; 5837 updateProcessForegroundLocked(app, false, false); 5838 app.hasShownUi = false; 5839 app.debugging = false; 5840 app.cached = false; 5841 5842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5843 5844 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5845 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5846 5847 if (!normalMode) { 5848 Slog.i(TAG, "Launching preboot mode app: " + app); 5849 } 5850 5851 if (localLOGV) Slog.v( 5852 TAG, "New app record " + app 5853 + " thread=" + thread.asBinder() + " pid=" + pid); 5854 try { 5855 int testMode = IApplicationThread.DEBUG_OFF; 5856 if (mDebugApp != null && mDebugApp.equals(processName)) { 5857 testMode = mWaitForDebugger 5858 ? IApplicationThread.DEBUG_WAIT 5859 : IApplicationThread.DEBUG_ON; 5860 app.debugging = true; 5861 if (mDebugTransient) { 5862 mDebugApp = mOrigDebugApp; 5863 mWaitForDebugger = mOrigWaitForDebugger; 5864 } 5865 } 5866 String profileFile = app.instrumentationProfileFile; 5867 ParcelFileDescriptor profileFd = null; 5868 int samplingInterval = 0; 5869 boolean profileAutoStop = false; 5870 if (mProfileApp != null && mProfileApp.equals(processName)) { 5871 mProfileProc = app; 5872 profileFile = mProfileFile; 5873 profileFd = mProfileFd; 5874 samplingInterval = mSamplingInterval; 5875 profileAutoStop = mAutoStopProfiler; 5876 } 5877 boolean enableOpenGlTrace = false; 5878 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5879 enableOpenGlTrace = true; 5880 mOpenGlTraceApp = null; 5881 } 5882 5883 // If the app is being launched for restore or full backup, set it up specially 5884 boolean isRestrictedBackupMode = false; 5885 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5886 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5887 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5888 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5889 } 5890 5891 ensurePackageDexOpt(app.instrumentationInfo != null 5892 ? app.instrumentationInfo.packageName 5893 : app.info.packageName); 5894 if (app.instrumentationClass != null) { 5895 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5896 } 5897 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5898 + processName + " with config " + mConfiguration); 5899 ApplicationInfo appInfo = app.instrumentationInfo != null 5900 ? app.instrumentationInfo : app.info; 5901 app.compat = compatibilityInfoForPackageLocked(appInfo); 5902 if (profileFd != null) { 5903 profileFd = profileFd.dup(); 5904 } 5905 ProfilerInfo profilerInfo = profileFile == null ? null 5906 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5907 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5908 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5909 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5910 isRestrictedBackupMode || !normalMode, app.persistent, 5911 new Configuration(mConfiguration), app.compat, 5912 getCommonServicesLocked(app.isolated), 5913 mCoreSettingsObserver.getCoreSettingsLocked()); 5914 updateLruProcessLocked(app, false, null); 5915 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5916 } catch (Exception e) { 5917 // todo: Yikes! What should we do? For now we will try to 5918 // start another process, but that could easily get us in 5919 // an infinite loop of restarting processes... 5920 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5921 5922 app.resetPackageList(mProcessStats); 5923 app.unlinkDeathRecipient(); 5924 startProcessLocked(app, "bind fail", processName); 5925 return false; 5926 } 5927 5928 // Remove this record from the list of starting applications. 5929 mPersistentStartingProcesses.remove(app); 5930 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5931 "Attach application locked removing on hold: " + app); 5932 mProcessesOnHold.remove(app); 5933 5934 boolean badApp = false; 5935 boolean didSomething = false; 5936 5937 // See if the top visible activity is waiting to run in this process... 5938 if (normalMode) { 5939 try { 5940 if (mStackSupervisor.attachApplicationLocked(app)) { 5941 didSomething = true; 5942 } 5943 } catch (Exception e) { 5944 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5945 badApp = true; 5946 } 5947 } 5948 5949 // Find any services that should be running in this process... 5950 if (!badApp) { 5951 try { 5952 didSomething |= mServices.attachApplicationLocked(app, processName); 5953 } catch (Exception e) { 5954 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5955 badApp = true; 5956 } 5957 } 5958 5959 // Check if a next-broadcast receiver is in this process... 5960 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5961 try { 5962 didSomething |= sendPendingBroadcastsLocked(app); 5963 } catch (Exception e) { 5964 // If the app died trying to launch the receiver we declare it 'bad' 5965 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5966 badApp = true; 5967 } 5968 } 5969 5970 // Check whether the next backup agent is in this process... 5971 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5972 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5973 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5974 try { 5975 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5976 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5977 mBackupTarget.backupMode); 5978 } catch (Exception e) { 5979 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5980 badApp = true; 5981 } 5982 } 5983 5984 if (badApp) { 5985 app.kill("error during init", true); 5986 handleAppDiedLocked(app, false, true); 5987 return false; 5988 } 5989 5990 if (!didSomething) { 5991 updateOomAdjLocked(); 5992 } 5993 5994 return true; 5995 } 5996 5997 @Override 5998 public final void attachApplication(IApplicationThread thread) { 5999 synchronized (this) { 6000 int callingPid = Binder.getCallingPid(); 6001 final long origId = Binder.clearCallingIdentity(); 6002 attachApplicationLocked(thread, callingPid); 6003 Binder.restoreCallingIdentity(origId); 6004 } 6005 } 6006 6007 @Override 6008 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6009 final long origId = Binder.clearCallingIdentity(); 6010 synchronized (this) { 6011 ActivityStack stack = ActivityRecord.getStackLocked(token); 6012 if (stack != null) { 6013 ActivityRecord r = 6014 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6015 if (stopProfiling) { 6016 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6017 try { 6018 mProfileFd.close(); 6019 } catch (IOException e) { 6020 } 6021 clearProfilerLocked(); 6022 } 6023 } 6024 } 6025 } 6026 Binder.restoreCallingIdentity(origId); 6027 } 6028 6029 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6030 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6031 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6032 } 6033 6034 void enableScreenAfterBoot() { 6035 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6036 SystemClock.uptimeMillis()); 6037 mWindowManager.enableScreenAfterBoot(); 6038 6039 synchronized (this) { 6040 updateEventDispatchingLocked(); 6041 } 6042 } 6043 6044 @Override 6045 public void showBootMessage(final CharSequence msg, final boolean always) { 6046 enforceNotIsolatedCaller("showBootMessage"); 6047 mWindowManager.showBootMessage(msg, always); 6048 } 6049 6050 @Override 6051 public void keyguardWaitingForActivityDrawn() { 6052 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6053 final long token = Binder.clearCallingIdentity(); 6054 try { 6055 synchronized (this) { 6056 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6057 mWindowManager.keyguardWaitingForActivityDrawn(); 6058 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6059 mLockScreenShown = LOCK_SCREEN_LEAVING; 6060 } 6061 } 6062 } finally { 6063 Binder.restoreCallingIdentity(token); 6064 } 6065 } 6066 6067 final void finishBooting() { 6068 synchronized (this) { 6069 if (!mBootAnimationComplete) { 6070 mCallFinishBooting = true; 6071 return; 6072 } 6073 mCallFinishBooting = false; 6074 } 6075 6076 ArraySet<String> completedIsas = new ArraySet<String>(); 6077 for (String abi : Build.SUPPORTED_ABIS) { 6078 Process.establishZygoteConnectionForAbi(abi); 6079 final String instructionSet = VMRuntime.getInstructionSet(abi); 6080 if (!completedIsas.contains(instructionSet)) { 6081 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6082 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6083 } 6084 completedIsas.add(instructionSet); 6085 } 6086 } 6087 6088 IntentFilter pkgFilter = new IntentFilter(); 6089 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6090 pkgFilter.addDataScheme("package"); 6091 mContext.registerReceiver(new BroadcastReceiver() { 6092 @Override 6093 public void onReceive(Context context, Intent intent) { 6094 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6095 if (pkgs != null) { 6096 for (String pkg : pkgs) { 6097 synchronized (ActivityManagerService.this) { 6098 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6099 0, "finished booting")) { 6100 setResultCode(Activity.RESULT_OK); 6101 return; 6102 } 6103 } 6104 } 6105 } 6106 } 6107 }, pkgFilter); 6108 6109 // Let system services know. 6110 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6111 6112 synchronized (this) { 6113 // Ensure that any processes we had put on hold are now started 6114 // up. 6115 final int NP = mProcessesOnHold.size(); 6116 if (NP > 0) { 6117 ArrayList<ProcessRecord> procs = 6118 new ArrayList<ProcessRecord>(mProcessesOnHold); 6119 for (int ip=0; ip<NP; ip++) { 6120 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6121 + procs.get(ip)); 6122 startProcessLocked(procs.get(ip), "on-hold", null); 6123 } 6124 } 6125 6126 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6127 // Start looking for apps that are abusing wake locks. 6128 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6129 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6130 // Tell anyone interested that we are done booting! 6131 SystemProperties.set("sys.boot_completed", "1"); 6132 6133 // And trigger dev.bootcomplete if we are not showing encryption progress 6134 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6135 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6136 SystemProperties.set("dev.bootcomplete", "1"); 6137 } 6138 for (int i=0; i<mStartedUsers.size(); i++) { 6139 UserStartedState uss = mStartedUsers.valueAt(i); 6140 if (uss.mState == UserStartedState.STATE_BOOTING) { 6141 uss.mState = UserStartedState.STATE_RUNNING; 6142 final int userId = mStartedUsers.keyAt(i); 6143 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6144 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6145 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6146 broadcastIntentLocked(null, null, intent, null, 6147 new IIntentReceiver.Stub() { 6148 @Override 6149 public void performReceive(Intent intent, int resultCode, 6150 String data, Bundle extras, boolean ordered, 6151 boolean sticky, int sendingUser) { 6152 synchronized (ActivityManagerService.this) { 6153 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6154 true, false); 6155 } 6156 } 6157 }, 6158 0, null, null, 6159 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6160 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6161 userId); 6162 } 6163 } 6164 scheduleStartProfilesLocked(); 6165 } 6166 } 6167 } 6168 6169 @Override 6170 public void bootAnimationComplete() { 6171 final boolean callFinishBooting; 6172 synchronized (this) { 6173 callFinishBooting = mCallFinishBooting; 6174 mBootAnimationComplete = true; 6175 } 6176 if (callFinishBooting) { 6177 finishBooting(); 6178 } 6179 } 6180 6181 final void ensureBootCompleted() { 6182 boolean booting; 6183 boolean enableScreen; 6184 synchronized (this) { 6185 booting = mBooting; 6186 mBooting = false; 6187 enableScreen = !mBooted; 6188 mBooted = true; 6189 } 6190 6191 if (booting) { 6192 finishBooting(); 6193 } 6194 6195 if (enableScreen) { 6196 enableScreenAfterBoot(); 6197 } 6198 } 6199 6200 @Override 6201 public final void activityResumed(IBinder token) { 6202 final long origId = Binder.clearCallingIdentity(); 6203 synchronized(this) { 6204 ActivityStack stack = ActivityRecord.getStackLocked(token); 6205 if (stack != null) { 6206 ActivityRecord.activityResumedLocked(token); 6207 } 6208 } 6209 Binder.restoreCallingIdentity(origId); 6210 } 6211 6212 @Override 6213 public final void activityPaused(IBinder token) { 6214 final long origId = Binder.clearCallingIdentity(); 6215 synchronized(this) { 6216 ActivityStack stack = ActivityRecord.getStackLocked(token); 6217 if (stack != null) { 6218 stack.activityPausedLocked(token, false); 6219 } 6220 } 6221 Binder.restoreCallingIdentity(origId); 6222 } 6223 6224 @Override 6225 public final void activityStopped(IBinder token, Bundle icicle, 6226 PersistableBundle persistentState, CharSequence description) { 6227 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6228 6229 // Refuse possible leaked file descriptors 6230 if (icicle != null && icicle.hasFileDescriptors()) { 6231 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6232 } 6233 6234 final long origId = Binder.clearCallingIdentity(); 6235 6236 synchronized (this) { 6237 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6238 if (r != null) { 6239 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6240 } 6241 } 6242 6243 trimApplications(); 6244 6245 Binder.restoreCallingIdentity(origId); 6246 } 6247 6248 @Override 6249 public final void activityDestroyed(IBinder token) { 6250 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6251 synchronized (this) { 6252 ActivityStack stack = ActivityRecord.getStackLocked(token); 6253 if (stack != null) { 6254 stack.activityDestroyedLocked(token); 6255 } 6256 } 6257 } 6258 6259 @Override 6260 public final void backgroundResourcesReleased(IBinder token) { 6261 final long origId = Binder.clearCallingIdentity(); 6262 try { 6263 synchronized (this) { 6264 ActivityStack stack = ActivityRecord.getStackLocked(token); 6265 if (stack != null) { 6266 stack.backgroundResourcesReleased(token); 6267 } 6268 } 6269 } finally { 6270 Binder.restoreCallingIdentity(origId); 6271 } 6272 } 6273 6274 @Override 6275 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6276 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6277 } 6278 6279 @Override 6280 public final void notifyEnterAnimationComplete(IBinder token) { 6281 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6282 } 6283 6284 @Override 6285 public String getCallingPackage(IBinder token) { 6286 synchronized (this) { 6287 ActivityRecord r = getCallingRecordLocked(token); 6288 return r != null ? r.info.packageName : null; 6289 } 6290 } 6291 6292 @Override 6293 public ComponentName getCallingActivity(IBinder token) { 6294 synchronized (this) { 6295 ActivityRecord r = getCallingRecordLocked(token); 6296 return r != null ? r.intent.getComponent() : null; 6297 } 6298 } 6299 6300 private ActivityRecord getCallingRecordLocked(IBinder token) { 6301 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6302 if (r == null) { 6303 return null; 6304 } 6305 return r.resultTo; 6306 } 6307 6308 @Override 6309 public ComponentName getActivityClassForToken(IBinder token) { 6310 synchronized(this) { 6311 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6312 if (r == null) { 6313 return null; 6314 } 6315 return r.intent.getComponent(); 6316 } 6317 } 6318 6319 @Override 6320 public String getPackageForToken(IBinder token) { 6321 synchronized(this) { 6322 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6323 if (r == null) { 6324 return null; 6325 } 6326 return r.packageName; 6327 } 6328 } 6329 6330 @Override 6331 public IIntentSender getIntentSender(int type, 6332 String packageName, IBinder token, String resultWho, 6333 int requestCode, Intent[] intents, String[] resolvedTypes, 6334 int flags, Bundle options, int userId) { 6335 enforceNotIsolatedCaller("getIntentSender"); 6336 // Refuse possible leaked file descriptors 6337 if (intents != null) { 6338 if (intents.length < 1) { 6339 throw new IllegalArgumentException("Intents array length must be >= 1"); 6340 } 6341 for (int i=0; i<intents.length; i++) { 6342 Intent intent = intents[i]; 6343 if (intent != null) { 6344 if (intent.hasFileDescriptors()) { 6345 throw new IllegalArgumentException("File descriptors passed in Intent"); 6346 } 6347 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6348 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6349 throw new IllegalArgumentException( 6350 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6351 } 6352 intents[i] = new Intent(intent); 6353 } 6354 } 6355 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6356 throw new IllegalArgumentException( 6357 "Intent array length does not match resolvedTypes length"); 6358 } 6359 } 6360 if (options != null) { 6361 if (options.hasFileDescriptors()) { 6362 throw new IllegalArgumentException("File descriptors passed in options"); 6363 } 6364 } 6365 6366 synchronized(this) { 6367 int callingUid = Binder.getCallingUid(); 6368 int origUserId = userId; 6369 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6370 type == ActivityManager.INTENT_SENDER_BROADCAST, 6371 ALLOW_NON_FULL, "getIntentSender", null); 6372 if (origUserId == UserHandle.USER_CURRENT) { 6373 // We don't want to evaluate this until the pending intent is 6374 // actually executed. However, we do want to always do the 6375 // security checking for it above. 6376 userId = UserHandle.USER_CURRENT; 6377 } 6378 try { 6379 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6380 int uid = AppGlobals.getPackageManager() 6381 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6382 if (!UserHandle.isSameApp(callingUid, uid)) { 6383 String msg = "Permission Denial: getIntentSender() from pid=" 6384 + Binder.getCallingPid() 6385 + ", uid=" + Binder.getCallingUid() 6386 + ", (need uid=" + uid + ")" 6387 + " is not allowed to send as package " + packageName; 6388 Slog.w(TAG, msg); 6389 throw new SecurityException(msg); 6390 } 6391 } 6392 6393 return getIntentSenderLocked(type, packageName, callingUid, userId, 6394 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6395 6396 } catch (RemoteException e) { 6397 throw new SecurityException(e); 6398 } 6399 } 6400 } 6401 6402 IIntentSender getIntentSenderLocked(int type, String packageName, 6403 int callingUid, int userId, IBinder token, String resultWho, 6404 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6405 Bundle options) { 6406 if (DEBUG_MU) 6407 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6408 ActivityRecord activity = null; 6409 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6410 activity = ActivityRecord.isInStackLocked(token); 6411 if (activity == null) { 6412 return null; 6413 } 6414 if (activity.finishing) { 6415 return null; 6416 } 6417 } 6418 6419 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6420 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6421 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6422 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6423 |PendingIntent.FLAG_UPDATE_CURRENT); 6424 6425 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6426 type, packageName, activity, resultWho, 6427 requestCode, intents, resolvedTypes, flags, options, userId); 6428 WeakReference<PendingIntentRecord> ref; 6429 ref = mIntentSenderRecords.get(key); 6430 PendingIntentRecord rec = ref != null ? ref.get() : null; 6431 if (rec != null) { 6432 if (!cancelCurrent) { 6433 if (updateCurrent) { 6434 if (rec.key.requestIntent != null) { 6435 rec.key.requestIntent.replaceExtras(intents != null ? 6436 intents[intents.length - 1] : null); 6437 } 6438 if (intents != null) { 6439 intents[intents.length-1] = rec.key.requestIntent; 6440 rec.key.allIntents = intents; 6441 rec.key.allResolvedTypes = resolvedTypes; 6442 } else { 6443 rec.key.allIntents = null; 6444 rec.key.allResolvedTypes = null; 6445 } 6446 } 6447 return rec; 6448 } 6449 rec.canceled = true; 6450 mIntentSenderRecords.remove(key); 6451 } 6452 if (noCreate) { 6453 return rec; 6454 } 6455 rec = new PendingIntentRecord(this, key, callingUid); 6456 mIntentSenderRecords.put(key, rec.ref); 6457 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6458 if (activity.pendingResults == null) { 6459 activity.pendingResults 6460 = new HashSet<WeakReference<PendingIntentRecord>>(); 6461 } 6462 activity.pendingResults.add(rec.ref); 6463 } 6464 return rec; 6465 } 6466 6467 @Override 6468 public void cancelIntentSender(IIntentSender sender) { 6469 if (!(sender instanceof PendingIntentRecord)) { 6470 return; 6471 } 6472 synchronized(this) { 6473 PendingIntentRecord rec = (PendingIntentRecord)sender; 6474 try { 6475 int uid = AppGlobals.getPackageManager() 6476 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6477 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6478 String msg = "Permission Denial: cancelIntentSender() from pid=" 6479 + Binder.getCallingPid() 6480 + ", uid=" + Binder.getCallingUid() 6481 + " is not allowed to cancel packges " 6482 + rec.key.packageName; 6483 Slog.w(TAG, msg); 6484 throw new SecurityException(msg); 6485 } 6486 } catch (RemoteException e) { 6487 throw new SecurityException(e); 6488 } 6489 cancelIntentSenderLocked(rec, true); 6490 } 6491 } 6492 6493 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6494 rec.canceled = true; 6495 mIntentSenderRecords.remove(rec.key); 6496 if (cleanActivity && rec.key.activity != null) { 6497 rec.key.activity.pendingResults.remove(rec.ref); 6498 } 6499 } 6500 6501 @Override 6502 public String getPackageForIntentSender(IIntentSender pendingResult) { 6503 if (!(pendingResult instanceof PendingIntentRecord)) { 6504 return null; 6505 } 6506 try { 6507 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6508 return res.key.packageName; 6509 } catch (ClassCastException e) { 6510 } 6511 return null; 6512 } 6513 6514 @Override 6515 public int getUidForIntentSender(IIntentSender sender) { 6516 if (sender instanceof PendingIntentRecord) { 6517 try { 6518 PendingIntentRecord res = (PendingIntentRecord)sender; 6519 return res.uid; 6520 } catch (ClassCastException e) { 6521 } 6522 } 6523 return -1; 6524 } 6525 6526 @Override 6527 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6528 if (!(pendingResult instanceof PendingIntentRecord)) { 6529 return false; 6530 } 6531 try { 6532 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6533 if (res.key.allIntents == null) { 6534 return false; 6535 } 6536 for (int i=0; i<res.key.allIntents.length; i++) { 6537 Intent intent = res.key.allIntents[i]; 6538 if (intent.getPackage() != null && intent.getComponent() != null) { 6539 return false; 6540 } 6541 } 6542 return true; 6543 } catch (ClassCastException e) { 6544 } 6545 return false; 6546 } 6547 6548 @Override 6549 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6550 if (!(pendingResult instanceof PendingIntentRecord)) { 6551 return false; 6552 } 6553 try { 6554 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6555 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6556 return true; 6557 } 6558 return false; 6559 } catch (ClassCastException e) { 6560 } 6561 return false; 6562 } 6563 6564 @Override 6565 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6566 if (!(pendingResult instanceof PendingIntentRecord)) { 6567 return null; 6568 } 6569 try { 6570 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6571 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6572 } catch (ClassCastException e) { 6573 } 6574 return null; 6575 } 6576 6577 @Override 6578 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6579 if (!(pendingResult instanceof PendingIntentRecord)) { 6580 return null; 6581 } 6582 try { 6583 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6584 Intent intent = res.key.requestIntent; 6585 if (intent != null) { 6586 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6587 || res.lastTagPrefix.equals(prefix))) { 6588 return res.lastTag; 6589 } 6590 res.lastTagPrefix = prefix; 6591 StringBuilder sb = new StringBuilder(128); 6592 if (prefix != null) { 6593 sb.append(prefix); 6594 } 6595 if (intent.getAction() != null) { 6596 sb.append(intent.getAction()); 6597 } else if (intent.getComponent() != null) { 6598 intent.getComponent().appendShortString(sb); 6599 } else { 6600 sb.append("?"); 6601 } 6602 return res.lastTag = sb.toString(); 6603 } 6604 } catch (ClassCastException e) { 6605 } 6606 return null; 6607 } 6608 6609 @Override 6610 public void setProcessLimit(int max) { 6611 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6612 "setProcessLimit()"); 6613 synchronized (this) { 6614 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6615 mProcessLimitOverride = max; 6616 } 6617 trimApplications(); 6618 } 6619 6620 @Override 6621 public int getProcessLimit() { 6622 synchronized (this) { 6623 return mProcessLimitOverride; 6624 } 6625 } 6626 6627 void foregroundTokenDied(ForegroundToken token) { 6628 synchronized (ActivityManagerService.this) { 6629 synchronized (mPidsSelfLocked) { 6630 ForegroundToken cur 6631 = mForegroundProcesses.get(token.pid); 6632 if (cur != token) { 6633 return; 6634 } 6635 mForegroundProcesses.remove(token.pid); 6636 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6637 if (pr == null) { 6638 return; 6639 } 6640 pr.forcingToForeground = null; 6641 updateProcessForegroundLocked(pr, false, false); 6642 } 6643 updateOomAdjLocked(); 6644 } 6645 } 6646 6647 @Override 6648 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6649 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6650 "setProcessForeground()"); 6651 synchronized(this) { 6652 boolean changed = false; 6653 6654 synchronized (mPidsSelfLocked) { 6655 ProcessRecord pr = mPidsSelfLocked.get(pid); 6656 if (pr == null && isForeground) { 6657 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6658 return; 6659 } 6660 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6661 if (oldToken != null) { 6662 oldToken.token.unlinkToDeath(oldToken, 0); 6663 mForegroundProcesses.remove(pid); 6664 if (pr != null) { 6665 pr.forcingToForeground = null; 6666 } 6667 changed = true; 6668 } 6669 if (isForeground && token != null) { 6670 ForegroundToken newToken = new ForegroundToken() { 6671 @Override 6672 public void binderDied() { 6673 foregroundTokenDied(this); 6674 } 6675 }; 6676 newToken.pid = pid; 6677 newToken.token = token; 6678 try { 6679 token.linkToDeath(newToken, 0); 6680 mForegroundProcesses.put(pid, newToken); 6681 pr.forcingToForeground = token; 6682 changed = true; 6683 } catch (RemoteException e) { 6684 // If the process died while doing this, we will later 6685 // do the cleanup with the process death link. 6686 } 6687 } 6688 } 6689 6690 if (changed) { 6691 updateOomAdjLocked(); 6692 } 6693 } 6694 } 6695 6696 // ========================================================= 6697 // PERMISSIONS 6698 // ========================================================= 6699 6700 static class PermissionController extends IPermissionController.Stub { 6701 ActivityManagerService mActivityManagerService; 6702 PermissionController(ActivityManagerService activityManagerService) { 6703 mActivityManagerService = activityManagerService; 6704 } 6705 6706 @Override 6707 public boolean checkPermission(String permission, int pid, int uid) { 6708 return mActivityManagerService.checkPermission(permission, pid, 6709 uid) == PackageManager.PERMISSION_GRANTED; 6710 } 6711 } 6712 6713 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6714 @Override 6715 public int checkComponentPermission(String permission, int pid, int uid, 6716 int owningUid, boolean exported) { 6717 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6718 owningUid, exported); 6719 } 6720 6721 @Override 6722 public Object getAMSLock() { 6723 return ActivityManagerService.this; 6724 } 6725 } 6726 6727 /** 6728 * This can be called with or without the global lock held. 6729 */ 6730 int checkComponentPermission(String permission, int pid, int uid, 6731 int owningUid, boolean exported) { 6732 if (pid == MY_PID) { 6733 return PackageManager.PERMISSION_GRANTED; 6734 } 6735 return ActivityManager.checkComponentPermission(permission, uid, 6736 owningUid, exported); 6737 } 6738 6739 /** 6740 * As the only public entry point for permissions checking, this method 6741 * can enforce the semantic that requesting a check on a null global 6742 * permission is automatically denied. (Internally a null permission 6743 * string is used when calling {@link #checkComponentPermission} in cases 6744 * when only uid-based security is needed.) 6745 * 6746 * This can be called with or without the global lock held. 6747 */ 6748 @Override 6749 public int checkPermission(String permission, int pid, int uid) { 6750 if (permission == null) { 6751 return PackageManager.PERMISSION_DENIED; 6752 } 6753 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6754 } 6755 6756 @Override 6757 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6758 if (permission == null) { 6759 return PackageManager.PERMISSION_DENIED; 6760 } 6761 6762 // We might be performing an operation on behalf of an indirect binder 6763 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6764 // client identity accordingly before proceeding. 6765 Identity tlsIdentity = sCallerIdentity.get(); 6766 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6767 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6768 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6769 uid = tlsIdentity.uid; 6770 pid = tlsIdentity.pid; 6771 } 6772 6773 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6774 } 6775 6776 /** 6777 * Binder IPC calls go through the public entry point. 6778 * This can be called with or without the global lock held. 6779 */ 6780 int checkCallingPermission(String permission) { 6781 return checkPermission(permission, 6782 Binder.getCallingPid(), 6783 UserHandle.getAppId(Binder.getCallingUid())); 6784 } 6785 6786 /** 6787 * This can be called with or without the global lock held. 6788 */ 6789 void enforceCallingPermission(String permission, String func) { 6790 if (checkCallingPermission(permission) 6791 == PackageManager.PERMISSION_GRANTED) { 6792 return; 6793 } 6794 6795 String msg = "Permission Denial: " + func + " from pid=" 6796 + Binder.getCallingPid() 6797 + ", uid=" + Binder.getCallingUid() 6798 + " requires " + permission; 6799 Slog.w(TAG, msg); 6800 throw new SecurityException(msg); 6801 } 6802 6803 /** 6804 * Determine if UID is holding permissions required to access {@link Uri} in 6805 * the given {@link ProviderInfo}. Final permission checking is always done 6806 * in {@link ContentProvider}. 6807 */ 6808 private final boolean checkHoldingPermissionsLocked( 6809 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6810 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6811 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6812 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6813 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6814 != PERMISSION_GRANTED) { 6815 return false; 6816 } 6817 } 6818 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6819 } 6820 6821 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6822 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6823 if (pi.applicationInfo.uid == uid) { 6824 return true; 6825 } else if (!pi.exported) { 6826 return false; 6827 } 6828 6829 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6830 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6831 try { 6832 // check if target holds top-level <provider> permissions 6833 if (!readMet && pi.readPermission != null && considerUidPermissions 6834 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6835 readMet = true; 6836 } 6837 if (!writeMet && pi.writePermission != null && considerUidPermissions 6838 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6839 writeMet = true; 6840 } 6841 6842 // track if unprotected read/write is allowed; any denied 6843 // <path-permission> below removes this ability 6844 boolean allowDefaultRead = pi.readPermission == null; 6845 boolean allowDefaultWrite = pi.writePermission == null; 6846 6847 // check if target holds any <path-permission> that match uri 6848 final PathPermission[] pps = pi.pathPermissions; 6849 if (pps != null) { 6850 final String path = grantUri.uri.getPath(); 6851 int i = pps.length; 6852 while (i > 0 && (!readMet || !writeMet)) { 6853 i--; 6854 PathPermission pp = pps[i]; 6855 if (pp.match(path)) { 6856 if (!readMet) { 6857 final String pprperm = pp.getReadPermission(); 6858 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6859 + pprperm + " for " + pp.getPath() 6860 + ": match=" + pp.match(path) 6861 + " check=" + pm.checkUidPermission(pprperm, uid)); 6862 if (pprperm != null) { 6863 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6864 == PERMISSION_GRANTED) { 6865 readMet = true; 6866 } else { 6867 allowDefaultRead = false; 6868 } 6869 } 6870 } 6871 if (!writeMet) { 6872 final String ppwperm = pp.getWritePermission(); 6873 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6874 + ppwperm + " for " + pp.getPath() 6875 + ": match=" + pp.match(path) 6876 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6877 if (ppwperm != null) { 6878 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6879 == PERMISSION_GRANTED) { 6880 writeMet = true; 6881 } else { 6882 allowDefaultWrite = false; 6883 } 6884 } 6885 } 6886 } 6887 } 6888 } 6889 6890 // grant unprotected <provider> read/write, if not blocked by 6891 // <path-permission> above 6892 if (allowDefaultRead) readMet = true; 6893 if (allowDefaultWrite) writeMet = true; 6894 6895 } catch (RemoteException e) { 6896 return false; 6897 } 6898 6899 return readMet && writeMet; 6900 } 6901 6902 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6903 ProviderInfo pi = null; 6904 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6905 if (cpr != null) { 6906 pi = cpr.info; 6907 } else { 6908 try { 6909 pi = AppGlobals.getPackageManager().resolveContentProvider( 6910 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6911 } catch (RemoteException ex) { 6912 } 6913 } 6914 return pi; 6915 } 6916 6917 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6918 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6919 if (targetUris != null) { 6920 return targetUris.get(grantUri); 6921 } 6922 return null; 6923 } 6924 6925 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6926 String targetPkg, int targetUid, GrantUri grantUri) { 6927 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6928 if (targetUris == null) { 6929 targetUris = Maps.newArrayMap(); 6930 mGrantedUriPermissions.put(targetUid, targetUris); 6931 } 6932 6933 UriPermission perm = targetUris.get(grantUri); 6934 if (perm == null) { 6935 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6936 targetUris.put(grantUri, perm); 6937 } 6938 6939 return perm; 6940 } 6941 6942 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6943 final int modeFlags) { 6944 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6945 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6946 : UriPermission.STRENGTH_OWNED; 6947 6948 // Root gets to do everything. 6949 if (uid == 0) { 6950 return true; 6951 } 6952 6953 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6954 if (perms == null) return false; 6955 6956 // First look for exact match 6957 final UriPermission exactPerm = perms.get(grantUri); 6958 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6959 return true; 6960 } 6961 6962 // No exact match, look for prefixes 6963 final int N = perms.size(); 6964 for (int i = 0; i < N; i++) { 6965 final UriPermission perm = perms.valueAt(i); 6966 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6967 && perm.getStrength(modeFlags) >= minStrength) { 6968 return true; 6969 } 6970 } 6971 6972 return false; 6973 } 6974 6975 /** 6976 * @param uri This uri must NOT contain an embedded userId. 6977 * @param userId The userId in which the uri is to be resolved. 6978 */ 6979 @Override 6980 public int checkUriPermission(Uri uri, int pid, int uid, 6981 final int modeFlags, int userId, IBinder callerToken) { 6982 enforceNotIsolatedCaller("checkUriPermission"); 6983 6984 // Another redirected-binder-call permissions check as in 6985 // {@link checkPermissionWithToken}. 6986 Identity tlsIdentity = sCallerIdentity.get(); 6987 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6988 uid = tlsIdentity.uid; 6989 pid = tlsIdentity.pid; 6990 } 6991 6992 // Our own process gets to do everything. 6993 if (pid == MY_PID) { 6994 return PackageManager.PERMISSION_GRANTED; 6995 } 6996 synchronized (this) { 6997 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6998 ? PackageManager.PERMISSION_GRANTED 6999 : PackageManager.PERMISSION_DENIED; 7000 } 7001 } 7002 7003 /** 7004 * Check if the targetPkg can be granted permission to access uri by 7005 * the callingUid using the given modeFlags. Throws a security exception 7006 * if callingUid is not allowed to do this. Returns the uid of the target 7007 * if the URI permission grant should be performed; returns -1 if it is not 7008 * needed (for example targetPkg already has permission to access the URI). 7009 * If you already know the uid of the target, you can supply it in 7010 * lastTargetUid else set that to -1. 7011 */ 7012 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7013 final int modeFlags, int lastTargetUid) { 7014 if (!Intent.isAccessUriMode(modeFlags)) { 7015 return -1; 7016 } 7017 7018 if (targetPkg != null) { 7019 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7020 "Checking grant " + targetPkg + " permission to " + grantUri); 7021 } 7022 7023 final IPackageManager pm = AppGlobals.getPackageManager(); 7024 7025 // If this is not a content: uri, we can't do anything with it. 7026 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7027 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7028 "Can't grant URI permission for non-content URI: " + grantUri); 7029 return -1; 7030 } 7031 7032 final String authority = grantUri.uri.getAuthority(); 7033 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7034 if (pi == null) { 7035 Slog.w(TAG, "No content provider found for permission check: " + 7036 grantUri.uri.toSafeString()); 7037 return -1; 7038 } 7039 7040 int targetUid = lastTargetUid; 7041 if (targetUid < 0 && targetPkg != null) { 7042 try { 7043 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7044 if (targetUid < 0) { 7045 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7046 "Can't grant URI permission no uid for: " + targetPkg); 7047 return -1; 7048 } 7049 } catch (RemoteException ex) { 7050 return -1; 7051 } 7052 } 7053 7054 if (targetUid >= 0) { 7055 // First... does the target actually need this permission? 7056 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7057 // No need to grant the target this permission. 7058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7059 "Target " + targetPkg + " already has full permission to " + grantUri); 7060 return -1; 7061 } 7062 } else { 7063 // First... there is no target package, so can anyone access it? 7064 boolean allowed = pi.exported; 7065 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7066 if (pi.readPermission != null) { 7067 allowed = false; 7068 } 7069 } 7070 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7071 if (pi.writePermission != null) { 7072 allowed = false; 7073 } 7074 } 7075 if (allowed) { 7076 return -1; 7077 } 7078 } 7079 7080 /* There is a special cross user grant if: 7081 * - The target is on another user. 7082 * - Apps on the current user can access the uri without any uid permissions. 7083 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7084 * grant uri permissions. 7085 */ 7086 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7087 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7088 modeFlags, false /*without considering the uid permissions*/); 7089 7090 // Second... is the provider allowing granting of URI permissions? 7091 if (!specialCrossUserGrant) { 7092 if (!pi.grantUriPermissions) { 7093 throw new SecurityException("Provider " + pi.packageName 7094 + "/" + pi.name 7095 + " does not allow granting of Uri permissions (uri " 7096 + grantUri + ")"); 7097 } 7098 if (pi.uriPermissionPatterns != null) { 7099 final int N = pi.uriPermissionPatterns.length; 7100 boolean allowed = false; 7101 for (int i=0; i<N; i++) { 7102 if (pi.uriPermissionPatterns[i] != null 7103 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7104 allowed = true; 7105 break; 7106 } 7107 } 7108 if (!allowed) { 7109 throw new SecurityException("Provider " + pi.packageName 7110 + "/" + pi.name 7111 + " does not allow granting of permission to path of Uri " 7112 + grantUri); 7113 } 7114 } 7115 } 7116 7117 // Third... does the caller itself have permission to access 7118 // this uri? 7119 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7120 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7121 // Require they hold a strong enough Uri permission 7122 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7123 throw new SecurityException("Uid " + callingUid 7124 + " does not have permission to uri " + grantUri); 7125 } 7126 } 7127 } 7128 return targetUid; 7129 } 7130 7131 /** 7132 * @param uri This uri must NOT contain an embedded userId. 7133 * @param userId The userId in which the uri is to be resolved. 7134 */ 7135 @Override 7136 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7137 final int modeFlags, int userId) { 7138 enforceNotIsolatedCaller("checkGrantUriPermission"); 7139 synchronized(this) { 7140 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7141 new GrantUri(userId, uri, false), modeFlags, -1); 7142 } 7143 } 7144 7145 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7146 final int modeFlags, UriPermissionOwner owner) { 7147 if (!Intent.isAccessUriMode(modeFlags)) { 7148 return; 7149 } 7150 7151 // So here we are: the caller has the assumed permission 7152 // to the uri, and the target doesn't. Let's now give this to 7153 // the target. 7154 7155 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7156 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7157 7158 final String authority = grantUri.uri.getAuthority(); 7159 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7160 if (pi == null) { 7161 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7162 return; 7163 } 7164 7165 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7166 grantUri.prefix = true; 7167 } 7168 final UriPermission perm = findOrCreateUriPermissionLocked( 7169 pi.packageName, targetPkg, targetUid, grantUri); 7170 perm.grantModes(modeFlags, owner); 7171 } 7172 7173 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7174 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7175 if (targetPkg == null) { 7176 throw new NullPointerException("targetPkg"); 7177 } 7178 int targetUid; 7179 final IPackageManager pm = AppGlobals.getPackageManager(); 7180 try { 7181 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7182 } catch (RemoteException ex) { 7183 return; 7184 } 7185 7186 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7187 targetUid); 7188 if (targetUid < 0) { 7189 return; 7190 } 7191 7192 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7193 owner); 7194 } 7195 7196 static class NeededUriGrants extends ArrayList<GrantUri> { 7197 final String targetPkg; 7198 final int targetUid; 7199 final int flags; 7200 7201 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7202 this.targetPkg = targetPkg; 7203 this.targetUid = targetUid; 7204 this.flags = flags; 7205 } 7206 } 7207 7208 /** 7209 * Like checkGrantUriPermissionLocked, but takes an Intent. 7210 */ 7211 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7212 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7214 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7215 + " clip=" + (intent != null ? intent.getClipData() : null) 7216 + " from " + intent + "; flags=0x" 7217 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7218 7219 if (targetPkg == null) { 7220 throw new NullPointerException("targetPkg"); 7221 } 7222 7223 if (intent == null) { 7224 return null; 7225 } 7226 Uri data = intent.getData(); 7227 ClipData clip = intent.getClipData(); 7228 if (data == null && clip == null) { 7229 return null; 7230 } 7231 // Default userId for uris in the intent (if they don't specify it themselves) 7232 int contentUserHint = intent.getContentUserHint(); 7233 if (contentUserHint == UserHandle.USER_CURRENT) { 7234 contentUserHint = UserHandle.getUserId(callingUid); 7235 } 7236 final IPackageManager pm = AppGlobals.getPackageManager(); 7237 int targetUid; 7238 if (needed != null) { 7239 targetUid = needed.targetUid; 7240 } else { 7241 try { 7242 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7243 } catch (RemoteException ex) { 7244 return null; 7245 } 7246 if (targetUid < 0) { 7247 if (DEBUG_URI_PERMISSION) { 7248 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7249 + " on user " + targetUserId); 7250 } 7251 return null; 7252 } 7253 } 7254 if (data != null) { 7255 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7256 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7257 targetUid); 7258 if (targetUid > 0) { 7259 if (needed == null) { 7260 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7261 } 7262 needed.add(grantUri); 7263 } 7264 } 7265 if (clip != null) { 7266 for (int i=0; i<clip.getItemCount(); i++) { 7267 Uri uri = clip.getItemAt(i).getUri(); 7268 if (uri != null) { 7269 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7270 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7271 targetUid); 7272 if (targetUid > 0) { 7273 if (needed == null) { 7274 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7275 } 7276 needed.add(grantUri); 7277 } 7278 } else { 7279 Intent clipIntent = clip.getItemAt(i).getIntent(); 7280 if (clipIntent != null) { 7281 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7282 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7283 if (newNeeded != null) { 7284 needed = newNeeded; 7285 } 7286 } 7287 } 7288 } 7289 } 7290 7291 return needed; 7292 } 7293 7294 /** 7295 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7296 */ 7297 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7298 UriPermissionOwner owner) { 7299 if (needed != null) { 7300 for (int i=0; i<needed.size(); i++) { 7301 GrantUri grantUri = needed.get(i); 7302 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7303 grantUri, needed.flags, owner); 7304 } 7305 } 7306 } 7307 7308 void grantUriPermissionFromIntentLocked(int callingUid, 7309 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7310 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7311 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7312 if (needed == null) { 7313 return; 7314 } 7315 7316 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7317 } 7318 7319 /** 7320 * @param uri This uri must NOT contain an embedded userId. 7321 * @param userId The userId in which the uri is to be resolved. 7322 */ 7323 @Override 7324 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7325 final int modeFlags, int userId) { 7326 enforceNotIsolatedCaller("grantUriPermission"); 7327 GrantUri grantUri = new GrantUri(userId, uri, false); 7328 synchronized(this) { 7329 final ProcessRecord r = getRecordForAppLocked(caller); 7330 if (r == null) { 7331 throw new SecurityException("Unable to find app for caller " 7332 + caller 7333 + " when granting permission to uri " + grantUri); 7334 } 7335 if (targetPkg == null) { 7336 throw new IllegalArgumentException("null target"); 7337 } 7338 if (grantUri == null) { 7339 throw new IllegalArgumentException("null uri"); 7340 } 7341 7342 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7343 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7344 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7345 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7346 7347 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7348 UserHandle.getUserId(r.uid)); 7349 } 7350 } 7351 7352 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7353 if (perm.modeFlags == 0) { 7354 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7355 perm.targetUid); 7356 if (perms != null) { 7357 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7358 "Removing " + perm.targetUid + " permission to " + perm.uri); 7359 7360 perms.remove(perm.uri); 7361 if (perms.isEmpty()) { 7362 mGrantedUriPermissions.remove(perm.targetUid); 7363 } 7364 } 7365 } 7366 } 7367 7368 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7369 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7370 7371 final IPackageManager pm = AppGlobals.getPackageManager(); 7372 final String authority = grantUri.uri.getAuthority(); 7373 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7374 if (pi == null) { 7375 Slog.w(TAG, "No content provider found for permission revoke: " 7376 + grantUri.toSafeString()); 7377 return; 7378 } 7379 7380 // Does the caller have this permission on the URI? 7381 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7382 // If they don't have direct access to the URI, then revoke any 7383 // ownerless URI permissions that have been granted to them. 7384 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7385 if (perms != null) { 7386 boolean persistChanged = false; 7387 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7388 final UriPermission perm = it.next(); 7389 if (perm.uri.sourceUserId == grantUri.sourceUserId 7390 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7391 if (DEBUG_URI_PERMISSION) 7392 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7393 " permission to " + perm.uri); 7394 persistChanged |= perm.revokeModes( 7395 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7396 if (perm.modeFlags == 0) { 7397 it.remove(); 7398 } 7399 } 7400 } 7401 if (perms.isEmpty()) { 7402 mGrantedUriPermissions.remove(callingUid); 7403 } 7404 if (persistChanged) { 7405 schedulePersistUriGrants(); 7406 } 7407 } 7408 return; 7409 } 7410 7411 boolean persistChanged = false; 7412 7413 // Go through all of the permissions and remove any that match. 7414 int N = mGrantedUriPermissions.size(); 7415 for (int i = 0; i < N; i++) { 7416 final int targetUid = mGrantedUriPermissions.keyAt(i); 7417 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7418 7419 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7420 final UriPermission perm = it.next(); 7421 if (perm.uri.sourceUserId == grantUri.sourceUserId 7422 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7423 if (DEBUG_URI_PERMISSION) 7424 Slog.v(TAG, 7425 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7426 persistChanged |= perm.revokeModes( 7427 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7428 if (perm.modeFlags == 0) { 7429 it.remove(); 7430 } 7431 } 7432 } 7433 7434 if (perms.isEmpty()) { 7435 mGrantedUriPermissions.remove(targetUid); 7436 N--; 7437 i--; 7438 } 7439 } 7440 7441 if (persistChanged) { 7442 schedulePersistUriGrants(); 7443 } 7444 } 7445 7446 /** 7447 * @param uri This uri must NOT contain an embedded userId. 7448 * @param userId The userId in which the uri is to be resolved. 7449 */ 7450 @Override 7451 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7452 int userId) { 7453 enforceNotIsolatedCaller("revokeUriPermission"); 7454 synchronized(this) { 7455 final ProcessRecord r = getRecordForAppLocked(caller); 7456 if (r == null) { 7457 throw new SecurityException("Unable to find app for caller " 7458 + caller 7459 + " when revoking permission to uri " + uri); 7460 } 7461 if (uri == null) { 7462 Slog.w(TAG, "revokeUriPermission: null uri"); 7463 return; 7464 } 7465 7466 if (!Intent.isAccessUriMode(modeFlags)) { 7467 return; 7468 } 7469 7470 final IPackageManager pm = AppGlobals.getPackageManager(); 7471 final String authority = uri.getAuthority(); 7472 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7473 if (pi == null) { 7474 Slog.w(TAG, "No content provider found for permission revoke: " 7475 + uri.toSafeString()); 7476 return; 7477 } 7478 7479 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7480 } 7481 } 7482 7483 /** 7484 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7485 * given package. 7486 * 7487 * @param packageName Package name to match, or {@code null} to apply to all 7488 * packages. 7489 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7490 * to all users. 7491 * @param persistable If persistable grants should be removed. 7492 */ 7493 private void removeUriPermissionsForPackageLocked( 7494 String packageName, int userHandle, boolean persistable) { 7495 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7496 throw new IllegalArgumentException("Must narrow by either package or user"); 7497 } 7498 7499 boolean persistChanged = false; 7500 7501 int N = mGrantedUriPermissions.size(); 7502 for (int i = 0; i < N; i++) { 7503 final int targetUid = mGrantedUriPermissions.keyAt(i); 7504 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7505 7506 // Only inspect grants matching user 7507 if (userHandle == UserHandle.USER_ALL 7508 || userHandle == UserHandle.getUserId(targetUid)) { 7509 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7510 final UriPermission perm = it.next(); 7511 7512 // Only inspect grants matching package 7513 if (packageName == null || perm.sourcePkg.equals(packageName) 7514 || perm.targetPkg.equals(packageName)) { 7515 persistChanged |= perm.revokeModes(persistable 7516 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7517 7518 // Only remove when no modes remain; any persisted grants 7519 // will keep this alive. 7520 if (perm.modeFlags == 0) { 7521 it.remove(); 7522 } 7523 } 7524 } 7525 7526 if (perms.isEmpty()) { 7527 mGrantedUriPermissions.remove(targetUid); 7528 N--; 7529 i--; 7530 } 7531 } 7532 } 7533 7534 if (persistChanged) { 7535 schedulePersistUriGrants(); 7536 } 7537 } 7538 7539 @Override 7540 public IBinder newUriPermissionOwner(String name) { 7541 enforceNotIsolatedCaller("newUriPermissionOwner"); 7542 synchronized(this) { 7543 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7544 return owner.getExternalTokenLocked(); 7545 } 7546 } 7547 7548 /** 7549 * @param uri This uri must NOT contain an embedded userId. 7550 * @param sourceUserId The userId in which the uri is to be resolved. 7551 * @param targetUserId The userId of the app that receives the grant. 7552 */ 7553 @Override 7554 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7555 final int modeFlags, int sourceUserId, int targetUserId) { 7556 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7557 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7558 synchronized(this) { 7559 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7560 if (owner == null) { 7561 throw new IllegalArgumentException("Unknown owner: " + token); 7562 } 7563 if (fromUid != Binder.getCallingUid()) { 7564 if (Binder.getCallingUid() != Process.myUid()) { 7565 // Only system code can grant URI permissions on behalf 7566 // of other users. 7567 throw new SecurityException("nice try"); 7568 } 7569 } 7570 if (targetPkg == null) { 7571 throw new IllegalArgumentException("null target"); 7572 } 7573 if (uri == null) { 7574 throw new IllegalArgumentException("null uri"); 7575 } 7576 7577 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7578 modeFlags, owner, targetUserId); 7579 } 7580 } 7581 7582 /** 7583 * @param uri This uri must NOT contain an embedded userId. 7584 * @param userId The userId in which the uri is to be resolved. 7585 */ 7586 @Override 7587 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7588 synchronized(this) { 7589 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7590 if (owner == null) { 7591 throw new IllegalArgumentException("Unknown owner: " + token); 7592 } 7593 7594 if (uri == null) { 7595 owner.removeUriPermissionsLocked(mode); 7596 } else { 7597 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7598 } 7599 } 7600 } 7601 7602 private void schedulePersistUriGrants() { 7603 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7604 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7605 10 * DateUtils.SECOND_IN_MILLIS); 7606 } 7607 } 7608 7609 private void writeGrantedUriPermissions() { 7610 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7611 7612 // Snapshot permissions so we can persist without lock 7613 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7614 synchronized (this) { 7615 final int size = mGrantedUriPermissions.size(); 7616 for (int i = 0; i < size; i++) { 7617 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7618 for (UriPermission perm : perms.values()) { 7619 if (perm.persistedModeFlags != 0) { 7620 persist.add(perm.snapshot()); 7621 } 7622 } 7623 } 7624 } 7625 7626 FileOutputStream fos = null; 7627 try { 7628 fos = mGrantFile.startWrite(); 7629 7630 XmlSerializer out = new FastXmlSerializer(); 7631 out.setOutput(fos, "utf-8"); 7632 out.startDocument(null, true); 7633 out.startTag(null, TAG_URI_GRANTS); 7634 for (UriPermission.Snapshot perm : persist) { 7635 out.startTag(null, TAG_URI_GRANT); 7636 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7637 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7638 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7639 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7640 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7641 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7642 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7643 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7644 out.endTag(null, TAG_URI_GRANT); 7645 } 7646 out.endTag(null, TAG_URI_GRANTS); 7647 out.endDocument(); 7648 7649 mGrantFile.finishWrite(fos); 7650 } catch (IOException e) { 7651 if (fos != null) { 7652 mGrantFile.failWrite(fos); 7653 } 7654 } 7655 } 7656 7657 private void readGrantedUriPermissionsLocked() { 7658 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7659 7660 final long now = System.currentTimeMillis(); 7661 7662 FileInputStream fis = null; 7663 try { 7664 fis = mGrantFile.openRead(); 7665 final XmlPullParser in = Xml.newPullParser(); 7666 in.setInput(fis, null); 7667 7668 int type; 7669 while ((type = in.next()) != END_DOCUMENT) { 7670 final String tag = in.getName(); 7671 if (type == START_TAG) { 7672 if (TAG_URI_GRANT.equals(tag)) { 7673 final int sourceUserId; 7674 final int targetUserId; 7675 final int userHandle = readIntAttribute(in, 7676 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7677 if (userHandle != UserHandle.USER_NULL) { 7678 // For backwards compatibility. 7679 sourceUserId = userHandle; 7680 targetUserId = userHandle; 7681 } else { 7682 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7683 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7684 } 7685 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7686 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7687 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7688 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7689 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7690 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7691 7692 // Sanity check that provider still belongs to source package 7693 final ProviderInfo pi = getProviderInfoLocked( 7694 uri.getAuthority(), sourceUserId); 7695 if (pi != null && sourcePkg.equals(pi.packageName)) { 7696 int targetUid = -1; 7697 try { 7698 targetUid = AppGlobals.getPackageManager() 7699 .getPackageUid(targetPkg, targetUserId); 7700 } catch (RemoteException e) { 7701 } 7702 if (targetUid != -1) { 7703 final UriPermission perm = findOrCreateUriPermissionLocked( 7704 sourcePkg, targetPkg, targetUid, 7705 new GrantUri(sourceUserId, uri, prefix)); 7706 perm.initPersistedModes(modeFlags, createdTime); 7707 } 7708 } else { 7709 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7710 + " but instead found " + pi); 7711 } 7712 } 7713 } 7714 } 7715 } catch (FileNotFoundException e) { 7716 // Missing grants is okay 7717 } catch (IOException e) { 7718 Slog.wtf(TAG, "Failed reading Uri grants", e); 7719 } catch (XmlPullParserException e) { 7720 Slog.wtf(TAG, "Failed reading Uri grants", e); 7721 } finally { 7722 IoUtils.closeQuietly(fis); 7723 } 7724 } 7725 7726 /** 7727 * @param uri This uri must NOT contain an embedded userId. 7728 * @param userId The userId in which the uri is to be resolved. 7729 */ 7730 @Override 7731 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7732 enforceNotIsolatedCaller("takePersistableUriPermission"); 7733 7734 Preconditions.checkFlagsArgument(modeFlags, 7735 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7736 7737 synchronized (this) { 7738 final int callingUid = Binder.getCallingUid(); 7739 boolean persistChanged = false; 7740 GrantUri grantUri = new GrantUri(userId, uri, false); 7741 7742 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7743 new GrantUri(userId, uri, false)); 7744 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7745 new GrantUri(userId, uri, true)); 7746 7747 final boolean exactValid = (exactPerm != null) 7748 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7749 final boolean prefixValid = (prefixPerm != null) 7750 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7751 7752 if (!(exactValid || prefixValid)) { 7753 throw new SecurityException("No persistable permission grants found for UID " 7754 + callingUid + " and Uri " + grantUri.toSafeString()); 7755 } 7756 7757 if (exactValid) { 7758 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7759 } 7760 if (prefixValid) { 7761 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7762 } 7763 7764 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7765 7766 if (persistChanged) { 7767 schedulePersistUriGrants(); 7768 } 7769 } 7770 } 7771 7772 /** 7773 * @param uri This uri must NOT contain an embedded userId. 7774 * @param userId The userId in which the uri is to be resolved. 7775 */ 7776 @Override 7777 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7778 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7779 7780 Preconditions.checkFlagsArgument(modeFlags, 7781 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7782 7783 synchronized (this) { 7784 final int callingUid = Binder.getCallingUid(); 7785 boolean persistChanged = false; 7786 7787 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7788 new GrantUri(userId, uri, false)); 7789 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7790 new GrantUri(userId, uri, true)); 7791 if (exactPerm == null && prefixPerm == null) { 7792 throw new SecurityException("No permission grants found for UID " + callingUid 7793 + " and Uri " + uri.toSafeString()); 7794 } 7795 7796 if (exactPerm != null) { 7797 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7798 removeUriPermissionIfNeededLocked(exactPerm); 7799 } 7800 if (prefixPerm != null) { 7801 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7802 removeUriPermissionIfNeededLocked(prefixPerm); 7803 } 7804 7805 if (persistChanged) { 7806 schedulePersistUriGrants(); 7807 } 7808 } 7809 } 7810 7811 /** 7812 * Prune any older {@link UriPermission} for the given UID until outstanding 7813 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7814 * 7815 * @return if any mutations occured that require persisting. 7816 */ 7817 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7818 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7819 if (perms == null) return false; 7820 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7821 7822 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7823 for (UriPermission perm : perms.values()) { 7824 if (perm.persistedModeFlags != 0) { 7825 persisted.add(perm); 7826 } 7827 } 7828 7829 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7830 if (trimCount <= 0) return false; 7831 7832 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7833 for (int i = 0; i < trimCount; i++) { 7834 final UriPermission perm = persisted.get(i); 7835 7836 if (DEBUG_URI_PERMISSION) { 7837 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7838 } 7839 7840 perm.releasePersistableModes(~0); 7841 removeUriPermissionIfNeededLocked(perm); 7842 } 7843 7844 return true; 7845 } 7846 7847 @Override 7848 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7849 String packageName, boolean incoming) { 7850 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7851 Preconditions.checkNotNull(packageName, "packageName"); 7852 7853 final int callingUid = Binder.getCallingUid(); 7854 final IPackageManager pm = AppGlobals.getPackageManager(); 7855 try { 7856 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7857 if (packageUid != callingUid) { 7858 throw new SecurityException( 7859 "Package " + packageName + " does not belong to calling UID " + callingUid); 7860 } 7861 } catch (RemoteException e) { 7862 throw new SecurityException("Failed to verify package name ownership"); 7863 } 7864 7865 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7866 synchronized (this) { 7867 if (incoming) { 7868 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7869 callingUid); 7870 if (perms == null) { 7871 Slog.w(TAG, "No permission grants found for " + packageName); 7872 } else { 7873 for (UriPermission perm : perms.values()) { 7874 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7875 result.add(perm.buildPersistedPublicApiObject()); 7876 } 7877 } 7878 } 7879 } else { 7880 final int size = mGrantedUriPermissions.size(); 7881 for (int i = 0; i < size; i++) { 7882 final ArrayMap<GrantUri, UriPermission> perms = 7883 mGrantedUriPermissions.valueAt(i); 7884 for (UriPermission perm : perms.values()) { 7885 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7886 result.add(perm.buildPersistedPublicApiObject()); 7887 } 7888 } 7889 } 7890 } 7891 } 7892 return new ParceledListSlice<android.content.UriPermission>(result); 7893 } 7894 7895 @Override 7896 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7897 synchronized (this) { 7898 ProcessRecord app = 7899 who != null ? getRecordForAppLocked(who) : null; 7900 if (app == null) return; 7901 7902 Message msg = Message.obtain(); 7903 msg.what = WAIT_FOR_DEBUGGER_MSG; 7904 msg.obj = app; 7905 msg.arg1 = waiting ? 1 : 0; 7906 mHandler.sendMessage(msg); 7907 } 7908 } 7909 7910 @Override 7911 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7912 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7913 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7914 outInfo.availMem = Process.getFreeMemory(); 7915 outInfo.totalMem = Process.getTotalMemory(); 7916 outInfo.threshold = homeAppMem; 7917 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7918 outInfo.hiddenAppThreshold = cachedAppMem; 7919 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7920 ProcessList.SERVICE_ADJ); 7921 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7922 ProcessList.VISIBLE_APP_ADJ); 7923 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7924 ProcessList.FOREGROUND_APP_ADJ); 7925 } 7926 7927 // ========================================================= 7928 // TASK MANAGEMENT 7929 // ========================================================= 7930 7931 @Override 7932 public List<IAppTask> getAppTasks(String callingPackage) { 7933 int callingUid = Binder.getCallingUid(); 7934 long ident = Binder.clearCallingIdentity(); 7935 7936 synchronized(this) { 7937 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7938 try { 7939 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7940 7941 final int N = mRecentTasks.size(); 7942 for (int i = 0; i < N; i++) { 7943 TaskRecord tr = mRecentTasks.get(i); 7944 // Skip tasks that do not match the caller. We don't need to verify 7945 // callingPackage, because we are also limiting to callingUid and know 7946 // that will limit to the correct security sandbox. 7947 if (tr.effectiveUid != callingUid) { 7948 continue; 7949 } 7950 Intent intent = tr.getBaseIntent(); 7951 if (intent == null || 7952 !callingPackage.equals(intent.getComponent().getPackageName())) { 7953 continue; 7954 } 7955 ActivityManager.RecentTaskInfo taskInfo = 7956 createRecentTaskInfoFromTaskRecord(tr); 7957 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7958 list.add(taskImpl); 7959 } 7960 } finally { 7961 Binder.restoreCallingIdentity(ident); 7962 } 7963 return list; 7964 } 7965 } 7966 7967 @Override 7968 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7969 final int callingUid = Binder.getCallingUid(); 7970 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7971 7972 synchronized(this) { 7973 if (localLOGV) Slog.v( 7974 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7975 7976 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7977 callingUid); 7978 7979 // TODO: Improve with MRU list from all ActivityStacks. 7980 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7981 } 7982 7983 return list; 7984 } 7985 7986 TaskRecord getMostRecentTask() { 7987 return mRecentTasks.get(0); 7988 } 7989 7990 /** 7991 * Creates a new RecentTaskInfo from a TaskRecord. 7992 */ 7993 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7994 // Update the task description to reflect any changes in the task stack 7995 tr.updateTaskDescription(); 7996 7997 // Compose the recent task info 7998 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7999 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8000 rti.persistentId = tr.taskId; 8001 rti.baseIntent = new Intent(tr.getBaseIntent()); 8002 rti.origActivity = tr.origActivity; 8003 rti.description = tr.lastDescription; 8004 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8005 rti.userId = tr.userId; 8006 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8007 rti.firstActiveTime = tr.firstActiveTime; 8008 rti.lastActiveTime = tr.lastActiveTime; 8009 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8010 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8011 return rti; 8012 } 8013 8014 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8015 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8016 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8017 if (!allowed) { 8018 if (checkPermission(android.Manifest.permission.GET_TASKS, 8019 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8020 // Temporary compatibility: some existing apps on the system image may 8021 // still be requesting the old permission and not switched to the new 8022 // one; if so, we'll still allow them full access. This means we need 8023 // to see if they are holding the old permission and are a system app. 8024 try { 8025 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8026 allowed = true; 8027 Slog.w(TAG, caller + ": caller " + callingUid 8028 + " is using old GET_TASKS but privileged; allowing"); 8029 } 8030 } catch (RemoteException e) { 8031 } 8032 } 8033 } 8034 if (!allowed) { 8035 Slog.w(TAG, caller + ": caller " + callingUid 8036 + " does not hold GET_TASKS; limiting output"); 8037 } 8038 return allowed; 8039 } 8040 8041 @Override 8042 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8043 final int callingUid = Binder.getCallingUid(); 8044 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8045 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8046 8047 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8048 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8049 synchronized (this) { 8050 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8051 callingUid); 8052 final boolean detailed = checkCallingPermission( 8053 android.Manifest.permission.GET_DETAILED_TASKS) 8054 == PackageManager.PERMISSION_GRANTED; 8055 8056 final int N = mRecentTasks.size(); 8057 ArrayList<ActivityManager.RecentTaskInfo> res 8058 = new ArrayList<ActivityManager.RecentTaskInfo>( 8059 maxNum < N ? maxNum : N); 8060 8061 final Set<Integer> includedUsers; 8062 if (includeProfiles) { 8063 includedUsers = getProfileIdsLocked(userId); 8064 } else { 8065 includedUsers = new HashSet<Integer>(); 8066 } 8067 includedUsers.add(Integer.valueOf(userId)); 8068 8069 for (int i=0; i<N && maxNum > 0; i++) { 8070 TaskRecord tr = mRecentTasks.get(i); 8071 // Only add calling user or related users recent tasks 8072 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8073 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8074 continue; 8075 } 8076 8077 // Return the entry if desired by the caller. We always return 8078 // the first entry, because callers always expect this to be the 8079 // foreground app. We may filter others if the caller has 8080 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8081 // we should exclude the entry. 8082 8083 if (i == 0 8084 || withExcluded 8085 || (tr.intent == null) 8086 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8087 == 0)) { 8088 if (!allowed) { 8089 // If the caller doesn't have the GET_TASKS permission, then only 8090 // allow them to see a small subset of tasks -- their own and home. 8091 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8092 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8093 continue; 8094 } 8095 } 8096 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8097 if (tr.stack != null && tr.stack.isHomeStack()) { 8098 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8099 continue; 8100 } 8101 } 8102 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8103 // Don't include auto remove tasks that are finished or finishing. 8104 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8105 + tr); 8106 continue; 8107 } 8108 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8109 && !tr.isAvailable) { 8110 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8111 continue; 8112 } 8113 8114 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8115 if (!detailed) { 8116 rti.baseIntent.replaceExtras((Bundle)null); 8117 } 8118 8119 res.add(rti); 8120 maxNum--; 8121 } 8122 } 8123 return res; 8124 } 8125 } 8126 8127 private TaskRecord taskForIdLocked(int id) { 8128 final TaskRecord task = recentTaskForIdLocked(id); 8129 if (task != null) { 8130 return task; 8131 } 8132 8133 // Don't give up. Sometimes it just hasn't made it to recents yet. 8134 return mStackSupervisor.anyTaskForIdLocked(id); 8135 } 8136 8137 private TaskRecord recentTaskForIdLocked(int id) { 8138 final int N = mRecentTasks.size(); 8139 for (int i=0; i<N; i++) { 8140 TaskRecord tr = mRecentTasks.get(i); 8141 if (tr.taskId == id) { 8142 return tr; 8143 } 8144 } 8145 return null; 8146 } 8147 8148 @Override 8149 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8150 synchronized (this) { 8151 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8152 "getTaskThumbnail()"); 8153 TaskRecord tr = recentTaskForIdLocked(id); 8154 if (tr != null) { 8155 return tr.getTaskThumbnailLocked(); 8156 } 8157 } 8158 return null; 8159 } 8160 8161 @Override 8162 public int addAppTask(IBinder activityToken, Intent intent, 8163 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8164 final int callingUid = Binder.getCallingUid(); 8165 final long callingIdent = Binder.clearCallingIdentity(); 8166 8167 try { 8168 synchronized (this) { 8169 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8170 if (r == null) { 8171 throw new IllegalArgumentException("Activity does not exist; token=" 8172 + activityToken); 8173 } 8174 ComponentName comp = intent.getComponent(); 8175 if (comp == null) { 8176 throw new IllegalArgumentException("Intent " + intent 8177 + " must specify explicit component"); 8178 } 8179 if (thumbnail.getWidth() != mThumbnailWidth 8180 || thumbnail.getHeight() != mThumbnailHeight) { 8181 throw new IllegalArgumentException("Bad thumbnail size: got " 8182 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8183 + mThumbnailWidth + "x" + mThumbnailHeight); 8184 } 8185 if (intent.getSelector() != null) { 8186 intent.setSelector(null); 8187 } 8188 if (intent.getSourceBounds() != null) { 8189 intent.setSourceBounds(null); 8190 } 8191 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8192 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8193 // The caller has added this as an auto-remove task... that makes no 8194 // sense, so turn off auto-remove. 8195 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8196 } 8197 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8198 // Must be a new task. 8199 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8200 } 8201 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8202 mLastAddedTaskActivity = null; 8203 } 8204 ActivityInfo ainfo = mLastAddedTaskActivity; 8205 if (ainfo == null) { 8206 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8207 comp, 0, UserHandle.getUserId(callingUid)); 8208 if (ainfo.applicationInfo.uid != callingUid) { 8209 throw new SecurityException( 8210 "Can't add task for another application: target uid=" 8211 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8212 } 8213 } 8214 8215 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8216 intent, description); 8217 8218 int trimIdx = trimRecentsForTask(task, false); 8219 if (trimIdx >= 0) { 8220 // If this would have caused a trim, then we'll abort because that 8221 // means it would be added at the end of the list but then just removed. 8222 return -1; 8223 } 8224 8225 final int N = mRecentTasks.size(); 8226 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8227 final TaskRecord tr = mRecentTasks.remove(N - 1); 8228 tr.removedFromRecents(mTaskPersister); 8229 } 8230 8231 task.inRecents = true; 8232 mRecentTasks.add(task); 8233 r.task.stack.addTask(task, false, false); 8234 8235 task.setLastThumbnail(thumbnail); 8236 task.freeLastThumbnail(); 8237 8238 return task.taskId; 8239 } 8240 } finally { 8241 Binder.restoreCallingIdentity(callingIdent); 8242 } 8243 } 8244 8245 @Override 8246 public Point getAppTaskThumbnailSize() { 8247 synchronized (this) { 8248 return new Point(mThumbnailWidth, mThumbnailHeight); 8249 } 8250 } 8251 8252 @Override 8253 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8254 synchronized (this) { 8255 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8256 if (r != null) { 8257 r.setTaskDescription(td); 8258 r.task.updateTaskDescription(); 8259 } 8260 } 8261 } 8262 8263 @Override 8264 public Bitmap getTaskDescriptionIcon(String filename) { 8265 if (!FileUtils.isValidExtFilename(filename) 8266 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8267 throw new IllegalArgumentException("Bad filename: " + filename); 8268 } 8269 return mTaskPersister.getTaskDescriptionIcon(filename); 8270 } 8271 8272 @Override 8273 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8274 throws RemoteException { 8275 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8276 opts.getCustomInPlaceResId() == 0) { 8277 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8278 "with valid animation"); 8279 } 8280 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8281 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8282 opts.getCustomInPlaceResId()); 8283 mWindowManager.executeAppTransition(); 8284 } 8285 8286 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8287 mRecentTasks.remove(tr); 8288 tr.removedFromRecents(mTaskPersister); 8289 ComponentName component = tr.getBaseIntent().getComponent(); 8290 if (component == null) { 8291 Slog.w(TAG, "No component for base intent of task: " + tr); 8292 return; 8293 } 8294 8295 if (!killProcess) { 8296 return; 8297 } 8298 8299 // Determine if the process(es) for this task should be killed. 8300 final String pkg = component.getPackageName(); 8301 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8302 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8303 for (int i = 0; i < pmap.size(); i++) { 8304 8305 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8306 for (int j = 0; j < uids.size(); j++) { 8307 ProcessRecord proc = uids.valueAt(j); 8308 if (proc.userId != tr.userId) { 8309 // Don't kill process for a different user. 8310 continue; 8311 } 8312 if (proc == mHomeProcess) { 8313 // Don't kill the home process along with tasks from the same package. 8314 continue; 8315 } 8316 if (!proc.pkgList.containsKey(pkg)) { 8317 // Don't kill process that is not associated with this task. 8318 continue; 8319 } 8320 8321 for (int k = 0; k < proc.activities.size(); k++) { 8322 TaskRecord otherTask = proc.activities.get(k).task; 8323 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8324 // Don't kill process(es) that has an activity in a different task that is 8325 // also in recents. 8326 return; 8327 } 8328 } 8329 8330 // Add process to kill list. 8331 procsToKill.add(proc); 8332 } 8333 } 8334 8335 // Find any running services associated with this app and stop if needed. 8336 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8337 8338 // Kill the running processes. 8339 for (int i = 0; i < procsToKill.size(); i++) { 8340 ProcessRecord pr = procsToKill.get(i); 8341 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8342 pr.kill("remove task", true); 8343 } else { 8344 pr.waitingToKill = "remove task"; 8345 } 8346 } 8347 } 8348 8349 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8350 // Remove all tasks with activities in the specified package from the list of recent tasks 8351 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8352 TaskRecord tr = mRecentTasks.get(i); 8353 if (tr.userId != userId) continue; 8354 8355 ComponentName cn = tr.intent.getComponent(); 8356 if (cn != null && cn.getPackageName().equals(packageName)) { 8357 // If the package name matches, remove the task. 8358 removeTaskByIdLocked(tr.taskId, true); 8359 } 8360 } 8361 } 8362 8363 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8364 final IPackageManager pm = AppGlobals.getPackageManager(); 8365 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8366 8367 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8368 TaskRecord tr = mRecentTasks.get(i); 8369 if (tr.userId != userId) continue; 8370 8371 ComponentName cn = tr.intent.getComponent(); 8372 if (cn != null && cn.getPackageName().equals(packageName)) { 8373 // Skip if component still exists in the package. 8374 if (componentsKnownToExist.contains(cn)) continue; 8375 8376 try { 8377 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8378 if (info != null) { 8379 componentsKnownToExist.add(cn); 8380 } else { 8381 removeTaskByIdLocked(tr.taskId, false); 8382 } 8383 } catch (RemoteException e) { 8384 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8385 } 8386 } 8387 } 8388 } 8389 8390 /** 8391 * Removes the task with the specified task id. 8392 * 8393 * @param taskId Identifier of the task to be removed. 8394 * @param killProcess Kill any process associated with the task if possible. 8395 * @return Returns true if the given task was found and removed. 8396 */ 8397 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8398 TaskRecord tr = taskForIdLocked(taskId); 8399 if (tr != null) { 8400 tr.removeTaskActivitiesLocked(); 8401 cleanUpRemovedTaskLocked(tr, killProcess); 8402 if (tr.isPersistable) { 8403 notifyTaskPersisterLocked(null, true); 8404 } 8405 return true; 8406 } 8407 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8408 return false; 8409 } 8410 8411 @Override 8412 public boolean removeTask(int taskId) { 8413 synchronized (this) { 8414 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8415 "removeTask()"); 8416 long ident = Binder.clearCallingIdentity(); 8417 try { 8418 return removeTaskByIdLocked(taskId, true); 8419 } finally { 8420 Binder.restoreCallingIdentity(ident); 8421 } 8422 } 8423 } 8424 8425 /** 8426 * TODO: Add mController hook 8427 */ 8428 @Override 8429 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8430 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8431 "moveTaskToFront()"); 8432 8433 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8434 synchronized(this) { 8435 moveTaskToFrontLocked(taskId, flags, options); 8436 } 8437 } 8438 8439 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8440 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8441 Binder.getCallingUid(), -1, -1, "Task to front")) { 8442 ActivityOptions.abort(options); 8443 return; 8444 } 8445 final long origId = Binder.clearCallingIdentity(); 8446 try { 8447 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8448 if (task == null) { 8449 Slog.d(TAG, "Could not find task for id: "+ taskId); 8450 return; 8451 } 8452 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8453 mStackSupervisor.showLockTaskToast(); 8454 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8455 return; 8456 } 8457 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8458 if (prev != null && prev.isRecentsActivity()) { 8459 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8460 } 8461 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8462 } finally { 8463 Binder.restoreCallingIdentity(origId); 8464 } 8465 ActivityOptions.abort(options); 8466 } 8467 8468 @Override 8469 public void moveTaskToBack(int taskId) { 8470 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8471 "moveTaskToBack()"); 8472 8473 synchronized(this) { 8474 TaskRecord tr = taskForIdLocked(taskId); 8475 if (tr != null) { 8476 if (tr == mStackSupervisor.mLockTaskModeTask) { 8477 mStackSupervisor.showLockTaskToast(); 8478 return; 8479 } 8480 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8481 ActivityStack stack = tr.stack; 8482 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8483 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8484 Binder.getCallingUid(), -1, -1, "Task to back")) { 8485 return; 8486 } 8487 } 8488 final long origId = Binder.clearCallingIdentity(); 8489 try { 8490 stack.moveTaskToBackLocked(taskId, null); 8491 } finally { 8492 Binder.restoreCallingIdentity(origId); 8493 } 8494 } 8495 } 8496 } 8497 8498 /** 8499 * Moves an activity, and all of the other activities within the same task, to the bottom 8500 * of the history stack. The activity's order within the task is unchanged. 8501 * 8502 * @param token A reference to the activity we wish to move 8503 * @param nonRoot If false then this only works if the activity is the root 8504 * of a task; if true it will work for any activity in a task. 8505 * @return Returns true if the move completed, false if not. 8506 */ 8507 @Override 8508 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8509 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8510 synchronized(this) { 8511 final long origId = Binder.clearCallingIdentity(); 8512 try { 8513 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8514 if (taskId >= 0) { 8515 if ((mStackSupervisor.mLockTaskModeTask != null) 8516 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8517 mStackSupervisor.showLockTaskToast(); 8518 return false; 8519 } 8520 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8521 } 8522 } finally { 8523 Binder.restoreCallingIdentity(origId); 8524 } 8525 } 8526 return false; 8527 } 8528 8529 @Override 8530 public void moveTaskBackwards(int task) { 8531 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8532 "moveTaskBackwards()"); 8533 8534 synchronized(this) { 8535 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8536 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8537 return; 8538 } 8539 final long origId = Binder.clearCallingIdentity(); 8540 moveTaskBackwardsLocked(task); 8541 Binder.restoreCallingIdentity(origId); 8542 } 8543 } 8544 8545 private final void moveTaskBackwardsLocked(int task) { 8546 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8547 } 8548 8549 @Override 8550 public IBinder getHomeActivityToken() throws RemoteException { 8551 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8552 "getHomeActivityToken()"); 8553 synchronized (this) { 8554 return mStackSupervisor.getHomeActivityToken(); 8555 } 8556 } 8557 8558 @Override 8559 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8560 IActivityContainerCallback callback) throws RemoteException { 8561 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8562 "createActivityContainer()"); 8563 synchronized (this) { 8564 if (parentActivityToken == null) { 8565 throw new IllegalArgumentException("parent token must not be null"); 8566 } 8567 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8568 if (r == null) { 8569 return null; 8570 } 8571 if (callback == null) { 8572 throw new IllegalArgumentException("callback must not be null"); 8573 } 8574 return mStackSupervisor.createActivityContainer(r, callback); 8575 } 8576 } 8577 8578 @Override 8579 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8580 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8581 "deleteActivityContainer()"); 8582 synchronized (this) { 8583 mStackSupervisor.deleteActivityContainer(container); 8584 } 8585 } 8586 8587 @Override 8588 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8589 throws RemoteException { 8590 synchronized (this) { 8591 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8592 if (stack != null) { 8593 return stack.mActivityContainer; 8594 } 8595 return null; 8596 } 8597 } 8598 8599 @Override 8600 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8601 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8602 "moveTaskToStack()"); 8603 if (stackId == HOME_STACK_ID) { 8604 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8605 new RuntimeException("here").fillInStackTrace()); 8606 } 8607 synchronized (this) { 8608 long ident = Binder.clearCallingIdentity(); 8609 try { 8610 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8611 + stackId + " toTop=" + toTop); 8612 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8613 } finally { 8614 Binder.restoreCallingIdentity(ident); 8615 } 8616 } 8617 } 8618 8619 @Override 8620 public void resizeStack(int stackBoxId, Rect bounds) { 8621 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8622 "resizeStackBox()"); 8623 long ident = Binder.clearCallingIdentity(); 8624 try { 8625 mWindowManager.resizeStack(stackBoxId, bounds); 8626 } finally { 8627 Binder.restoreCallingIdentity(ident); 8628 } 8629 } 8630 8631 @Override 8632 public List<StackInfo> getAllStackInfos() { 8633 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8634 "getAllStackInfos()"); 8635 long ident = Binder.clearCallingIdentity(); 8636 try { 8637 synchronized (this) { 8638 return mStackSupervisor.getAllStackInfosLocked(); 8639 } 8640 } finally { 8641 Binder.restoreCallingIdentity(ident); 8642 } 8643 } 8644 8645 @Override 8646 public StackInfo getStackInfo(int stackId) { 8647 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8648 "getStackInfo()"); 8649 long ident = Binder.clearCallingIdentity(); 8650 try { 8651 synchronized (this) { 8652 return mStackSupervisor.getStackInfoLocked(stackId); 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(ident); 8656 } 8657 } 8658 8659 @Override 8660 public boolean isInHomeStack(int taskId) { 8661 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8662 "getStackInfo()"); 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 synchronized (this) { 8666 TaskRecord tr = taskForIdLocked(taskId); 8667 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8668 } 8669 } finally { 8670 Binder.restoreCallingIdentity(ident); 8671 } 8672 } 8673 8674 @Override 8675 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8676 synchronized(this) { 8677 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8678 } 8679 } 8680 8681 private boolean isLockTaskAuthorized(String pkg) { 8682 final DevicePolicyManager dpm = (DevicePolicyManager) 8683 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8684 try { 8685 int uid = mContext.getPackageManager().getPackageUid(pkg, 8686 Binder.getCallingUserHandle().getIdentifier()); 8687 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8688 } catch (NameNotFoundException e) { 8689 return false; 8690 } 8691 } 8692 8693 void startLockTaskMode(TaskRecord task) { 8694 final String pkg; 8695 synchronized (this) { 8696 pkg = task.intent.getComponent().getPackageName(); 8697 } 8698 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8699 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8700 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8701 StatusBarManagerInternal.class); 8702 if (statusBarManager != null) { 8703 statusBarManager.showScreenPinningRequest(); 8704 } 8705 return; 8706 } 8707 long ident = Binder.clearCallingIdentity(); 8708 try { 8709 synchronized (this) { 8710 // Since we lost lock on task, make sure it is still there. 8711 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8712 if (task != null) { 8713 if (!isSystemInitiated 8714 && ((mStackSupervisor.getFocusedStack() == null) 8715 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8716 throw new IllegalArgumentException("Invalid task, not in foreground"); 8717 } 8718 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8719 } 8720 } 8721 } finally { 8722 Binder.restoreCallingIdentity(ident); 8723 } 8724 } 8725 8726 @Override 8727 public void startLockTaskMode(int taskId) { 8728 final TaskRecord task; 8729 long ident = Binder.clearCallingIdentity(); 8730 try { 8731 synchronized (this) { 8732 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8733 } 8734 } finally { 8735 Binder.restoreCallingIdentity(ident); 8736 } 8737 if (task != null) { 8738 startLockTaskMode(task); 8739 } 8740 } 8741 8742 @Override 8743 public void startLockTaskMode(IBinder token) { 8744 final TaskRecord task; 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 synchronized (this) { 8748 final ActivityRecord r = ActivityRecord.forToken(token); 8749 if (r == null) { 8750 return; 8751 } 8752 task = r.task; 8753 } 8754 } finally { 8755 Binder.restoreCallingIdentity(ident); 8756 } 8757 if (task != null) { 8758 startLockTaskMode(task); 8759 } 8760 } 8761 8762 @Override 8763 public void startLockTaskModeOnCurrent() throws RemoteException { 8764 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8765 "startLockTaskModeOnCurrent"); 8766 long ident = Binder.clearCallingIdentity(); 8767 try { 8768 ActivityRecord r = null; 8769 synchronized (this) { 8770 r = mStackSupervisor.topRunningActivityLocked(); 8771 } 8772 startLockTaskMode(r.task); 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 } 8777 8778 @Override 8779 public void stopLockTaskMode() { 8780 // Verify that the user matches the package of the intent for the TaskRecord 8781 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8782 // and stopLockTaskMode. 8783 final int callingUid = Binder.getCallingUid(); 8784 if (callingUid != Process.SYSTEM_UID) { 8785 try { 8786 String pkg = 8787 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8788 int uid = mContext.getPackageManager().getPackageUid(pkg, 8789 Binder.getCallingUserHandle().getIdentifier()); 8790 if (uid != callingUid) { 8791 throw new SecurityException("Invalid uid, expected " + uid); 8792 } 8793 } catch (NameNotFoundException e) { 8794 Log.d(TAG, "stopLockTaskMode " + e); 8795 return; 8796 } 8797 } 8798 long ident = Binder.clearCallingIdentity(); 8799 try { 8800 Log.d(TAG, "stopLockTaskMode"); 8801 // Stop lock task 8802 synchronized (this) { 8803 mStackSupervisor.setLockTaskModeLocked(null, false); 8804 } 8805 } finally { 8806 Binder.restoreCallingIdentity(ident); 8807 } 8808 } 8809 8810 @Override 8811 public void stopLockTaskModeOnCurrent() throws RemoteException { 8812 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8813 "stopLockTaskModeOnCurrent"); 8814 long ident = Binder.clearCallingIdentity(); 8815 try { 8816 stopLockTaskMode(); 8817 } finally { 8818 Binder.restoreCallingIdentity(ident); 8819 } 8820 } 8821 8822 @Override 8823 public boolean isInLockTaskMode() { 8824 synchronized (this) { 8825 return mStackSupervisor.isInLockTaskMode(); 8826 } 8827 } 8828 8829 // ========================================================= 8830 // CONTENT PROVIDERS 8831 // ========================================================= 8832 8833 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8834 List<ProviderInfo> providers = null; 8835 try { 8836 providers = AppGlobals.getPackageManager(). 8837 queryContentProviders(app.processName, app.uid, 8838 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8839 } catch (RemoteException ex) { 8840 } 8841 if (DEBUG_MU) 8842 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8843 int userId = app.userId; 8844 if (providers != null) { 8845 int N = providers.size(); 8846 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8847 for (int i=0; i<N; i++) { 8848 ProviderInfo cpi = 8849 (ProviderInfo)providers.get(i); 8850 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8851 cpi.name, cpi.flags); 8852 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8853 // This is a singleton provider, but a user besides the 8854 // default user is asking to initialize a process it runs 8855 // in... well, no, it doesn't actually run in this process, 8856 // it runs in the process of the default user. Get rid of it. 8857 providers.remove(i); 8858 N--; 8859 i--; 8860 continue; 8861 } 8862 8863 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8864 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8865 if (cpr == null) { 8866 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8867 mProviderMap.putProviderByClass(comp, cpr); 8868 } 8869 if (DEBUG_MU) 8870 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8871 app.pubProviders.put(cpi.name, cpr); 8872 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8873 // Don't add this if it is a platform component that is marked 8874 // to run in multiple processes, because this is actually 8875 // part of the framework so doesn't make sense to track as a 8876 // separate apk in the process. 8877 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8878 mProcessStats); 8879 } 8880 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8881 } 8882 } 8883 return providers; 8884 } 8885 8886 /** 8887 * Check if {@link ProcessRecord} has a possible chance at accessing the 8888 * given {@link ProviderInfo}. Final permission checking is always done 8889 * in {@link ContentProvider}. 8890 */ 8891 private final String checkContentProviderPermissionLocked( 8892 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8893 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8894 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8895 boolean checkedGrants = false; 8896 if (checkUser) { 8897 // Looking for cross-user grants before enforcing the typical cross-users permissions 8898 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8899 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8900 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8901 return null; 8902 } 8903 checkedGrants = true; 8904 } 8905 userId = handleIncomingUser(callingPid, callingUid, userId, 8906 false, ALLOW_NON_FULL, 8907 "checkContentProviderPermissionLocked " + cpi.authority, null); 8908 if (userId != tmpTargetUserId) { 8909 // When we actually went to determine the final targer user ID, this ended 8910 // up different than our initial check for the authority. This is because 8911 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8912 // SELF. So we need to re-check the grants again. 8913 checkedGrants = false; 8914 } 8915 } 8916 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8917 cpi.applicationInfo.uid, cpi.exported) 8918 == PackageManager.PERMISSION_GRANTED) { 8919 return null; 8920 } 8921 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8922 cpi.applicationInfo.uid, cpi.exported) 8923 == PackageManager.PERMISSION_GRANTED) { 8924 return null; 8925 } 8926 8927 PathPermission[] pps = cpi.pathPermissions; 8928 if (pps != null) { 8929 int i = pps.length; 8930 while (i > 0) { 8931 i--; 8932 PathPermission pp = pps[i]; 8933 String pprperm = pp.getReadPermission(); 8934 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8935 cpi.applicationInfo.uid, cpi.exported) 8936 == PackageManager.PERMISSION_GRANTED) { 8937 return null; 8938 } 8939 String ppwperm = pp.getWritePermission(); 8940 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8941 cpi.applicationInfo.uid, cpi.exported) 8942 == PackageManager.PERMISSION_GRANTED) { 8943 return null; 8944 } 8945 } 8946 } 8947 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8948 return null; 8949 } 8950 8951 String msg; 8952 if (!cpi.exported) { 8953 msg = "Permission Denial: opening provider " + cpi.name 8954 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8955 + ", uid=" + callingUid + ") that is not exported from uid " 8956 + cpi.applicationInfo.uid; 8957 } else { 8958 msg = "Permission Denial: opening provider " + cpi.name 8959 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8960 + ", uid=" + callingUid + ") requires " 8961 + cpi.readPermission + " or " + cpi.writePermission; 8962 } 8963 Slog.w(TAG, msg); 8964 return msg; 8965 } 8966 8967 /** 8968 * Returns if the ContentProvider has granted a uri to callingUid 8969 */ 8970 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8971 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8972 if (perms != null) { 8973 for (int i=perms.size()-1; i>=0; i--) { 8974 GrantUri grantUri = perms.keyAt(i); 8975 if (grantUri.sourceUserId == userId || !checkUser) { 8976 if (matchesProvider(grantUri.uri, cpi)) { 8977 return true; 8978 } 8979 } 8980 } 8981 } 8982 return false; 8983 } 8984 8985 /** 8986 * Returns true if the uri authority is one of the authorities specified in the provider. 8987 */ 8988 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8989 String uriAuth = uri.getAuthority(); 8990 String cpiAuth = cpi.authority; 8991 if (cpiAuth.indexOf(';') == -1) { 8992 return cpiAuth.equals(uriAuth); 8993 } 8994 String[] cpiAuths = cpiAuth.split(";"); 8995 int length = cpiAuths.length; 8996 for (int i = 0; i < length; i++) { 8997 if (cpiAuths[i].equals(uriAuth)) return true; 8998 } 8999 return false; 9000 } 9001 9002 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9003 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9004 if (r != null) { 9005 for (int i=0; i<r.conProviders.size(); i++) { 9006 ContentProviderConnection conn = r.conProviders.get(i); 9007 if (conn.provider == cpr) { 9008 if (DEBUG_PROVIDER) Slog.v(TAG, 9009 "Adding provider requested by " 9010 + r.processName + " from process " 9011 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9012 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9013 if (stable) { 9014 conn.stableCount++; 9015 conn.numStableIncs++; 9016 } else { 9017 conn.unstableCount++; 9018 conn.numUnstableIncs++; 9019 } 9020 return conn; 9021 } 9022 } 9023 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9024 if (stable) { 9025 conn.stableCount = 1; 9026 conn.numStableIncs = 1; 9027 } else { 9028 conn.unstableCount = 1; 9029 conn.numUnstableIncs = 1; 9030 } 9031 cpr.connections.add(conn); 9032 r.conProviders.add(conn); 9033 return conn; 9034 } 9035 cpr.addExternalProcessHandleLocked(externalProcessToken); 9036 return null; 9037 } 9038 9039 boolean decProviderCountLocked(ContentProviderConnection conn, 9040 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9041 if (conn != null) { 9042 cpr = conn.provider; 9043 if (DEBUG_PROVIDER) Slog.v(TAG, 9044 "Removing provider requested by " 9045 + conn.client.processName + " from process " 9046 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9047 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9048 if (stable) { 9049 conn.stableCount--; 9050 } else { 9051 conn.unstableCount--; 9052 } 9053 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9054 cpr.connections.remove(conn); 9055 conn.client.conProviders.remove(conn); 9056 return true; 9057 } 9058 return false; 9059 } 9060 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9061 return false; 9062 } 9063 9064 private void checkTime(long startTime, String where) { 9065 long now = SystemClock.elapsedRealtime(); 9066 if ((now-startTime) > 1000) { 9067 // If we are taking more than a second, log about it. 9068 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9069 } 9070 } 9071 9072 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9073 String name, IBinder token, boolean stable, int userId) { 9074 ContentProviderRecord cpr; 9075 ContentProviderConnection conn = null; 9076 ProviderInfo cpi = null; 9077 9078 synchronized(this) { 9079 long startTime = SystemClock.elapsedRealtime(); 9080 9081 ProcessRecord r = null; 9082 if (caller != null) { 9083 r = getRecordForAppLocked(caller); 9084 if (r == null) { 9085 throw new SecurityException( 9086 "Unable to find app for caller " + caller 9087 + " (pid=" + Binder.getCallingPid() 9088 + ") when getting content provider " + name); 9089 } 9090 } 9091 9092 boolean checkCrossUser = true; 9093 9094 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9095 9096 // First check if this content provider has been published... 9097 cpr = mProviderMap.getProviderByName(name, userId); 9098 // If that didn't work, check if it exists for user 0 and then 9099 // verify that it's a singleton provider before using it. 9100 if (cpr == null && userId != UserHandle.USER_OWNER) { 9101 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9102 if (cpr != null) { 9103 cpi = cpr.info; 9104 if (isSingleton(cpi.processName, cpi.applicationInfo, 9105 cpi.name, cpi.flags) 9106 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9107 userId = UserHandle.USER_OWNER; 9108 checkCrossUser = false; 9109 } else { 9110 cpr = null; 9111 cpi = null; 9112 } 9113 } 9114 } 9115 9116 boolean providerRunning = cpr != null; 9117 if (providerRunning) { 9118 cpi = cpr.info; 9119 String msg; 9120 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9121 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9122 != null) { 9123 throw new SecurityException(msg); 9124 } 9125 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9126 9127 if (r != null && cpr.canRunHere(r)) { 9128 // This provider has been published or is in the process 9129 // of being published... but it is also allowed to run 9130 // in the caller's process, so don't make a connection 9131 // and just let the caller instantiate its own instance. 9132 ContentProviderHolder holder = cpr.newHolder(null); 9133 // don't give caller the provider object, it needs 9134 // to make its own. 9135 holder.provider = null; 9136 return holder; 9137 } 9138 9139 final long origId = Binder.clearCallingIdentity(); 9140 9141 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9142 9143 // In this case the provider instance already exists, so we can 9144 // return it right away. 9145 conn = incProviderCountLocked(r, cpr, token, stable); 9146 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9147 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9148 // If this is a perceptible app accessing the provider, 9149 // make sure to count it as being accessed and thus 9150 // back up on the LRU list. This is good because 9151 // content providers are often expensive to start. 9152 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9153 updateLruProcessLocked(cpr.proc, false, null); 9154 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9155 } 9156 } 9157 9158 if (cpr.proc != null) { 9159 if (false) { 9160 if (cpr.name.flattenToShortString().equals( 9161 "com.android.providers.calendar/.CalendarProvider2")) { 9162 Slog.v(TAG, "****************** KILLING " 9163 + cpr.name.flattenToShortString()); 9164 Process.killProcess(cpr.proc.pid); 9165 } 9166 } 9167 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9168 boolean success = updateOomAdjLocked(cpr.proc); 9169 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9170 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9171 // NOTE: there is still a race here where a signal could be 9172 // pending on the process even though we managed to update its 9173 // adj level. Not sure what to do about this, but at least 9174 // the race is now smaller. 9175 if (!success) { 9176 // Uh oh... it looks like the provider's process 9177 // has been killed on us. We need to wait for a new 9178 // process to be started, and make sure its death 9179 // doesn't kill our process. 9180 Slog.i(TAG, 9181 "Existing provider " + cpr.name.flattenToShortString() 9182 + " is crashing; detaching " + r); 9183 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9184 checkTime(startTime, "getContentProviderImpl: before appDied"); 9185 appDiedLocked(cpr.proc); 9186 checkTime(startTime, "getContentProviderImpl: after appDied"); 9187 if (!lastRef) { 9188 // This wasn't the last ref our process had on 9189 // the provider... we have now been killed, bail. 9190 return null; 9191 } 9192 providerRunning = false; 9193 conn = null; 9194 } 9195 } 9196 9197 Binder.restoreCallingIdentity(origId); 9198 } 9199 9200 boolean singleton; 9201 if (!providerRunning) { 9202 try { 9203 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9204 cpi = AppGlobals.getPackageManager(). 9205 resolveContentProvider(name, 9206 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9207 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9208 } catch (RemoteException ex) { 9209 } 9210 if (cpi == null) { 9211 return null; 9212 } 9213 // If the provider is a singleton AND 9214 // (it's a call within the same user || the provider is a 9215 // privileged app) 9216 // Then allow connecting to the singleton provider 9217 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9218 cpi.name, cpi.flags) 9219 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9220 if (singleton) { 9221 userId = UserHandle.USER_OWNER; 9222 } 9223 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9224 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9225 9226 String msg; 9227 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9228 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9229 != null) { 9230 throw new SecurityException(msg); 9231 } 9232 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9233 9234 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9235 && !cpi.processName.equals("system")) { 9236 // If this content provider does not run in the system 9237 // process, and the system is not yet ready to run other 9238 // processes, then fail fast instead of hanging. 9239 throw new IllegalArgumentException( 9240 "Attempt to launch content provider before system ready"); 9241 } 9242 9243 // Make sure that the user who owns this provider is started. If not, 9244 // we don't want to allow it to run. 9245 if (mStartedUsers.get(userId) == null) { 9246 Slog.w(TAG, "Unable to launch app " 9247 + cpi.applicationInfo.packageName + "/" 9248 + cpi.applicationInfo.uid + " for provider " 9249 + name + ": user " + userId + " is stopped"); 9250 return null; 9251 } 9252 9253 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9254 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9255 cpr = mProviderMap.getProviderByClass(comp, userId); 9256 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9257 final boolean firstClass = cpr == null; 9258 if (firstClass) { 9259 final long ident = Binder.clearCallingIdentity(); 9260 try { 9261 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9262 ApplicationInfo ai = 9263 AppGlobals.getPackageManager(). 9264 getApplicationInfo( 9265 cpi.applicationInfo.packageName, 9266 STOCK_PM_FLAGS, userId); 9267 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9268 if (ai == null) { 9269 Slog.w(TAG, "No package info for content provider " 9270 + cpi.name); 9271 return null; 9272 } 9273 ai = getAppInfoForUser(ai, userId); 9274 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9275 } catch (RemoteException ex) { 9276 // pm is in same process, this will never happen. 9277 } finally { 9278 Binder.restoreCallingIdentity(ident); 9279 } 9280 } 9281 9282 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9283 9284 if (r != null && cpr.canRunHere(r)) { 9285 // If this is a multiprocess provider, then just return its 9286 // info and allow the caller to instantiate it. Only do 9287 // this if the provider is the same user as the caller's 9288 // process, or can run as root (so can be in any process). 9289 return cpr.newHolder(null); 9290 } 9291 9292 if (DEBUG_PROVIDER) { 9293 RuntimeException e = new RuntimeException("here"); 9294 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9295 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9296 } 9297 9298 // This is single process, and our app is now connecting to it. 9299 // See if we are already in the process of launching this 9300 // provider. 9301 final int N = mLaunchingProviders.size(); 9302 int i; 9303 for (i=0; i<N; i++) { 9304 if (mLaunchingProviders.get(i) == cpr) { 9305 break; 9306 } 9307 } 9308 9309 // If the provider is not already being launched, then get it 9310 // started. 9311 if (i >= N) { 9312 final long origId = Binder.clearCallingIdentity(); 9313 9314 try { 9315 // Content provider is now in use, its package can't be stopped. 9316 try { 9317 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9318 AppGlobals.getPackageManager().setPackageStoppedState( 9319 cpr.appInfo.packageName, false, userId); 9320 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9321 } catch (RemoteException e) { 9322 } catch (IllegalArgumentException e) { 9323 Slog.w(TAG, "Failed trying to unstop package " 9324 + cpr.appInfo.packageName + ": " + e); 9325 } 9326 9327 // Use existing process if already started 9328 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9329 ProcessRecord proc = getProcessRecordLocked( 9330 cpi.processName, cpr.appInfo.uid, false); 9331 if (proc != null && proc.thread != null) { 9332 if (DEBUG_PROVIDER) { 9333 Slog.d(TAG, "Installing in existing process " + proc); 9334 } 9335 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9336 proc.pubProviders.put(cpi.name, cpr); 9337 try { 9338 proc.thread.scheduleInstallProvider(cpi); 9339 } catch (RemoteException e) { 9340 } 9341 } else { 9342 checkTime(startTime, "getContentProviderImpl: before start process"); 9343 proc = startProcessLocked(cpi.processName, 9344 cpr.appInfo, false, 0, "content provider", 9345 new ComponentName(cpi.applicationInfo.packageName, 9346 cpi.name), false, false, false); 9347 checkTime(startTime, "getContentProviderImpl: after start process"); 9348 if (proc == null) { 9349 Slog.w(TAG, "Unable to launch app " 9350 + cpi.applicationInfo.packageName + "/" 9351 + cpi.applicationInfo.uid + " for provider " 9352 + name + ": process is bad"); 9353 return null; 9354 } 9355 } 9356 cpr.launchingApp = proc; 9357 mLaunchingProviders.add(cpr); 9358 } finally { 9359 Binder.restoreCallingIdentity(origId); 9360 } 9361 } 9362 9363 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9364 9365 // Make sure the provider is published (the same provider class 9366 // may be published under multiple names). 9367 if (firstClass) { 9368 mProviderMap.putProviderByClass(comp, cpr); 9369 } 9370 9371 mProviderMap.putProviderByName(name, cpr); 9372 conn = incProviderCountLocked(r, cpr, token, stable); 9373 if (conn != null) { 9374 conn.waiting = true; 9375 } 9376 } 9377 checkTime(startTime, "getContentProviderImpl: done!"); 9378 } 9379 9380 // Wait for the provider to be published... 9381 synchronized (cpr) { 9382 while (cpr.provider == null) { 9383 if (cpr.launchingApp == null) { 9384 Slog.w(TAG, "Unable to launch app " 9385 + cpi.applicationInfo.packageName + "/" 9386 + cpi.applicationInfo.uid + " for provider " 9387 + name + ": launching app became null"); 9388 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9389 UserHandle.getUserId(cpi.applicationInfo.uid), 9390 cpi.applicationInfo.packageName, 9391 cpi.applicationInfo.uid, name); 9392 return null; 9393 } 9394 try { 9395 if (DEBUG_MU) { 9396 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9397 + cpr.launchingApp); 9398 } 9399 if (conn != null) { 9400 conn.waiting = true; 9401 } 9402 cpr.wait(); 9403 } catch (InterruptedException ex) { 9404 } finally { 9405 if (conn != null) { 9406 conn.waiting = false; 9407 } 9408 } 9409 } 9410 } 9411 return cpr != null ? cpr.newHolder(conn) : null; 9412 } 9413 9414 @Override 9415 public final ContentProviderHolder getContentProvider( 9416 IApplicationThread caller, String name, int userId, boolean stable) { 9417 enforceNotIsolatedCaller("getContentProvider"); 9418 if (caller == null) { 9419 String msg = "null IApplicationThread when getting content provider " 9420 + name; 9421 Slog.w(TAG, msg); 9422 throw new SecurityException(msg); 9423 } 9424 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9425 // with cross-user grant. 9426 return getContentProviderImpl(caller, name, null, stable, userId); 9427 } 9428 9429 public ContentProviderHolder getContentProviderExternal( 9430 String name, int userId, IBinder token) { 9431 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9432 "Do not have permission in call getContentProviderExternal()"); 9433 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9434 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9435 return getContentProviderExternalUnchecked(name, token, userId); 9436 } 9437 9438 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9439 IBinder token, int userId) { 9440 return getContentProviderImpl(null, name, token, true, userId); 9441 } 9442 9443 /** 9444 * Drop a content provider from a ProcessRecord's bookkeeping 9445 */ 9446 public void removeContentProvider(IBinder connection, boolean stable) { 9447 enforceNotIsolatedCaller("removeContentProvider"); 9448 long ident = Binder.clearCallingIdentity(); 9449 try { 9450 synchronized (this) { 9451 ContentProviderConnection conn; 9452 try { 9453 conn = (ContentProviderConnection)connection; 9454 } catch (ClassCastException e) { 9455 String msg ="removeContentProvider: " + connection 9456 + " not a ContentProviderConnection"; 9457 Slog.w(TAG, msg); 9458 throw new IllegalArgumentException(msg); 9459 } 9460 if (conn == null) { 9461 throw new NullPointerException("connection is null"); 9462 } 9463 if (decProviderCountLocked(conn, null, null, stable)) { 9464 updateOomAdjLocked(); 9465 } 9466 } 9467 } finally { 9468 Binder.restoreCallingIdentity(ident); 9469 } 9470 } 9471 9472 public void removeContentProviderExternal(String name, IBinder token) { 9473 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9474 "Do not have permission in call removeContentProviderExternal()"); 9475 int userId = UserHandle.getCallingUserId(); 9476 long ident = Binder.clearCallingIdentity(); 9477 try { 9478 removeContentProviderExternalUnchecked(name, token, userId); 9479 } finally { 9480 Binder.restoreCallingIdentity(ident); 9481 } 9482 } 9483 9484 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9485 synchronized (this) { 9486 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9487 if(cpr == null) { 9488 //remove from mProvidersByClass 9489 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9490 return; 9491 } 9492 9493 //update content provider record entry info 9494 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9495 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9496 if (localCpr.hasExternalProcessHandles()) { 9497 if (localCpr.removeExternalProcessHandleLocked(token)) { 9498 updateOomAdjLocked(); 9499 } else { 9500 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9501 + " with no external reference for token: " 9502 + token + "."); 9503 } 9504 } else { 9505 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9506 + " with no external references."); 9507 } 9508 } 9509 } 9510 9511 public final void publishContentProviders(IApplicationThread caller, 9512 List<ContentProviderHolder> providers) { 9513 if (providers == null) { 9514 return; 9515 } 9516 9517 enforceNotIsolatedCaller("publishContentProviders"); 9518 synchronized (this) { 9519 final ProcessRecord r = getRecordForAppLocked(caller); 9520 if (DEBUG_MU) 9521 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9522 if (r == null) { 9523 throw new SecurityException( 9524 "Unable to find app for caller " + caller 9525 + " (pid=" + Binder.getCallingPid() 9526 + ") when publishing content providers"); 9527 } 9528 9529 final long origId = Binder.clearCallingIdentity(); 9530 9531 final int N = providers.size(); 9532 for (int i=0; i<N; i++) { 9533 ContentProviderHolder src = providers.get(i); 9534 if (src == null || src.info == null || src.provider == null) { 9535 continue; 9536 } 9537 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9538 if (DEBUG_MU) 9539 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9540 if (dst != null) { 9541 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9542 mProviderMap.putProviderByClass(comp, dst); 9543 String names[] = dst.info.authority.split(";"); 9544 for (int j = 0; j < names.length; j++) { 9545 mProviderMap.putProviderByName(names[j], dst); 9546 } 9547 9548 int NL = mLaunchingProviders.size(); 9549 int j; 9550 for (j=0; j<NL; j++) { 9551 if (mLaunchingProviders.get(j) == dst) { 9552 mLaunchingProviders.remove(j); 9553 j--; 9554 NL--; 9555 } 9556 } 9557 synchronized (dst) { 9558 dst.provider = src.provider; 9559 dst.proc = r; 9560 dst.notifyAll(); 9561 } 9562 updateOomAdjLocked(r); 9563 } 9564 } 9565 9566 Binder.restoreCallingIdentity(origId); 9567 } 9568 } 9569 9570 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9571 ContentProviderConnection conn; 9572 try { 9573 conn = (ContentProviderConnection)connection; 9574 } catch (ClassCastException e) { 9575 String msg ="refContentProvider: " + connection 9576 + " not a ContentProviderConnection"; 9577 Slog.w(TAG, msg); 9578 throw new IllegalArgumentException(msg); 9579 } 9580 if (conn == null) { 9581 throw new NullPointerException("connection is null"); 9582 } 9583 9584 synchronized (this) { 9585 if (stable > 0) { 9586 conn.numStableIncs += stable; 9587 } 9588 stable = conn.stableCount + stable; 9589 if (stable < 0) { 9590 throw new IllegalStateException("stableCount < 0: " + stable); 9591 } 9592 9593 if (unstable > 0) { 9594 conn.numUnstableIncs += unstable; 9595 } 9596 unstable = conn.unstableCount + unstable; 9597 if (unstable < 0) { 9598 throw new IllegalStateException("unstableCount < 0: " + unstable); 9599 } 9600 9601 if ((stable+unstable) <= 0) { 9602 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9603 + stable + " unstable=" + unstable); 9604 } 9605 conn.stableCount = stable; 9606 conn.unstableCount = unstable; 9607 return !conn.dead; 9608 } 9609 } 9610 9611 public void unstableProviderDied(IBinder connection) { 9612 ContentProviderConnection conn; 9613 try { 9614 conn = (ContentProviderConnection)connection; 9615 } catch (ClassCastException e) { 9616 String msg ="refContentProvider: " + connection 9617 + " not a ContentProviderConnection"; 9618 Slog.w(TAG, msg); 9619 throw new IllegalArgumentException(msg); 9620 } 9621 if (conn == null) { 9622 throw new NullPointerException("connection is null"); 9623 } 9624 9625 // Safely retrieve the content provider associated with the connection. 9626 IContentProvider provider; 9627 synchronized (this) { 9628 provider = conn.provider.provider; 9629 } 9630 9631 if (provider == null) { 9632 // Um, yeah, we're way ahead of you. 9633 return; 9634 } 9635 9636 // Make sure the caller is being honest with us. 9637 if (provider.asBinder().pingBinder()) { 9638 // Er, no, still looks good to us. 9639 synchronized (this) { 9640 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9641 + " says " + conn + " died, but we don't agree"); 9642 return; 9643 } 9644 } 9645 9646 // Well look at that! It's dead! 9647 synchronized (this) { 9648 if (conn.provider.provider != provider) { 9649 // But something changed... good enough. 9650 return; 9651 } 9652 9653 ProcessRecord proc = conn.provider.proc; 9654 if (proc == null || proc.thread == null) { 9655 // Seems like the process is already cleaned up. 9656 return; 9657 } 9658 9659 // As far as we're concerned, this is just like receiving a 9660 // death notification... just a bit prematurely. 9661 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9662 + ") early provider death"); 9663 final long ident = Binder.clearCallingIdentity(); 9664 try { 9665 appDiedLocked(proc); 9666 } finally { 9667 Binder.restoreCallingIdentity(ident); 9668 } 9669 } 9670 } 9671 9672 @Override 9673 public void appNotRespondingViaProvider(IBinder connection) { 9674 enforceCallingPermission( 9675 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9676 9677 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9678 if (conn == null) { 9679 Slog.w(TAG, "ContentProviderConnection is null"); 9680 return; 9681 } 9682 9683 final ProcessRecord host = conn.provider.proc; 9684 if (host == null) { 9685 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9686 return; 9687 } 9688 9689 final long token = Binder.clearCallingIdentity(); 9690 try { 9691 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9692 } finally { 9693 Binder.restoreCallingIdentity(token); 9694 } 9695 } 9696 9697 public final void installSystemProviders() { 9698 List<ProviderInfo> providers; 9699 synchronized (this) { 9700 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9701 providers = generateApplicationProvidersLocked(app); 9702 if (providers != null) { 9703 for (int i=providers.size()-1; i>=0; i--) { 9704 ProviderInfo pi = (ProviderInfo)providers.get(i); 9705 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9706 Slog.w(TAG, "Not installing system proc provider " + pi.name 9707 + ": not system .apk"); 9708 providers.remove(i); 9709 } 9710 } 9711 } 9712 } 9713 if (providers != null) { 9714 mSystemThread.installSystemProviders(providers); 9715 } 9716 9717 mCoreSettingsObserver = new CoreSettingsObserver(this); 9718 9719 //mUsageStatsService.monitorPackages(); 9720 } 9721 9722 /** 9723 * Allows apps to retrieve the MIME type of a URI. 9724 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9725 * users, then it does not need permission to access the ContentProvider. 9726 * Either, it needs cross-user uri grants. 9727 * 9728 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9729 * 9730 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9731 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9732 */ 9733 public String getProviderMimeType(Uri uri, int userId) { 9734 enforceNotIsolatedCaller("getProviderMimeType"); 9735 final String name = uri.getAuthority(); 9736 int callingUid = Binder.getCallingUid(); 9737 int callingPid = Binder.getCallingPid(); 9738 long ident = 0; 9739 boolean clearedIdentity = false; 9740 userId = unsafeConvertIncomingUser(userId); 9741 if (canClearIdentity(callingPid, callingUid, userId)) { 9742 clearedIdentity = true; 9743 ident = Binder.clearCallingIdentity(); 9744 } 9745 ContentProviderHolder holder = null; 9746 try { 9747 holder = getContentProviderExternalUnchecked(name, null, userId); 9748 if (holder != null) { 9749 return holder.provider.getType(uri); 9750 } 9751 } catch (RemoteException e) { 9752 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9753 return null; 9754 } finally { 9755 // We need to clear the identity to call removeContentProviderExternalUnchecked 9756 if (!clearedIdentity) { 9757 ident = Binder.clearCallingIdentity(); 9758 } 9759 try { 9760 if (holder != null) { 9761 removeContentProviderExternalUnchecked(name, null, userId); 9762 } 9763 } finally { 9764 Binder.restoreCallingIdentity(ident); 9765 } 9766 } 9767 9768 return null; 9769 } 9770 9771 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9772 if (UserHandle.getUserId(callingUid) == userId) { 9773 return true; 9774 } 9775 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9776 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9777 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9778 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9779 return true; 9780 } 9781 return false; 9782 } 9783 9784 // ========================================================= 9785 // GLOBAL MANAGEMENT 9786 // ========================================================= 9787 9788 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9789 boolean isolated, int isolatedUid) { 9790 String proc = customProcess != null ? customProcess : info.processName; 9791 BatteryStatsImpl.Uid.Proc ps = null; 9792 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9793 int uid = info.uid; 9794 if (isolated) { 9795 if (isolatedUid == 0) { 9796 int userId = UserHandle.getUserId(uid); 9797 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9798 while (true) { 9799 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9800 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9801 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9802 } 9803 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9804 mNextIsolatedProcessUid++; 9805 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9806 // No process for this uid, use it. 9807 break; 9808 } 9809 stepsLeft--; 9810 if (stepsLeft <= 0) { 9811 return null; 9812 } 9813 } 9814 } else { 9815 // Special case for startIsolatedProcess (internal only), where 9816 // the uid of the isolated process is specified by the caller. 9817 uid = isolatedUid; 9818 } 9819 } 9820 return new ProcessRecord(stats, info, proc, uid); 9821 } 9822 9823 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9824 String abiOverride) { 9825 ProcessRecord app; 9826 if (!isolated) { 9827 app = getProcessRecordLocked(info.processName, info.uid, true); 9828 } else { 9829 app = null; 9830 } 9831 9832 if (app == null) { 9833 app = newProcessRecordLocked(info, null, isolated, 0); 9834 mProcessNames.put(info.processName, app.uid, app); 9835 if (isolated) { 9836 mIsolatedProcesses.put(app.uid, app); 9837 } 9838 updateLruProcessLocked(app, false, null); 9839 updateOomAdjLocked(); 9840 } 9841 9842 // This package really, really can not be stopped. 9843 try { 9844 AppGlobals.getPackageManager().setPackageStoppedState( 9845 info.packageName, false, UserHandle.getUserId(app.uid)); 9846 } catch (RemoteException e) { 9847 } catch (IllegalArgumentException e) { 9848 Slog.w(TAG, "Failed trying to unstop package " 9849 + info.packageName + ": " + e); 9850 } 9851 9852 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9853 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9854 app.persistent = true; 9855 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9856 } 9857 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9858 mPersistentStartingProcesses.add(app); 9859 startProcessLocked(app, "added application", app.processName, abiOverride, 9860 null /* entryPoint */, null /* entryPointArgs */); 9861 } 9862 9863 return app; 9864 } 9865 9866 public void unhandledBack() { 9867 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9868 "unhandledBack()"); 9869 9870 synchronized(this) { 9871 final long origId = Binder.clearCallingIdentity(); 9872 try { 9873 getFocusedStack().unhandledBackLocked(); 9874 } finally { 9875 Binder.restoreCallingIdentity(origId); 9876 } 9877 } 9878 } 9879 9880 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9881 enforceNotIsolatedCaller("openContentUri"); 9882 final int userId = UserHandle.getCallingUserId(); 9883 String name = uri.getAuthority(); 9884 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9885 ParcelFileDescriptor pfd = null; 9886 if (cph != null) { 9887 // We record the binder invoker's uid in thread-local storage before 9888 // going to the content provider to open the file. Later, in the code 9889 // that handles all permissions checks, we look for this uid and use 9890 // that rather than the Activity Manager's own uid. The effect is that 9891 // we do the check against the caller's permissions even though it looks 9892 // to the content provider like the Activity Manager itself is making 9893 // the request. 9894 Binder token = new Binder(); 9895 sCallerIdentity.set(new Identity( 9896 token, Binder.getCallingPid(), Binder.getCallingUid())); 9897 try { 9898 pfd = cph.provider.openFile(null, uri, "r", null, token); 9899 } catch (FileNotFoundException e) { 9900 // do nothing; pfd will be returned null 9901 } finally { 9902 // Ensure that whatever happens, we clean up the identity state 9903 sCallerIdentity.remove(); 9904 } 9905 9906 // We've got the fd now, so we're done with the provider. 9907 removeContentProviderExternalUnchecked(name, null, userId); 9908 } else { 9909 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9910 } 9911 return pfd; 9912 } 9913 9914 // Actually is sleeping or shutting down or whatever else in the future 9915 // is an inactive state. 9916 public boolean isSleepingOrShuttingDown() { 9917 return isSleeping() || mShuttingDown; 9918 } 9919 9920 public boolean isSleeping() { 9921 return mSleeping; 9922 } 9923 9924 void goingToSleep() { 9925 synchronized(this) { 9926 mWentToSleep = true; 9927 goToSleepIfNeededLocked(); 9928 } 9929 } 9930 9931 void finishRunningVoiceLocked() { 9932 if (mRunningVoice) { 9933 mRunningVoice = false; 9934 goToSleepIfNeededLocked(); 9935 } 9936 } 9937 9938 void goToSleepIfNeededLocked() { 9939 if (mWentToSleep && !mRunningVoice) { 9940 if (!mSleeping) { 9941 mSleeping = true; 9942 mStackSupervisor.goingToSleepLocked(); 9943 9944 // Initialize the wake times of all processes. 9945 checkExcessivePowerUsageLocked(false); 9946 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9947 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9948 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9949 } 9950 } 9951 } 9952 9953 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9954 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9955 // Never persist the home stack. 9956 return; 9957 } 9958 mTaskPersister.wakeup(task, flush); 9959 } 9960 9961 @Override 9962 public boolean shutdown(int timeout) { 9963 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9964 != PackageManager.PERMISSION_GRANTED) { 9965 throw new SecurityException("Requires permission " 9966 + android.Manifest.permission.SHUTDOWN); 9967 } 9968 9969 boolean timedout = false; 9970 9971 synchronized(this) { 9972 mShuttingDown = true; 9973 updateEventDispatchingLocked(); 9974 timedout = mStackSupervisor.shutdownLocked(timeout); 9975 } 9976 9977 mAppOpsService.shutdown(); 9978 if (mUsageStatsService != null) { 9979 mUsageStatsService.prepareShutdown(); 9980 } 9981 mBatteryStatsService.shutdown(); 9982 synchronized (this) { 9983 mProcessStats.shutdownLocked(); 9984 } 9985 notifyTaskPersisterLocked(null, true); 9986 9987 return timedout; 9988 } 9989 9990 public final void activitySlept(IBinder token) { 9991 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9992 9993 final long origId = Binder.clearCallingIdentity(); 9994 9995 synchronized (this) { 9996 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9997 if (r != null) { 9998 mStackSupervisor.activitySleptLocked(r); 9999 } 10000 } 10001 10002 Binder.restoreCallingIdentity(origId); 10003 } 10004 10005 private String lockScreenShownToString() { 10006 switch (mLockScreenShown) { 10007 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10008 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10009 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10010 default: return "Unknown=" + mLockScreenShown; 10011 } 10012 } 10013 10014 void logLockScreen(String msg) { 10015 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10016 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10017 mWentToSleep + " mSleeping=" + mSleeping); 10018 } 10019 10020 void comeOutOfSleepIfNeededLocked() { 10021 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10022 if (mSleeping) { 10023 mSleeping = false; 10024 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10025 } 10026 } 10027 } 10028 10029 void wakingUp() { 10030 synchronized(this) { 10031 mWentToSleep = false; 10032 comeOutOfSleepIfNeededLocked(); 10033 } 10034 } 10035 10036 void startRunningVoiceLocked() { 10037 if (!mRunningVoice) { 10038 mRunningVoice = true; 10039 comeOutOfSleepIfNeededLocked(); 10040 } 10041 } 10042 10043 private void updateEventDispatchingLocked() { 10044 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10045 } 10046 10047 public void setLockScreenShown(boolean shown) { 10048 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10049 != PackageManager.PERMISSION_GRANTED) { 10050 throw new SecurityException("Requires permission " 10051 + android.Manifest.permission.DEVICE_POWER); 10052 } 10053 10054 synchronized(this) { 10055 long ident = Binder.clearCallingIdentity(); 10056 try { 10057 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10058 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10059 comeOutOfSleepIfNeededLocked(); 10060 } finally { 10061 Binder.restoreCallingIdentity(ident); 10062 } 10063 } 10064 } 10065 10066 @Override 10067 public void stopAppSwitches() { 10068 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10069 != PackageManager.PERMISSION_GRANTED) { 10070 throw new SecurityException("Requires permission " 10071 + android.Manifest.permission.STOP_APP_SWITCHES); 10072 } 10073 10074 synchronized(this) { 10075 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10076 + APP_SWITCH_DELAY_TIME; 10077 mDidAppSwitch = false; 10078 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10079 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10080 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10081 } 10082 } 10083 10084 public void resumeAppSwitches() { 10085 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10086 != PackageManager.PERMISSION_GRANTED) { 10087 throw new SecurityException("Requires permission " 10088 + android.Manifest.permission.STOP_APP_SWITCHES); 10089 } 10090 10091 synchronized(this) { 10092 // Note that we don't execute any pending app switches... we will 10093 // let those wait until either the timeout, or the next start 10094 // activity request. 10095 mAppSwitchesAllowedTime = 0; 10096 } 10097 } 10098 10099 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10100 int callingPid, int callingUid, String name) { 10101 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10102 return true; 10103 } 10104 10105 int perm = checkComponentPermission( 10106 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10107 sourceUid, -1, true); 10108 if (perm == PackageManager.PERMISSION_GRANTED) { 10109 return true; 10110 } 10111 10112 // If the actual IPC caller is different from the logical source, then 10113 // also see if they are allowed to control app switches. 10114 if (callingUid != -1 && callingUid != sourceUid) { 10115 perm = checkComponentPermission( 10116 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10117 callingUid, -1, true); 10118 if (perm == PackageManager.PERMISSION_GRANTED) { 10119 return true; 10120 } 10121 } 10122 10123 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10124 return false; 10125 } 10126 10127 public void setDebugApp(String packageName, boolean waitForDebugger, 10128 boolean persistent) { 10129 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10130 "setDebugApp()"); 10131 10132 long ident = Binder.clearCallingIdentity(); 10133 try { 10134 // Note that this is not really thread safe if there are multiple 10135 // callers into it at the same time, but that's not a situation we 10136 // care about. 10137 if (persistent) { 10138 final ContentResolver resolver = mContext.getContentResolver(); 10139 Settings.Global.putString( 10140 resolver, Settings.Global.DEBUG_APP, 10141 packageName); 10142 Settings.Global.putInt( 10143 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10144 waitForDebugger ? 1 : 0); 10145 } 10146 10147 synchronized (this) { 10148 if (!persistent) { 10149 mOrigDebugApp = mDebugApp; 10150 mOrigWaitForDebugger = mWaitForDebugger; 10151 } 10152 mDebugApp = packageName; 10153 mWaitForDebugger = waitForDebugger; 10154 mDebugTransient = !persistent; 10155 if (packageName != null) { 10156 forceStopPackageLocked(packageName, -1, false, false, true, true, 10157 false, UserHandle.USER_ALL, "set debug app"); 10158 } 10159 } 10160 } finally { 10161 Binder.restoreCallingIdentity(ident); 10162 } 10163 } 10164 10165 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10166 synchronized (this) { 10167 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10168 if (!isDebuggable) { 10169 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10170 throw new SecurityException("Process not debuggable: " + app.packageName); 10171 } 10172 } 10173 10174 mOpenGlTraceApp = processName; 10175 } 10176 } 10177 10178 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10179 synchronized (this) { 10180 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10181 if (!isDebuggable) { 10182 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10183 throw new SecurityException("Process not debuggable: " + app.packageName); 10184 } 10185 } 10186 mProfileApp = processName; 10187 mProfileFile = profilerInfo.profileFile; 10188 if (mProfileFd != null) { 10189 try { 10190 mProfileFd.close(); 10191 } catch (IOException e) { 10192 } 10193 mProfileFd = null; 10194 } 10195 mProfileFd = profilerInfo.profileFd; 10196 mSamplingInterval = profilerInfo.samplingInterval; 10197 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10198 mProfileType = 0; 10199 } 10200 } 10201 10202 @Override 10203 public void setAlwaysFinish(boolean enabled) { 10204 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10205 "setAlwaysFinish()"); 10206 10207 Settings.Global.putInt( 10208 mContext.getContentResolver(), 10209 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10210 10211 synchronized (this) { 10212 mAlwaysFinishActivities = enabled; 10213 } 10214 } 10215 10216 @Override 10217 public void setActivityController(IActivityController controller) { 10218 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10219 "setActivityController()"); 10220 synchronized (this) { 10221 mController = controller; 10222 Watchdog.getInstance().setActivityController(controller); 10223 } 10224 } 10225 10226 @Override 10227 public void setUserIsMonkey(boolean userIsMonkey) { 10228 synchronized (this) { 10229 synchronized (mPidsSelfLocked) { 10230 final int callingPid = Binder.getCallingPid(); 10231 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10232 if (precessRecord == null) { 10233 throw new SecurityException("Unknown process: " + callingPid); 10234 } 10235 if (precessRecord.instrumentationUiAutomationConnection == null) { 10236 throw new SecurityException("Only an instrumentation process " 10237 + "with a UiAutomation can call setUserIsMonkey"); 10238 } 10239 } 10240 mUserIsMonkey = userIsMonkey; 10241 } 10242 } 10243 10244 @Override 10245 public boolean isUserAMonkey() { 10246 synchronized (this) { 10247 // If there is a controller also implies the user is a monkey. 10248 return (mUserIsMonkey || mController != null); 10249 } 10250 } 10251 10252 public void requestBugReport() { 10253 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10254 SystemProperties.set("ctl.start", "bugreport"); 10255 } 10256 10257 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10258 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10259 } 10260 10261 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10262 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10263 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10264 } 10265 return KEY_DISPATCHING_TIMEOUT; 10266 } 10267 10268 @Override 10269 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10270 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10271 != PackageManager.PERMISSION_GRANTED) { 10272 throw new SecurityException("Requires permission " 10273 + android.Manifest.permission.FILTER_EVENTS); 10274 } 10275 ProcessRecord proc; 10276 long timeout; 10277 synchronized (this) { 10278 synchronized (mPidsSelfLocked) { 10279 proc = mPidsSelfLocked.get(pid); 10280 } 10281 timeout = getInputDispatchingTimeoutLocked(proc); 10282 } 10283 10284 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10285 return -1; 10286 } 10287 10288 return timeout; 10289 } 10290 10291 /** 10292 * Handle input dispatching timeouts. 10293 * Returns whether input dispatching should be aborted or not. 10294 */ 10295 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10296 final ActivityRecord activity, final ActivityRecord parent, 10297 final boolean aboveSystem, String reason) { 10298 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10299 != PackageManager.PERMISSION_GRANTED) { 10300 throw new SecurityException("Requires permission " 10301 + android.Manifest.permission.FILTER_EVENTS); 10302 } 10303 10304 final String annotation; 10305 if (reason == null) { 10306 annotation = "Input dispatching timed out"; 10307 } else { 10308 annotation = "Input dispatching timed out (" + reason + ")"; 10309 } 10310 10311 if (proc != null) { 10312 synchronized (this) { 10313 if (proc.debugging) { 10314 return false; 10315 } 10316 10317 if (mDidDexOpt) { 10318 // Give more time since we were dexopting. 10319 mDidDexOpt = false; 10320 return false; 10321 } 10322 10323 if (proc.instrumentationClass != null) { 10324 Bundle info = new Bundle(); 10325 info.putString("shortMsg", "keyDispatchingTimedOut"); 10326 info.putString("longMsg", annotation); 10327 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10328 return true; 10329 } 10330 } 10331 mHandler.post(new Runnable() { 10332 @Override 10333 public void run() { 10334 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10335 } 10336 }); 10337 } 10338 10339 return true; 10340 } 10341 10342 public Bundle getAssistContextExtras(int requestType) { 10343 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10344 UserHandle.getCallingUserId()); 10345 if (pae == null) { 10346 return null; 10347 } 10348 synchronized (pae) { 10349 while (!pae.haveResult) { 10350 try { 10351 pae.wait(); 10352 } catch (InterruptedException e) { 10353 } 10354 } 10355 if (pae.result != null) { 10356 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10357 } 10358 } 10359 synchronized (this) { 10360 mPendingAssistExtras.remove(pae); 10361 mHandler.removeCallbacks(pae); 10362 } 10363 return pae.extras; 10364 } 10365 10366 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10367 int userHandle) { 10368 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10369 "getAssistContextExtras()"); 10370 PendingAssistExtras pae; 10371 Bundle extras = new Bundle(); 10372 synchronized (this) { 10373 ActivityRecord activity = getFocusedStack().mResumedActivity; 10374 if (activity == null) { 10375 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10376 return null; 10377 } 10378 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10379 if (activity.app == null || activity.app.thread == null) { 10380 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10381 return null; 10382 } 10383 if (activity.app.pid == Binder.getCallingPid()) { 10384 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10385 return null; 10386 } 10387 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10388 try { 10389 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10390 requestType); 10391 mPendingAssistExtras.add(pae); 10392 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10393 } catch (RemoteException e) { 10394 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10395 return null; 10396 } 10397 return pae; 10398 } 10399 } 10400 10401 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10402 PendingAssistExtras pae = (PendingAssistExtras)token; 10403 synchronized (pae) { 10404 pae.result = extras; 10405 pae.haveResult = true; 10406 pae.notifyAll(); 10407 if (pae.intent == null) { 10408 // Caller is just waiting for the result. 10409 return; 10410 } 10411 } 10412 10413 // We are now ready to launch the assist activity. 10414 synchronized (this) { 10415 boolean exists = mPendingAssistExtras.remove(pae); 10416 mHandler.removeCallbacks(pae); 10417 if (!exists) { 10418 // Timed out. 10419 return; 10420 } 10421 } 10422 pae.intent.replaceExtras(extras); 10423 if (pae.hint != null) { 10424 pae.intent.putExtra(pae.hint, true); 10425 } 10426 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10427 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10428 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10429 closeSystemDialogs("assist"); 10430 try { 10431 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10432 } catch (ActivityNotFoundException e) { 10433 Slog.w(TAG, "No activity to handle assist action.", e); 10434 } 10435 } 10436 10437 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10438 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10439 } 10440 10441 public void registerProcessObserver(IProcessObserver observer) { 10442 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10443 "registerProcessObserver()"); 10444 synchronized (this) { 10445 mProcessObservers.register(observer); 10446 } 10447 } 10448 10449 @Override 10450 public void unregisterProcessObserver(IProcessObserver observer) { 10451 synchronized (this) { 10452 mProcessObservers.unregister(observer); 10453 } 10454 } 10455 10456 @Override 10457 public boolean convertFromTranslucent(IBinder token) { 10458 final long origId = Binder.clearCallingIdentity(); 10459 try { 10460 synchronized (this) { 10461 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10462 if (r == null) { 10463 return false; 10464 } 10465 final boolean translucentChanged = r.changeWindowTranslucency(true); 10466 if (translucentChanged) { 10467 r.task.stack.releaseBackgroundResources(); 10468 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10469 } 10470 mWindowManager.setAppFullscreen(token, true); 10471 return translucentChanged; 10472 } 10473 } finally { 10474 Binder.restoreCallingIdentity(origId); 10475 } 10476 } 10477 10478 @Override 10479 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10480 final long origId = Binder.clearCallingIdentity(); 10481 try { 10482 synchronized (this) { 10483 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10484 if (r == null) { 10485 return false; 10486 } 10487 int index = r.task.mActivities.lastIndexOf(r); 10488 if (index > 0) { 10489 ActivityRecord under = r.task.mActivities.get(index - 1); 10490 under.returningOptions = options; 10491 } 10492 final boolean translucentChanged = r.changeWindowTranslucency(false); 10493 if (translucentChanged) { 10494 r.task.stack.convertToTranslucent(r); 10495 } 10496 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10497 mWindowManager.setAppFullscreen(token, false); 10498 return translucentChanged; 10499 } 10500 } finally { 10501 Binder.restoreCallingIdentity(origId); 10502 } 10503 } 10504 10505 @Override 10506 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10507 final long origId = Binder.clearCallingIdentity(); 10508 try { 10509 synchronized (this) { 10510 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10511 if (r != null) { 10512 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10513 } 10514 } 10515 return false; 10516 } finally { 10517 Binder.restoreCallingIdentity(origId); 10518 } 10519 } 10520 10521 @Override 10522 public boolean isBackgroundVisibleBehind(IBinder token) { 10523 final long origId = Binder.clearCallingIdentity(); 10524 try { 10525 synchronized (this) { 10526 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10527 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10528 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10529 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10530 return visible; 10531 } 10532 } finally { 10533 Binder.restoreCallingIdentity(origId); 10534 } 10535 } 10536 10537 @Override 10538 public ActivityOptions getActivityOptions(IBinder token) { 10539 final long origId = Binder.clearCallingIdentity(); 10540 try { 10541 synchronized (this) { 10542 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10543 if (r != null) { 10544 final ActivityOptions activityOptions = r.pendingOptions; 10545 r.pendingOptions = null; 10546 return activityOptions; 10547 } 10548 return null; 10549 } 10550 } finally { 10551 Binder.restoreCallingIdentity(origId); 10552 } 10553 } 10554 10555 @Override 10556 public void setImmersive(IBinder token, boolean immersive) { 10557 synchronized(this) { 10558 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10559 if (r == null) { 10560 throw new IllegalArgumentException(); 10561 } 10562 r.immersive = immersive; 10563 10564 // update associated state if we're frontmost 10565 if (r == mFocusedActivity) { 10566 if (DEBUG_IMMERSIVE) { 10567 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10568 } 10569 applyUpdateLockStateLocked(r); 10570 } 10571 } 10572 } 10573 10574 @Override 10575 public boolean isImmersive(IBinder token) { 10576 synchronized (this) { 10577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10578 if (r == null) { 10579 throw new IllegalArgumentException(); 10580 } 10581 return r.immersive; 10582 } 10583 } 10584 10585 public boolean isTopActivityImmersive() { 10586 enforceNotIsolatedCaller("startActivity"); 10587 synchronized (this) { 10588 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10589 return (r != null) ? r.immersive : false; 10590 } 10591 } 10592 10593 @Override 10594 public boolean isTopOfTask(IBinder token) { 10595 synchronized (this) { 10596 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10597 if (r == null) { 10598 throw new IllegalArgumentException(); 10599 } 10600 return r.task.getTopActivity() == r; 10601 } 10602 } 10603 10604 public final void enterSafeMode() { 10605 synchronized(this) { 10606 // It only makes sense to do this before the system is ready 10607 // and started launching other packages. 10608 if (!mSystemReady) { 10609 try { 10610 AppGlobals.getPackageManager().enterSafeMode(); 10611 } catch (RemoteException e) { 10612 } 10613 } 10614 10615 mSafeMode = true; 10616 } 10617 } 10618 10619 public final void showSafeModeOverlay() { 10620 View v = LayoutInflater.from(mContext).inflate( 10621 com.android.internal.R.layout.safe_mode, null); 10622 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10623 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10624 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10625 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10626 lp.gravity = Gravity.BOTTOM | Gravity.START; 10627 lp.format = v.getBackground().getOpacity(); 10628 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10629 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10630 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10631 ((WindowManager)mContext.getSystemService( 10632 Context.WINDOW_SERVICE)).addView(v, lp); 10633 } 10634 10635 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10636 if (!(sender instanceof PendingIntentRecord)) { 10637 return; 10638 } 10639 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10640 synchronized (stats) { 10641 if (mBatteryStatsService.isOnBattery()) { 10642 mBatteryStatsService.enforceCallingPermission(); 10643 PendingIntentRecord rec = (PendingIntentRecord)sender; 10644 int MY_UID = Binder.getCallingUid(); 10645 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10646 BatteryStatsImpl.Uid.Pkg pkg = 10647 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10648 sourcePkg != null ? sourcePkg : rec.key.packageName); 10649 pkg.incWakeupsLocked(); 10650 } 10651 } 10652 } 10653 10654 public boolean killPids(int[] pids, String pReason, boolean secure) { 10655 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10656 throw new SecurityException("killPids only available to the system"); 10657 } 10658 String reason = (pReason == null) ? "Unknown" : pReason; 10659 // XXX Note: don't acquire main activity lock here, because the window 10660 // manager calls in with its locks held. 10661 10662 boolean killed = false; 10663 synchronized (mPidsSelfLocked) { 10664 int[] types = new int[pids.length]; 10665 int worstType = 0; 10666 for (int i=0; i<pids.length; i++) { 10667 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10668 if (proc != null) { 10669 int type = proc.setAdj; 10670 types[i] = type; 10671 if (type > worstType) { 10672 worstType = type; 10673 } 10674 } 10675 } 10676 10677 // If the worst oom_adj is somewhere in the cached proc LRU range, 10678 // then constrain it so we will kill all cached procs. 10679 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10680 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10681 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10682 } 10683 10684 // If this is not a secure call, don't let it kill processes that 10685 // are important. 10686 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10687 worstType = ProcessList.SERVICE_ADJ; 10688 } 10689 10690 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10691 for (int i=0; i<pids.length; i++) { 10692 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10693 if (proc == null) { 10694 continue; 10695 } 10696 int adj = proc.setAdj; 10697 if (adj >= worstType && !proc.killedByAm) { 10698 proc.kill(reason, true); 10699 killed = true; 10700 } 10701 } 10702 } 10703 return killed; 10704 } 10705 10706 @Override 10707 public void killUid(int uid, String reason) { 10708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10709 throw new SecurityException("killUid only available to the system"); 10710 } 10711 synchronized (this) { 10712 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10713 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10714 reason != null ? reason : "kill uid"); 10715 } 10716 } 10717 10718 @Override 10719 public boolean killProcessesBelowForeground(String reason) { 10720 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10721 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10722 } 10723 10724 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10725 } 10726 10727 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10728 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10729 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10730 } 10731 10732 boolean killed = false; 10733 synchronized (mPidsSelfLocked) { 10734 final int size = mPidsSelfLocked.size(); 10735 for (int i = 0; i < size; i++) { 10736 final int pid = mPidsSelfLocked.keyAt(i); 10737 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10738 if (proc == null) continue; 10739 10740 final int adj = proc.setAdj; 10741 if (adj > belowAdj && !proc.killedByAm) { 10742 proc.kill(reason, true); 10743 killed = true; 10744 } 10745 } 10746 } 10747 return killed; 10748 } 10749 10750 @Override 10751 public void hang(final IBinder who, boolean allowRestart) { 10752 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10753 != PackageManager.PERMISSION_GRANTED) { 10754 throw new SecurityException("Requires permission " 10755 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10756 } 10757 10758 final IBinder.DeathRecipient death = new DeathRecipient() { 10759 @Override 10760 public void binderDied() { 10761 synchronized (this) { 10762 notifyAll(); 10763 } 10764 } 10765 }; 10766 10767 try { 10768 who.linkToDeath(death, 0); 10769 } catch (RemoteException e) { 10770 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10771 return; 10772 } 10773 10774 synchronized (this) { 10775 Watchdog.getInstance().setAllowRestart(allowRestart); 10776 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10777 synchronized (death) { 10778 while (who.isBinderAlive()) { 10779 try { 10780 death.wait(); 10781 } catch (InterruptedException e) { 10782 } 10783 } 10784 } 10785 Watchdog.getInstance().setAllowRestart(true); 10786 } 10787 } 10788 10789 @Override 10790 public void restart() { 10791 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10792 != PackageManager.PERMISSION_GRANTED) { 10793 throw new SecurityException("Requires permission " 10794 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10795 } 10796 10797 Log.i(TAG, "Sending shutdown broadcast..."); 10798 10799 BroadcastReceiver br = new BroadcastReceiver() { 10800 @Override public void onReceive(Context context, Intent intent) { 10801 // Now the broadcast is done, finish up the low-level shutdown. 10802 Log.i(TAG, "Shutting down activity manager..."); 10803 shutdown(10000); 10804 Log.i(TAG, "Shutdown complete, restarting!"); 10805 Process.killProcess(Process.myPid()); 10806 System.exit(10); 10807 } 10808 }; 10809 10810 // First send the high-level shut down broadcast. 10811 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10812 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10813 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10814 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10815 mContext.sendOrderedBroadcastAsUser(intent, 10816 UserHandle.ALL, null, br, mHandler, 0, null, null); 10817 */ 10818 br.onReceive(mContext, intent); 10819 } 10820 10821 private long getLowRamTimeSinceIdle(long now) { 10822 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10823 } 10824 10825 @Override 10826 public void performIdleMaintenance() { 10827 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10828 != PackageManager.PERMISSION_GRANTED) { 10829 throw new SecurityException("Requires permission " 10830 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10831 } 10832 10833 synchronized (this) { 10834 final long now = SystemClock.uptimeMillis(); 10835 final long timeSinceLastIdle = now - mLastIdleTime; 10836 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10837 mLastIdleTime = now; 10838 mLowRamTimeSinceLastIdle = 0; 10839 if (mLowRamStartTime != 0) { 10840 mLowRamStartTime = now; 10841 } 10842 10843 StringBuilder sb = new StringBuilder(128); 10844 sb.append("Idle maintenance over "); 10845 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10846 sb.append(" low RAM for "); 10847 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10848 Slog.i(TAG, sb.toString()); 10849 10850 // If at least 1/3 of our time since the last idle period has been spent 10851 // with RAM low, then we want to kill processes. 10852 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10853 10854 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10855 ProcessRecord proc = mLruProcesses.get(i); 10856 if (proc.notCachedSinceIdle) { 10857 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10858 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10859 if (doKilling && proc.initialIdlePss != 0 10860 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10861 proc.kill("idle maint (pss " + proc.lastPss 10862 + " from " + proc.initialIdlePss + ")", true); 10863 } 10864 } 10865 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10866 proc.notCachedSinceIdle = true; 10867 proc.initialIdlePss = 0; 10868 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10869 isSleeping(), now); 10870 } 10871 } 10872 10873 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10874 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10875 } 10876 } 10877 10878 private void retrieveSettings() { 10879 final ContentResolver resolver = mContext.getContentResolver(); 10880 String debugApp = Settings.Global.getString( 10881 resolver, Settings.Global.DEBUG_APP); 10882 boolean waitForDebugger = Settings.Global.getInt( 10883 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10884 boolean alwaysFinishActivities = Settings.Global.getInt( 10885 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10886 boolean forceRtl = Settings.Global.getInt( 10887 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10888 // Transfer any global setting for forcing RTL layout, into a System Property 10889 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10890 10891 Configuration configuration = new Configuration(); 10892 Settings.System.getConfiguration(resolver, configuration); 10893 if (forceRtl) { 10894 // This will take care of setting the correct layout direction flags 10895 configuration.setLayoutDirection(configuration.locale); 10896 } 10897 10898 synchronized (this) { 10899 mDebugApp = mOrigDebugApp = debugApp; 10900 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10901 mAlwaysFinishActivities = alwaysFinishActivities; 10902 // This happens before any activities are started, so we can 10903 // change mConfiguration in-place. 10904 updateConfigurationLocked(configuration, null, false, true); 10905 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10906 } 10907 } 10908 10909 /** Loads resources after the current configuration has been set. */ 10910 private void loadResourcesOnSystemReady() { 10911 final Resources res = mContext.getResources(); 10912 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10913 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10914 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10915 } 10916 10917 public boolean testIsSystemReady() { 10918 // no need to synchronize(this) just to read & return the value 10919 return mSystemReady; 10920 } 10921 10922 private static File getCalledPreBootReceiversFile() { 10923 File dataDir = Environment.getDataDirectory(); 10924 File systemDir = new File(dataDir, "system"); 10925 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10926 return fname; 10927 } 10928 10929 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10930 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10931 File file = getCalledPreBootReceiversFile(); 10932 FileInputStream fis = null; 10933 try { 10934 fis = new FileInputStream(file); 10935 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10936 int fvers = dis.readInt(); 10937 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10938 String vers = dis.readUTF(); 10939 String codename = dis.readUTF(); 10940 String build = dis.readUTF(); 10941 if (android.os.Build.VERSION.RELEASE.equals(vers) 10942 && android.os.Build.VERSION.CODENAME.equals(codename) 10943 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10944 int num = dis.readInt(); 10945 while (num > 0) { 10946 num--; 10947 String pkg = dis.readUTF(); 10948 String cls = dis.readUTF(); 10949 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10950 } 10951 } 10952 } 10953 } catch (FileNotFoundException e) { 10954 } catch (IOException e) { 10955 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10956 } finally { 10957 if (fis != null) { 10958 try { 10959 fis.close(); 10960 } catch (IOException e) { 10961 } 10962 } 10963 } 10964 return lastDoneReceivers; 10965 } 10966 10967 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10968 File file = getCalledPreBootReceiversFile(); 10969 FileOutputStream fos = null; 10970 DataOutputStream dos = null; 10971 try { 10972 fos = new FileOutputStream(file); 10973 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10974 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10975 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10976 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10977 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10978 dos.writeInt(list.size()); 10979 for (int i=0; i<list.size(); i++) { 10980 dos.writeUTF(list.get(i).getPackageName()); 10981 dos.writeUTF(list.get(i).getClassName()); 10982 } 10983 } catch (IOException e) { 10984 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10985 file.delete(); 10986 } finally { 10987 FileUtils.sync(fos); 10988 if (dos != null) { 10989 try { 10990 dos.close(); 10991 } catch (IOException e) { 10992 // TODO Auto-generated catch block 10993 e.printStackTrace(); 10994 } 10995 } 10996 } 10997 } 10998 10999 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11000 ArrayList<ComponentName> doneReceivers, int userId) { 11001 boolean waitingUpdate = false; 11002 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11003 List<ResolveInfo> ris = null; 11004 try { 11005 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11006 intent, null, 0, userId); 11007 } catch (RemoteException e) { 11008 } 11009 if (ris != null) { 11010 for (int i=ris.size()-1; i>=0; i--) { 11011 if ((ris.get(i).activityInfo.applicationInfo.flags 11012 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11013 ris.remove(i); 11014 } 11015 } 11016 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11017 11018 // For User 0, load the version number. When delivering to a new user, deliver 11019 // to all receivers. 11020 if (userId == UserHandle.USER_OWNER) { 11021 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11022 for (int i=0; i<ris.size(); i++) { 11023 ActivityInfo ai = ris.get(i).activityInfo; 11024 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11025 if (lastDoneReceivers.contains(comp)) { 11026 // We already did the pre boot receiver for this app with the current 11027 // platform version, so don't do it again... 11028 ris.remove(i); 11029 i--; 11030 // ...however, do keep it as one that has been done, so we don't 11031 // forget about it when rewriting the file of last done receivers. 11032 doneReceivers.add(comp); 11033 } 11034 } 11035 } 11036 11037 // If primary user, send broadcast to all available users, else just to userId 11038 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11039 : new int[] { userId }; 11040 for (int i = 0; i < ris.size(); i++) { 11041 ActivityInfo ai = ris.get(i).activityInfo; 11042 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11043 doneReceivers.add(comp); 11044 intent.setComponent(comp); 11045 for (int j=0; j<users.length; j++) { 11046 IIntentReceiver finisher = null; 11047 // On last receiver and user, set up a completion callback 11048 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11049 finisher = new IIntentReceiver.Stub() { 11050 public void performReceive(Intent intent, int resultCode, 11051 String data, Bundle extras, boolean ordered, 11052 boolean sticky, int sendingUser) { 11053 // The raw IIntentReceiver interface is called 11054 // with the AM lock held, so redispatch to 11055 // execute our code without the lock. 11056 mHandler.post(onFinishCallback); 11057 } 11058 }; 11059 } 11060 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11061 + " for user " + users[j]); 11062 broadcastIntentLocked(null, null, intent, null, finisher, 11063 0, null, null, null, AppOpsManager.OP_NONE, 11064 true, false, MY_PID, Process.SYSTEM_UID, 11065 users[j]); 11066 if (finisher != null) { 11067 waitingUpdate = true; 11068 } 11069 } 11070 } 11071 } 11072 11073 return waitingUpdate; 11074 } 11075 11076 public void systemReady(final Runnable goingCallback) { 11077 synchronized(this) { 11078 if (mSystemReady) { 11079 // If we're done calling all the receivers, run the next "boot phase" passed in 11080 // by the SystemServer 11081 if (goingCallback != null) { 11082 goingCallback.run(); 11083 } 11084 return; 11085 } 11086 11087 // Make sure we have the current profile info, since it is needed for 11088 // security checks. 11089 updateCurrentProfileIdsLocked(); 11090 11091 if (mRecentTasks == null) { 11092 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11093 if (!mRecentTasks.isEmpty()) { 11094 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11095 } 11096 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11097 mTaskPersister.startPersisting(); 11098 } 11099 11100 // Check to see if there are any update receivers to run. 11101 if (!mDidUpdate) { 11102 if (mWaitingUpdate) { 11103 return; 11104 } 11105 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11106 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11107 public void run() { 11108 synchronized (ActivityManagerService.this) { 11109 mDidUpdate = true; 11110 } 11111 writeLastDonePreBootReceivers(doneReceivers); 11112 showBootMessage(mContext.getText( 11113 R.string.android_upgrading_complete), 11114 false); 11115 systemReady(goingCallback); 11116 } 11117 }, doneReceivers, UserHandle.USER_OWNER); 11118 11119 if (mWaitingUpdate) { 11120 return; 11121 } 11122 mDidUpdate = true; 11123 } 11124 11125 mAppOpsService.systemReady(); 11126 mSystemReady = true; 11127 } 11128 11129 ArrayList<ProcessRecord> procsToKill = null; 11130 synchronized(mPidsSelfLocked) { 11131 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11132 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11133 if (!isAllowedWhileBooting(proc.info)){ 11134 if (procsToKill == null) { 11135 procsToKill = new ArrayList<ProcessRecord>(); 11136 } 11137 procsToKill.add(proc); 11138 } 11139 } 11140 } 11141 11142 synchronized(this) { 11143 if (procsToKill != null) { 11144 for (int i=procsToKill.size()-1; i>=0; i--) { 11145 ProcessRecord proc = procsToKill.get(i); 11146 Slog.i(TAG, "Removing system update proc: " + proc); 11147 removeProcessLocked(proc, true, false, "system update done"); 11148 } 11149 } 11150 11151 // Now that we have cleaned up any update processes, we 11152 // are ready to start launching real processes and know that 11153 // we won't trample on them any more. 11154 mProcessesReady = true; 11155 } 11156 11157 Slog.i(TAG, "System now ready"); 11158 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11159 SystemClock.uptimeMillis()); 11160 11161 synchronized(this) { 11162 // Make sure we have no pre-ready processes sitting around. 11163 11164 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11165 ResolveInfo ri = mContext.getPackageManager() 11166 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11167 STOCK_PM_FLAGS); 11168 CharSequence errorMsg = null; 11169 if (ri != null) { 11170 ActivityInfo ai = ri.activityInfo; 11171 ApplicationInfo app = ai.applicationInfo; 11172 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11173 mTopAction = Intent.ACTION_FACTORY_TEST; 11174 mTopData = null; 11175 mTopComponent = new ComponentName(app.packageName, 11176 ai.name); 11177 } else { 11178 errorMsg = mContext.getResources().getText( 11179 com.android.internal.R.string.factorytest_not_system); 11180 } 11181 } else { 11182 errorMsg = mContext.getResources().getText( 11183 com.android.internal.R.string.factorytest_no_action); 11184 } 11185 if (errorMsg != null) { 11186 mTopAction = null; 11187 mTopData = null; 11188 mTopComponent = null; 11189 Message msg = Message.obtain(); 11190 msg.what = SHOW_FACTORY_ERROR_MSG; 11191 msg.getData().putCharSequence("msg", errorMsg); 11192 mHandler.sendMessage(msg); 11193 } 11194 } 11195 } 11196 11197 retrieveSettings(); 11198 loadResourcesOnSystemReady(); 11199 11200 synchronized (this) { 11201 readGrantedUriPermissionsLocked(); 11202 } 11203 11204 if (goingCallback != null) goingCallback.run(); 11205 11206 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11207 Integer.toString(mCurrentUserId), mCurrentUserId); 11208 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11209 Integer.toString(mCurrentUserId), mCurrentUserId); 11210 mSystemServiceManager.startUser(mCurrentUserId); 11211 11212 synchronized (this) { 11213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11214 try { 11215 List apps = AppGlobals.getPackageManager(). 11216 getPersistentApplications(STOCK_PM_FLAGS); 11217 if (apps != null) { 11218 int N = apps.size(); 11219 int i; 11220 for (i=0; i<N; i++) { 11221 ApplicationInfo info 11222 = (ApplicationInfo)apps.get(i); 11223 if (info != null && 11224 !info.packageName.equals("android")) { 11225 addAppLocked(info, false, null /* ABI override */); 11226 } 11227 } 11228 } 11229 } catch (RemoteException ex) { 11230 // pm is in same process, this will never happen. 11231 } 11232 } 11233 11234 // Start up initial activity. 11235 mBooting = true; 11236 startHomeActivityLocked(mCurrentUserId); 11237 11238 try { 11239 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11240 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11241 + " data partition or your device will be unstable."); 11242 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11243 } 11244 } catch (RemoteException e) { 11245 } 11246 11247 if (!Build.isFingerprintConsistent()) { 11248 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11249 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11250 } 11251 11252 long ident = Binder.clearCallingIdentity(); 11253 try { 11254 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11255 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11256 | Intent.FLAG_RECEIVER_FOREGROUND); 11257 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11258 broadcastIntentLocked(null, null, intent, 11259 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11260 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11261 intent = new Intent(Intent.ACTION_USER_STARTING); 11262 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11263 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11264 broadcastIntentLocked(null, null, intent, 11265 null, new IIntentReceiver.Stub() { 11266 @Override 11267 public void performReceive(Intent intent, int resultCode, String data, 11268 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11269 throws RemoteException { 11270 } 11271 }, 0, null, null, 11272 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11273 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11274 } catch (Throwable t) { 11275 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11276 } finally { 11277 Binder.restoreCallingIdentity(ident); 11278 } 11279 mStackSupervisor.resumeTopActivitiesLocked(); 11280 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11281 } 11282 } 11283 11284 private boolean makeAppCrashingLocked(ProcessRecord app, 11285 String shortMsg, String longMsg, String stackTrace) { 11286 app.crashing = true; 11287 app.crashingReport = generateProcessError(app, 11288 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11289 startAppProblemLocked(app); 11290 app.stopFreezingAllLocked(); 11291 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11292 } 11293 11294 private void makeAppNotRespondingLocked(ProcessRecord app, 11295 String activity, String shortMsg, String longMsg) { 11296 app.notResponding = true; 11297 app.notRespondingReport = generateProcessError(app, 11298 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11299 activity, shortMsg, longMsg, null); 11300 startAppProblemLocked(app); 11301 app.stopFreezingAllLocked(); 11302 } 11303 11304 /** 11305 * Generate a process error record, suitable for attachment to a ProcessRecord. 11306 * 11307 * @param app The ProcessRecord in which the error occurred. 11308 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11309 * ActivityManager.AppErrorStateInfo 11310 * @param activity The activity associated with the crash, if known. 11311 * @param shortMsg Short message describing the crash. 11312 * @param longMsg Long message describing the crash. 11313 * @param stackTrace Full crash stack trace, may be null. 11314 * 11315 * @return Returns a fully-formed AppErrorStateInfo record. 11316 */ 11317 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11318 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11319 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11320 11321 report.condition = condition; 11322 report.processName = app.processName; 11323 report.pid = app.pid; 11324 report.uid = app.info.uid; 11325 report.tag = activity; 11326 report.shortMsg = shortMsg; 11327 report.longMsg = longMsg; 11328 report.stackTrace = stackTrace; 11329 11330 return report; 11331 } 11332 11333 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11334 synchronized (this) { 11335 app.crashing = false; 11336 app.crashingReport = null; 11337 app.notResponding = false; 11338 app.notRespondingReport = null; 11339 if (app.anrDialog == fromDialog) { 11340 app.anrDialog = null; 11341 } 11342 if (app.waitDialog == fromDialog) { 11343 app.waitDialog = null; 11344 } 11345 if (app.pid > 0 && app.pid != MY_PID) { 11346 handleAppCrashLocked(app, null, null, null); 11347 app.kill("user request after error", true); 11348 } 11349 } 11350 } 11351 11352 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11353 String stackTrace) { 11354 long now = SystemClock.uptimeMillis(); 11355 11356 Long crashTime; 11357 if (!app.isolated) { 11358 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11359 } else { 11360 crashTime = null; 11361 } 11362 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11363 // This process loses! 11364 Slog.w(TAG, "Process " + app.info.processName 11365 + " has crashed too many times: killing!"); 11366 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11367 app.userId, app.info.processName, app.uid); 11368 mStackSupervisor.handleAppCrashLocked(app); 11369 if (!app.persistent) { 11370 // We don't want to start this process again until the user 11371 // explicitly does so... but for persistent process, we really 11372 // need to keep it running. If a persistent process is actually 11373 // repeatedly crashing, then badness for everyone. 11374 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11375 app.info.processName); 11376 if (!app.isolated) { 11377 // XXX We don't have a way to mark isolated processes 11378 // as bad, since they don't have a peristent identity. 11379 mBadProcesses.put(app.info.processName, app.uid, 11380 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11381 mProcessCrashTimes.remove(app.info.processName, app.uid); 11382 } 11383 app.bad = true; 11384 app.removed = true; 11385 // Don't let services in this process be restarted and potentially 11386 // annoy the user repeatedly. Unless it is persistent, since those 11387 // processes run critical code. 11388 removeProcessLocked(app, false, false, "crash"); 11389 mStackSupervisor.resumeTopActivitiesLocked(); 11390 return false; 11391 } 11392 mStackSupervisor.resumeTopActivitiesLocked(); 11393 } else { 11394 mStackSupervisor.finishTopRunningActivityLocked(app); 11395 } 11396 11397 // Bump up the crash count of any services currently running in the proc. 11398 for (int i=app.services.size()-1; i>=0; i--) { 11399 // Any services running in the application need to be placed 11400 // back in the pending list. 11401 ServiceRecord sr = app.services.valueAt(i); 11402 sr.crashCount++; 11403 } 11404 11405 // If the crashing process is what we consider to be the "home process" and it has been 11406 // replaced by a third-party app, clear the package preferred activities from packages 11407 // with a home activity running in the process to prevent a repeatedly crashing app 11408 // from blocking the user to manually clear the list. 11409 final ArrayList<ActivityRecord> activities = app.activities; 11410 if (app == mHomeProcess && activities.size() > 0 11411 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11412 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11413 final ActivityRecord r = activities.get(activityNdx); 11414 if (r.isHomeActivity()) { 11415 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11416 try { 11417 ActivityThread.getPackageManager() 11418 .clearPackagePreferredActivities(r.packageName); 11419 } catch (RemoteException c) { 11420 // pm is in same process, this will never happen. 11421 } 11422 } 11423 } 11424 } 11425 11426 if (!app.isolated) { 11427 // XXX Can't keep track of crash times for isolated processes, 11428 // because they don't have a perisistent identity. 11429 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11430 } 11431 11432 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11433 return true; 11434 } 11435 11436 void startAppProblemLocked(ProcessRecord app) { 11437 // If this app is not running under the current user, then we 11438 // can't give it a report button because that would require 11439 // launching the report UI under a different user. 11440 app.errorReportReceiver = null; 11441 11442 for (int userId : mCurrentProfileIds) { 11443 if (app.userId == userId) { 11444 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11445 mContext, app.info.packageName, app.info.flags); 11446 } 11447 } 11448 skipCurrentReceiverLocked(app); 11449 } 11450 11451 void skipCurrentReceiverLocked(ProcessRecord app) { 11452 for (BroadcastQueue queue : mBroadcastQueues) { 11453 queue.skipCurrentReceiverLocked(app); 11454 } 11455 } 11456 11457 /** 11458 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11459 * The application process will exit immediately after this call returns. 11460 * @param app object of the crashing app, null for the system server 11461 * @param crashInfo describing the exception 11462 */ 11463 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11464 ProcessRecord r = findAppProcess(app, "Crash"); 11465 final String processName = app == null ? "system_server" 11466 : (r == null ? "unknown" : r.processName); 11467 11468 handleApplicationCrashInner("crash", r, processName, crashInfo); 11469 } 11470 11471 /* Native crash reporting uses this inner version because it needs to be somewhat 11472 * decoupled from the AM-managed cleanup lifecycle 11473 */ 11474 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11475 ApplicationErrorReport.CrashInfo crashInfo) { 11476 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11477 UserHandle.getUserId(Binder.getCallingUid()), processName, 11478 r == null ? -1 : r.info.flags, 11479 crashInfo.exceptionClassName, 11480 crashInfo.exceptionMessage, 11481 crashInfo.throwFileName, 11482 crashInfo.throwLineNumber); 11483 11484 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11485 11486 crashApplication(r, crashInfo); 11487 } 11488 11489 public void handleApplicationStrictModeViolation( 11490 IBinder app, 11491 int violationMask, 11492 StrictMode.ViolationInfo info) { 11493 ProcessRecord r = findAppProcess(app, "StrictMode"); 11494 if (r == null) { 11495 return; 11496 } 11497 11498 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11499 Integer stackFingerprint = info.hashCode(); 11500 boolean logIt = true; 11501 synchronized (mAlreadyLoggedViolatedStacks) { 11502 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11503 logIt = false; 11504 // TODO: sub-sample into EventLog for these, with 11505 // the info.durationMillis? Then we'd get 11506 // the relative pain numbers, without logging all 11507 // the stack traces repeatedly. We'd want to do 11508 // likewise in the client code, which also does 11509 // dup suppression, before the Binder call. 11510 } else { 11511 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11512 mAlreadyLoggedViolatedStacks.clear(); 11513 } 11514 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11515 } 11516 } 11517 if (logIt) { 11518 logStrictModeViolationToDropBox(r, info); 11519 } 11520 } 11521 11522 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11523 AppErrorResult result = new AppErrorResult(); 11524 synchronized (this) { 11525 final long origId = Binder.clearCallingIdentity(); 11526 11527 Message msg = Message.obtain(); 11528 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11529 HashMap<String, Object> data = new HashMap<String, Object>(); 11530 data.put("result", result); 11531 data.put("app", r); 11532 data.put("violationMask", violationMask); 11533 data.put("info", info); 11534 msg.obj = data; 11535 mHandler.sendMessage(msg); 11536 11537 Binder.restoreCallingIdentity(origId); 11538 } 11539 int res = result.get(); 11540 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11541 } 11542 } 11543 11544 // Depending on the policy in effect, there could be a bunch of 11545 // these in quick succession so we try to batch these together to 11546 // minimize disk writes, number of dropbox entries, and maximize 11547 // compression, by having more fewer, larger records. 11548 private void logStrictModeViolationToDropBox( 11549 ProcessRecord process, 11550 StrictMode.ViolationInfo info) { 11551 if (info == null) { 11552 return; 11553 } 11554 final boolean isSystemApp = process == null || 11555 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11556 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11557 final String processName = process == null ? "unknown" : process.processName; 11558 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11559 final DropBoxManager dbox = (DropBoxManager) 11560 mContext.getSystemService(Context.DROPBOX_SERVICE); 11561 11562 // Exit early if the dropbox isn't configured to accept this report type. 11563 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11564 11565 boolean bufferWasEmpty; 11566 boolean needsFlush; 11567 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11568 synchronized (sb) { 11569 bufferWasEmpty = sb.length() == 0; 11570 appendDropBoxProcessHeaders(process, processName, sb); 11571 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11572 sb.append("System-App: ").append(isSystemApp).append("\n"); 11573 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11574 if (info.violationNumThisLoop != 0) { 11575 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11576 } 11577 if (info.numAnimationsRunning != 0) { 11578 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11579 } 11580 if (info.broadcastIntentAction != null) { 11581 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11582 } 11583 if (info.durationMillis != -1) { 11584 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11585 } 11586 if (info.numInstances != -1) { 11587 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11588 } 11589 if (info.tags != null) { 11590 for (String tag : info.tags) { 11591 sb.append("Span-Tag: ").append(tag).append("\n"); 11592 } 11593 } 11594 sb.append("\n"); 11595 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11596 sb.append(info.crashInfo.stackTrace); 11597 } 11598 sb.append("\n"); 11599 11600 // Only buffer up to ~64k. Various logging bits truncate 11601 // things at 128k. 11602 needsFlush = (sb.length() > 64 * 1024); 11603 } 11604 11605 // Flush immediately if the buffer's grown too large, or this 11606 // is a non-system app. Non-system apps are isolated with a 11607 // different tag & policy and not batched. 11608 // 11609 // Batching is useful during internal testing with 11610 // StrictMode settings turned up high. Without batching, 11611 // thousands of separate files could be created on boot. 11612 if (!isSystemApp || needsFlush) { 11613 new Thread("Error dump: " + dropboxTag) { 11614 @Override 11615 public void run() { 11616 String report; 11617 synchronized (sb) { 11618 report = sb.toString(); 11619 sb.delete(0, sb.length()); 11620 sb.trimToSize(); 11621 } 11622 if (report.length() != 0) { 11623 dbox.addText(dropboxTag, report); 11624 } 11625 } 11626 }.start(); 11627 return; 11628 } 11629 11630 // System app batching: 11631 if (!bufferWasEmpty) { 11632 // An existing dropbox-writing thread is outstanding, so 11633 // we don't need to start it up. The existing thread will 11634 // catch the buffer appends we just did. 11635 return; 11636 } 11637 11638 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11639 // (After this point, we shouldn't access AMS internal data structures.) 11640 new Thread("Error dump: " + dropboxTag) { 11641 @Override 11642 public void run() { 11643 // 5 second sleep to let stacks arrive and be batched together 11644 try { 11645 Thread.sleep(5000); // 5 seconds 11646 } catch (InterruptedException e) {} 11647 11648 String errorReport; 11649 synchronized (mStrictModeBuffer) { 11650 errorReport = mStrictModeBuffer.toString(); 11651 if (errorReport.length() == 0) { 11652 return; 11653 } 11654 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11655 mStrictModeBuffer.trimToSize(); 11656 } 11657 dbox.addText(dropboxTag, errorReport); 11658 } 11659 }.start(); 11660 } 11661 11662 /** 11663 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11664 * @param app object of the crashing app, null for the system server 11665 * @param tag reported by the caller 11666 * @param system whether this wtf is coming from the system 11667 * @param crashInfo describing the context of the error 11668 * @return true if the process should exit immediately (WTF is fatal) 11669 */ 11670 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11671 final ApplicationErrorReport.CrashInfo crashInfo) { 11672 final int callingUid = Binder.getCallingUid(); 11673 final int callingPid = Binder.getCallingPid(); 11674 11675 if (system) { 11676 // If this is coming from the system, we could very well have low-level 11677 // system locks held, so we want to do this all asynchronously. And we 11678 // never want this to become fatal, so there is that too. 11679 mHandler.post(new Runnable() { 11680 @Override public void run() { 11681 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11682 } 11683 }); 11684 return false; 11685 } 11686 11687 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11688 crashInfo); 11689 11690 if (r != null && r.pid != Process.myPid() && 11691 Settings.Global.getInt(mContext.getContentResolver(), 11692 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11693 crashApplication(r, crashInfo); 11694 return true; 11695 } else { 11696 return false; 11697 } 11698 } 11699 11700 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11701 final ApplicationErrorReport.CrashInfo crashInfo) { 11702 final ProcessRecord r = findAppProcess(app, "WTF"); 11703 final String processName = app == null ? "system_server" 11704 : (r == null ? "unknown" : r.processName); 11705 11706 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11707 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11708 11709 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11710 11711 return r; 11712 } 11713 11714 /** 11715 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11716 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11717 */ 11718 private ProcessRecord findAppProcess(IBinder app, String reason) { 11719 if (app == null) { 11720 return null; 11721 } 11722 11723 synchronized (this) { 11724 final int NP = mProcessNames.getMap().size(); 11725 for (int ip=0; ip<NP; ip++) { 11726 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11727 final int NA = apps.size(); 11728 for (int ia=0; ia<NA; ia++) { 11729 ProcessRecord p = apps.valueAt(ia); 11730 if (p.thread != null && p.thread.asBinder() == app) { 11731 return p; 11732 } 11733 } 11734 } 11735 11736 Slog.w(TAG, "Can't find mystery application for " + reason 11737 + " from pid=" + Binder.getCallingPid() 11738 + " uid=" + Binder.getCallingUid() + ": " + app); 11739 return null; 11740 } 11741 } 11742 11743 /** 11744 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11745 * to append various headers to the dropbox log text. 11746 */ 11747 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11748 StringBuilder sb) { 11749 // Watchdog thread ends up invoking this function (with 11750 // a null ProcessRecord) to add the stack file to dropbox. 11751 // Do not acquire a lock on this (am) in such cases, as it 11752 // could cause a potential deadlock, if and when watchdog 11753 // is invoked due to unavailability of lock on am and it 11754 // would prevent watchdog from killing system_server. 11755 if (process == null) { 11756 sb.append("Process: ").append(processName).append("\n"); 11757 return; 11758 } 11759 // Note: ProcessRecord 'process' is guarded by the service 11760 // instance. (notably process.pkgList, which could otherwise change 11761 // concurrently during execution of this method) 11762 synchronized (this) { 11763 sb.append("Process: ").append(processName).append("\n"); 11764 int flags = process.info.flags; 11765 IPackageManager pm = AppGlobals.getPackageManager(); 11766 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11767 for (int ip=0; ip<process.pkgList.size(); ip++) { 11768 String pkg = process.pkgList.keyAt(ip); 11769 sb.append("Package: ").append(pkg); 11770 try { 11771 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11772 if (pi != null) { 11773 sb.append(" v").append(pi.versionCode); 11774 if (pi.versionName != null) { 11775 sb.append(" (").append(pi.versionName).append(")"); 11776 } 11777 } 11778 } catch (RemoteException e) { 11779 Slog.e(TAG, "Error getting package info: " + pkg, e); 11780 } 11781 sb.append("\n"); 11782 } 11783 } 11784 } 11785 11786 private static String processClass(ProcessRecord process) { 11787 if (process == null || process.pid == MY_PID) { 11788 return "system_server"; 11789 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11790 return "system_app"; 11791 } else { 11792 return "data_app"; 11793 } 11794 } 11795 11796 /** 11797 * Write a description of an error (crash, WTF, ANR) to the drop box. 11798 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11799 * @param process which caused the error, null means the system server 11800 * @param activity which triggered the error, null if unknown 11801 * @param parent activity related to the error, null if unknown 11802 * @param subject line related to the error, null if absent 11803 * @param report in long form describing the error, null if absent 11804 * @param logFile to include in the report, null if none 11805 * @param crashInfo giving an application stack trace, null if absent 11806 */ 11807 public void addErrorToDropBox(String eventType, 11808 ProcessRecord process, String processName, ActivityRecord activity, 11809 ActivityRecord parent, String subject, 11810 final String report, final File logFile, 11811 final ApplicationErrorReport.CrashInfo crashInfo) { 11812 // NOTE -- this must never acquire the ActivityManagerService lock, 11813 // otherwise the watchdog may be prevented from resetting the system. 11814 11815 final String dropboxTag = processClass(process) + "_" + eventType; 11816 final DropBoxManager dbox = (DropBoxManager) 11817 mContext.getSystemService(Context.DROPBOX_SERVICE); 11818 11819 // Exit early if the dropbox isn't configured to accept this report type. 11820 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11821 11822 final StringBuilder sb = new StringBuilder(1024); 11823 appendDropBoxProcessHeaders(process, processName, sb); 11824 if (activity != null) { 11825 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11826 } 11827 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11828 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11829 } 11830 if (parent != null && parent != activity) { 11831 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11832 } 11833 if (subject != null) { 11834 sb.append("Subject: ").append(subject).append("\n"); 11835 } 11836 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11837 if (Debug.isDebuggerConnected()) { 11838 sb.append("Debugger: Connected\n"); 11839 } 11840 sb.append("\n"); 11841 11842 // Do the rest in a worker thread to avoid blocking the caller on I/O 11843 // (After this point, we shouldn't access AMS internal data structures.) 11844 Thread worker = new Thread("Error dump: " + dropboxTag) { 11845 @Override 11846 public void run() { 11847 if (report != null) { 11848 sb.append(report); 11849 } 11850 if (logFile != null) { 11851 try { 11852 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11853 "\n\n[[TRUNCATED]]")); 11854 } catch (IOException e) { 11855 Slog.e(TAG, "Error reading " + logFile, e); 11856 } 11857 } 11858 if (crashInfo != null && crashInfo.stackTrace != null) { 11859 sb.append(crashInfo.stackTrace); 11860 } 11861 11862 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11863 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11864 if (lines > 0) { 11865 sb.append("\n"); 11866 11867 // Merge several logcat streams, and take the last N lines 11868 InputStreamReader input = null; 11869 try { 11870 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11871 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11872 "-b", "crash", 11873 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11874 11875 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11876 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11877 input = new InputStreamReader(logcat.getInputStream()); 11878 11879 int num; 11880 char[] buf = new char[8192]; 11881 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11882 } catch (IOException e) { 11883 Slog.e(TAG, "Error running logcat", e); 11884 } finally { 11885 if (input != null) try { input.close(); } catch (IOException e) {} 11886 } 11887 } 11888 11889 dbox.addText(dropboxTag, sb.toString()); 11890 } 11891 }; 11892 11893 if (process == null) { 11894 // If process is null, we are being called from some internal code 11895 // and may be about to die -- run this synchronously. 11896 worker.run(); 11897 } else { 11898 worker.start(); 11899 } 11900 } 11901 11902 /** 11903 * Bring up the "unexpected error" dialog box for a crashing app. 11904 * Deal with edge cases (intercepts from instrumented applications, 11905 * ActivityController, error intent receivers, that sort of thing). 11906 * @param r the application crashing 11907 * @param crashInfo describing the failure 11908 */ 11909 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11910 long timeMillis = System.currentTimeMillis(); 11911 String shortMsg = crashInfo.exceptionClassName; 11912 String longMsg = crashInfo.exceptionMessage; 11913 String stackTrace = crashInfo.stackTrace; 11914 if (shortMsg != null && longMsg != null) { 11915 longMsg = shortMsg + ": " + longMsg; 11916 } else if (shortMsg != null) { 11917 longMsg = shortMsg; 11918 } 11919 11920 AppErrorResult result = new AppErrorResult(); 11921 synchronized (this) { 11922 if (mController != null) { 11923 try { 11924 String name = r != null ? r.processName : null; 11925 int pid = r != null ? r.pid : Binder.getCallingPid(); 11926 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11927 if (!mController.appCrashed(name, pid, 11928 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11929 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11930 && "Native crash".equals(crashInfo.exceptionClassName)) { 11931 Slog.w(TAG, "Skip killing native crashed app " + name 11932 + "(" + pid + ") during testing"); 11933 } else { 11934 Slog.w(TAG, "Force-killing crashed app " + name 11935 + " at watcher's request"); 11936 if (r != null) { 11937 r.kill("crash", true); 11938 } else { 11939 // Huh. 11940 Process.killProcess(pid); 11941 Process.killProcessGroup(uid, pid); 11942 } 11943 } 11944 return; 11945 } 11946 } catch (RemoteException e) { 11947 mController = null; 11948 Watchdog.getInstance().setActivityController(null); 11949 } 11950 } 11951 11952 final long origId = Binder.clearCallingIdentity(); 11953 11954 // If this process is running instrumentation, finish it. 11955 if (r != null && r.instrumentationClass != null) { 11956 Slog.w(TAG, "Error in app " + r.processName 11957 + " running instrumentation " + r.instrumentationClass + ":"); 11958 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11959 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11960 Bundle info = new Bundle(); 11961 info.putString("shortMsg", shortMsg); 11962 info.putString("longMsg", longMsg); 11963 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11964 Binder.restoreCallingIdentity(origId); 11965 return; 11966 } 11967 11968 // If we can't identify the process or it's already exceeded its crash quota, 11969 // quit right away without showing a crash dialog. 11970 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11971 Binder.restoreCallingIdentity(origId); 11972 return; 11973 } 11974 11975 Message msg = Message.obtain(); 11976 msg.what = SHOW_ERROR_MSG; 11977 HashMap data = new HashMap(); 11978 data.put("result", result); 11979 data.put("app", r); 11980 msg.obj = data; 11981 mHandler.sendMessage(msg); 11982 11983 Binder.restoreCallingIdentity(origId); 11984 } 11985 11986 int res = result.get(); 11987 11988 Intent appErrorIntent = null; 11989 synchronized (this) { 11990 if (r != null && !r.isolated) { 11991 // XXX Can't keep track of crash time for isolated processes, 11992 // since they don't have a persistent identity. 11993 mProcessCrashTimes.put(r.info.processName, r.uid, 11994 SystemClock.uptimeMillis()); 11995 } 11996 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11997 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11998 } 11999 } 12000 12001 if (appErrorIntent != null) { 12002 try { 12003 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12004 } catch (ActivityNotFoundException e) { 12005 Slog.w(TAG, "bug report receiver dissappeared", e); 12006 } 12007 } 12008 } 12009 12010 Intent createAppErrorIntentLocked(ProcessRecord r, 12011 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12012 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12013 if (report == null) { 12014 return null; 12015 } 12016 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12017 result.setComponent(r.errorReportReceiver); 12018 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12019 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12020 return result; 12021 } 12022 12023 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12024 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12025 if (r.errorReportReceiver == null) { 12026 return null; 12027 } 12028 12029 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12030 return null; 12031 } 12032 12033 ApplicationErrorReport report = new ApplicationErrorReport(); 12034 report.packageName = r.info.packageName; 12035 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12036 report.processName = r.processName; 12037 report.time = timeMillis; 12038 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12039 12040 if (r.crashing || r.forceCrashReport) { 12041 report.type = ApplicationErrorReport.TYPE_CRASH; 12042 report.crashInfo = crashInfo; 12043 } else if (r.notResponding) { 12044 report.type = ApplicationErrorReport.TYPE_ANR; 12045 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12046 12047 report.anrInfo.activity = r.notRespondingReport.tag; 12048 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12049 report.anrInfo.info = r.notRespondingReport.longMsg; 12050 } 12051 12052 return report; 12053 } 12054 12055 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12056 enforceNotIsolatedCaller("getProcessesInErrorState"); 12057 // assume our apps are happy - lazy create the list 12058 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12059 12060 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12061 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12062 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12063 12064 synchronized (this) { 12065 12066 // iterate across all processes 12067 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12068 ProcessRecord app = mLruProcesses.get(i); 12069 if (!allUsers && app.userId != userId) { 12070 continue; 12071 } 12072 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12073 // This one's in trouble, so we'll generate a report for it 12074 // crashes are higher priority (in case there's a crash *and* an anr) 12075 ActivityManager.ProcessErrorStateInfo report = null; 12076 if (app.crashing) { 12077 report = app.crashingReport; 12078 } else if (app.notResponding) { 12079 report = app.notRespondingReport; 12080 } 12081 12082 if (report != null) { 12083 if (errList == null) { 12084 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12085 } 12086 errList.add(report); 12087 } else { 12088 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12089 " crashing = " + app.crashing + 12090 " notResponding = " + app.notResponding); 12091 } 12092 } 12093 } 12094 } 12095 12096 return errList; 12097 } 12098 12099 static int procStateToImportance(int procState, int memAdj, 12100 ActivityManager.RunningAppProcessInfo currApp) { 12101 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12102 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12103 currApp.lru = memAdj; 12104 } else { 12105 currApp.lru = 0; 12106 } 12107 return imp; 12108 } 12109 12110 private void fillInProcMemInfo(ProcessRecord app, 12111 ActivityManager.RunningAppProcessInfo outInfo) { 12112 outInfo.pid = app.pid; 12113 outInfo.uid = app.info.uid; 12114 if (mHeavyWeightProcess == app) { 12115 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12116 } 12117 if (app.persistent) { 12118 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12119 } 12120 if (app.activities.size() > 0) { 12121 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12122 } 12123 outInfo.lastTrimLevel = app.trimMemoryLevel; 12124 int adj = app.curAdj; 12125 int procState = app.curProcState; 12126 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12127 outInfo.importanceReasonCode = app.adjTypeCode; 12128 outInfo.processState = app.curProcState; 12129 } 12130 12131 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12132 enforceNotIsolatedCaller("getRunningAppProcesses"); 12133 // Lazy instantiation of list 12134 List<ActivityManager.RunningAppProcessInfo> runList = null; 12135 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12136 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12137 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12138 synchronized (this) { 12139 // Iterate across all processes 12140 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12141 ProcessRecord app = mLruProcesses.get(i); 12142 if (!allUsers && app.userId != userId) { 12143 continue; 12144 } 12145 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12146 // Generate process state info for running application 12147 ActivityManager.RunningAppProcessInfo currApp = 12148 new ActivityManager.RunningAppProcessInfo(app.processName, 12149 app.pid, app.getPackageList()); 12150 fillInProcMemInfo(app, currApp); 12151 if (app.adjSource instanceof ProcessRecord) { 12152 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12153 currApp.importanceReasonImportance = 12154 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12155 app.adjSourceProcState); 12156 } else if (app.adjSource instanceof ActivityRecord) { 12157 ActivityRecord r = (ActivityRecord)app.adjSource; 12158 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12159 } 12160 if (app.adjTarget instanceof ComponentName) { 12161 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12162 } 12163 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12164 // + " lru=" + currApp.lru); 12165 if (runList == null) { 12166 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12167 } 12168 runList.add(currApp); 12169 } 12170 } 12171 } 12172 return runList; 12173 } 12174 12175 public List<ApplicationInfo> getRunningExternalApplications() { 12176 enforceNotIsolatedCaller("getRunningExternalApplications"); 12177 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12178 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12179 if (runningApps != null && runningApps.size() > 0) { 12180 Set<String> extList = new HashSet<String>(); 12181 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12182 if (app.pkgList != null) { 12183 for (String pkg : app.pkgList) { 12184 extList.add(pkg); 12185 } 12186 } 12187 } 12188 IPackageManager pm = AppGlobals.getPackageManager(); 12189 for (String pkg : extList) { 12190 try { 12191 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12192 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12193 retList.add(info); 12194 } 12195 } catch (RemoteException e) { 12196 } 12197 } 12198 } 12199 return retList; 12200 } 12201 12202 @Override 12203 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12204 enforceNotIsolatedCaller("getMyMemoryState"); 12205 synchronized (this) { 12206 ProcessRecord proc; 12207 synchronized (mPidsSelfLocked) { 12208 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12209 } 12210 fillInProcMemInfo(proc, outInfo); 12211 } 12212 } 12213 12214 @Override 12215 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12216 if (checkCallingPermission(android.Manifest.permission.DUMP) 12217 != PackageManager.PERMISSION_GRANTED) { 12218 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12219 + Binder.getCallingPid() 12220 + ", uid=" + Binder.getCallingUid() 12221 + " without permission " 12222 + android.Manifest.permission.DUMP); 12223 return; 12224 } 12225 12226 boolean dumpAll = false; 12227 boolean dumpClient = false; 12228 String dumpPackage = null; 12229 12230 int opti = 0; 12231 while (opti < args.length) { 12232 String opt = args[opti]; 12233 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12234 break; 12235 } 12236 opti++; 12237 if ("-a".equals(opt)) { 12238 dumpAll = true; 12239 } else if ("-c".equals(opt)) { 12240 dumpClient = true; 12241 } else if ("-h".equals(opt)) { 12242 pw.println("Activity manager dump options:"); 12243 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12244 pw.println(" cmd may be one of:"); 12245 pw.println(" a[ctivities]: activity stack state"); 12246 pw.println(" r[recents]: recent activities state"); 12247 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12248 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12249 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12250 pw.println(" o[om]: out of memory management"); 12251 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12252 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12253 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12254 pw.println(" service [COMP_SPEC]: service client-side state"); 12255 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12256 pw.println(" all: dump all activities"); 12257 pw.println(" top: dump the top activity"); 12258 pw.println(" write: write all pending state to storage"); 12259 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12260 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12261 pw.println(" a partial substring in a component name, a"); 12262 pw.println(" hex object identifier."); 12263 pw.println(" -a: include all available server state."); 12264 pw.println(" -c: include client state."); 12265 return; 12266 } else { 12267 pw.println("Unknown argument: " + opt + "; use -h for help"); 12268 } 12269 } 12270 12271 long origId = Binder.clearCallingIdentity(); 12272 boolean more = false; 12273 // Is the caller requesting to dump a particular piece of data? 12274 if (opti < args.length) { 12275 String cmd = args[opti]; 12276 opti++; 12277 if ("activities".equals(cmd) || "a".equals(cmd)) { 12278 synchronized (this) { 12279 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12280 } 12281 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12282 synchronized (this) { 12283 dumpRecentsLocked(fd, pw, args, opti, true, null); 12284 } 12285 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12286 String[] newArgs; 12287 String name; 12288 if (opti >= args.length) { 12289 name = null; 12290 newArgs = EMPTY_STRING_ARRAY; 12291 } else { 12292 name = args[opti]; 12293 opti++; 12294 newArgs = new String[args.length - opti]; 12295 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12296 args.length - opti); 12297 } 12298 synchronized (this) { 12299 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12300 } 12301 } else if ("intents".equals(cmd) || "i".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, 12312 args.length - opti); 12313 } 12314 synchronized (this) { 12315 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12316 } 12317 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12318 String[] newArgs; 12319 String name; 12320 if (opti >= args.length) { 12321 name = null; 12322 newArgs = EMPTY_STRING_ARRAY; 12323 } else { 12324 name = args[opti]; 12325 opti++; 12326 newArgs = new String[args.length - opti]; 12327 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12328 args.length - opti); 12329 } 12330 synchronized (this) { 12331 dumpProcessesLocked(fd, pw, args, opti, true, name); 12332 } 12333 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12334 synchronized (this) { 12335 dumpOomLocked(fd, pw, args, opti, true); 12336 } 12337 } else if ("provider".equals(cmd)) { 12338 String[] newArgs; 12339 String name; 12340 if (opti >= args.length) { 12341 name = null; 12342 newArgs = EMPTY_STRING_ARRAY; 12343 } else { 12344 name = args[opti]; 12345 opti++; 12346 newArgs = new String[args.length - opti]; 12347 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12348 } 12349 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12350 pw.println("No providers match: " + name); 12351 pw.println("Use -h for help."); 12352 } 12353 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12354 synchronized (this) { 12355 dumpProvidersLocked(fd, pw, args, opti, true, null); 12356 } 12357 } else if ("service".equals(cmd)) { 12358 String[] newArgs; 12359 String name; 12360 if (opti >= args.length) { 12361 name = null; 12362 newArgs = EMPTY_STRING_ARRAY; 12363 } else { 12364 name = args[opti]; 12365 opti++; 12366 newArgs = new String[args.length - opti]; 12367 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12368 args.length - opti); 12369 } 12370 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12371 pw.println("No services match: " + name); 12372 pw.println("Use -h for help."); 12373 } 12374 } else if ("package".equals(cmd)) { 12375 String[] newArgs; 12376 if (opti >= args.length) { 12377 pw.println("package: no package name specified"); 12378 pw.println("Use -h for help."); 12379 } else { 12380 dumpPackage = args[opti]; 12381 opti++; 12382 newArgs = new String[args.length - opti]; 12383 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12384 args.length - opti); 12385 args = newArgs; 12386 opti = 0; 12387 more = true; 12388 } 12389 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12390 synchronized (this) { 12391 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12392 } 12393 } else if ("write".equals(cmd)) { 12394 mTaskPersister.flush(); 12395 pw.println("All tasks persisted."); 12396 return; 12397 } else { 12398 // Dumping a single activity? 12399 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12400 pw.println("Bad activity command, or no activities match: " + cmd); 12401 pw.println("Use -h for help."); 12402 } 12403 } 12404 if (!more) { 12405 Binder.restoreCallingIdentity(origId); 12406 return; 12407 } 12408 } 12409 12410 // No piece of data specified, dump everything. 12411 synchronized (this) { 12412 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12413 pw.println(); 12414 if (dumpAll) { 12415 pw.println("-------------------------------------------------------------------------------"); 12416 } 12417 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12418 pw.println(); 12419 if (dumpAll) { 12420 pw.println("-------------------------------------------------------------------------------"); 12421 } 12422 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12423 pw.println(); 12424 if (dumpAll) { 12425 pw.println("-------------------------------------------------------------------------------"); 12426 } 12427 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12428 pw.println(); 12429 if (dumpAll) { 12430 pw.println("-------------------------------------------------------------------------------"); 12431 } 12432 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12433 pw.println(); 12434 if (dumpAll) { 12435 pw.println("-------------------------------------------------------------------------------"); 12436 } 12437 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12438 pw.println(); 12439 if (dumpAll) { 12440 pw.println("-------------------------------------------------------------------------------"); 12441 } 12442 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12443 } 12444 Binder.restoreCallingIdentity(origId); 12445 } 12446 12447 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12448 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12449 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12450 12451 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12452 dumpPackage); 12453 boolean needSep = printedAnything; 12454 12455 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12456 dumpPackage, needSep, " mFocusedActivity: "); 12457 if (printed) { 12458 printedAnything = true; 12459 needSep = false; 12460 } 12461 12462 if (dumpPackage == null) { 12463 if (needSep) { 12464 pw.println(); 12465 } 12466 needSep = true; 12467 printedAnything = true; 12468 mStackSupervisor.dump(pw, " "); 12469 } 12470 12471 if (!printedAnything) { 12472 pw.println(" (nothing)"); 12473 } 12474 } 12475 12476 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12477 int opti, boolean dumpAll, String dumpPackage) { 12478 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12479 12480 boolean printedAnything = false; 12481 12482 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12483 boolean printedHeader = false; 12484 12485 final int N = mRecentTasks.size(); 12486 for (int i=0; i<N; i++) { 12487 TaskRecord tr = mRecentTasks.get(i); 12488 if (dumpPackage != null) { 12489 if (tr.realActivity == null || 12490 !dumpPackage.equals(tr.realActivity)) { 12491 continue; 12492 } 12493 } 12494 if (!printedHeader) { 12495 pw.println(" Recent tasks:"); 12496 printedHeader = true; 12497 printedAnything = true; 12498 } 12499 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12500 pw.println(tr); 12501 if (dumpAll) { 12502 mRecentTasks.get(i).dump(pw, " "); 12503 } 12504 } 12505 } 12506 12507 if (!printedAnything) { 12508 pw.println(" (nothing)"); 12509 } 12510 } 12511 12512 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12513 int opti, boolean dumpAll, String dumpPackage) { 12514 boolean needSep = false; 12515 boolean printedAnything = false; 12516 int numPers = 0; 12517 12518 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12519 12520 if (dumpAll) { 12521 final int NP = mProcessNames.getMap().size(); 12522 for (int ip=0; ip<NP; ip++) { 12523 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12524 final int NA = procs.size(); 12525 for (int ia=0; ia<NA; ia++) { 12526 ProcessRecord r = procs.valueAt(ia); 12527 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12528 continue; 12529 } 12530 if (!needSep) { 12531 pw.println(" All known processes:"); 12532 needSep = true; 12533 printedAnything = true; 12534 } 12535 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12536 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12537 pw.print(" "); pw.println(r); 12538 r.dump(pw, " "); 12539 if (r.persistent) { 12540 numPers++; 12541 } 12542 } 12543 } 12544 } 12545 12546 if (mIsolatedProcesses.size() > 0) { 12547 boolean printed = false; 12548 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12549 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12550 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12551 continue; 12552 } 12553 if (!printed) { 12554 if (needSep) { 12555 pw.println(); 12556 } 12557 pw.println(" Isolated process list (sorted by uid):"); 12558 printedAnything = true; 12559 printed = true; 12560 needSep = true; 12561 } 12562 pw.println(String.format("%sIsolated #%2d: %s", 12563 " ", i, r.toString())); 12564 } 12565 } 12566 12567 if (mLruProcesses.size() > 0) { 12568 if (needSep) { 12569 pw.println(); 12570 } 12571 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12572 pw.print(" total, non-act at "); 12573 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12574 pw.print(", non-svc at "); 12575 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12576 pw.println("):"); 12577 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12578 needSep = true; 12579 printedAnything = true; 12580 } 12581 12582 if (dumpAll || dumpPackage != null) { 12583 synchronized (mPidsSelfLocked) { 12584 boolean printed = false; 12585 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12586 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12587 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12588 continue; 12589 } 12590 if (!printed) { 12591 if (needSep) pw.println(); 12592 needSep = true; 12593 pw.println(" PID mappings:"); 12594 printed = true; 12595 printedAnything = true; 12596 } 12597 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12598 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12599 } 12600 } 12601 } 12602 12603 if (mForegroundProcesses.size() > 0) { 12604 synchronized (mPidsSelfLocked) { 12605 boolean printed = false; 12606 for (int i=0; i<mForegroundProcesses.size(); i++) { 12607 ProcessRecord r = mPidsSelfLocked.get( 12608 mForegroundProcesses.valueAt(i).pid); 12609 if (dumpPackage != null && (r == null 12610 || !r.pkgList.containsKey(dumpPackage))) { 12611 continue; 12612 } 12613 if (!printed) { 12614 if (needSep) pw.println(); 12615 needSep = true; 12616 pw.println(" Foreground Processes:"); 12617 printed = true; 12618 printedAnything = true; 12619 } 12620 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12621 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12622 } 12623 } 12624 } 12625 12626 if (mPersistentStartingProcesses.size() > 0) { 12627 if (needSep) pw.println(); 12628 needSep = true; 12629 printedAnything = true; 12630 pw.println(" Persisent processes that are starting:"); 12631 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12632 "Starting Norm", "Restarting PERS", dumpPackage); 12633 } 12634 12635 if (mRemovedProcesses.size() > 0) { 12636 if (needSep) pw.println(); 12637 needSep = true; 12638 printedAnything = true; 12639 pw.println(" Processes that are being removed:"); 12640 dumpProcessList(pw, this, mRemovedProcesses, " ", 12641 "Removed Norm", "Removed PERS", dumpPackage); 12642 } 12643 12644 if (mProcessesOnHold.size() > 0) { 12645 if (needSep) pw.println(); 12646 needSep = true; 12647 printedAnything = true; 12648 pw.println(" Processes that are on old until the system is ready:"); 12649 dumpProcessList(pw, this, mProcessesOnHold, " ", 12650 "OnHold Norm", "OnHold PERS", dumpPackage); 12651 } 12652 12653 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12654 12655 if (mProcessCrashTimes.getMap().size() > 0) { 12656 boolean printed = false; 12657 long now = SystemClock.uptimeMillis(); 12658 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12659 final int NP = pmap.size(); 12660 for (int ip=0; ip<NP; ip++) { 12661 String pname = pmap.keyAt(ip); 12662 SparseArray<Long> uids = pmap.valueAt(ip); 12663 final int N = uids.size(); 12664 for (int i=0; i<N; i++) { 12665 int puid = uids.keyAt(i); 12666 ProcessRecord r = mProcessNames.get(pname, puid); 12667 if (dumpPackage != null && (r == null 12668 || !r.pkgList.containsKey(dumpPackage))) { 12669 continue; 12670 } 12671 if (!printed) { 12672 if (needSep) pw.println(); 12673 needSep = true; 12674 pw.println(" Time since processes crashed:"); 12675 printed = true; 12676 printedAnything = true; 12677 } 12678 pw.print(" Process "); pw.print(pname); 12679 pw.print(" uid "); pw.print(puid); 12680 pw.print(": last crashed "); 12681 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12682 pw.println(" ago"); 12683 } 12684 } 12685 } 12686 12687 if (mBadProcesses.getMap().size() > 0) { 12688 boolean printed = false; 12689 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12690 final int NP = pmap.size(); 12691 for (int ip=0; ip<NP; ip++) { 12692 String pname = pmap.keyAt(ip); 12693 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12694 final int N = uids.size(); 12695 for (int i=0; i<N; i++) { 12696 int puid = uids.keyAt(i); 12697 ProcessRecord r = mProcessNames.get(pname, puid); 12698 if (dumpPackage != null && (r == null 12699 || !r.pkgList.containsKey(dumpPackage))) { 12700 continue; 12701 } 12702 if (!printed) { 12703 if (needSep) pw.println(); 12704 needSep = true; 12705 pw.println(" Bad processes:"); 12706 printedAnything = true; 12707 } 12708 BadProcessInfo info = uids.valueAt(i); 12709 pw.print(" Bad process "); pw.print(pname); 12710 pw.print(" uid "); pw.print(puid); 12711 pw.print(": crashed at time "); pw.println(info.time); 12712 if (info.shortMsg != null) { 12713 pw.print(" Short msg: "); pw.println(info.shortMsg); 12714 } 12715 if (info.longMsg != null) { 12716 pw.print(" Long msg: "); pw.println(info.longMsg); 12717 } 12718 if (info.stack != null) { 12719 pw.println(" Stack:"); 12720 int lastPos = 0; 12721 for (int pos=0; pos<info.stack.length(); pos++) { 12722 if (info.stack.charAt(pos) == '\n') { 12723 pw.print(" "); 12724 pw.write(info.stack, lastPos, pos-lastPos); 12725 pw.println(); 12726 lastPos = pos+1; 12727 } 12728 } 12729 if (lastPos < info.stack.length()) { 12730 pw.print(" "); 12731 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12732 pw.println(); 12733 } 12734 } 12735 } 12736 } 12737 } 12738 12739 if (dumpPackage == null) { 12740 pw.println(); 12741 needSep = false; 12742 pw.println(" mStartedUsers:"); 12743 for (int i=0; i<mStartedUsers.size(); i++) { 12744 UserStartedState uss = mStartedUsers.valueAt(i); 12745 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12746 pw.print(": "); uss.dump("", pw); 12747 } 12748 pw.print(" mStartedUserArray: ["); 12749 for (int i=0; i<mStartedUserArray.length; i++) { 12750 if (i > 0) pw.print(", "); 12751 pw.print(mStartedUserArray[i]); 12752 } 12753 pw.println("]"); 12754 pw.print(" mUserLru: ["); 12755 for (int i=0; i<mUserLru.size(); i++) { 12756 if (i > 0) pw.print(", "); 12757 pw.print(mUserLru.get(i)); 12758 } 12759 pw.println("]"); 12760 if (dumpAll) { 12761 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12762 } 12763 synchronized (mUserProfileGroupIdsSelfLocked) { 12764 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12765 pw.println(" mUserProfileGroupIds:"); 12766 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12767 pw.print(" User #"); 12768 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12769 pw.print(" -> profile #"); 12770 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12771 } 12772 } 12773 } 12774 } 12775 if (mHomeProcess != null && (dumpPackage == null 12776 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12777 if (needSep) { 12778 pw.println(); 12779 needSep = false; 12780 } 12781 pw.println(" mHomeProcess: " + mHomeProcess); 12782 } 12783 if (mPreviousProcess != null && (dumpPackage == null 12784 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12785 if (needSep) { 12786 pw.println(); 12787 needSep = false; 12788 } 12789 pw.println(" mPreviousProcess: " + mPreviousProcess); 12790 } 12791 if (dumpAll) { 12792 StringBuilder sb = new StringBuilder(128); 12793 sb.append(" mPreviousProcessVisibleTime: "); 12794 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12795 pw.println(sb); 12796 } 12797 if (mHeavyWeightProcess != null && (dumpPackage == null 12798 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12799 if (needSep) { 12800 pw.println(); 12801 needSep = false; 12802 } 12803 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12804 } 12805 if (dumpPackage == null) { 12806 pw.println(" mConfiguration: " + mConfiguration); 12807 } 12808 if (dumpAll) { 12809 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12810 if (mCompatModePackages.getPackages().size() > 0) { 12811 boolean printed = false; 12812 for (Map.Entry<String, Integer> entry 12813 : mCompatModePackages.getPackages().entrySet()) { 12814 String pkg = entry.getKey(); 12815 int mode = entry.getValue(); 12816 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12817 continue; 12818 } 12819 if (!printed) { 12820 pw.println(" mScreenCompatPackages:"); 12821 printed = true; 12822 } 12823 pw.print(" "); pw.print(pkg); pw.print(": "); 12824 pw.print(mode); pw.println(); 12825 } 12826 } 12827 } 12828 if (dumpPackage == null) { 12829 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12830 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12831 + " mLockScreenShown " + lockScreenShownToString()); 12832 } 12833 if (mShuttingDown || mRunningVoice) { 12834 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12835 } 12836 } 12837 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12838 || mOrigWaitForDebugger) { 12839 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12840 || dumpPackage.equals(mOrigDebugApp)) { 12841 if (needSep) { 12842 pw.println(); 12843 needSep = false; 12844 } 12845 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12846 + " mDebugTransient=" + mDebugTransient 12847 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12848 } 12849 } 12850 if (mOpenGlTraceApp != null) { 12851 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12852 if (needSep) { 12853 pw.println(); 12854 needSep = false; 12855 } 12856 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12857 } 12858 } 12859 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12860 || mProfileFd != null) { 12861 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12862 if (needSep) { 12863 pw.println(); 12864 needSep = false; 12865 } 12866 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12867 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12868 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12869 + mAutoStopProfiler); 12870 pw.println(" mProfileType=" + mProfileType); 12871 } 12872 } 12873 if (dumpPackage == null) { 12874 if (mAlwaysFinishActivities || mController != null) { 12875 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12876 + " mController=" + mController); 12877 } 12878 if (dumpAll) { 12879 pw.println(" Total persistent processes: " + numPers); 12880 pw.println(" mProcessesReady=" + mProcessesReady 12881 + " mSystemReady=" + mSystemReady 12882 + " mBooted=" + mBooted 12883 + " mFactoryTest=" + mFactoryTest); 12884 pw.println(" mBooting=" + mBooting 12885 + " mCallFinishBooting=" + mCallFinishBooting 12886 + " mBootAnimationComplete=" + mBootAnimationComplete); 12887 pw.print(" mLastPowerCheckRealtime="); 12888 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12889 pw.println(""); 12890 pw.print(" mLastPowerCheckUptime="); 12891 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12892 pw.println(""); 12893 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12894 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12895 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12896 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12897 + " (" + mLruProcesses.size() + " total)" 12898 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12899 + " mNumServiceProcs=" + mNumServiceProcs 12900 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12901 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12902 + " mLastMemoryLevel" + mLastMemoryLevel 12903 + " mLastNumProcesses" + mLastNumProcesses); 12904 long now = SystemClock.uptimeMillis(); 12905 pw.print(" mLastIdleTime="); 12906 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12907 pw.print(" mLowRamSinceLastIdle="); 12908 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12909 pw.println(); 12910 } 12911 } 12912 12913 if (!printedAnything) { 12914 pw.println(" (nothing)"); 12915 } 12916 } 12917 12918 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12919 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12920 if (mProcessesToGc.size() > 0) { 12921 boolean printed = false; 12922 long now = SystemClock.uptimeMillis(); 12923 for (int i=0; i<mProcessesToGc.size(); i++) { 12924 ProcessRecord proc = mProcessesToGc.get(i); 12925 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12926 continue; 12927 } 12928 if (!printed) { 12929 if (needSep) pw.println(); 12930 needSep = true; 12931 pw.println(" Processes that are waiting to GC:"); 12932 printed = true; 12933 } 12934 pw.print(" Process "); pw.println(proc); 12935 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12936 pw.print(", last gced="); 12937 pw.print(now-proc.lastRequestedGc); 12938 pw.print(" ms ago, last lowMem="); 12939 pw.print(now-proc.lastLowMemory); 12940 pw.println(" ms ago"); 12941 12942 } 12943 } 12944 return needSep; 12945 } 12946 12947 void printOomLevel(PrintWriter pw, String name, int adj) { 12948 pw.print(" "); 12949 if (adj >= 0) { 12950 pw.print(' '); 12951 if (adj < 10) pw.print(' '); 12952 } else { 12953 if (adj > -10) pw.print(' '); 12954 } 12955 pw.print(adj); 12956 pw.print(": "); 12957 pw.print(name); 12958 pw.print(" ("); 12959 pw.print(mProcessList.getMemLevel(adj)/1024); 12960 pw.println(" kB)"); 12961 } 12962 12963 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12964 int opti, boolean dumpAll) { 12965 boolean needSep = false; 12966 12967 if (mLruProcesses.size() > 0) { 12968 if (needSep) pw.println(); 12969 needSep = true; 12970 pw.println(" OOM levels:"); 12971 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12972 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12973 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12974 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12975 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12976 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12977 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12978 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12979 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12980 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12981 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12982 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12983 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12984 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12985 12986 if (needSep) pw.println(); 12987 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12988 pw.print(" total, non-act at "); 12989 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12990 pw.print(", non-svc at "); 12991 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12992 pw.println("):"); 12993 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12994 needSep = true; 12995 } 12996 12997 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12998 12999 pw.println(); 13000 pw.println(" mHomeProcess: " + mHomeProcess); 13001 pw.println(" mPreviousProcess: " + mPreviousProcess); 13002 if (mHeavyWeightProcess != null) { 13003 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13004 } 13005 13006 return true; 13007 } 13008 13009 /** 13010 * There are three ways to call this: 13011 * - no provider specified: dump all the providers 13012 * - a flattened component name that matched an existing provider was specified as the 13013 * first arg: dump that one provider 13014 * - the first arg isn't the flattened component name of an existing provider: 13015 * dump all providers whose component contains the first arg as a substring 13016 */ 13017 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13018 int opti, boolean dumpAll) { 13019 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13020 } 13021 13022 static class ItemMatcher { 13023 ArrayList<ComponentName> components; 13024 ArrayList<String> strings; 13025 ArrayList<Integer> objects; 13026 boolean all; 13027 13028 ItemMatcher() { 13029 all = true; 13030 } 13031 13032 void build(String name) { 13033 ComponentName componentName = ComponentName.unflattenFromString(name); 13034 if (componentName != null) { 13035 if (components == null) { 13036 components = new ArrayList<ComponentName>(); 13037 } 13038 components.add(componentName); 13039 all = false; 13040 } else { 13041 int objectId = 0; 13042 // Not a '/' separated full component name; maybe an object ID? 13043 try { 13044 objectId = Integer.parseInt(name, 16); 13045 if (objects == null) { 13046 objects = new ArrayList<Integer>(); 13047 } 13048 objects.add(objectId); 13049 all = false; 13050 } catch (RuntimeException e) { 13051 // Not an integer; just do string match. 13052 if (strings == null) { 13053 strings = new ArrayList<String>(); 13054 } 13055 strings.add(name); 13056 all = false; 13057 } 13058 } 13059 } 13060 13061 int build(String[] args, int opti) { 13062 for (; opti<args.length; opti++) { 13063 String name = args[opti]; 13064 if ("--".equals(name)) { 13065 return opti+1; 13066 } 13067 build(name); 13068 } 13069 return opti; 13070 } 13071 13072 boolean match(Object object, ComponentName comp) { 13073 if (all) { 13074 return true; 13075 } 13076 if (components != null) { 13077 for (int i=0; i<components.size(); i++) { 13078 if (components.get(i).equals(comp)) { 13079 return true; 13080 } 13081 } 13082 } 13083 if (objects != null) { 13084 for (int i=0; i<objects.size(); i++) { 13085 if (System.identityHashCode(object) == objects.get(i)) { 13086 return true; 13087 } 13088 } 13089 } 13090 if (strings != null) { 13091 String flat = comp.flattenToString(); 13092 for (int i=0; i<strings.size(); i++) { 13093 if (flat.contains(strings.get(i))) { 13094 return true; 13095 } 13096 } 13097 } 13098 return false; 13099 } 13100 } 13101 13102 /** 13103 * There are three things that cmd can be: 13104 * - a flattened component name that matches an existing activity 13105 * - the cmd arg isn't the flattened component name of an existing activity: 13106 * dump all activity whose component contains the cmd as a substring 13107 * - A hex number of the ActivityRecord object instance. 13108 */ 13109 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13110 int opti, boolean dumpAll) { 13111 ArrayList<ActivityRecord> activities; 13112 13113 synchronized (this) { 13114 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13115 } 13116 13117 if (activities.size() <= 0) { 13118 return false; 13119 } 13120 13121 String[] newArgs = new String[args.length - opti]; 13122 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13123 13124 TaskRecord lastTask = null; 13125 boolean needSep = false; 13126 for (int i=activities.size()-1; i>=0; i--) { 13127 ActivityRecord r = activities.get(i); 13128 if (needSep) { 13129 pw.println(); 13130 } 13131 needSep = true; 13132 synchronized (this) { 13133 if (lastTask != r.task) { 13134 lastTask = r.task; 13135 pw.print("TASK "); pw.print(lastTask.affinity); 13136 pw.print(" id="); pw.println(lastTask.taskId); 13137 if (dumpAll) { 13138 lastTask.dump(pw, " "); 13139 } 13140 } 13141 } 13142 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13143 } 13144 return true; 13145 } 13146 13147 /** 13148 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13149 * there is a thread associated with the activity. 13150 */ 13151 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13152 final ActivityRecord r, String[] args, boolean dumpAll) { 13153 String innerPrefix = prefix + " "; 13154 synchronized (this) { 13155 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13156 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13157 pw.print(" pid="); 13158 if (r.app != null) pw.println(r.app.pid); 13159 else pw.println("(not running)"); 13160 if (dumpAll) { 13161 r.dump(pw, innerPrefix); 13162 } 13163 } 13164 if (r.app != null && r.app.thread != null) { 13165 // flush anything that is already in the PrintWriter since the thread is going 13166 // to write to the file descriptor directly 13167 pw.flush(); 13168 try { 13169 TransferPipe tp = new TransferPipe(); 13170 try { 13171 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13172 r.appToken, innerPrefix, args); 13173 tp.go(fd); 13174 } finally { 13175 tp.kill(); 13176 } 13177 } catch (IOException e) { 13178 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13179 } catch (RemoteException e) { 13180 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13181 } 13182 } 13183 } 13184 13185 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13186 int opti, boolean dumpAll, String dumpPackage) { 13187 boolean needSep = false; 13188 boolean onlyHistory = false; 13189 boolean printedAnything = false; 13190 13191 if ("history".equals(dumpPackage)) { 13192 if (opti < args.length && "-s".equals(args[opti])) { 13193 dumpAll = false; 13194 } 13195 onlyHistory = true; 13196 dumpPackage = null; 13197 } 13198 13199 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13200 if (!onlyHistory && dumpAll) { 13201 if (mRegisteredReceivers.size() > 0) { 13202 boolean printed = false; 13203 Iterator it = mRegisteredReceivers.values().iterator(); 13204 while (it.hasNext()) { 13205 ReceiverList r = (ReceiverList)it.next(); 13206 if (dumpPackage != null && (r.app == null || 13207 !dumpPackage.equals(r.app.info.packageName))) { 13208 continue; 13209 } 13210 if (!printed) { 13211 pw.println(" Registered Receivers:"); 13212 needSep = true; 13213 printed = true; 13214 printedAnything = true; 13215 } 13216 pw.print(" * "); pw.println(r); 13217 r.dump(pw, " "); 13218 } 13219 } 13220 13221 if (mReceiverResolver.dump(pw, needSep ? 13222 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13223 " ", dumpPackage, false)) { 13224 needSep = true; 13225 printedAnything = true; 13226 } 13227 } 13228 13229 for (BroadcastQueue q : mBroadcastQueues) { 13230 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13231 printedAnything |= needSep; 13232 } 13233 13234 needSep = true; 13235 13236 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13237 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13238 if (needSep) { 13239 pw.println(); 13240 } 13241 needSep = true; 13242 printedAnything = true; 13243 pw.print(" Sticky broadcasts for user "); 13244 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13245 StringBuilder sb = new StringBuilder(128); 13246 for (Map.Entry<String, ArrayList<Intent>> ent 13247 : mStickyBroadcasts.valueAt(user).entrySet()) { 13248 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13249 if (dumpAll) { 13250 pw.println(":"); 13251 ArrayList<Intent> intents = ent.getValue(); 13252 final int N = intents.size(); 13253 for (int i=0; i<N; i++) { 13254 sb.setLength(0); 13255 sb.append(" Intent: "); 13256 intents.get(i).toShortString(sb, false, true, false, false); 13257 pw.println(sb.toString()); 13258 Bundle bundle = intents.get(i).getExtras(); 13259 if (bundle != null) { 13260 pw.print(" "); 13261 pw.println(bundle.toString()); 13262 } 13263 } 13264 } else { 13265 pw.println(""); 13266 } 13267 } 13268 } 13269 } 13270 13271 if (!onlyHistory && dumpAll) { 13272 pw.println(); 13273 for (BroadcastQueue queue : mBroadcastQueues) { 13274 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13275 + queue.mBroadcastsScheduled); 13276 } 13277 pw.println(" mHandler:"); 13278 mHandler.dump(new PrintWriterPrinter(pw), " "); 13279 needSep = true; 13280 printedAnything = true; 13281 } 13282 13283 if (!printedAnything) { 13284 pw.println(" (nothing)"); 13285 } 13286 } 13287 13288 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13289 int opti, boolean dumpAll, String dumpPackage) { 13290 boolean needSep; 13291 boolean printedAnything = false; 13292 13293 ItemMatcher matcher = new ItemMatcher(); 13294 matcher.build(args, opti); 13295 13296 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13297 13298 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13299 printedAnything |= needSep; 13300 13301 if (mLaunchingProviders.size() > 0) { 13302 boolean printed = false; 13303 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13304 ContentProviderRecord r = mLaunchingProviders.get(i); 13305 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13306 continue; 13307 } 13308 if (!printed) { 13309 if (needSep) pw.println(); 13310 needSep = true; 13311 pw.println(" Launching content providers:"); 13312 printed = true; 13313 printedAnything = true; 13314 } 13315 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13316 pw.println(r); 13317 } 13318 } 13319 13320 if (mGrantedUriPermissions.size() > 0) { 13321 boolean printed = false; 13322 int dumpUid = -2; 13323 if (dumpPackage != null) { 13324 try { 13325 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13326 } catch (NameNotFoundException e) { 13327 dumpUid = -1; 13328 } 13329 } 13330 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13331 int uid = mGrantedUriPermissions.keyAt(i); 13332 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13333 continue; 13334 } 13335 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13336 if (!printed) { 13337 if (needSep) pw.println(); 13338 needSep = true; 13339 pw.println(" Granted Uri Permissions:"); 13340 printed = true; 13341 printedAnything = true; 13342 } 13343 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13344 for (UriPermission perm : perms.values()) { 13345 pw.print(" "); pw.println(perm); 13346 if (dumpAll) { 13347 perm.dump(pw, " "); 13348 } 13349 } 13350 } 13351 } 13352 13353 if (!printedAnything) { 13354 pw.println(" (nothing)"); 13355 } 13356 } 13357 13358 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13359 int opti, boolean dumpAll, String dumpPackage) { 13360 boolean printed = false; 13361 13362 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13363 13364 if (mIntentSenderRecords.size() > 0) { 13365 Iterator<WeakReference<PendingIntentRecord>> it 13366 = mIntentSenderRecords.values().iterator(); 13367 while (it.hasNext()) { 13368 WeakReference<PendingIntentRecord> ref = it.next(); 13369 PendingIntentRecord rec = ref != null ? ref.get(): null; 13370 if (dumpPackage != null && (rec == null 13371 || !dumpPackage.equals(rec.key.packageName))) { 13372 continue; 13373 } 13374 printed = true; 13375 if (rec != null) { 13376 pw.print(" * "); pw.println(rec); 13377 if (dumpAll) { 13378 rec.dump(pw, " "); 13379 } 13380 } else { 13381 pw.print(" * "); pw.println(ref); 13382 } 13383 } 13384 } 13385 13386 if (!printed) { 13387 pw.println(" (nothing)"); 13388 } 13389 } 13390 13391 private static final int dumpProcessList(PrintWriter pw, 13392 ActivityManagerService service, List list, 13393 String prefix, String normalLabel, String persistentLabel, 13394 String dumpPackage) { 13395 int numPers = 0; 13396 final int N = list.size()-1; 13397 for (int i=N; i>=0; i--) { 13398 ProcessRecord r = (ProcessRecord)list.get(i); 13399 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13400 continue; 13401 } 13402 pw.println(String.format("%s%s #%2d: %s", 13403 prefix, (r.persistent ? persistentLabel : normalLabel), 13404 i, r.toString())); 13405 if (r.persistent) { 13406 numPers++; 13407 } 13408 } 13409 return numPers; 13410 } 13411 13412 private static final boolean dumpProcessOomList(PrintWriter pw, 13413 ActivityManagerService service, List<ProcessRecord> origList, 13414 String prefix, String normalLabel, String persistentLabel, 13415 boolean inclDetails, String dumpPackage) { 13416 13417 ArrayList<Pair<ProcessRecord, Integer>> list 13418 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13419 for (int i=0; i<origList.size(); i++) { 13420 ProcessRecord r = origList.get(i); 13421 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13422 continue; 13423 } 13424 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13425 } 13426 13427 if (list.size() <= 0) { 13428 return false; 13429 } 13430 13431 Comparator<Pair<ProcessRecord, Integer>> comparator 13432 = new Comparator<Pair<ProcessRecord, Integer>>() { 13433 @Override 13434 public int compare(Pair<ProcessRecord, Integer> object1, 13435 Pair<ProcessRecord, Integer> object2) { 13436 if (object1.first.setAdj != object2.first.setAdj) { 13437 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13438 } 13439 if (object1.second.intValue() != object2.second.intValue()) { 13440 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13441 } 13442 return 0; 13443 } 13444 }; 13445 13446 Collections.sort(list, comparator); 13447 13448 final long curRealtime = SystemClock.elapsedRealtime(); 13449 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13450 final long curUptime = SystemClock.uptimeMillis(); 13451 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13452 13453 for (int i=list.size()-1; i>=0; i--) { 13454 ProcessRecord r = list.get(i).first; 13455 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13456 char schedGroup; 13457 switch (r.setSchedGroup) { 13458 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13459 schedGroup = 'B'; 13460 break; 13461 case Process.THREAD_GROUP_DEFAULT: 13462 schedGroup = 'F'; 13463 break; 13464 default: 13465 schedGroup = '?'; 13466 break; 13467 } 13468 char foreground; 13469 if (r.foregroundActivities) { 13470 foreground = 'A'; 13471 } else if (r.foregroundServices) { 13472 foreground = 'S'; 13473 } else { 13474 foreground = ' '; 13475 } 13476 String procState = ProcessList.makeProcStateString(r.curProcState); 13477 pw.print(prefix); 13478 pw.print(r.persistent ? persistentLabel : normalLabel); 13479 pw.print(" #"); 13480 int num = (origList.size()-1)-list.get(i).second; 13481 if (num < 10) pw.print(' '); 13482 pw.print(num); 13483 pw.print(": "); 13484 pw.print(oomAdj); 13485 pw.print(' '); 13486 pw.print(schedGroup); 13487 pw.print('/'); 13488 pw.print(foreground); 13489 pw.print('/'); 13490 pw.print(procState); 13491 pw.print(" trm:"); 13492 if (r.trimMemoryLevel < 10) pw.print(' '); 13493 pw.print(r.trimMemoryLevel); 13494 pw.print(' '); 13495 pw.print(r.toShortString()); 13496 pw.print(" ("); 13497 pw.print(r.adjType); 13498 pw.println(')'); 13499 if (r.adjSource != null || r.adjTarget != null) { 13500 pw.print(prefix); 13501 pw.print(" "); 13502 if (r.adjTarget instanceof ComponentName) { 13503 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13504 } else if (r.adjTarget != null) { 13505 pw.print(r.adjTarget.toString()); 13506 } else { 13507 pw.print("{null}"); 13508 } 13509 pw.print("<="); 13510 if (r.adjSource instanceof ProcessRecord) { 13511 pw.print("Proc{"); 13512 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13513 pw.println("}"); 13514 } else if (r.adjSource != null) { 13515 pw.println(r.adjSource.toString()); 13516 } else { 13517 pw.println("{null}"); 13518 } 13519 } 13520 if (inclDetails) { 13521 pw.print(prefix); 13522 pw.print(" "); 13523 pw.print("oom: max="); pw.print(r.maxAdj); 13524 pw.print(" curRaw="); pw.print(r.curRawAdj); 13525 pw.print(" setRaw="); pw.print(r.setRawAdj); 13526 pw.print(" cur="); pw.print(r.curAdj); 13527 pw.print(" set="); pw.println(r.setAdj); 13528 pw.print(prefix); 13529 pw.print(" "); 13530 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13531 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13532 pw.print(" lastPss="); pw.print(r.lastPss); 13533 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13534 pw.print(prefix); 13535 pw.print(" "); 13536 pw.print("cached="); pw.print(r.cached); 13537 pw.print(" empty="); pw.print(r.empty); 13538 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13539 13540 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13541 if (r.lastWakeTime != 0) { 13542 long wtime; 13543 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13544 synchronized (stats) { 13545 wtime = stats.getProcessWakeTime(r.info.uid, 13546 r.pid, curRealtime); 13547 } 13548 long timeUsed = wtime - r.lastWakeTime; 13549 pw.print(prefix); 13550 pw.print(" "); 13551 pw.print("keep awake over "); 13552 TimeUtils.formatDuration(realtimeSince, pw); 13553 pw.print(" used "); 13554 TimeUtils.formatDuration(timeUsed, pw); 13555 pw.print(" ("); 13556 pw.print((timeUsed*100)/realtimeSince); 13557 pw.println("%)"); 13558 } 13559 if (r.lastCpuTime != 0) { 13560 long timeUsed = r.curCpuTime - r.lastCpuTime; 13561 pw.print(prefix); 13562 pw.print(" "); 13563 pw.print("run cpu over "); 13564 TimeUtils.formatDuration(uptimeSince, pw); 13565 pw.print(" used "); 13566 TimeUtils.formatDuration(timeUsed, pw); 13567 pw.print(" ("); 13568 pw.print((timeUsed*100)/uptimeSince); 13569 pw.println("%)"); 13570 } 13571 } 13572 } 13573 } 13574 return true; 13575 } 13576 13577 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13578 String[] args) { 13579 ArrayList<ProcessRecord> procs; 13580 synchronized (this) { 13581 if (args != null && args.length > start 13582 && args[start].charAt(0) != '-') { 13583 procs = new ArrayList<ProcessRecord>(); 13584 int pid = -1; 13585 try { 13586 pid = Integer.parseInt(args[start]); 13587 } catch (NumberFormatException e) { 13588 } 13589 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13590 ProcessRecord proc = mLruProcesses.get(i); 13591 if (proc.pid == pid) { 13592 procs.add(proc); 13593 } else if (allPkgs && proc.pkgList != null 13594 && proc.pkgList.containsKey(args[start])) { 13595 procs.add(proc); 13596 } else if (proc.processName.equals(args[start])) { 13597 procs.add(proc); 13598 } 13599 } 13600 if (procs.size() <= 0) { 13601 return null; 13602 } 13603 } else { 13604 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13605 } 13606 } 13607 return procs; 13608 } 13609 13610 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13611 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 long uptime = SystemClock.uptimeMillis(); 13619 long realtime = SystemClock.elapsedRealtime(); 13620 pw.println("Applications Graphics Acceleration Info:"); 13621 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13622 13623 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13624 ProcessRecord r = procs.get(i); 13625 if (r.thread != null) { 13626 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13627 pw.flush(); 13628 try { 13629 TransferPipe tp = new TransferPipe(); 13630 try { 13631 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13632 tp.go(fd); 13633 } finally { 13634 tp.kill(); 13635 } 13636 } catch (IOException e) { 13637 pw.println("Failure while dumping the app: " + r); 13638 pw.flush(); 13639 } catch (RemoteException e) { 13640 pw.println("Got a RemoteException while dumping the app " + r); 13641 pw.flush(); 13642 } 13643 } 13644 } 13645 } 13646 13647 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13648 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13649 if (procs == null) { 13650 pw.println("No process found for: " + args[0]); 13651 return; 13652 } 13653 13654 pw.println("Applications Database Info:"); 13655 13656 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13657 ProcessRecord r = procs.get(i); 13658 if (r.thread != null) { 13659 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13660 pw.flush(); 13661 try { 13662 TransferPipe tp = new TransferPipe(); 13663 try { 13664 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13665 tp.go(fd); 13666 } finally { 13667 tp.kill(); 13668 } 13669 } catch (IOException e) { 13670 pw.println("Failure while dumping the app: " + r); 13671 pw.flush(); 13672 } catch (RemoteException e) { 13673 pw.println("Got a RemoteException while dumping the app " + r); 13674 pw.flush(); 13675 } 13676 } 13677 } 13678 } 13679 13680 final static class MemItem { 13681 final boolean isProc; 13682 final String label; 13683 final String shortLabel; 13684 final long pss; 13685 final int id; 13686 final boolean hasActivities; 13687 ArrayList<MemItem> subitems; 13688 13689 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13690 boolean _hasActivities) { 13691 isProc = true; 13692 label = _label; 13693 shortLabel = _shortLabel; 13694 pss = _pss; 13695 id = _id; 13696 hasActivities = _hasActivities; 13697 } 13698 13699 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13700 isProc = false; 13701 label = _label; 13702 shortLabel = _shortLabel; 13703 pss = _pss; 13704 id = _id; 13705 hasActivities = false; 13706 } 13707 } 13708 13709 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13710 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13711 if (sort && !isCompact) { 13712 Collections.sort(items, new Comparator<MemItem>() { 13713 @Override 13714 public int compare(MemItem lhs, MemItem rhs) { 13715 if (lhs.pss < rhs.pss) { 13716 return 1; 13717 } else if (lhs.pss > rhs.pss) { 13718 return -1; 13719 } 13720 return 0; 13721 } 13722 }); 13723 } 13724 13725 for (int i=0; i<items.size(); i++) { 13726 MemItem mi = items.get(i); 13727 if (!isCompact) { 13728 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13729 } else if (mi.isProc) { 13730 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13731 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13732 pw.println(mi.hasActivities ? ",a" : ",e"); 13733 } else { 13734 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13735 pw.println(mi.pss); 13736 } 13737 if (mi.subitems != null) { 13738 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13739 true, isCompact); 13740 } 13741 } 13742 } 13743 13744 // These are in KB. 13745 static final long[] DUMP_MEM_BUCKETS = new long[] { 13746 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13747 120*1024, 160*1024, 200*1024, 13748 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13749 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13750 }; 13751 13752 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13753 boolean stackLike) { 13754 int start = label.lastIndexOf('.'); 13755 if (start >= 0) start++; 13756 else start = 0; 13757 int end = label.length(); 13758 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13759 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13760 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13761 out.append(bucket); 13762 out.append(stackLike ? "MB." : "MB "); 13763 out.append(label, start, end); 13764 return; 13765 } 13766 } 13767 out.append(memKB/1024); 13768 out.append(stackLike ? "MB." : "MB "); 13769 out.append(label, start, end); 13770 } 13771 13772 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13773 ProcessList.NATIVE_ADJ, 13774 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13775 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13776 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13777 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13778 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13779 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13780 }; 13781 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13782 "Native", 13783 "System", "Persistent", "Persistent Service", "Foreground", 13784 "Visible", "Perceptible", 13785 "Heavy Weight", "Backup", 13786 "A Services", "Home", 13787 "Previous", "B Services", "Cached" 13788 }; 13789 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13790 "native", 13791 "sys", "pers", "persvc", "fore", 13792 "vis", "percept", 13793 "heavy", "backup", 13794 "servicea", "home", 13795 "prev", "serviceb", "cached" 13796 }; 13797 13798 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13799 long realtime, boolean isCheckinRequest, boolean isCompact) { 13800 if (isCheckinRequest || isCompact) { 13801 // short checkin version 13802 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13803 } else { 13804 pw.println("Applications Memory Usage (kB):"); 13805 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13806 } 13807 } 13808 13809 private static final int KSM_SHARED = 0; 13810 private static final int KSM_SHARING = 1; 13811 private static final int KSM_UNSHARED = 2; 13812 private static final int KSM_VOLATILE = 3; 13813 13814 private final long[] getKsmInfo() { 13815 long[] longOut = new long[4]; 13816 final int[] SINGLE_LONG_FORMAT = new int[] { 13817 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13818 }; 13819 long[] longTmp = new long[1]; 13820 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13821 SINGLE_LONG_FORMAT, null, longTmp, null); 13822 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13823 longTmp[0] = 0; 13824 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13825 SINGLE_LONG_FORMAT, null, longTmp, null); 13826 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13827 longTmp[0] = 0; 13828 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13829 SINGLE_LONG_FORMAT, null, longTmp, null); 13830 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13831 longTmp[0] = 0; 13832 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13833 SINGLE_LONG_FORMAT, null, longTmp, null); 13834 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13835 return longOut; 13836 } 13837 13838 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13839 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13840 boolean dumpDetails = false; 13841 boolean dumpFullDetails = false; 13842 boolean dumpDalvik = false; 13843 boolean oomOnly = false; 13844 boolean isCompact = false; 13845 boolean localOnly = false; 13846 boolean packages = false; 13847 13848 int opti = 0; 13849 while (opti < args.length) { 13850 String opt = args[opti]; 13851 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13852 break; 13853 } 13854 opti++; 13855 if ("-a".equals(opt)) { 13856 dumpDetails = true; 13857 dumpFullDetails = true; 13858 dumpDalvik = true; 13859 } else if ("-d".equals(opt)) { 13860 dumpDalvik = true; 13861 } else if ("-c".equals(opt)) { 13862 isCompact = true; 13863 } else if ("--oom".equals(opt)) { 13864 oomOnly = true; 13865 } else if ("--local".equals(opt)) { 13866 localOnly = true; 13867 } else if ("--package".equals(opt)) { 13868 packages = true; 13869 } else if ("-h".equals(opt)) { 13870 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13871 pw.println(" -a: include all available information for each process."); 13872 pw.println(" -d: include dalvik details when dumping process details."); 13873 pw.println(" -c: dump in a compact machine-parseable representation."); 13874 pw.println(" --oom: only show processes organized by oom adj."); 13875 pw.println(" --local: only collect details locally, don't call process."); 13876 pw.println(" --package: interpret process arg as package, dumping all"); 13877 pw.println(" processes that have loaded that package."); 13878 pw.println("If [process] is specified it can be the name or "); 13879 pw.println("pid of a specific process to dump."); 13880 return; 13881 } else { 13882 pw.println("Unknown argument: " + opt + "; use -h for help"); 13883 } 13884 } 13885 13886 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13887 long uptime = SystemClock.uptimeMillis(); 13888 long realtime = SystemClock.elapsedRealtime(); 13889 final long[] tmpLong = new long[1]; 13890 13891 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13892 if (procs == null) { 13893 // No Java processes. Maybe they want to print a native process. 13894 if (args != null && args.length > opti 13895 && args[opti].charAt(0) != '-') { 13896 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13897 = new ArrayList<ProcessCpuTracker.Stats>(); 13898 updateCpuStatsNow(); 13899 int findPid = -1; 13900 try { 13901 findPid = Integer.parseInt(args[opti]); 13902 } catch (NumberFormatException e) { 13903 } 13904 synchronized (mProcessCpuTracker) { 13905 final int N = mProcessCpuTracker.countStats(); 13906 for (int i=0; i<N; i++) { 13907 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13908 if (st.pid == findPid || (st.baseName != null 13909 && st.baseName.equals(args[opti]))) { 13910 nativeProcs.add(st); 13911 } 13912 } 13913 } 13914 if (nativeProcs.size() > 0) { 13915 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13916 isCompact); 13917 Debug.MemoryInfo mi = null; 13918 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13919 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13920 final int pid = r.pid; 13921 if (!isCheckinRequest && dumpDetails) { 13922 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13923 } 13924 if (mi == null) { 13925 mi = new Debug.MemoryInfo(); 13926 } 13927 if (dumpDetails || (!brief && !oomOnly)) { 13928 Debug.getMemoryInfo(pid, mi); 13929 } else { 13930 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13931 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13932 } 13933 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13934 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13935 if (isCheckinRequest) { 13936 pw.println(); 13937 } 13938 } 13939 return; 13940 } 13941 } 13942 pw.println("No process found for: " + args[opti]); 13943 return; 13944 } 13945 13946 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13947 dumpDetails = true; 13948 } 13949 13950 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13951 13952 String[] innerArgs = new String[args.length-opti]; 13953 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13954 13955 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13956 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13957 long nativePss = 0; 13958 long dalvikPss = 0; 13959 long otherPss = 0; 13960 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13961 13962 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13963 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13964 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13965 13966 long totalPss = 0; 13967 long cachedPss = 0; 13968 13969 Debug.MemoryInfo mi = null; 13970 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13971 final ProcessRecord r = procs.get(i); 13972 final IApplicationThread thread; 13973 final int pid; 13974 final int oomAdj; 13975 final boolean hasActivities; 13976 synchronized (this) { 13977 thread = r.thread; 13978 pid = r.pid; 13979 oomAdj = r.getSetAdjWithServices(); 13980 hasActivities = r.activities.size() > 0; 13981 } 13982 if (thread != null) { 13983 if (!isCheckinRequest && dumpDetails) { 13984 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13985 } 13986 if (mi == null) { 13987 mi = new Debug.MemoryInfo(); 13988 } 13989 if (dumpDetails || (!brief && !oomOnly)) { 13990 Debug.getMemoryInfo(pid, mi); 13991 } else { 13992 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13993 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13994 } 13995 if (dumpDetails) { 13996 if (localOnly) { 13997 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13998 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13999 if (isCheckinRequest) { 14000 pw.println(); 14001 } 14002 } else { 14003 try { 14004 pw.flush(); 14005 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14006 dumpDalvik, innerArgs); 14007 } catch (RemoteException e) { 14008 if (!isCheckinRequest) { 14009 pw.println("Got RemoteException!"); 14010 pw.flush(); 14011 } 14012 } 14013 } 14014 } 14015 14016 final long myTotalPss = mi.getTotalPss(); 14017 final long myTotalUss = mi.getTotalUss(); 14018 14019 synchronized (this) { 14020 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14021 // Record this for posterity if the process has been stable. 14022 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14023 } 14024 } 14025 14026 if (!isCheckinRequest && mi != null) { 14027 totalPss += myTotalPss; 14028 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14029 (hasActivities ? " / activities)" : ")"), 14030 r.processName, myTotalPss, pid, hasActivities); 14031 procMems.add(pssItem); 14032 procMemsMap.put(pid, pssItem); 14033 14034 nativePss += mi.nativePss; 14035 dalvikPss += mi.dalvikPss; 14036 otherPss += mi.otherPss; 14037 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14038 long mem = mi.getOtherPss(j); 14039 miscPss[j] += mem; 14040 otherPss -= mem; 14041 } 14042 14043 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14044 cachedPss += myTotalPss; 14045 } 14046 14047 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14048 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14049 || oomIndex == (oomPss.length-1)) { 14050 oomPss[oomIndex] += myTotalPss; 14051 if (oomProcs[oomIndex] == null) { 14052 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14053 } 14054 oomProcs[oomIndex].add(pssItem); 14055 break; 14056 } 14057 } 14058 } 14059 } 14060 } 14061 14062 long nativeProcTotalPss = 0; 14063 14064 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14065 // If we are showing aggregations, also look for native processes to 14066 // include so that our aggregations are more accurate. 14067 updateCpuStatsNow(); 14068 synchronized (mProcessCpuTracker) { 14069 final int N = mProcessCpuTracker.countStats(); 14070 for (int i=0; i<N; i++) { 14071 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14072 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14073 if (mi == null) { 14074 mi = new Debug.MemoryInfo(); 14075 } 14076 if (!brief && !oomOnly) { 14077 Debug.getMemoryInfo(st.pid, mi); 14078 } else { 14079 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14080 mi.nativePrivateDirty = (int)tmpLong[0]; 14081 } 14082 14083 final long myTotalPss = mi.getTotalPss(); 14084 totalPss += myTotalPss; 14085 nativeProcTotalPss += myTotalPss; 14086 14087 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14088 st.name, myTotalPss, st.pid, false); 14089 procMems.add(pssItem); 14090 14091 nativePss += mi.nativePss; 14092 dalvikPss += mi.dalvikPss; 14093 otherPss += mi.otherPss; 14094 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14095 long mem = mi.getOtherPss(j); 14096 miscPss[j] += mem; 14097 otherPss -= mem; 14098 } 14099 oomPss[0] += myTotalPss; 14100 if (oomProcs[0] == null) { 14101 oomProcs[0] = new ArrayList<MemItem>(); 14102 } 14103 oomProcs[0].add(pssItem); 14104 } 14105 } 14106 } 14107 14108 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14109 14110 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14111 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14112 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14113 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14114 String label = Debug.MemoryInfo.getOtherLabel(j); 14115 catMems.add(new MemItem(label, label, miscPss[j], j)); 14116 } 14117 14118 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14119 for (int j=0; j<oomPss.length; j++) { 14120 if (oomPss[j] != 0) { 14121 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14122 : DUMP_MEM_OOM_LABEL[j]; 14123 MemItem item = new MemItem(label, label, oomPss[j], 14124 DUMP_MEM_OOM_ADJ[j]); 14125 item.subitems = oomProcs[j]; 14126 oomMems.add(item); 14127 } 14128 } 14129 14130 if (!brief && !oomOnly && !isCompact) { 14131 pw.println(); 14132 pw.println("Total PSS by process:"); 14133 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14134 pw.println(); 14135 } 14136 if (!isCompact) { 14137 pw.println("Total PSS by OOM adjustment:"); 14138 } 14139 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14140 if (!brief && !oomOnly) { 14141 PrintWriter out = categoryPw != null ? categoryPw : pw; 14142 if (!isCompact) { 14143 out.println(); 14144 out.println("Total PSS by category:"); 14145 } 14146 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14147 } 14148 if (!isCompact) { 14149 pw.println(); 14150 } 14151 MemInfoReader memInfo = new MemInfoReader(); 14152 memInfo.readMemInfo(); 14153 if (nativeProcTotalPss > 0) { 14154 synchronized (this) { 14155 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14156 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14157 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14158 } 14159 } 14160 if (!brief) { 14161 if (!isCompact) { 14162 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14163 pw.print(" kB (status "); 14164 switch (mLastMemoryLevel) { 14165 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14166 pw.println("normal)"); 14167 break; 14168 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14169 pw.println("moderate)"); 14170 break; 14171 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14172 pw.println("low)"); 14173 break; 14174 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14175 pw.println("critical)"); 14176 break; 14177 default: 14178 pw.print(mLastMemoryLevel); 14179 pw.println(")"); 14180 break; 14181 } 14182 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14183 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14184 pw.print(cachedPss); pw.print(" cached pss + "); 14185 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14186 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14187 } else { 14188 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14189 pw.print(cachedPss + memInfo.getCachedSizeKb() 14190 + memInfo.getFreeSizeKb()); pw.print(","); 14191 pw.println(totalPss - cachedPss); 14192 } 14193 } 14194 if (!isCompact) { 14195 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14196 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14197 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14198 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14199 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14200 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14201 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14202 } 14203 if (!brief) { 14204 if (memInfo.getZramTotalSizeKb() != 0) { 14205 if (!isCompact) { 14206 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14207 pw.print(" kB physical used for "); 14208 pw.print(memInfo.getSwapTotalSizeKb() 14209 - memInfo.getSwapFreeSizeKb()); 14210 pw.print(" kB in swap ("); 14211 pw.print(memInfo.getSwapTotalSizeKb()); 14212 pw.println(" kB total swap)"); 14213 } else { 14214 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14215 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14216 pw.println(memInfo.getSwapFreeSizeKb()); 14217 } 14218 } 14219 final long[] ksm = getKsmInfo(); 14220 if (!isCompact) { 14221 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14222 || ksm[KSM_VOLATILE] != 0) { 14223 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14224 pw.print(" kB saved from shared "); 14225 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14226 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14227 pw.print(" kB unshared; "); 14228 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14229 } 14230 pw.print(" Tuning: "); 14231 pw.print(ActivityManager.staticGetMemoryClass()); 14232 pw.print(" (large "); 14233 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14234 pw.print("), oom "); 14235 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14236 pw.print(" kB"); 14237 pw.print(", restore limit "); 14238 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14239 pw.print(" kB"); 14240 if (ActivityManager.isLowRamDeviceStatic()) { 14241 pw.print(" (low-ram)"); 14242 } 14243 if (ActivityManager.isHighEndGfx()) { 14244 pw.print(" (high-end-gfx)"); 14245 } 14246 pw.println(); 14247 } else { 14248 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14249 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14250 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14251 pw.print("tuning,"); 14252 pw.print(ActivityManager.staticGetMemoryClass()); 14253 pw.print(','); 14254 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14255 pw.print(','); 14256 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14257 if (ActivityManager.isLowRamDeviceStatic()) { 14258 pw.print(",low-ram"); 14259 } 14260 if (ActivityManager.isHighEndGfx()) { 14261 pw.print(",high-end-gfx"); 14262 } 14263 pw.println(); 14264 } 14265 } 14266 } 14267 } 14268 14269 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14270 String name) { 14271 sb.append(" "); 14272 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14273 sb.append(' '); 14274 sb.append(ProcessList.makeProcStateString(procState)); 14275 sb.append(' '); 14276 ProcessList.appendRamKb(sb, pss); 14277 sb.append(" kB: "); 14278 sb.append(name); 14279 } 14280 14281 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14282 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14283 sb.append(" ("); 14284 sb.append(mi.pid); 14285 sb.append(") "); 14286 sb.append(mi.adjType); 14287 sb.append('\n'); 14288 if (mi.adjReason != null) { 14289 sb.append(" "); 14290 sb.append(mi.adjReason); 14291 sb.append('\n'); 14292 } 14293 } 14294 14295 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14296 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14297 for (int i=0, N=memInfos.size(); i<N; i++) { 14298 ProcessMemInfo mi = memInfos.get(i); 14299 infoMap.put(mi.pid, mi); 14300 } 14301 updateCpuStatsNow(); 14302 synchronized (mProcessCpuTracker) { 14303 final int N = mProcessCpuTracker.countStats(); 14304 for (int i=0; i<N; i++) { 14305 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14306 if (st.vsize > 0) { 14307 long pss = Debug.getPss(st.pid, null); 14308 if (pss > 0) { 14309 if (infoMap.indexOfKey(st.pid) < 0) { 14310 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14311 ProcessList.NATIVE_ADJ, -1, "native", null); 14312 mi.pss = pss; 14313 memInfos.add(mi); 14314 } 14315 } 14316 } 14317 } 14318 } 14319 14320 long totalPss = 0; 14321 for (int i=0, N=memInfos.size(); i<N; i++) { 14322 ProcessMemInfo mi = memInfos.get(i); 14323 if (mi.pss == 0) { 14324 mi.pss = Debug.getPss(mi.pid, null); 14325 } 14326 totalPss += mi.pss; 14327 } 14328 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14329 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14330 if (lhs.oomAdj != rhs.oomAdj) { 14331 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14332 } 14333 if (lhs.pss != rhs.pss) { 14334 return lhs.pss < rhs.pss ? 1 : -1; 14335 } 14336 return 0; 14337 } 14338 }); 14339 14340 StringBuilder tag = new StringBuilder(128); 14341 StringBuilder stack = new StringBuilder(128); 14342 tag.append("Low on memory -- "); 14343 appendMemBucket(tag, totalPss, "total", false); 14344 appendMemBucket(stack, totalPss, "total", true); 14345 14346 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14347 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14348 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14349 14350 boolean firstLine = true; 14351 int lastOomAdj = Integer.MIN_VALUE; 14352 long extraNativeRam = 0; 14353 long cachedPss = 0; 14354 for (int i=0, N=memInfos.size(); i<N; i++) { 14355 ProcessMemInfo mi = memInfos.get(i); 14356 14357 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14358 cachedPss += mi.pss; 14359 } 14360 14361 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14362 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14363 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14364 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14365 if (lastOomAdj != mi.oomAdj) { 14366 lastOomAdj = mi.oomAdj; 14367 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14368 tag.append(" / "); 14369 } 14370 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14371 if (firstLine) { 14372 stack.append(":"); 14373 firstLine = false; 14374 } 14375 stack.append("\n\t at "); 14376 } else { 14377 stack.append("$"); 14378 } 14379 } else { 14380 tag.append(" "); 14381 stack.append("$"); 14382 } 14383 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14384 appendMemBucket(tag, mi.pss, mi.name, false); 14385 } 14386 appendMemBucket(stack, mi.pss, mi.name, true); 14387 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14388 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14389 stack.append("("); 14390 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14391 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14392 stack.append(DUMP_MEM_OOM_LABEL[k]); 14393 stack.append(":"); 14394 stack.append(DUMP_MEM_OOM_ADJ[k]); 14395 } 14396 } 14397 stack.append(")"); 14398 } 14399 } 14400 14401 appendMemInfo(fullNativeBuilder, mi); 14402 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14403 // The short form only has native processes that are >= 1MB. 14404 if (mi.pss >= 1000) { 14405 appendMemInfo(shortNativeBuilder, mi); 14406 } else { 14407 extraNativeRam += mi.pss; 14408 } 14409 } else { 14410 // Short form has all other details, but if we have collected RAM 14411 // from smaller native processes let's dump a summary of that. 14412 if (extraNativeRam > 0) { 14413 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14414 -1, extraNativeRam, "(Other native)"); 14415 shortNativeBuilder.append('\n'); 14416 extraNativeRam = 0; 14417 } 14418 appendMemInfo(fullJavaBuilder, mi); 14419 } 14420 } 14421 14422 fullJavaBuilder.append(" "); 14423 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14424 fullJavaBuilder.append(" kB: TOTAL\n"); 14425 14426 MemInfoReader memInfo = new MemInfoReader(); 14427 memInfo.readMemInfo(); 14428 final long[] infos = memInfo.getRawInfo(); 14429 14430 StringBuilder memInfoBuilder = new StringBuilder(1024); 14431 Debug.getMemInfo(infos); 14432 memInfoBuilder.append(" MemInfo: "); 14433 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14434 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14435 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14436 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14437 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14438 memInfoBuilder.append(" "); 14439 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14440 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14441 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14442 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14443 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14444 memInfoBuilder.append(" ZRAM: "); 14445 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14446 memInfoBuilder.append(" kB RAM, "); 14447 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14448 memInfoBuilder.append(" kB swap total, "); 14449 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14450 memInfoBuilder.append(" kB swap free\n"); 14451 } 14452 final long[] ksm = getKsmInfo(); 14453 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14454 || ksm[KSM_VOLATILE] != 0) { 14455 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14456 memInfoBuilder.append(" kB saved from shared "); 14457 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14458 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14459 memInfoBuilder.append(" kB unshared; "); 14460 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14461 } 14462 memInfoBuilder.append(" Free RAM: "); 14463 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14464 + memInfo.getFreeSizeKb()); 14465 memInfoBuilder.append(" kB\n"); 14466 memInfoBuilder.append(" Used RAM: "); 14467 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14468 memInfoBuilder.append(" kB\n"); 14469 memInfoBuilder.append(" Lost RAM: "); 14470 memInfoBuilder.append(memInfo.getTotalSizeKb() 14471 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14472 - memInfo.getKernelUsedSizeKb()); 14473 memInfoBuilder.append(" kB\n"); 14474 Slog.i(TAG, "Low on memory:"); 14475 Slog.i(TAG, shortNativeBuilder.toString()); 14476 Slog.i(TAG, fullJavaBuilder.toString()); 14477 Slog.i(TAG, memInfoBuilder.toString()); 14478 14479 StringBuilder dropBuilder = new StringBuilder(1024); 14480 /* 14481 StringWriter oomSw = new StringWriter(); 14482 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14483 StringWriter catSw = new StringWriter(); 14484 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14485 String[] emptyArgs = new String[] { }; 14486 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14487 oomPw.flush(); 14488 String oomString = oomSw.toString(); 14489 */ 14490 dropBuilder.append("Low on memory:"); 14491 dropBuilder.append(stack); 14492 dropBuilder.append('\n'); 14493 dropBuilder.append(fullNativeBuilder); 14494 dropBuilder.append(fullJavaBuilder); 14495 dropBuilder.append('\n'); 14496 dropBuilder.append(memInfoBuilder); 14497 dropBuilder.append('\n'); 14498 /* 14499 dropBuilder.append(oomString); 14500 dropBuilder.append('\n'); 14501 */ 14502 StringWriter catSw = new StringWriter(); 14503 synchronized (ActivityManagerService.this) { 14504 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14505 String[] emptyArgs = new String[] { }; 14506 catPw.println(); 14507 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14508 catPw.println(); 14509 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14510 false, false, null); 14511 catPw.println(); 14512 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14513 catPw.flush(); 14514 } 14515 dropBuilder.append(catSw.toString()); 14516 addErrorToDropBox("lowmem", null, "system_server", null, 14517 null, tag.toString(), dropBuilder.toString(), null, null); 14518 //Slog.i(TAG, "Sent to dropbox:"); 14519 //Slog.i(TAG, dropBuilder.toString()); 14520 synchronized (ActivityManagerService.this) { 14521 long now = SystemClock.uptimeMillis(); 14522 if (mLastMemUsageReportTime < now) { 14523 mLastMemUsageReportTime = now; 14524 } 14525 } 14526 } 14527 14528 /** 14529 * Searches array of arguments for the specified string 14530 * @param args array of argument strings 14531 * @param value value to search for 14532 * @return true if the value is contained in the array 14533 */ 14534 private static boolean scanArgs(String[] args, String value) { 14535 if (args != null) { 14536 for (String arg : args) { 14537 if (value.equals(arg)) { 14538 return true; 14539 } 14540 } 14541 } 14542 return false; 14543 } 14544 14545 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14546 ContentProviderRecord cpr, boolean always) { 14547 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14548 14549 if (!inLaunching || always) { 14550 synchronized (cpr) { 14551 cpr.launchingApp = null; 14552 cpr.notifyAll(); 14553 } 14554 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14555 String names[] = cpr.info.authority.split(";"); 14556 for (int j = 0; j < names.length; j++) { 14557 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14558 } 14559 } 14560 14561 for (int i=0; i<cpr.connections.size(); i++) { 14562 ContentProviderConnection conn = cpr.connections.get(i); 14563 if (conn.waiting) { 14564 // If this connection is waiting for the provider, then we don't 14565 // need to mess with its process unless we are always removing 14566 // or for some reason the provider is not currently launching. 14567 if (inLaunching && !always) { 14568 continue; 14569 } 14570 } 14571 ProcessRecord capp = conn.client; 14572 conn.dead = true; 14573 if (conn.stableCount > 0) { 14574 if (!capp.persistent && capp.thread != null 14575 && capp.pid != 0 14576 && capp.pid != MY_PID) { 14577 capp.kill("depends on provider " 14578 + cpr.name.flattenToShortString() 14579 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14580 } 14581 } else if (capp.thread != null && conn.provider.provider != null) { 14582 try { 14583 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14584 } catch (RemoteException e) { 14585 } 14586 // In the protocol here, we don't expect the client to correctly 14587 // clean up this connection, we'll just remove it. 14588 cpr.connections.remove(i); 14589 conn.client.conProviders.remove(conn); 14590 } 14591 } 14592 14593 if (inLaunching && always) { 14594 mLaunchingProviders.remove(cpr); 14595 } 14596 return inLaunching; 14597 } 14598 14599 /** 14600 * Main code for cleaning up a process when it has gone away. This is 14601 * called both as a result of the process dying, or directly when stopping 14602 * a process when running in single process mode. 14603 * 14604 * @return Returns true if the given process has been restarted, so the 14605 * app that was passed in must remain on the process lists. 14606 */ 14607 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14608 boolean restarting, boolean allowRestart, int index) { 14609 if (index >= 0) { 14610 removeLruProcessLocked(app); 14611 ProcessList.remove(app.pid); 14612 } 14613 14614 mProcessesToGc.remove(app); 14615 mPendingPssProcesses.remove(app); 14616 14617 // Dismiss any open dialogs. 14618 if (app.crashDialog != null && !app.forceCrashReport) { 14619 app.crashDialog.dismiss(); 14620 app.crashDialog = null; 14621 } 14622 if (app.anrDialog != null) { 14623 app.anrDialog.dismiss(); 14624 app.anrDialog = null; 14625 } 14626 if (app.waitDialog != null) { 14627 app.waitDialog.dismiss(); 14628 app.waitDialog = null; 14629 } 14630 14631 app.crashing = false; 14632 app.notResponding = false; 14633 14634 app.resetPackageList(mProcessStats); 14635 app.unlinkDeathRecipient(); 14636 app.makeInactive(mProcessStats); 14637 app.waitingToKill = null; 14638 app.forcingToForeground = null; 14639 updateProcessForegroundLocked(app, false, false); 14640 app.foregroundActivities = false; 14641 app.hasShownUi = false; 14642 app.treatLikeActivity = false; 14643 app.hasAboveClient = false; 14644 app.hasClientActivities = false; 14645 14646 mServices.killServicesLocked(app, allowRestart); 14647 14648 boolean restart = false; 14649 14650 // Remove published content providers. 14651 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14652 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14653 final boolean always = app.bad || !allowRestart; 14654 if (removeDyingProviderLocked(app, cpr, always) || always) { 14655 // We left the provider in the launching list, need to 14656 // restart it. 14657 restart = true; 14658 } 14659 14660 cpr.provider = null; 14661 cpr.proc = null; 14662 } 14663 app.pubProviders.clear(); 14664 14665 // Take care of any launching providers waiting for this process. 14666 if (checkAppInLaunchingProvidersLocked(app, false)) { 14667 restart = true; 14668 } 14669 14670 // Unregister from connected content providers. 14671 if (!app.conProviders.isEmpty()) { 14672 for (int i=0; i<app.conProviders.size(); i++) { 14673 ContentProviderConnection conn = app.conProviders.get(i); 14674 conn.provider.connections.remove(conn); 14675 } 14676 app.conProviders.clear(); 14677 } 14678 14679 // At this point there may be remaining entries in mLaunchingProviders 14680 // where we were the only one waiting, so they are no longer of use. 14681 // Look for these and clean up if found. 14682 // XXX Commented out for now. Trying to figure out a way to reproduce 14683 // the actual situation to identify what is actually going on. 14684 if (false) { 14685 for (int i=0; i<mLaunchingProviders.size(); i++) { 14686 ContentProviderRecord cpr = (ContentProviderRecord) 14687 mLaunchingProviders.get(i); 14688 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14689 synchronized (cpr) { 14690 cpr.launchingApp = null; 14691 cpr.notifyAll(); 14692 } 14693 } 14694 } 14695 } 14696 14697 skipCurrentReceiverLocked(app); 14698 14699 // Unregister any receivers. 14700 for (int i=app.receivers.size()-1; i>=0; i--) { 14701 removeReceiverLocked(app.receivers.valueAt(i)); 14702 } 14703 app.receivers.clear(); 14704 14705 // If the app is undergoing backup, tell the backup manager about it 14706 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14707 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14708 + mBackupTarget.appInfo + " died during backup"); 14709 try { 14710 IBackupManager bm = IBackupManager.Stub.asInterface( 14711 ServiceManager.getService(Context.BACKUP_SERVICE)); 14712 bm.agentDisconnected(app.info.packageName); 14713 } catch (RemoteException e) { 14714 // can't happen; backup manager is local 14715 } 14716 } 14717 14718 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14719 ProcessChangeItem item = mPendingProcessChanges.get(i); 14720 if (item.pid == app.pid) { 14721 mPendingProcessChanges.remove(i); 14722 mAvailProcessChanges.add(item); 14723 } 14724 } 14725 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14726 14727 // If the caller is restarting this app, then leave it in its 14728 // current lists and let the caller take care of it. 14729 if (restarting) { 14730 return false; 14731 } 14732 14733 if (!app.persistent || app.isolated) { 14734 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14735 "Removing non-persistent process during cleanup: " + app); 14736 mProcessNames.remove(app.processName, app.uid); 14737 mIsolatedProcesses.remove(app.uid); 14738 if (mHeavyWeightProcess == app) { 14739 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14740 mHeavyWeightProcess.userId, 0)); 14741 mHeavyWeightProcess = null; 14742 } 14743 } else if (!app.removed) { 14744 // This app is persistent, so we need to keep its record around. 14745 // If it is not already on the pending app list, add it there 14746 // and start a new process for it. 14747 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14748 mPersistentStartingProcesses.add(app); 14749 restart = true; 14750 } 14751 } 14752 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14753 "Clean-up removing on hold: " + app); 14754 mProcessesOnHold.remove(app); 14755 14756 if (app == mHomeProcess) { 14757 mHomeProcess = null; 14758 } 14759 if (app == mPreviousProcess) { 14760 mPreviousProcess = null; 14761 } 14762 14763 if (restart && !app.isolated) { 14764 // We have components that still need to be running in the 14765 // process, so re-launch it. 14766 if (index < 0) { 14767 ProcessList.remove(app.pid); 14768 } 14769 mProcessNames.put(app.processName, app.uid, app); 14770 startProcessLocked(app, "restart", app.processName); 14771 return true; 14772 } else if (app.pid > 0 && app.pid != MY_PID) { 14773 // Goodbye! 14774 boolean removed; 14775 synchronized (mPidsSelfLocked) { 14776 mPidsSelfLocked.remove(app.pid); 14777 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14778 } 14779 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14780 if (app.isolated) { 14781 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14782 } 14783 app.setPid(0); 14784 } 14785 return false; 14786 } 14787 14788 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14789 // Look through the content providers we are waiting to have launched, 14790 // and if any run in this process then either schedule a restart of 14791 // the process or kill the client waiting for it if this process has 14792 // gone bad. 14793 int NL = mLaunchingProviders.size(); 14794 boolean restart = false; 14795 for (int i=0; i<NL; i++) { 14796 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14797 if (cpr.launchingApp == app) { 14798 if (!alwaysBad && !app.bad) { 14799 restart = true; 14800 } else { 14801 removeDyingProviderLocked(app, cpr, true); 14802 // cpr should have been removed from mLaunchingProviders 14803 NL = mLaunchingProviders.size(); 14804 i--; 14805 } 14806 } 14807 } 14808 return restart; 14809 } 14810 14811 // ========================================================= 14812 // SERVICES 14813 // ========================================================= 14814 14815 @Override 14816 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14817 int flags) { 14818 enforceNotIsolatedCaller("getServices"); 14819 synchronized (this) { 14820 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14821 } 14822 } 14823 14824 @Override 14825 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14826 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14827 synchronized (this) { 14828 return mServices.getRunningServiceControlPanelLocked(name); 14829 } 14830 } 14831 14832 @Override 14833 public ComponentName startService(IApplicationThread caller, Intent service, 14834 String resolvedType, int userId) { 14835 enforceNotIsolatedCaller("startService"); 14836 // Refuse possible leaked file descriptors 14837 if (service != null && service.hasFileDescriptors() == true) { 14838 throw new IllegalArgumentException("File descriptors passed in Intent"); 14839 } 14840 14841 if (DEBUG_SERVICE) 14842 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14843 synchronized(this) { 14844 final int callingPid = Binder.getCallingPid(); 14845 final int callingUid = Binder.getCallingUid(); 14846 final long origId = Binder.clearCallingIdentity(); 14847 ComponentName res = mServices.startServiceLocked(caller, service, 14848 resolvedType, callingPid, callingUid, userId); 14849 Binder.restoreCallingIdentity(origId); 14850 return res; 14851 } 14852 } 14853 14854 ComponentName startServiceInPackage(int uid, 14855 Intent service, String resolvedType, int userId) { 14856 synchronized(this) { 14857 if (DEBUG_SERVICE) 14858 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14859 final long origId = Binder.clearCallingIdentity(); 14860 ComponentName res = mServices.startServiceLocked(null, service, 14861 resolvedType, -1, uid, userId); 14862 Binder.restoreCallingIdentity(origId); 14863 return res; 14864 } 14865 } 14866 14867 @Override 14868 public int stopService(IApplicationThread caller, Intent service, 14869 String resolvedType, int userId) { 14870 enforceNotIsolatedCaller("stopService"); 14871 // Refuse possible leaked file descriptors 14872 if (service != null && service.hasFileDescriptors() == true) { 14873 throw new IllegalArgumentException("File descriptors passed in Intent"); 14874 } 14875 14876 synchronized(this) { 14877 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14878 } 14879 } 14880 14881 @Override 14882 public IBinder peekService(Intent service, String resolvedType) { 14883 enforceNotIsolatedCaller("peekService"); 14884 // Refuse possible leaked file descriptors 14885 if (service != null && service.hasFileDescriptors() == true) { 14886 throw new IllegalArgumentException("File descriptors passed in Intent"); 14887 } 14888 synchronized(this) { 14889 return mServices.peekServiceLocked(service, resolvedType); 14890 } 14891 } 14892 14893 @Override 14894 public boolean stopServiceToken(ComponentName className, IBinder token, 14895 int startId) { 14896 synchronized(this) { 14897 return mServices.stopServiceTokenLocked(className, token, startId); 14898 } 14899 } 14900 14901 @Override 14902 public void setServiceForeground(ComponentName className, IBinder token, 14903 int id, Notification notification, boolean removeNotification) { 14904 synchronized(this) { 14905 mServices.setServiceForegroundLocked(className, token, id, notification, 14906 removeNotification); 14907 } 14908 } 14909 14910 @Override 14911 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14912 boolean requireFull, String name, String callerPackage) { 14913 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14914 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14915 } 14916 14917 int unsafeConvertIncomingUser(int userId) { 14918 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14919 ? mCurrentUserId : userId; 14920 } 14921 14922 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14923 int allowMode, String name, String callerPackage) { 14924 final int callingUserId = UserHandle.getUserId(callingUid); 14925 if (callingUserId == userId) { 14926 return userId; 14927 } 14928 14929 // Note that we may be accessing mCurrentUserId outside of a lock... 14930 // shouldn't be a big deal, if this is being called outside 14931 // of a locked context there is intrinsically a race with 14932 // the value the caller will receive and someone else changing it. 14933 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14934 // we will switch to the calling user if access to the current user fails. 14935 int targetUserId = unsafeConvertIncomingUser(userId); 14936 14937 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14938 final boolean allow; 14939 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14940 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14941 // If the caller has this permission, they always pass go. And collect $200. 14942 allow = true; 14943 } else if (allowMode == ALLOW_FULL_ONLY) { 14944 // We require full access, sucks to be you. 14945 allow = false; 14946 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14947 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14948 // If the caller does not have either permission, they are always doomed. 14949 allow = false; 14950 } else if (allowMode == ALLOW_NON_FULL) { 14951 // We are blanket allowing non-full access, you lucky caller! 14952 allow = true; 14953 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14954 // We may or may not allow this depending on whether the two users are 14955 // in the same profile. 14956 synchronized (mUserProfileGroupIdsSelfLocked) { 14957 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14958 UserInfo.NO_PROFILE_GROUP_ID); 14959 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14960 UserInfo.NO_PROFILE_GROUP_ID); 14961 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14962 && callingProfile == targetProfile; 14963 } 14964 } else { 14965 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14966 } 14967 if (!allow) { 14968 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14969 // In this case, they would like to just execute as their 14970 // owner user instead of failing. 14971 targetUserId = callingUserId; 14972 } else { 14973 StringBuilder builder = new StringBuilder(128); 14974 builder.append("Permission Denial: "); 14975 builder.append(name); 14976 if (callerPackage != null) { 14977 builder.append(" from "); 14978 builder.append(callerPackage); 14979 } 14980 builder.append(" asks to run as user "); 14981 builder.append(userId); 14982 builder.append(" but is calling from user "); 14983 builder.append(UserHandle.getUserId(callingUid)); 14984 builder.append("; this requires "); 14985 builder.append(INTERACT_ACROSS_USERS_FULL); 14986 if (allowMode != ALLOW_FULL_ONLY) { 14987 builder.append(" or "); 14988 builder.append(INTERACT_ACROSS_USERS); 14989 } 14990 String msg = builder.toString(); 14991 Slog.w(TAG, msg); 14992 throw new SecurityException(msg); 14993 } 14994 } 14995 } 14996 if (!allowAll && targetUserId < 0) { 14997 throw new IllegalArgumentException( 14998 "Call does not support special user #" + targetUserId); 14999 } 15000 // Check shell permission 15001 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15002 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15003 targetUserId)) { 15004 throw new SecurityException("Shell does not have permission to access user " 15005 + targetUserId + "\n " + Debug.getCallers(3)); 15006 } 15007 } 15008 return targetUserId; 15009 } 15010 15011 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15012 String className, int flags) { 15013 boolean result = false; 15014 // For apps that don't have pre-defined UIDs, check for permission 15015 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15016 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15017 if (ActivityManager.checkUidPermission( 15018 INTERACT_ACROSS_USERS, 15019 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15020 ComponentName comp = new ComponentName(aInfo.packageName, className); 15021 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15022 + " requests FLAG_SINGLE_USER, but app does not hold " 15023 + INTERACT_ACROSS_USERS; 15024 Slog.w(TAG, msg); 15025 throw new SecurityException(msg); 15026 } 15027 // Permission passed 15028 result = true; 15029 } 15030 } else if ("system".equals(componentProcessName)) { 15031 result = true; 15032 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15033 // Phone app and persistent apps are allowed to export singleuser providers. 15034 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15035 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15036 } 15037 if (DEBUG_MU) { 15038 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15039 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15040 } 15041 return result; 15042 } 15043 15044 /** 15045 * Checks to see if the caller is in the same app as the singleton 15046 * component, or the component is in a special app. It allows special apps 15047 * to export singleton components but prevents exporting singleton 15048 * components for regular apps. 15049 */ 15050 boolean isValidSingletonCall(int callingUid, int componentUid) { 15051 int componentAppId = UserHandle.getAppId(componentUid); 15052 return UserHandle.isSameApp(callingUid, componentUid) 15053 || componentAppId == Process.SYSTEM_UID 15054 || componentAppId == Process.PHONE_UID 15055 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15056 == PackageManager.PERMISSION_GRANTED; 15057 } 15058 15059 public int bindService(IApplicationThread caller, IBinder token, 15060 Intent service, String resolvedType, 15061 IServiceConnection connection, int flags, int userId) { 15062 enforceNotIsolatedCaller("bindService"); 15063 15064 // Refuse possible leaked file descriptors 15065 if (service != null && service.hasFileDescriptors() == true) { 15066 throw new IllegalArgumentException("File descriptors passed in Intent"); 15067 } 15068 15069 synchronized(this) { 15070 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15071 connection, flags, userId); 15072 } 15073 } 15074 15075 public boolean unbindService(IServiceConnection connection) { 15076 synchronized (this) { 15077 return mServices.unbindServiceLocked(connection); 15078 } 15079 } 15080 15081 public void publishService(IBinder token, Intent intent, IBinder service) { 15082 // Refuse possible leaked file descriptors 15083 if (intent != null && intent.hasFileDescriptors() == true) { 15084 throw new IllegalArgumentException("File descriptors passed in Intent"); 15085 } 15086 15087 synchronized(this) { 15088 if (!(token instanceof ServiceRecord)) { 15089 throw new IllegalArgumentException("Invalid service token"); 15090 } 15091 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15092 } 15093 } 15094 15095 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15096 // Refuse possible leaked file descriptors 15097 if (intent != null && intent.hasFileDescriptors() == true) { 15098 throw new IllegalArgumentException("File descriptors passed in Intent"); 15099 } 15100 15101 synchronized(this) { 15102 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15103 } 15104 } 15105 15106 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15107 synchronized(this) { 15108 if (!(token instanceof ServiceRecord)) { 15109 throw new IllegalArgumentException("Invalid service token"); 15110 } 15111 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15112 } 15113 } 15114 15115 // ========================================================= 15116 // BACKUP AND RESTORE 15117 // ========================================================= 15118 15119 // Cause the target app to be launched if necessary and its backup agent 15120 // instantiated. The backup agent will invoke backupAgentCreated() on the 15121 // activity manager to announce its creation. 15122 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15123 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15124 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15125 15126 synchronized(this) { 15127 // !!! TODO: currently no check here that we're already bound 15128 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15129 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15130 synchronized (stats) { 15131 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15132 } 15133 15134 // Backup agent is now in use, its package can't be stopped. 15135 try { 15136 AppGlobals.getPackageManager().setPackageStoppedState( 15137 app.packageName, false, UserHandle.getUserId(app.uid)); 15138 } catch (RemoteException e) { 15139 } catch (IllegalArgumentException e) { 15140 Slog.w(TAG, "Failed trying to unstop package " 15141 + app.packageName + ": " + e); 15142 } 15143 15144 BackupRecord r = new BackupRecord(ss, app, backupMode); 15145 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15146 ? new ComponentName(app.packageName, app.backupAgentName) 15147 : new ComponentName("android", "FullBackupAgent"); 15148 // startProcessLocked() returns existing proc's record if it's already running 15149 ProcessRecord proc = startProcessLocked(app.processName, app, 15150 false, 0, "backup", hostingName, false, false, false); 15151 if (proc == null) { 15152 Slog.e(TAG, "Unable to start backup agent process " + r); 15153 return false; 15154 } 15155 15156 r.app = proc; 15157 mBackupTarget = r; 15158 mBackupAppName = app.packageName; 15159 15160 // Try not to kill the process during backup 15161 updateOomAdjLocked(proc); 15162 15163 // If the process is already attached, schedule the creation of the backup agent now. 15164 // If it is not yet live, this will be done when it attaches to the framework. 15165 if (proc.thread != null) { 15166 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15167 try { 15168 proc.thread.scheduleCreateBackupAgent(app, 15169 compatibilityInfoForPackageLocked(app), backupMode); 15170 } catch (RemoteException e) { 15171 // Will time out on the backup manager side 15172 } 15173 } else { 15174 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15175 } 15176 // Invariants: at this point, the target app process exists and the application 15177 // is either already running or in the process of coming up. mBackupTarget and 15178 // mBackupAppName describe the app, so that when it binds back to the AM we 15179 // know that it's scheduled for a backup-agent operation. 15180 } 15181 15182 return true; 15183 } 15184 15185 @Override 15186 public void clearPendingBackup() { 15187 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15188 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15189 15190 synchronized (this) { 15191 mBackupTarget = null; 15192 mBackupAppName = null; 15193 } 15194 } 15195 15196 // A backup agent has just come up 15197 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15198 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15199 + " = " + agent); 15200 15201 synchronized(this) { 15202 if (!agentPackageName.equals(mBackupAppName)) { 15203 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15204 return; 15205 } 15206 } 15207 15208 long oldIdent = Binder.clearCallingIdentity(); 15209 try { 15210 IBackupManager bm = IBackupManager.Stub.asInterface( 15211 ServiceManager.getService(Context.BACKUP_SERVICE)); 15212 bm.agentConnected(agentPackageName, agent); 15213 } catch (RemoteException e) { 15214 // can't happen; the backup manager service is local 15215 } catch (Exception e) { 15216 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15217 e.printStackTrace(); 15218 } finally { 15219 Binder.restoreCallingIdentity(oldIdent); 15220 } 15221 } 15222 15223 // done with this agent 15224 public void unbindBackupAgent(ApplicationInfo appInfo) { 15225 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15226 if (appInfo == null) { 15227 Slog.w(TAG, "unbind backup agent for null app"); 15228 return; 15229 } 15230 15231 synchronized(this) { 15232 try { 15233 if (mBackupAppName == null) { 15234 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15235 return; 15236 } 15237 15238 if (!mBackupAppName.equals(appInfo.packageName)) { 15239 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15240 return; 15241 } 15242 15243 // Not backing this app up any more; reset its OOM adjustment 15244 final ProcessRecord proc = mBackupTarget.app; 15245 updateOomAdjLocked(proc); 15246 15247 // If the app crashed during backup, 'thread' will be null here 15248 if (proc.thread != null) { 15249 try { 15250 proc.thread.scheduleDestroyBackupAgent(appInfo, 15251 compatibilityInfoForPackageLocked(appInfo)); 15252 } catch (Exception e) { 15253 Slog.e(TAG, "Exception when unbinding backup agent:"); 15254 e.printStackTrace(); 15255 } 15256 } 15257 } finally { 15258 mBackupTarget = null; 15259 mBackupAppName = null; 15260 } 15261 } 15262 } 15263 // ========================================================= 15264 // BROADCASTS 15265 // ========================================================= 15266 15267 private final List getStickiesLocked(String action, IntentFilter filter, 15268 List cur, int userId) { 15269 final ContentResolver resolver = mContext.getContentResolver(); 15270 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15271 if (stickies == null) { 15272 return cur; 15273 } 15274 final ArrayList<Intent> list = stickies.get(action); 15275 if (list == null) { 15276 return cur; 15277 } 15278 int N = list.size(); 15279 for (int i=0; i<N; i++) { 15280 Intent intent = list.get(i); 15281 if (filter.match(resolver, intent, true, TAG) >= 0) { 15282 if (cur == null) { 15283 cur = new ArrayList<Intent>(); 15284 } 15285 cur.add(intent); 15286 } 15287 } 15288 return cur; 15289 } 15290 15291 boolean isPendingBroadcastProcessLocked(int pid) { 15292 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15293 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15294 } 15295 15296 void skipPendingBroadcastLocked(int pid) { 15297 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15298 for (BroadcastQueue queue : mBroadcastQueues) { 15299 queue.skipPendingBroadcastLocked(pid); 15300 } 15301 } 15302 15303 // The app just attached; send any pending broadcasts that it should receive 15304 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15305 boolean didSomething = false; 15306 for (BroadcastQueue queue : mBroadcastQueues) { 15307 didSomething |= queue.sendPendingBroadcastsLocked(app); 15308 } 15309 return didSomething; 15310 } 15311 15312 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15313 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15314 enforceNotIsolatedCaller("registerReceiver"); 15315 int callingUid; 15316 int callingPid; 15317 synchronized(this) { 15318 ProcessRecord callerApp = null; 15319 if (caller != null) { 15320 callerApp = getRecordForAppLocked(caller); 15321 if (callerApp == null) { 15322 throw new SecurityException( 15323 "Unable to find app for caller " + caller 15324 + " (pid=" + Binder.getCallingPid() 15325 + ") when registering receiver " + receiver); 15326 } 15327 if (callerApp.info.uid != Process.SYSTEM_UID && 15328 !callerApp.pkgList.containsKey(callerPackage) && 15329 !"android".equals(callerPackage)) { 15330 throw new SecurityException("Given caller package " + callerPackage 15331 + " is not running in process " + callerApp); 15332 } 15333 callingUid = callerApp.info.uid; 15334 callingPid = callerApp.pid; 15335 } else { 15336 callerPackage = null; 15337 callingUid = Binder.getCallingUid(); 15338 callingPid = Binder.getCallingPid(); 15339 } 15340 15341 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15342 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15343 15344 List allSticky = null; 15345 15346 // Look for any matching sticky broadcasts... 15347 Iterator actions = filter.actionsIterator(); 15348 if (actions != null) { 15349 while (actions.hasNext()) { 15350 String action = (String)actions.next(); 15351 allSticky = getStickiesLocked(action, filter, allSticky, 15352 UserHandle.USER_ALL); 15353 allSticky = getStickiesLocked(action, filter, allSticky, 15354 UserHandle.getUserId(callingUid)); 15355 } 15356 } else { 15357 allSticky = getStickiesLocked(null, filter, allSticky, 15358 UserHandle.USER_ALL); 15359 allSticky = getStickiesLocked(null, filter, allSticky, 15360 UserHandle.getUserId(callingUid)); 15361 } 15362 15363 // The first sticky in the list is returned directly back to 15364 // the client. 15365 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15366 15367 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15368 + ": " + sticky); 15369 15370 if (receiver == null) { 15371 return sticky; 15372 } 15373 15374 ReceiverList rl 15375 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15376 if (rl == null) { 15377 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15378 userId, receiver); 15379 if (rl.app != null) { 15380 rl.app.receivers.add(rl); 15381 } else { 15382 try { 15383 receiver.asBinder().linkToDeath(rl, 0); 15384 } catch (RemoteException e) { 15385 return sticky; 15386 } 15387 rl.linkedToDeath = true; 15388 } 15389 mRegisteredReceivers.put(receiver.asBinder(), rl); 15390 } else if (rl.uid != callingUid) { 15391 throw new IllegalArgumentException( 15392 "Receiver requested to register for uid " + callingUid 15393 + " was previously registered for uid " + rl.uid); 15394 } else if (rl.pid != callingPid) { 15395 throw new IllegalArgumentException( 15396 "Receiver requested to register for pid " + callingPid 15397 + " was previously registered for pid " + rl.pid); 15398 } else if (rl.userId != userId) { 15399 throw new IllegalArgumentException( 15400 "Receiver requested to register for user " + userId 15401 + " was previously registered for user " + rl.userId); 15402 } 15403 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15404 permission, callingUid, userId); 15405 rl.add(bf); 15406 if (!bf.debugCheck()) { 15407 Slog.w(TAG, "==> For Dynamic broadast"); 15408 } 15409 mReceiverResolver.addFilter(bf); 15410 15411 // Enqueue broadcasts for all existing stickies that match 15412 // this filter. 15413 if (allSticky != null) { 15414 ArrayList receivers = new ArrayList(); 15415 receivers.add(bf); 15416 15417 int N = allSticky.size(); 15418 for (int i=0; i<N; i++) { 15419 Intent intent = (Intent)allSticky.get(i); 15420 BroadcastQueue queue = broadcastQueueForIntent(intent); 15421 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15422 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15423 null, null, false, true, true, -1); 15424 queue.enqueueParallelBroadcastLocked(r); 15425 queue.scheduleBroadcastsLocked(); 15426 } 15427 } 15428 15429 return sticky; 15430 } 15431 } 15432 15433 public void unregisterReceiver(IIntentReceiver receiver) { 15434 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15435 15436 final long origId = Binder.clearCallingIdentity(); 15437 try { 15438 boolean doTrim = false; 15439 15440 synchronized(this) { 15441 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15442 if (rl != null) { 15443 if (rl.curBroadcast != null) { 15444 BroadcastRecord r = rl.curBroadcast; 15445 final boolean doNext = finishReceiverLocked( 15446 receiver.asBinder(), r.resultCode, r.resultData, 15447 r.resultExtras, r.resultAbort); 15448 if (doNext) { 15449 doTrim = true; 15450 r.queue.processNextBroadcast(false); 15451 } 15452 } 15453 15454 if (rl.app != null) { 15455 rl.app.receivers.remove(rl); 15456 } 15457 removeReceiverLocked(rl); 15458 if (rl.linkedToDeath) { 15459 rl.linkedToDeath = false; 15460 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15461 } 15462 } 15463 } 15464 15465 // If we actually concluded any broadcasts, we might now be able 15466 // to trim the recipients' apps from our working set 15467 if (doTrim) { 15468 trimApplications(); 15469 return; 15470 } 15471 15472 } finally { 15473 Binder.restoreCallingIdentity(origId); 15474 } 15475 } 15476 15477 void removeReceiverLocked(ReceiverList rl) { 15478 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15479 int N = rl.size(); 15480 for (int i=0; i<N; i++) { 15481 mReceiverResolver.removeFilter(rl.get(i)); 15482 } 15483 } 15484 15485 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15486 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15487 ProcessRecord r = mLruProcesses.get(i); 15488 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15489 try { 15490 r.thread.dispatchPackageBroadcast(cmd, packages); 15491 } catch (RemoteException ex) { 15492 } 15493 } 15494 } 15495 } 15496 15497 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15498 int callingUid, int[] users) { 15499 List<ResolveInfo> receivers = null; 15500 try { 15501 HashSet<ComponentName> singleUserReceivers = null; 15502 boolean scannedFirstReceivers = false; 15503 for (int user : users) { 15504 // Skip users that have Shell restrictions 15505 if (callingUid == Process.SHELL_UID 15506 && getUserManagerLocked().hasUserRestriction( 15507 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15508 continue; 15509 } 15510 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15511 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15512 if (user != 0 && newReceivers != null) { 15513 // If this is not the primary user, we need to check for 15514 // any receivers that should be filtered out. 15515 for (int i=0; i<newReceivers.size(); i++) { 15516 ResolveInfo ri = newReceivers.get(i); 15517 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15518 newReceivers.remove(i); 15519 i--; 15520 } 15521 } 15522 } 15523 if (newReceivers != null && newReceivers.size() == 0) { 15524 newReceivers = null; 15525 } 15526 if (receivers == null) { 15527 receivers = newReceivers; 15528 } else if (newReceivers != null) { 15529 // We need to concatenate the additional receivers 15530 // found with what we have do far. This would be easy, 15531 // but we also need to de-dup any receivers that are 15532 // singleUser. 15533 if (!scannedFirstReceivers) { 15534 // Collect any single user receivers we had already retrieved. 15535 scannedFirstReceivers = true; 15536 for (int i=0; i<receivers.size(); i++) { 15537 ResolveInfo ri = receivers.get(i); 15538 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15539 ComponentName cn = new ComponentName( 15540 ri.activityInfo.packageName, ri.activityInfo.name); 15541 if (singleUserReceivers == null) { 15542 singleUserReceivers = new HashSet<ComponentName>(); 15543 } 15544 singleUserReceivers.add(cn); 15545 } 15546 } 15547 } 15548 // Add the new results to the existing results, tracking 15549 // and de-dupping single user receivers. 15550 for (int i=0; i<newReceivers.size(); i++) { 15551 ResolveInfo ri = newReceivers.get(i); 15552 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15553 ComponentName cn = new ComponentName( 15554 ri.activityInfo.packageName, ri.activityInfo.name); 15555 if (singleUserReceivers == null) { 15556 singleUserReceivers = new HashSet<ComponentName>(); 15557 } 15558 if (!singleUserReceivers.contains(cn)) { 15559 singleUserReceivers.add(cn); 15560 receivers.add(ri); 15561 } 15562 } else { 15563 receivers.add(ri); 15564 } 15565 } 15566 } 15567 } 15568 } catch (RemoteException ex) { 15569 // pm is in same process, this will never happen. 15570 } 15571 return receivers; 15572 } 15573 15574 private final int broadcastIntentLocked(ProcessRecord callerApp, 15575 String callerPackage, Intent intent, String resolvedType, 15576 IIntentReceiver resultTo, int resultCode, String resultData, 15577 Bundle map, String requiredPermission, int appOp, 15578 boolean ordered, boolean sticky, int callingPid, int callingUid, 15579 int userId) { 15580 intent = new Intent(intent); 15581 15582 // By default broadcasts do not go to stopped apps. 15583 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15584 15585 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15586 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15587 + " ordered=" + ordered + " userid=" + userId); 15588 if ((resultTo != null) && !ordered) { 15589 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15590 } 15591 15592 userId = handleIncomingUser(callingPid, callingUid, userId, 15593 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15594 15595 // Make sure that the user who is receiving this broadcast is started. 15596 // If not, we will just skip it. 15597 15598 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15599 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15600 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15601 Slog.w(TAG, "Skipping broadcast of " + intent 15602 + ": user " + userId + " is stopped"); 15603 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15604 } 15605 } 15606 15607 /* 15608 * Prevent non-system code (defined here to be non-persistent 15609 * processes) from sending protected broadcasts. 15610 */ 15611 int callingAppId = UserHandle.getAppId(callingUid); 15612 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15613 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15614 || callingAppId == Process.NFC_UID || callingUid == 0) { 15615 // Always okay. 15616 } else if (callerApp == null || !callerApp.persistent) { 15617 try { 15618 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15619 intent.getAction())) { 15620 String msg = "Permission Denial: not allowed to send broadcast " 15621 + intent.getAction() + " from pid=" 15622 + callingPid + ", uid=" + callingUid; 15623 Slog.w(TAG, msg); 15624 throw new SecurityException(msg); 15625 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15626 // Special case for compatibility: we don't want apps to send this, 15627 // but historically it has not been protected and apps may be using it 15628 // to poke their own app widget. So, instead of making it protected, 15629 // just limit it to the caller. 15630 if (callerApp == null) { 15631 String msg = "Permission Denial: not allowed to send broadcast " 15632 + intent.getAction() + " from unknown caller."; 15633 Slog.w(TAG, msg); 15634 throw new SecurityException(msg); 15635 } else if (intent.getComponent() != null) { 15636 // They are good enough to send to an explicit component... verify 15637 // it is being sent to the calling app. 15638 if (!intent.getComponent().getPackageName().equals( 15639 callerApp.info.packageName)) { 15640 String msg = "Permission Denial: not allowed to send broadcast " 15641 + intent.getAction() + " to " 15642 + intent.getComponent().getPackageName() + " from " 15643 + callerApp.info.packageName; 15644 Slog.w(TAG, msg); 15645 throw new SecurityException(msg); 15646 } 15647 } else { 15648 // Limit broadcast to their own package. 15649 intent.setPackage(callerApp.info.packageName); 15650 } 15651 } 15652 } catch (RemoteException e) { 15653 Slog.w(TAG, "Remote exception", e); 15654 return ActivityManager.BROADCAST_SUCCESS; 15655 } 15656 } 15657 15658 final String action = intent.getAction(); 15659 if (action != null) { 15660 switch (action) { 15661 case Intent.ACTION_UID_REMOVED: 15662 case Intent.ACTION_PACKAGE_REMOVED: 15663 case Intent.ACTION_PACKAGE_CHANGED: 15664 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15665 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15666 // Handle special intents: if this broadcast is from the package 15667 // manager about a package being removed, we need to remove all of 15668 // its activities from the history stack. 15669 if (checkComponentPermission( 15670 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15671 callingPid, callingUid, -1, true) 15672 != PackageManager.PERMISSION_GRANTED) { 15673 String msg = "Permission Denial: " + intent.getAction() 15674 + " broadcast from " + callerPackage + " (pid=" + callingPid 15675 + ", uid=" + callingUid + ")" 15676 + " requires " 15677 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15678 Slog.w(TAG, msg); 15679 throw new SecurityException(msg); 15680 } 15681 switch (action) { 15682 case Intent.ACTION_UID_REMOVED: 15683 final Bundle intentExtras = intent.getExtras(); 15684 final int uid = intentExtras != null 15685 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15686 if (uid >= 0) { 15687 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15688 synchronized (bs) { 15689 bs.removeUidStatsLocked(uid); 15690 } 15691 mAppOpsService.uidRemoved(uid); 15692 } 15693 break; 15694 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15695 // If resources are unavailable just force stop all those packages 15696 // and flush the attribute cache as well. 15697 String list[] = 15698 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15699 if (list != null && list.length > 0) { 15700 for (int i = 0; i < list.length; i++) { 15701 forceStopPackageLocked(list[i], -1, false, true, true, 15702 false, false, userId, "storage unmount"); 15703 } 15704 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15705 sendPackageBroadcastLocked( 15706 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15707 userId); 15708 } 15709 break; 15710 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15711 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15712 break; 15713 case Intent.ACTION_PACKAGE_REMOVED: 15714 case Intent.ACTION_PACKAGE_CHANGED: 15715 Uri data = intent.getData(); 15716 String ssp; 15717 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15718 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15719 boolean fullUninstall = removed && 15720 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15721 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15722 forceStopPackageLocked(ssp, UserHandle.getAppId( 15723 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15724 false, true, true, false, fullUninstall, userId, 15725 removed ? "pkg removed" : "pkg changed"); 15726 } 15727 if (removed) { 15728 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15729 new String[] {ssp}, userId); 15730 if (fullUninstall) { 15731 mAppOpsService.packageRemoved( 15732 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15733 15734 // Remove all permissions granted from/to this package 15735 removeUriPermissionsForPackageLocked(ssp, userId, true); 15736 15737 removeTasksByPackageNameLocked(ssp, userId); 15738 } 15739 } else { 15740 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15741 } 15742 } 15743 break; 15744 } 15745 break; 15746 case Intent.ACTION_PACKAGE_ADDED: 15747 // Special case for adding a package: by default turn on compatibility mode. 15748 Uri data = intent.getData(); 15749 String ssp; 15750 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15751 final boolean replacing = 15752 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15753 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15754 15755 if (replacing) { 15756 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15757 } 15758 } 15759 break; 15760 case Intent.ACTION_TIMEZONE_CHANGED: 15761 // If this is the time zone changed action, queue up a message that will reset 15762 // the timezone of all currently running processes. This message will get 15763 // queued up before the broadcast happens. 15764 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15765 break; 15766 case Intent.ACTION_TIME_CHANGED: 15767 // If the user set the time, let all running processes know. 15768 final int is24Hour = 15769 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15770 : 0; 15771 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15772 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15773 synchronized (stats) { 15774 stats.noteCurrentTimeChangedLocked(); 15775 } 15776 break; 15777 case Intent.ACTION_CLEAR_DNS_CACHE: 15778 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15779 break; 15780 case Proxy.PROXY_CHANGE_ACTION: 15781 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15782 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15783 break; 15784 } 15785 } 15786 15787 // Add to the sticky list if requested. 15788 if (sticky) { 15789 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15790 callingPid, callingUid) 15791 != PackageManager.PERMISSION_GRANTED) { 15792 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15793 + callingPid + ", uid=" + callingUid 15794 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15795 Slog.w(TAG, msg); 15796 throw new SecurityException(msg); 15797 } 15798 if (requiredPermission != null) { 15799 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15800 + " and enforce permission " + requiredPermission); 15801 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15802 } 15803 if (intent.getComponent() != null) { 15804 throw new SecurityException( 15805 "Sticky broadcasts can't target a specific component"); 15806 } 15807 // We use userId directly here, since the "all" target is maintained 15808 // as a separate set of sticky broadcasts. 15809 if (userId != UserHandle.USER_ALL) { 15810 // But first, if this is not a broadcast to all users, then 15811 // make sure it doesn't conflict with an existing broadcast to 15812 // all users. 15813 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15814 UserHandle.USER_ALL); 15815 if (stickies != null) { 15816 ArrayList<Intent> list = stickies.get(intent.getAction()); 15817 if (list != null) { 15818 int N = list.size(); 15819 int i; 15820 for (i=0; i<N; i++) { 15821 if (intent.filterEquals(list.get(i))) { 15822 throw new IllegalArgumentException( 15823 "Sticky broadcast " + intent + " for user " 15824 + userId + " conflicts with existing global broadcast"); 15825 } 15826 } 15827 } 15828 } 15829 } 15830 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15831 if (stickies == null) { 15832 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15833 mStickyBroadcasts.put(userId, stickies); 15834 } 15835 ArrayList<Intent> list = stickies.get(intent.getAction()); 15836 if (list == null) { 15837 list = new ArrayList<Intent>(); 15838 stickies.put(intent.getAction(), list); 15839 } 15840 int N = list.size(); 15841 int i; 15842 for (i=0; i<N; i++) { 15843 if (intent.filterEquals(list.get(i))) { 15844 // This sticky already exists, replace it. 15845 list.set(i, new Intent(intent)); 15846 break; 15847 } 15848 } 15849 if (i >= N) { 15850 list.add(new Intent(intent)); 15851 } 15852 } 15853 15854 int[] users; 15855 if (userId == UserHandle.USER_ALL) { 15856 // Caller wants broadcast to go to all started users. 15857 users = mStartedUserArray; 15858 } else { 15859 // Caller wants broadcast to go to one specific user. 15860 users = new int[] {userId}; 15861 } 15862 15863 // Figure out who all will receive this broadcast. 15864 List receivers = null; 15865 List<BroadcastFilter> registeredReceivers = null; 15866 // Need to resolve the intent to interested receivers... 15867 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15868 == 0) { 15869 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15870 } 15871 if (intent.getComponent() == null) { 15872 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15873 // Query one target user at a time, excluding shell-restricted users 15874 UserManagerService ums = getUserManagerLocked(); 15875 for (int i = 0; i < users.length; i++) { 15876 if (ums.hasUserRestriction( 15877 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15878 continue; 15879 } 15880 List<BroadcastFilter> registeredReceiversForUser = 15881 mReceiverResolver.queryIntent(intent, 15882 resolvedType, false, users[i]); 15883 if (registeredReceivers == null) { 15884 registeredReceivers = registeredReceiversForUser; 15885 } else if (registeredReceiversForUser != null) { 15886 registeredReceivers.addAll(registeredReceiversForUser); 15887 } 15888 } 15889 } else { 15890 registeredReceivers = mReceiverResolver.queryIntent(intent, 15891 resolvedType, false, userId); 15892 } 15893 } 15894 15895 final boolean replacePending = 15896 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15897 15898 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15899 + " replacePending=" + replacePending); 15900 15901 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15902 if (!ordered && NR > 0) { 15903 // If we are not serializing this broadcast, then send the 15904 // registered receivers separately so they don't wait for the 15905 // components to be launched. 15906 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15907 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15908 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15909 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15910 ordered, sticky, false, userId); 15911 if (DEBUG_BROADCAST) Slog.v( 15912 TAG, "Enqueueing parallel broadcast " + r); 15913 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15914 if (!replaced) { 15915 queue.enqueueParallelBroadcastLocked(r); 15916 queue.scheduleBroadcastsLocked(); 15917 } 15918 registeredReceivers = null; 15919 NR = 0; 15920 } 15921 15922 // Merge into one list. 15923 int ir = 0; 15924 if (receivers != null) { 15925 // A special case for PACKAGE_ADDED: do not allow the package 15926 // being added to see this broadcast. This prevents them from 15927 // using this as a back door to get run as soon as they are 15928 // installed. Maybe in the future we want to have a special install 15929 // broadcast or such for apps, but we'd like to deliberately make 15930 // this decision. 15931 String skipPackages[] = null; 15932 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15933 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15934 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15935 Uri data = intent.getData(); 15936 if (data != null) { 15937 String pkgName = data.getSchemeSpecificPart(); 15938 if (pkgName != null) { 15939 skipPackages = new String[] { pkgName }; 15940 } 15941 } 15942 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15943 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15944 } 15945 if (skipPackages != null && (skipPackages.length > 0)) { 15946 for (String skipPackage : skipPackages) { 15947 if (skipPackage != null) { 15948 int NT = receivers.size(); 15949 for (int it=0; it<NT; it++) { 15950 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15951 if (curt.activityInfo.packageName.equals(skipPackage)) { 15952 receivers.remove(it); 15953 it--; 15954 NT--; 15955 } 15956 } 15957 } 15958 } 15959 } 15960 15961 int NT = receivers != null ? receivers.size() : 0; 15962 int it = 0; 15963 ResolveInfo curt = null; 15964 BroadcastFilter curr = null; 15965 while (it < NT && ir < NR) { 15966 if (curt == null) { 15967 curt = (ResolveInfo)receivers.get(it); 15968 } 15969 if (curr == null) { 15970 curr = registeredReceivers.get(ir); 15971 } 15972 if (curr.getPriority() >= curt.priority) { 15973 // Insert this broadcast record into the final list. 15974 receivers.add(it, curr); 15975 ir++; 15976 curr = null; 15977 it++; 15978 NT++; 15979 } else { 15980 // Skip to the next ResolveInfo in the final list. 15981 it++; 15982 curt = null; 15983 } 15984 } 15985 } 15986 while (ir < NR) { 15987 if (receivers == null) { 15988 receivers = new ArrayList(); 15989 } 15990 receivers.add(registeredReceivers.get(ir)); 15991 ir++; 15992 } 15993 15994 if ((receivers != null && receivers.size() > 0) 15995 || resultTo != null) { 15996 BroadcastQueue queue = broadcastQueueForIntent(intent); 15997 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15998 callerPackage, callingPid, callingUid, resolvedType, 15999 requiredPermission, appOp, receivers, resultTo, resultCode, 16000 resultData, map, ordered, sticky, false, userId); 16001 if (DEBUG_BROADCAST) Slog.v( 16002 TAG, "Enqueueing ordered broadcast " + r 16003 + ": prev had " + queue.mOrderedBroadcasts.size()); 16004 if (DEBUG_BROADCAST) { 16005 int seq = r.intent.getIntExtra("seq", -1); 16006 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16007 } 16008 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16009 if (!replaced) { 16010 queue.enqueueOrderedBroadcastLocked(r); 16011 queue.scheduleBroadcastsLocked(); 16012 } 16013 } 16014 16015 return ActivityManager.BROADCAST_SUCCESS; 16016 } 16017 16018 final Intent verifyBroadcastLocked(Intent intent) { 16019 // Refuse possible leaked file descriptors 16020 if (intent != null && intent.hasFileDescriptors() == true) { 16021 throw new IllegalArgumentException("File descriptors passed in Intent"); 16022 } 16023 16024 int flags = intent.getFlags(); 16025 16026 if (!mProcessesReady) { 16027 // if the caller really truly claims to know what they're doing, go 16028 // ahead and allow the broadcast without launching any receivers 16029 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16030 intent = new Intent(intent); 16031 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16032 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16033 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16034 + " before boot completion"); 16035 throw new IllegalStateException("Cannot broadcast before boot completed"); 16036 } 16037 } 16038 16039 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16040 throw new IllegalArgumentException( 16041 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16042 } 16043 16044 return intent; 16045 } 16046 16047 public final int broadcastIntent(IApplicationThread caller, 16048 Intent intent, String resolvedType, IIntentReceiver resultTo, 16049 int resultCode, String resultData, Bundle map, 16050 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16051 enforceNotIsolatedCaller("broadcastIntent"); 16052 synchronized(this) { 16053 intent = verifyBroadcastLocked(intent); 16054 16055 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16056 final int callingPid = Binder.getCallingPid(); 16057 final int callingUid = Binder.getCallingUid(); 16058 final long origId = Binder.clearCallingIdentity(); 16059 int res = broadcastIntentLocked(callerApp, 16060 callerApp != null ? callerApp.info.packageName : null, 16061 intent, resolvedType, resultTo, 16062 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16063 callingPid, callingUid, userId); 16064 Binder.restoreCallingIdentity(origId); 16065 return res; 16066 } 16067 } 16068 16069 int broadcastIntentInPackage(String packageName, int uid, 16070 Intent intent, String resolvedType, IIntentReceiver resultTo, 16071 int resultCode, String resultData, Bundle map, 16072 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16073 synchronized(this) { 16074 intent = verifyBroadcastLocked(intent); 16075 16076 final long origId = Binder.clearCallingIdentity(); 16077 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16078 resultTo, resultCode, resultData, map, requiredPermission, 16079 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16080 Binder.restoreCallingIdentity(origId); 16081 return res; 16082 } 16083 } 16084 16085 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16086 // Refuse possible leaked file descriptors 16087 if (intent != null && intent.hasFileDescriptors() == true) { 16088 throw new IllegalArgumentException("File descriptors passed in Intent"); 16089 } 16090 16091 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16092 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16093 16094 synchronized(this) { 16095 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16096 != PackageManager.PERMISSION_GRANTED) { 16097 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16098 + Binder.getCallingPid() 16099 + ", uid=" + Binder.getCallingUid() 16100 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16101 Slog.w(TAG, msg); 16102 throw new SecurityException(msg); 16103 } 16104 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16105 if (stickies != null) { 16106 ArrayList<Intent> list = stickies.get(intent.getAction()); 16107 if (list != null) { 16108 int N = list.size(); 16109 int i; 16110 for (i=0; i<N; i++) { 16111 if (intent.filterEquals(list.get(i))) { 16112 list.remove(i); 16113 break; 16114 } 16115 } 16116 if (list.size() <= 0) { 16117 stickies.remove(intent.getAction()); 16118 } 16119 } 16120 if (stickies.size() <= 0) { 16121 mStickyBroadcasts.remove(userId); 16122 } 16123 } 16124 } 16125 } 16126 16127 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16128 String resultData, Bundle resultExtras, boolean resultAbort) { 16129 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16130 if (r == null) { 16131 Slog.w(TAG, "finishReceiver called but not found on queue"); 16132 return false; 16133 } 16134 16135 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16136 } 16137 16138 void backgroundServicesFinishedLocked(int userId) { 16139 for (BroadcastQueue queue : mBroadcastQueues) { 16140 queue.backgroundServicesFinishedLocked(userId); 16141 } 16142 } 16143 16144 public void finishReceiver(IBinder who, int resultCode, String resultData, 16145 Bundle resultExtras, boolean resultAbort) { 16146 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16147 16148 // Refuse possible leaked file descriptors 16149 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16150 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16151 } 16152 16153 final long origId = Binder.clearCallingIdentity(); 16154 try { 16155 boolean doNext = false; 16156 BroadcastRecord r; 16157 16158 synchronized(this) { 16159 r = broadcastRecordForReceiverLocked(who); 16160 if (r != null) { 16161 doNext = r.queue.finishReceiverLocked(r, resultCode, 16162 resultData, resultExtras, resultAbort, true); 16163 } 16164 } 16165 16166 if (doNext) { 16167 r.queue.processNextBroadcast(false); 16168 } 16169 trimApplications(); 16170 } finally { 16171 Binder.restoreCallingIdentity(origId); 16172 } 16173 } 16174 16175 // ========================================================= 16176 // INSTRUMENTATION 16177 // ========================================================= 16178 16179 public boolean startInstrumentation(ComponentName className, 16180 String profileFile, int flags, Bundle arguments, 16181 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16182 int userId, String abiOverride) { 16183 enforceNotIsolatedCaller("startInstrumentation"); 16184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16185 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16186 // Refuse possible leaked file descriptors 16187 if (arguments != null && arguments.hasFileDescriptors()) { 16188 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16189 } 16190 16191 synchronized(this) { 16192 InstrumentationInfo ii = null; 16193 ApplicationInfo ai = null; 16194 try { 16195 ii = mContext.getPackageManager().getInstrumentationInfo( 16196 className, STOCK_PM_FLAGS); 16197 ai = AppGlobals.getPackageManager().getApplicationInfo( 16198 ii.targetPackage, STOCK_PM_FLAGS, userId); 16199 } catch (PackageManager.NameNotFoundException e) { 16200 } catch (RemoteException e) { 16201 } 16202 if (ii == null) { 16203 reportStartInstrumentationFailure(watcher, className, 16204 "Unable to find instrumentation info for: " + className); 16205 return false; 16206 } 16207 if (ai == null) { 16208 reportStartInstrumentationFailure(watcher, className, 16209 "Unable to find instrumentation target package: " + ii.targetPackage); 16210 return false; 16211 } 16212 16213 int match = mContext.getPackageManager().checkSignatures( 16214 ii.targetPackage, ii.packageName); 16215 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16216 String msg = "Permission Denial: starting instrumentation " 16217 + className + " from pid=" 16218 + Binder.getCallingPid() 16219 + ", uid=" + Binder.getCallingPid() 16220 + " not allowed because package " + ii.packageName 16221 + " does not have a signature matching the target " 16222 + ii.targetPackage; 16223 reportStartInstrumentationFailure(watcher, className, msg); 16224 throw new SecurityException(msg); 16225 } 16226 16227 final long origId = Binder.clearCallingIdentity(); 16228 // Instrumentation can kill and relaunch even persistent processes 16229 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16230 "start instr"); 16231 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16232 app.instrumentationClass = className; 16233 app.instrumentationInfo = ai; 16234 app.instrumentationProfileFile = profileFile; 16235 app.instrumentationArguments = arguments; 16236 app.instrumentationWatcher = watcher; 16237 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16238 app.instrumentationResultClass = className; 16239 Binder.restoreCallingIdentity(origId); 16240 } 16241 16242 return true; 16243 } 16244 16245 /** 16246 * Report errors that occur while attempting to start Instrumentation. Always writes the 16247 * error to the logs, but if somebody is watching, send the report there too. This enables 16248 * the "am" command to report errors with more information. 16249 * 16250 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16251 * @param cn The component name of the instrumentation. 16252 * @param report The error report. 16253 */ 16254 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16255 ComponentName cn, String report) { 16256 Slog.w(TAG, report); 16257 try { 16258 if (watcher != null) { 16259 Bundle results = new Bundle(); 16260 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16261 results.putString("Error", report); 16262 watcher.instrumentationStatus(cn, -1, results); 16263 } 16264 } catch (RemoteException e) { 16265 Slog.w(TAG, e); 16266 } 16267 } 16268 16269 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16270 if (app.instrumentationWatcher != null) { 16271 try { 16272 // NOTE: IInstrumentationWatcher *must* be oneway here 16273 app.instrumentationWatcher.instrumentationFinished( 16274 app.instrumentationClass, 16275 resultCode, 16276 results); 16277 } catch (RemoteException e) { 16278 } 16279 } 16280 if (app.instrumentationUiAutomationConnection != null) { 16281 try { 16282 app.instrumentationUiAutomationConnection.shutdown(); 16283 } catch (RemoteException re) { 16284 /* ignore */ 16285 } 16286 // Only a UiAutomation can set this flag and now that 16287 // it is finished we make sure it is reset to its default. 16288 mUserIsMonkey = false; 16289 } 16290 app.instrumentationWatcher = null; 16291 app.instrumentationUiAutomationConnection = null; 16292 app.instrumentationClass = null; 16293 app.instrumentationInfo = null; 16294 app.instrumentationProfileFile = null; 16295 app.instrumentationArguments = null; 16296 16297 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16298 "finished inst"); 16299 } 16300 16301 public void finishInstrumentation(IApplicationThread target, 16302 int resultCode, Bundle results) { 16303 int userId = UserHandle.getCallingUserId(); 16304 // Refuse possible leaked file descriptors 16305 if (results != null && results.hasFileDescriptors()) { 16306 throw new IllegalArgumentException("File descriptors passed in Intent"); 16307 } 16308 16309 synchronized(this) { 16310 ProcessRecord app = getRecordForAppLocked(target); 16311 if (app == null) { 16312 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16313 return; 16314 } 16315 final long origId = Binder.clearCallingIdentity(); 16316 finishInstrumentationLocked(app, resultCode, results); 16317 Binder.restoreCallingIdentity(origId); 16318 } 16319 } 16320 16321 // ========================================================= 16322 // CONFIGURATION 16323 // ========================================================= 16324 16325 public ConfigurationInfo getDeviceConfigurationInfo() { 16326 ConfigurationInfo config = new ConfigurationInfo(); 16327 synchronized (this) { 16328 config.reqTouchScreen = mConfiguration.touchscreen; 16329 config.reqKeyboardType = mConfiguration.keyboard; 16330 config.reqNavigation = mConfiguration.navigation; 16331 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16332 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16333 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16334 } 16335 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16336 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16337 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16338 } 16339 config.reqGlEsVersion = GL_ES_VERSION; 16340 } 16341 return config; 16342 } 16343 16344 ActivityStack getFocusedStack() { 16345 return mStackSupervisor.getFocusedStack(); 16346 } 16347 16348 public Configuration getConfiguration() { 16349 Configuration ci; 16350 synchronized(this) { 16351 ci = new Configuration(mConfiguration); 16352 } 16353 return ci; 16354 } 16355 16356 public void updatePersistentConfiguration(Configuration values) { 16357 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16358 "updateConfiguration()"); 16359 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16360 "updateConfiguration()"); 16361 if (values == null) { 16362 throw new NullPointerException("Configuration must not be null"); 16363 } 16364 16365 synchronized(this) { 16366 final long origId = Binder.clearCallingIdentity(); 16367 updateConfigurationLocked(values, null, true, false); 16368 Binder.restoreCallingIdentity(origId); 16369 } 16370 } 16371 16372 public void updateConfiguration(Configuration values) { 16373 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16374 "updateConfiguration()"); 16375 16376 synchronized(this) { 16377 if (values == null && mWindowManager != null) { 16378 // sentinel: fetch the current configuration from the window manager 16379 values = mWindowManager.computeNewConfiguration(); 16380 } 16381 16382 if (mWindowManager != null) { 16383 mProcessList.applyDisplaySize(mWindowManager); 16384 } 16385 16386 final long origId = Binder.clearCallingIdentity(); 16387 if (values != null) { 16388 Settings.System.clearConfiguration(values); 16389 } 16390 updateConfigurationLocked(values, null, false, false); 16391 Binder.restoreCallingIdentity(origId); 16392 } 16393 } 16394 16395 /** 16396 * Do either or both things: (1) change the current configuration, and (2) 16397 * make sure the given activity is running with the (now) current 16398 * configuration. Returns true if the activity has been left running, or 16399 * false if <var>starting</var> is being destroyed to match the new 16400 * configuration. 16401 * @param persistent TODO 16402 */ 16403 boolean updateConfigurationLocked(Configuration values, 16404 ActivityRecord starting, boolean persistent, boolean initLocale) { 16405 int changes = 0; 16406 16407 if (values != null) { 16408 Configuration newConfig = new Configuration(mConfiguration); 16409 changes = newConfig.updateFrom(values); 16410 if (changes != 0) { 16411 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16412 Slog.i(TAG, "Updating configuration to: " + values); 16413 } 16414 16415 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16416 16417 if (values.locale != null && !initLocale) { 16418 saveLocaleLocked(values.locale, 16419 !values.locale.equals(mConfiguration.locale), 16420 values.userSetLocale); 16421 } 16422 16423 mConfigurationSeq++; 16424 if (mConfigurationSeq <= 0) { 16425 mConfigurationSeq = 1; 16426 } 16427 newConfig.seq = mConfigurationSeq; 16428 mConfiguration = newConfig; 16429 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16430 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16431 //mUsageStatsService.noteStartConfig(newConfig); 16432 16433 final Configuration configCopy = new Configuration(mConfiguration); 16434 16435 // TODO: If our config changes, should we auto dismiss any currently 16436 // showing dialogs? 16437 mShowDialogs = shouldShowDialogs(newConfig); 16438 16439 AttributeCache ac = AttributeCache.instance(); 16440 if (ac != null) { 16441 ac.updateConfiguration(configCopy); 16442 } 16443 16444 // Make sure all resources in our process are updated 16445 // right now, so that anyone who is going to retrieve 16446 // resource values after we return will be sure to get 16447 // the new ones. This is especially important during 16448 // boot, where the first config change needs to guarantee 16449 // all resources have that config before following boot 16450 // code is executed. 16451 mSystemThread.applyConfigurationToResources(configCopy); 16452 16453 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16454 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16455 msg.obj = new Configuration(configCopy); 16456 mHandler.sendMessage(msg); 16457 } 16458 16459 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16460 ProcessRecord app = mLruProcesses.get(i); 16461 try { 16462 if (app.thread != null) { 16463 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16464 + app.processName + " new config " + mConfiguration); 16465 app.thread.scheduleConfigurationChanged(configCopy); 16466 } 16467 } catch (Exception e) { 16468 } 16469 } 16470 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16472 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16473 | Intent.FLAG_RECEIVER_FOREGROUND); 16474 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16475 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16476 Process.SYSTEM_UID, UserHandle.USER_ALL); 16477 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16478 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16479 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16480 broadcastIntentLocked(null, null, intent, 16481 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16482 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16483 } 16484 } 16485 } 16486 16487 boolean kept = true; 16488 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16489 // mainStack is null during startup. 16490 if (mainStack != null) { 16491 if (changes != 0 && starting == null) { 16492 // If the configuration changed, and the caller is not already 16493 // in the process of starting an activity, then find the top 16494 // activity to check if its configuration needs to change. 16495 starting = mainStack.topRunningActivityLocked(null); 16496 } 16497 16498 if (starting != null) { 16499 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16500 // And we need to make sure at this point that all other activities 16501 // are made visible with the correct configuration. 16502 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16503 } 16504 } 16505 16506 if (values != null && mWindowManager != null) { 16507 mWindowManager.setNewConfiguration(mConfiguration); 16508 } 16509 16510 return kept; 16511 } 16512 16513 /** 16514 * Decide based on the configuration whether we should shouw the ANR, 16515 * crash, etc dialogs. The idea is that if there is no affordnace to 16516 * press the on-screen buttons, we shouldn't show the dialog. 16517 * 16518 * A thought: SystemUI might also want to get told about this, the Power 16519 * dialog / global actions also might want different behaviors. 16520 */ 16521 private static final boolean shouldShowDialogs(Configuration config) { 16522 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16523 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16524 } 16525 16526 /** 16527 * Save the locale. You must be inside a synchronized (this) block. 16528 */ 16529 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16530 if(isDiff) { 16531 SystemProperties.set("user.language", l.getLanguage()); 16532 SystemProperties.set("user.region", l.getCountry()); 16533 } 16534 16535 if(isPersist) { 16536 SystemProperties.set("persist.sys.language", l.getLanguage()); 16537 SystemProperties.set("persist.sys.country", l.getCountry()); 16538 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16539 16540 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16541 } 16542 } 16543 16544 @Override 16545 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16546 synchronized (this) { 16547 ActivityRecord srec = ActivityRecord.forToken(token); 16548 if (srec.task != null && srec.task.stack != null) { 16549 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16550 } 16551 } 16552 return false; 16553 } 16554 16555 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16556 Intent resultData) { 16557 16558 synchronized (this) { 16559 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16560 if (stack != null) { 16561 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16562 } 16563 return false; 16564 } 16565 } 16566 16567 public int getLaunchedFromUid(IBinder activityToken) { 16568 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16569 if (srec == null) { 16570 return -1; 16571 } 16572 return srec.launchedFromUid; 16573 } 16574 16575 public String getLaunchedFromPackage(IBinder activityToken) { 16576 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16577 if (srec == null) { 16578 return null; 16579 } 16580 return srec.launchedFromPackage; 16581 } 16582 16583 // ========================================================= 16584 // LIFETIME MANAGEMENT 16585 // ========================================================= 16586 16587 // Returns which broadcast queue the app is the current [or imminent] receiver 16588 // on, or 'null' if the app is not an active broadcast recipient. 16589 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16590 BroadcastRecord r = app.curReceiver; 16591 if (r != null) { 16592 return r.queue; 16593 } 16594 16595 // It's not the current receiver, but it might be starting up to become one 16596 synchronized (this) { 16597 for (BroadcastQueue queue : mBroadcastQueues) { 16598 r = queue.mPendingBroadcast; 16599 if (r != null && r.curApp == app) { 16600 // found it; report which queue it's in 16601 return queue; 16602 } 16603 } 16604 } 16605 16606 return null; 16607 } 16608 16609 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16610 boolean doingAll, long now) { 16611 if (mAdjSeq == app.adjSeq) { 16612 // This adjustment has already been computed. 16613 return app.curRawAdj; 16614 } 16615 16616 if (app.thread == null) { 16617 app.adjSeq = mAdjSeq; 16618 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16619 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16620 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16621 } 16622 16623 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16624 app.adjSource = null; 16625 app.adjTarget = null; 16626 app.empty = false; 16627 app.cached = false; 16628 16629 final int activitiesSize = app.activities.size(); 16630 16631 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16632 // The max adjustment doesn't allow this app to be anything 16633 // below foreground, so it is not worth doing work for it. 16634 app.adjType = "fixed"; 16635 app.adjSeq = mAdjSeq; 16636 app.curRawAdj = app.maxAdj; 16637 app.foregroundActivities = false; 16638 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16639 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16640 // System processes can do UI, and when they do we want to have 16641 // them trim their memory after the user leaves the UI. To 16642 // facilitate this, here we need to determine whether or not it 16643 // is currently showing UI. 16644 app.systemNoUi = true; 16645 if (app == TOP_APP) { 16646 app.systemNoUi = false; 16647 } else if (activitiesSize > 0) { 16648 for (int j = 0; j < activitiesSize; j++) { 16649 final ActivityRecord r = app.activities.get(j); 16650 if (r.visible) { 16651 app.systemNoUi = false; 16652 } 16653 } 16654 } 16655 if (!app.systemNoUi) { 16656 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16657 } 16658 return (app.curAdj=app.maxAdj); 16659 } 16660 16661 app.systemNoUi = false; 16662 16663 // Determine the importance of the process, starting with most 16664 // important to least, and assign an appropriate OOM adjustment. 16665 int adj; 16666 int schedGroup; 16667 int procState; 16668 boolean foregroundActivities = false; 16669 BroadcastQueue queue; 16670 if (app == TOP_APP) { 16671 // The last app on the list is the foreground app. 16672 adj = ProcessList.FOREGROUND_APP_ADJ; 16673 schedGroup = Process.THREAD_GROUP_DEFAULT; 16674 app.adjType = "top-activity"; 16675 foregroundActivities = true; 16676 procState = ActivityManager.PROCESS_STATE_TOP; 16677 } else if (app.instrumentationClass != null) { 16678 // Don't want to kill running instrumentation. 16679 adj = ProcessList.FOREGROUND_APP_ADJ; 16680 schedGroup = Process.THREAD_GROUP_DEFAULT; 16681 app.adjType = "instrumentation"; 16682 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16683 } else if ((queue = isReceivingBroadcast(app)) != null) { 16684 // An app that is currently receiving a broadcast also 16685 // counts as being in the foreground for OOM killer purposes. 16686 // It's placed in a sched group based on the nature of the 16687 // broadcast as reflected by which queue it's active in. 16688 adj = ProcessList.FOREGROUND_APP_ADJ; 16689 schedGroup = (queue == mFgBroadcastQueue) 16690 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16691 app.adjType = "broadcast"; 16692 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16693 } else if (app.executingServices.size() > 0) { 16694 // An app that is currently executing a service callback also 16695 // counts as being in the foreground. 16696 adj = ProcessList.FOREGROUND_APP_ADJ; 16697 schedGroup = app.execServicesFg ? 16698 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16699 app.adjType = "exec-service"; 16700 procState = ActivityManager.PROCESS_STATE_SERVICE; 16701 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16702 } else { 16703 // As far as we know the process is empty. We may change our mind later. 16704 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16705 // At this point we don't actually know the adjustment. Use the cached adj 16706 // value that the caller wants us to. 16707 adj = cachedAdj; 16708 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16709 app.cached = true; 16710 app.empty = true; 16711 app.adjType = "cch-empty"; 16712 } 16713 16714 // Examine all activities if not already foreground. 16715 if (!foregroundActivities && activitiesSize > 0) { 16716 for (int j = 0; j < activitiesSize; j++) { 16717 final ActivityRecord r = app.activities.get(j); 16718 if (r.app != app) { 16719 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16720 + app + "?!?"); 16721 continue; 16722 } 16723 if (r.visible) { 16724 // App has a visible activity; only upgrade adjustment. 16725 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16726 adj = ProcessList.VISIBLE_APP_ADJ; 16727 app.adjType = "visible"; 16728 } 16729 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16730 procState = ActivityManager.PROCESS_STATE_TOP; 16731 } 16732 schedGroup = Process.THREAD_GROUP_DEFAULT; 16733 app.cached = false; 16734 app.empty = false; 16735 foregroundActivities = true; 16736 break; 16737 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16738 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16739 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16740 app.adjType = "pausing"; 16741 } 16742 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16743 procState = ActivityManager.PROCESS_STATE_TOP; 16744 } 16745 schedGroup = Process.THREAD_GROUP_DEFAULT; 16746 app.cached = false; 16747 app.empty = false; 16748 foregroundActivities = true; 16749 } else if (r.state == ActivityState.STOPPING) { 16750 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16751 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16752 app.adjType = "stopping"; 16753 } 16754 // For the process state, we will at this point consider the 16755 // process to be cached. It will be cached either as an activity 16756 // or empty depending on whether the activity is finishing. We do 16757 // this so that we can treat the process as cached for purposes of 16758 // memory trimming (determing current memory level, trim command to 16759 // send to process) since there can be an arbitrary number of stopping 16760 // processes and they should soon all go into the cached state. 16761 if (!r.finishing) { 16762 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16763 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16764 } 16765 } 16766 app.cached = false; 16767 app.empty = false; 16768 foregroundActivities = true; 16769 } else { 16770 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16771 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16772 app.adjType = "cch-act"; 16773 } 16774 } 16775 } 16776 } 16777 16778 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16779 if (app.foregroundServices) { 16780 // The user is aware of this app, so make it visible. 16781 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16782 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16783 app.cached = false; 16784 app.adjType = "fg-service"; 16785 schedGroup = Process.THREAD_GROUP_DEFAULT; 16786 } else if (app.forcingToForeground != null) { 16787 // The user is aware of this app, so make it visible. 16788 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16789 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16790 app.cached = false; 16791 app.adjType = "force-fg"; 16792 app.adjSource = app.forcingToForeground; 16793 schedGroup = Process.THREAD_GROUP_DEFAULT; 16794 } 16795 } 16796 16797 if (app == mHeavyWeightProcess) { 16798 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16799 // We don't want to kill the current heavy-weight process. 16800 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16801 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16802 app.cached = false; 16803 app.adjType = "heavy"; 16804 } 16805 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16806 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16807 } 16808 } 16809 16810 if (app == mHomeProcess) { 16811 if (adj > ProcessList.HOME_APP_ADJ) { 16812 // This process is hosting what we currently consider to be the 16813 // home app, so we don't want to let it go into the background. 16814 adj = ProcessList.HOME_APP_ADJ; 16815 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16816 app.cached = false; 16817 app.adjType = "home"; 16818 } 16819 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16820 procState = ActivityManager.PROCESS_STATE_HOME; 16821 } 16822 } 16823 16824 if (app == mPreviousProcess && app.activities.size() > 0) { 16825 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16826 // This was the previous process that showed UI to the user. 16827 // We want to try to keep it around more aggressively, to give 16828 // a good experience around switching between two apps. 16829 adj = ProcessList.PREVIOUS_APP_ADJ; 16830 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16831 app.cached = false; 16832 app.adjType = "previous"; 16833 } 16834 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16835 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16836 } 16837 } 16838 16839 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16840 + " reason=" + app.adjType); 16841 16842 // By default, we use the computed adjustment. It may be changed if 16843 // there are applications dependent on our services or providers, but 16844 // this gives us a baseline and makes sure we don't get into an 16845 // infinite recursion. 16846 app.adjSeq = mAdjSeq; 16847 app.curRawAdj = adj; 16848 app.hasStartedServices = false; 16849 16850 if (mBackupTarget != null && app == mBackupTarget.app) { 16851 // If possible we want to avoid killing apps while they're being backed up 16852 if (adj > ProcessList.BACKUP_APP_ADJ) { 16853 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16854 adj = ProcessList.BACKUP_APP_ADJ; 16855 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16856 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16857 } 16858 app.adjType = "backup"; 16859 app.cached = false; 16860 } 16861 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16862 procState = ActivityManager.PROCESS_STATE_BACKUP; 16863 } 16864 } 16865 16866 boolean mayBeTop = false; 16867 16868 for (int is = app.services.size()-1; 16869 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16870 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16871 || procState > ActivityManager.PROCESS_STATE_TOP); 16872 is--) { 16873 ServiceRecord s = app.services.valueAt(is); 16874 if (s.startRequested) { 16875 app.hasStartedServices = true; 16876 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16877 procState = ActivityManager.PROCESS_STATE_SERVICE; 16878 } 16879 if (app.hasShownUi && app != mHomeProcess) { 16880 // If this process has shown some UI, let it immediately 16881 // go to the LRU list because it may be pretty heavy with 16882 // UI stuff. We'll tag it with a label just to help 16883 // debug and understand what is going on. 16884 if (adj > ProcessList.SERVICE_ADJ) { 16885 app.adjType = "cch-started-ui-services"; 16886 } 16887 } else { 16888 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16889 // This service has seen some activity within 16890 // recent memory, so we will keep its process ahead 16891 // of the background processes. 16892 if (adj > ProcessList.SERVICE_ADJ) { 16893 adj = ProcessList.SERVICE_ADJ; 16894 app.adjType = "started-services"; 16895 app.cached = false; 16896 } 16897 } 16898 // If we have let the service slide into the background 16899 // state, still have some text describing what it is doing 16900 // even though the service no longer has an impact. 16901 if (adj > ProcessList.SERVICE_ADJ) { 16902 app.adjType = "cch-started-services"; 16903 } 16904 } 16905 } 16906 for (int conni = s.connections.size()-1; 16907 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16908 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16909 || procState > ActivityManager.PROCESS_STATE_TOP); 16910 conni--) { 16911 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16912 for (int i = 0; 16913 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16914 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16915 || procState > ActivityManager.PROCESS_STATE_TOP); 16916 i++) { 16917 // XXX should compute this based on the max of 16918 // all connected clients. 16919 ConnectionRecord cr = clist.get(i); 16920 if (cr.binding.client == app) { 16921 // Binding to ourself is not interesting. 16922 continue; 16923 } 16924 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16925 ProcessRecord client = cr.binding.client; 16926 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16927 TOP_APP, doingAll, now); 16928 int clientProcState = client.curProcState; 16929 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16930 // If the other app is cached for any reason, for purposes here 16931 // we are going to consider it empty. The specific cached state 16932 // doesn't propagate except under certain conditions. 16933 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16934 } 16935 String adjType = null; 16936 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16937 // Not doing bind OOM management, so treat 16938 // this guy more like a started service. 16939 if (app.hasShownUi && app != mHomeProcess) { 16940 // If this process has shown some UI, let it immediately 16941 // go to the LRU list because it may be pretty heavy with 16942 // UI stuff. We'll tag it with a label just to help 16943 // debug and understand what is going on. 16944 if (adj > clientAdj) { 16945 adjType = "cch-bound-ui-services"; 16946 } 16947 app.cached = false; 16948 clientAdj = adj; 16949 clientProcState = procState; 16950 } else { 16951 if (now >= (s.lastActivity 16952 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16953 // This service has not seen activity within 16954 // recent memory, so allow it to drop to the 16955 // LRU list if there is no other reason to keep 16956 // it around. We'll also tag it with a label just 16957 // to help debug and undertand what is going on. 16958 if (adj > clientAdj) { 16959 adjType = "cch-bound-services"; 16960 } 16961 clientAdj = adj; 16962 } 16963 } 16964 } 16965 if (adj > clientAdj) { 16966 // If this process has recently shown UI, and 16967 // the process that is binding to it is less 16968 // important than being visible, then we don't 16969 // care about the binding as much as we care 16970 // about letting this process get into the LRU 16971 // list to be killed and restarted if needed for 16972 // memory. 16973 if (app.hasShownUi && app != mHomeProcess 16974 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16975 adjType = "cch-bound-ui-services"; 16976 } else { 16977 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16978 |Context.BIND_IMPORTANT)) != 0) { 16979 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16980 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16981 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16982 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16983 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16984 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16985 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16986 adj = clientAdj; 16987 } else { 16988 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16989 adj = ProcessList.VISIBLE_APP_ADJ; 16990 } 16991 } 16992 if (!client.cached) { 16993 app.cached = false; 16994 } 16995 adjType = "service"; 16996 } 16997 } 16998 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16999 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17000 schedGroup = Process.THREAD_GROUP_DEFAULT; 17001 } 17002 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17003 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17004 // Special handling of clients who are in the top state. 17005 // We *may* want to consider this process to be in the 17006 // top state as well, but only if there is not another 17007 // reason for it to be running. Being on the top is a 17008 // special state, meaning you are specifically running 17009 // for the current top app. If the process is already 17010 // running in the background for some other reason, it 17011 // is more important to continue considering it to be 17012 // in the background state. 17013 mayBeTop = true; 17014 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17015 } else { 17016 // Special handling for above-top states (persistent 17017 // processes). These should not bring the current process 17018 // into the top state, since they are not on top. Instead 17019 // give them the best state after that. 17020 clientProcState = 17021 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17022 } 17023 } 17024 } else { 17025 if (clientProcState < 17026 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17027 clientProcState = 17028 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17029 } 17030 } 17031 if (procState > clientProcState) { 17032 procState = clientProcState; 17033 } 17034 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17035 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17036 app.pendingUiClean = true; 17037 } 17038 if (adjType != null) { 17039 app.adjType = adjType; 17040 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17041 .REASON_SERVICE_IN_USE; 17042 app.adjSource = cr.binding.client; 17043 app.adjSourceProcState = clientProcState; 17044 app.adjTarget = s.name; 17045 } 17046 } 17047 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17048 app.treatLikeActivity = true; 17049 } 17050 final ActivityRecord a = cr.activity; 17051 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17052 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17053 (a.visible || a.state == ActivityState.RESUMED 17054 || a.state == ActivityState.PAUSING)) { 17055 adj = ProcessList.FOREGROUND_APP_ADJ; 17056 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17057 schedGroup = Process.THREAD_GROUP_DEFAULT; 17058 } 17059 app.cached = false; 17060 app.adjType = "service"; 17061 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17062 .REASON_SERVICE_IN_USE; 17063 app.adjSource = a; 17064 app.adjSourceProcState = procState; 17065 app.adjTarget = s.name; 17066 } 17067 } 17068 } 17069 } 17070 } 17071 17072 for (int provi = app.pubProviders.size()-1; 17073 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17074 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17075 || procState > ActivityManager.PROCESS_STATE_TOP); 17076 provi--) { 17077 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17078 for (int i = cpr.connections.size()-1; 17079 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17080 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17081 || procState > ActivityManager.PROCESS_STATE_TOP); 17082 i--) { 17083 ContentProviderConnection conn = cpr.connections.get(i); 17084 ProcessRecord client = conn.client; 17085 if (client == app) { 17086 // Being our own client is not interesting. 17087 continue; 17088 } 17089 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17090 int clientProcState = client.curProcState; 17091 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17092 // If the other app is cached for any reason, for purposes here 17093 // we are going to consider it empty. 17094 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17095 } 17096 if (adj > clientAdj) { 17097 if (app.hasShownUi && app != mHomeProcess 17098 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17099 app.adjType = "cch-ui-provider"; 17100 } else { 17101 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17102 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17103 app.adjType = "provider"; 17104 } 17105 app.cached &= client.cached; 17106 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17107 .REASON_PROVIDER_IN_USE; 17108 app.adjSource = client; 17109 app.adjSourceProcState = clientProcState; 17110 app.adjTarget = cpr.name; 17111 } 17112 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17113 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17114 // Special handling of clients who are in the top state. 17115 // We *may* want to consider this process to be in the 17116 // top state as well, but only if there is not another 17117 // reason for it to be running. Being on the top is a 17118 // special state, meaning you are specifically running 17119 // for the current top app. If the process is already 17120 // running in the background for some other reason, it 17121 // is more important to continue considering it to be 17122 // in the background state. 17123 mayBeTop = true; 17124 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17125 } else { 17126 // Special handling for above-top states (persistent 17127 // processes). These should not bring the current process 17128 // into the top state, since they are not on top. Instead 17129 // give them the best state after that. 17130 clientProcState = 17131 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17132 } 17133 } 17134 if (procState > clientProcState) { 17135 procState = clientProcState; 17136 } 17137 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17138 schedGroup = Process.THREAD_GROUP_DEFAULT; 17139 } 17140 } 17141 // If the provider has external (non-framework) process 17142 // dependencies, ensure that its adjustment is at least 17143 // FOREGROUND_APP_ADJ. 17144 if (cpr.hasExternalProcessHandles()) { 17145 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17146 adj = ProcessList.FOREGROUND_APP_ADJ; 17147 schedGroup = Process.THREAD_GROUP_DEFAULT; 17148 app.cached = false; 17149 app.adjType = "provider"; 17150 app.adjTarget = cpr.name; 17151 } 17152 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17153 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17154 } 17155 } 17156 } 17157 17158 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17159 // A client of one of our services or providers is in the top state. We 17160 // *may* want to be in the top state, but not if we are already running in 17161 // the background for some other reason. For the decision here, we are going 17162 // to pick out a few specific states that we want to remain in when a client 17163 // is top (states that tend to be longer-term) and otherwise allow it to go 17164 // to the top state. 17165 switch (procState) { 17166 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17167 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17168 case ActivityManager.PROCESS_STATE_SERVICE: 17169 // These all are longer-term states, so pull them up to the top 17170 // of the background states, but not all the way to the top state. 17171 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17172 break; 17173 default: 17174 // Otherwise, top is a better choice, so take it. 17175 procState = ActivityManager.PROCESS_STATE_TOP; 17176 break; 17177 } 17178 } 17179 17180 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17181 if (app.hasClientActivities) { 17182 // This is a cached process, but with client activities. Mark it so. 17183 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17184 app.adjType = "cch-client-act"; 17185 } else if (app.treatLikeActivity) { 17186 // This is a cached process, but somebody wants us to treat it like it has 17187 // an activity, okay! 17188 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17189 app.adjType = "cch-as-act"; 17190 } 17191 } 17192 17193 if (adj == ProcessList.SERVICE_ADJ) { 17194 if (doingAll) { 17195 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17196 mNewNumServiceProcs++; 17197 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17198 if (!app.serviceb) { 17199 // This service isn't far enough down on the LRU list to 17200 // normally be a B service, but if we are low on RAM and it 17201 // is large we want to force it down since we would prefer to 17202 // keep launcher over it. 17203 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17204 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17205 app.serviceHighRam = true; 17206 app.serviceb = true; 17207 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17208 } else { 17209 mNewNumAServiceProcs++; 17210 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17211 } 17212 } else { 17213 app.serviceHighRam = false; 17214 } 17215 } 17216 if (app.serviceb) { 17217 adj = ProcessList.SERVICE_B_ADJ; 17218 } 17219 } 17220 17221 app.curRawAdj = adj; 17222 17223 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17224 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17225 if (adj > app.maxAdj) { 17226 adj = app.maxAdj; 17227 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17228 schedGroup = Process.THREAD_GROUP_DEFAULT; 17229 } 17230 } 17231 17232 // Do final modification to adj. Everything we do between here and applying 17233 // the final setAdj must be done in this function, because we will also use 17234 // it when computing the final cached adj later. Note that we don't need to 17235 // worry about this for max adj above, since max adj will always be used to 17236 // keep it out of the cached vaues. 17237 app.curAdj = app.modifyRawOomAdj(adj); 17238 app.curSchedGroup = schedGroup; 17239 app.curProcState = procState; 17240 app.foregroundActivities = foregroundActivities; 17241 17242 return app.curRawAdj; 17243 } 17244 17245 /** 17246 * Schedule PSS collection of a process. 17247 */ 17248 void requestPssLocked(ProcessRecord proc, int procState) { 17249 if (mPendingPssProcesses.contains(proc)) { 17250 return; 17251 } 17252 if (mPendingPssProcesses.size() == 0) { 17253 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17254 } 17255 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17256 proc.pssProcState = procState; 17257 mPendingPssProcesses.add(proc); 17258 } 17259 17260 /** 17261 * Schedule PSS collection of all processes. 17262 */ 17263 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17264 if (!always) { 17265 if (now < (mLastFullPssTime + 17266 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17267 return; 17268 } 17269 } 17270 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17271 mLastFullPssTime = now; 17272 mFullPssPending = true; 17273 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17274 mPendingPssProcesses.clear(); 17275 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17276 ProcessRecord app = mLruProcesses.get(i); 17277 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17278 app.pssProcState = app.setProcState; 17279 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17280 isSleeping(), now); 17281 mPendingPssProcesses.add(app); 17282 } 17283 } 17284 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17285 } 17286 17287 /** 17288 * Ask a given process to GC right now. 17289 */ 17290 final void performAppGcLocked(ProcessRecord app) { 17291 try { 17292 app.lastRequestedGc = SystemClock.uptimeMillis(); 17293 if (app.thread != null) { 17294 if (app.reportLowMemory) { 17295 app.reportLowMemory = false; 17296 app.thread.scheduleLowMemory(); 17297 } else { 17298 app.thread.processInBackground(); 17299 } 17300 } 17301 } catch (Exception e) { 17302 // whatever. 17303 } 17304 } 17305 17306 /** 17307 * Returns true if things are idle enough to perform GCs. 17308 */ 17309 private final boolean canGcNowLocked() { 17310 boolean processingBroadcasts = false; 17311 for (BroadcastQueue q : mBroadcastQueues) { 17312 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17313 processingBroadcasts = true; 17314 } 17315 } 17316 return !processingBroadcasts 17317 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17318 } 17319 17320 /** 17321 * Perform GCs on all processes that are waiting for it, but only 17322 * if things are idle. 17323 */ 17324 final void performAppGcsLocked() { 17325 final int N = mProcessesToGc.size(); 17326 if (N <= 0) { 17327 return; 17328 } 17329 if (canGcNowLocked()) { 17330 while (mProcessesToGc.size() > 0) { 17331 ProcessRecord proc = mProcessesToGc.remove(0); 17332 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17333 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17334 <= SystemClock.uptimeMillis()) { 17335 // To avoid spamming the system, we will GC processes one 17336 // at a time, waiting a few seconds between each. 17337 performAppGcLocked(proc); 17338 scheduleAppGcsLocked(); 17339 return; 17340 } else { 17341 // It hasn't been long enough since we last GCed this 17342 // process... put it in the list to wait for its time. 17343 addProcessToGcListLocked(proc); 17344 break; 17345 } 17346 } 17347 } 17348 17349 scheduleAppGcsLocked(); 17350 } 17351 } 17352 17353 /** 17354 * If all looks good, perform GCs on all processes waiting for them. 17355 */ 17356 final void performAppGcsIfAppropriateLocked() { 17357 if (canGcNowLocked()) { 17358 performAppGcsLocked(); 17359 return; 17360 } 17361 // Still not idle, wait some more. 17362 scheduleAppGcsLocked(); 17363 } 17364 17365 /** 17366 * Schedule the execution of all pending app GCs. 17367 */ 17368 final void scheduleAppGcsLocked() { 17369 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17370 17371 if (mProcessesToGc.size() > 0) { 17372 // Schedule a GC for the time to the next process. 17373 ProcessRecord proc = mProcessesToGc.get(0); 17374 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17375 17376 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17377 long now = SystemClock.uptimeMillis(); 17378 if (when < (now+GC_TIMEOUT)) { 17379 when = now + GC_TIMEOUT; 17380 } 17381 mHandler.sendMessageAtTime(msg, when); 17382 } 17383 } 17384 17385 /** 17386 * Add a process to the array of processes waiting to be GCed. Keeps the 17387 * list in sorted order by the last GC time. The process can't already be 17388 * on the list. 17389 */ 17390 final void addProcessToGcListLocked(ProcessRecord proc) { 17391 boolean added = false; 17392 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17393 if (mProcessesToGc.get(i).lastRequestedGc < 17394 proc.lastRequestedGc) { 17395 added = true; 17396 mProcessesToGc.add(i+1, proc); 17397 break; 17398 } 17399 } 17400 if (!added) { 17401 mProcessesToGc.add(0, proc); 17402 } 17403 } 17404 17405 /** 17406 * Set up to ask a process to GC itself. This will either do it 17407 * immediately, or put it on the list of processes to gc the next 17408 * time things are idle. 17409 */ 17410 final void scheduleAppGcLocked(ProcessRecord app) { 17411 long now = SystemClock.uptimeMillis(); 17412 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17413 return; 17414 } 17415 if (!mProcessesToGc.contains(app)) { 17416 addProcessToGcListLocked(app); 17417 scheduleAppGcsLocked(); 17418 } 17419 } 17420 17421 final void checkExcessivePowerUsageLocked(boolean doKills) { 17422 updateCpuStatsNow(); 17423 17424 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17425 boolean doWakeKills = doKills; 17426 boolean doCpuKills = doKills; 17427 if (mLastPowerCheckRealtime == 0) { 17428 doWakeKills = false; 17429 } 17430 if (mLastPowerCheckUptime == 0) { 17431 doCpuKills = false; 17432 } 17433 if (stats.isScreenOn()) { 17434 doWakeKills = false; 17435 } 17436 final long curRealtime = SystemClock.elapsedRealtime(); 17437 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17438 final long curUptime = SystemClock.uptimeMillis(); 17439 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17440 mLastPowerCheckRealtime = curRealtime; 17441 mLastPowerCheckUptime = curUptime; 17442 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17443 doWakeKills = false; 17444 } 17445 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17446 doCpuKills = false; 17447 } 17448 int i = mLruProcesses.size(); 17449 while (i > 0) { 17450 i--; 17451 ProcessRecord app = mLruProcesses.get(i); 17452 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17453 long wtime; 17454 synchronized (stats) { 17455 wtime = stats.getProcessWakeTime(app.info.uid, 17456 app.pid, curRealtime); 17457 } 17458 long wtimeUsed = wtime - app.lastWakeTime; 17459 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17460 if (DEBUG_POWER) { 17461 StringBuilder sb = new StringBuilder(128); 17462 sb.append("Wake for "); 17463 app.toShortString(sb); 17464 sb.append(": over "); 17465 TimeUtils.formatDuration(realtimeSince, sb); 17466 sb.append(" used "); 17467 TimeUtils.formatDuration(wtimeUsed, sb); 17468 sb.append(" ("); 17469 sb.append((wtimeUsed*100)/realtimeSince); 17470 sb.append("%)"); 17471 Slog.i(TAG, sb.toString()); 17472 sb.setLength(0); 17473 sb.append("CPU for "); 17474 app.toShortString(sb); 17475 sb.append(": over "); 17476 TimeUtils.formatDuration(uptimeSince, sb); 17477 sb.append(" used "); 17478 TimeUtils.formatDuration(cputimeUsed, sb); 17479 sb.append(" ("); 17480 sb.append((cputimeUsed*100)/uptimeSince); 17481 sb.append("%)"); 17482 Slog.i(TAG, sb.toString()); 17483 } 17484 // If a process has held a wake lock for more 17485 // than 50% of the time during this period, 17486 // that sounds bad. Kill! 17487 if (doWakeKills && realtimeSince > 0 17488 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17489 synchronized (stats) { 17490 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17491 realtimeSince, wtimeUsed); 17492 } 17493 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17494 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17495 } else if (doCpuKills && uptimeSince > 0 17496 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17497 synchronized (stats) { 17498 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17499 uptimeSince, cputimeUsed); 17500 } 17501 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17502 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17503 } else { 17504 app.lastWakeTime = wtime; 17505 app.lastCpuTime = app.curCpuTime; 17506 } 17507 } 17508 } 17509 } 17510 17511 private final boolean applyOomAdjLocked(ProcessRecord app, 17512 ProcessRecord TOP_APP, boolean doingAll, long now) { 17513 boolean success = true; 17514 17515 if (app.curRawAdj != app.setRawAdj) { 17516 app.setRawAdj = app.curRawAdj; 17517 } 17518 17519 int changes = 0; 17520 17521 if (app.curAdj != app.setAdj) { 17522 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17523 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17524 TAG, "Set " + app.pid + " " + app.processName + 17525 " adj " + app.curAdj + ": " + app.adjType); 17526 app.setAdj = app.curAdj; 17527 } 17528 17529 if (app.setSchedGroup != app.curSchedGroup) { 17530 app.setSchedGroup = app.curSchedGroup; 17531 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17532 "Setting process group of " + app.processName 17533 + " to " + app.curSchedGroup); 17534 if (app.waitingToKill != null && 17535 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17536 app.kill(app.waitingToKill, true); 17537 success = false; 17538 } else { 17539 if (true) { 17540 long oldId = Binder.clearCallingIdentity(); 17541 try { 17542 Process.setProcessGroup(app.pid, app.curSchedGroup); 17543 } catch (Exception e) { 17544 Slog.w(TAG, "Failed setting process group of " + app.pid 17545 + " to " + app.curSchedGroup); 17546 e.printStackTrace(); 17547 } finally { 17548 Binder.restoreCallingIdentity(oldId); 17549 } 17550 } else { 17551 if (app.thread != null) { 17552 try { 17553 app.thread.setSchedulingGroup(app.curSchedGroup); 17554 } catch (RemoteException e) { 17555 } 17556 } 17557 } 17558 Process.setSwappiness(app.pid, 17559 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17560 } 17561 } 17562 if (app.repForegroundActivities != app.foregroundActivities) { 17563 app.repForegroundActivities = app.foregroundActivities; 17564 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17565 } 17566 if (app.repProcState != app.curProcState) { 17567 app.repProcState = app.curProcState; 17568 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17569 if (app.thread != null) { 17570 try { 17571 if (false) { 17572 //RuntimeException h = new RuntimeException("here"); 17573 Slog.i(TAG, "Sending new process state " + app.repProcState 17574 + " to " + app /*, h*/); 17575 } 17576 app.thread.setProcessState(app.repProcState); 17577 } catch (RemoteException e) { 17578 } 17579 } 17580 } 17581 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17582 app.setProcState)) { 17583 app.lastStateTime = now; 17584 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17585 isSleeping(), now); 17586 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17587 + ProcessList.makeProcStateString(app.setProcState) + " to " 17588 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17589 + (app.nextPssTime-now) + ": " + app); 17590 } else { 17591 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17592 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17593 requestPssLocked(app, app.setProcState); 17594 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17595 isSleeping(), now); 17596 } else if (false && DEBUG_PSS) { 17597 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17598 } 17599 } 17600 if (app.setProcState != app.curProcState) { 17601 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17602 "Proc state change of " + app.processName 17603 + " to " + app.curProcState); 17604 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17605 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17606 if (setImportant && !curImportant) { 17607 // This app is no longer something we consider important enough to allow to 17608 // use arbitrary amounts of battery power. Note 17609 // its current wake lock time to later know to kill it if 17610 // it is not behaving well. 17611 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17612 synchronized (stats) { 17613 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17614 app.pid, SystemClock.elapsedRealtime()); 17615 } 17616 app.lastCpuTime = app.curCpuTime; 17617 17618 } 17619 app.setProcState = app.curProcState; 17620 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17621 app.notCachedSinceIdle = false; 17622 } 17623 if (!doingAll) { 17624 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17625 } else { 17626 app.procStateChanged = true; 17627 } 17628 } 17629 17630 if (changes != 0) { 17631 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17632 int i = mPendingProcessChanges.size()-1; 17633 ProcessChangeItem item = null; 17634 while (i >= 0) { 17635 item = mPendingProcessChanges.get(i); 17636 if (item.pid == app.pid) { 17637 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17638 break; 17639 } 17640 i--; 17641 } 17642 if (i < 0) { 17643 // No existing item in pending changes; need a new one. 17644 final int NA = mAvailProcessChanges.size(); 17645 if (NA > 0) { 17646 item = mAvailProcessChanges.remove(NA-1); 17647 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17648 } else { 17649 item = new ProcessChangeItem(); 17650 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17651 } 17652 item.changes = 0; 17653 item.pid = app.pid; 17654 item.uid = app.info.uid; 17655 if (mPendingProcessChanges.size() == 0) { 17656 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17657 "*** Enqueueing dispatch processes changed!"); 17658 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17659 } 17660 mPendingProcessChanges.add(item); 17661 } 17662 item.changes |= changes; 17663 item.processState = app.repProcState; 17664 item.foregroundActivities = app.repForegroundActivities; 17665 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17666 + Integer.toHexString(System.identityHashCode(item)) 17667 + " " + app.toShortString() + ": changes=" + item.changes 17668 + " procState=" + item.processState 17669 + " foreground=" + item.foregroundActivities 17670 + " type=" + app.adjType + " source=" + app.adjSource 17671 + " target=" + app.adjTarget); 17672 } 17673 17674 return success; 17675 } 17676 17677 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17678 if (proc.thread != null) { 17679 if (proc.baseProcessTracker != null) { 17680 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17681 } 17682 if (proc.repProcState >= 0) { 17683 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17684 proc.repProcState); 17685 } 17686 } 17687 } 17688 17689 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17690 ProcessRecord TOP_APP, boolean doingAll, long now) { 17691 if (app.thread == null) { 17692 return false; 17693 } 17694 17695 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17696 17697 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17698 } 17699 17700 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17701 boolean oomAdj) { 17702 if (isForeground != proc.foregroundServices) { 17703 proc.foregroundServices = isForeground; 17704 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17705 proc.info.uid); 17706 if (isForeground) { 17707 if (curProcs == null) { 17708 curProcs = new ArrayList<ProcessRecord>(); 17709 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17710 } 17711 if (!curProcs.contains(proc)) { 17712 curProcs.add(proc); 17713 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17714 proc.info.packageName, proc.info.uid); 17715 } 17716 } else { 17717 if (curProcs != null) { 17718 if (curProcs.remove(proc)) { 17719 mBatteryStatsService.noteEvent( 17720 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17721 proc.info.packageName, proc.info.uid); 17722 if (curProcs.size() <= 0) { 17723 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17724 } 17725 } 17726 } 17727 } 17728 if (oomAdj) { 17729 updateOomAdjLocked(); 17730 } 17731 } 17732 } 17733 17734 private final ActivityRecord resumedAppLocked() { 17735 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17736 String pkg; 17737 int uid; 17738 if (act != null) { 17739 pkg = act.packageName; 17740 uid = act.info.applicationInfo.uid; 17741 } else { 17742 pkg = null; 17743 uid = -1; 17744 } 17745 // Has the UID or resumed package name changed? 17746 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17747 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17748 if (mCurResumedPackage != null) { 17749 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17750 mCurResumedPackage, mCurResumedUid); 17751 } 17752 mCurResumedPackage = pkg; 17753 mCurResumedUid = uid; 17754 if (mCurResumedPackage != null) { 17755 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17756 mCurResumedPackage, mCurResumedUid); 17757 } 17758 } 17759 return act; 17760 } 17761 17762 final boolean updateOomAdjLocked(ProcessRecord app) { 17763 final ActivityRecord TOP_ACT = resumedAppLocked(); 17764 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17765 final boolean wasCached = app.cached; 17766 17767 mAdjSeq++; 17768 17769 // This is the desired cached adjusment we want to tell it to use. 17770 // If our app is currently cached, we know it, and that is it. Otherwise, 17771 // we don't know it yet, and it needs to now be cached we will then 17772 // need to do a complete oom adj. 17773 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17774 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17775 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17776 SystemClock.uptimeMillis()); 17777 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17778 // Changed to/from cached state, so apps after it in the LRU 17779 // list may also be changed. 17780 updateOomAdjLocked(); 17781 } 17782 return success; 17783 } 17784 17785 final void updateOomAdjLocked() { 17786 final ActivityRecord TOP_ACT = resumedAppLocked(); 17787 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17788 final long now = SystemClock.uptimeMillis(); 17789 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17790 final int N = mLruProcesses.size(); 17791 17792 if (false) { 17793 RuntimeException e = new RuntimeException(); 17794 e.fillInStackTrace(); 17795 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17796 } 17797 17798 mAdjSeq++; 17799 mNewNumServiceProcs = 0; 17800 mNewNumAServiceProcs = 0; 17801 17802 final int emptyProcessLimit; 17803 final int cachedProcessLimit; 17804 if (mProcessLimit <= 0) { 17805 emptyProcessLimit = cachedProcessLimit = 0; 17806 } else if (mProcessLimit == 1) { 17807 emptyProcessLimit = 1; 17808 cachedProcessLimit = 0; 17809 } else { 17810 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17811 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17812 } 17813 17814 // Let's determine how many processes we have running vs. 17815 // how many slots we have for background processes; we may want 17816 // to put multiple processes in a slot of there are enough of 17817 // them. 17818 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17819 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17820 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17821 if (numEmptyProcs > cachedProcessLimit) { 17822 // If there are more empty processes than our limit on cached 17823 // processes, then use the cached process limit for the factor. 17824 // This ensures that the really old empty processes get pushed 17825 // down to the bottom, so if we are running low on memory we will 17826 // have a better chance at keeping around more cached processes 17827 // instead of a gazillion empty processes. 17828 numEmptyProcs = cachedProcessLimit; 17829 } 17830 int emptyFactor = numEmptyProcs/numSlots; 17831 if (emptyFactor < 1) emptyFactor = 1; 17832 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17833 if (cachedFactor < 1) cachedFactor = 1; 17834 int stepCached = 0; 17835 int stepEmpty = 0; 17836 int numCached = 0; 17837 int numEmpty = 0; 17838 int numTrimming = 0; 17839 17840 mNumNonCachedProcs = 0; 17841 mNumCachedHiddenProcs = 0; 17842 17843 // First update the OOM adjustment for each of the 17844 // application processes based on their current state. 17845 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17846 int nextCachedAdj = curCachedAdj+1; 17847 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17848 int nextEmptyAdj = curEmptyAdj+2; 17849 for (int i=N-1; i>=0; i--) { 17850 ProcessRecord app = mLruProcesses.get(i); 17851 if (!app.killedByAm && app.thread != null) { 17852 app.procStateChanged = false; 17853 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17854 17855 // If we haven't yet assigned the final cached adj 17856 // to the process, do that now. 17857 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17858 switch (app.curProcState) { 17859 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17860 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17861 // This process is a cached process holding activities... 17862 // assign it the next cached value for that type, and then 17863 // step that cached level. 17864 app.curRawAdj = curCachedAdj; 17865 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17866 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17867 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17868 + ")"); 17869 if (curCachedAdj != nextCachedAdj) { 17870 stepCached++; 17871 if (stepCached >= cachedFactor) { 17872 stepCached = 0; 17873 curCachedAdj = nextCachedAdj; 17874 nextCachedAdj += 2; 17875 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17876 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17877 } 17878 } 17879 } 17880 break; 17881 default: 17882 // For everything else, assign next empty cached process 17883 // level and bump that up. Note that this means that 17884 // long-running services that have dropped down to the 17885 // cached level will be treated as empty (since their process 17886 // state is still as a service), which is what we want. 17887 app.curRawAdj = curEmptyAdj; 17888 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17889 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17890 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17891 + ")"); 17892 if (curEmptyAdj != nextEmptyAdj) { 17893 stepEmpty++; 17894 if (stepEmpty >= emptyFactor) { 17895 stepEmpty = 0; 17896 curEmptyAdj = nextEmptyAdj; 17897 nextEmptyAdj += 2; 17898 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17899 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17900 } 17901 } 17902 } 17903 break; 17904 } 17905 } 17906 17907 applyOomAdjLocked(app, TOP_APP, true, now); 17908 17909 // Count the number of process types. 17910 switch (app.curProcState) { 17911 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17912 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17913 mNumCachedHiddenProcs++; 17914 numCached++; 17915 if (numCached > cachedProcessLimit) { 17916 app.kill("cached #" + numCached, true); 17917 } 17918 break; 17919 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17920 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17921 && app.lastActivityTime < oldTime) { 17922 app.kill("empty for " 17923 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17924 / 1000) + "s", true); 17925 } else { 17926 numEmpty++; 17927 if (numEmpty > emptyProcessLimit) { 17928 app.kill("empty #" + numEmpty, true); 17929 } 17930 } 17931 break; 17932 default: 17933 mNumNonCachedProcs++; 17934 break; 17935 } 17936 17937 if (app.isolated && app.services.size() <= 0) { 17938 // If this is an isolated process, and there are no 17939 // services running in it, then the process is no longer 17940 // needed. We agressively kill these because we can by 17941 // definition not re-use the same process again, and it is 17942 // good to avoid having whatever code was running in them 17943 // left sitting around after no longer needed. 17944 app.kill("isolated not needed", true); 17945 } 17946 17947 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17948 && !app.killedByAm) { 17949 numTrimming++; 17950 } 17951 } 17952 } 17953 17954 mNumServiceProcs = mNewNumServiceProcs; 17955 17956 // Now determine the memory trimming level of background processes. 17957 // Unfortunately we need to start at the back of the list to do this 17958 // properly. We only do this if the number of background apps we 17959 // are managing to keep around is less than half the maximum we desire; 17960 // if we are keeping a good number around, we'll let them use whatever 17961 // memory they want. 17962 final int numCachedAndEmpty = numCached + numEmpty; 17963 int memFactor; 17964 if (numCached <= ProcessList.TRIM_CACHED_APPS 17965 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17966 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17967 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17968 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17969 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17970 } else { 17971 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17972 } 17973 } else { 17974 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17975 } 17976 // We always allow the memory level to go up (better). We only allow it to go 17977 // down if we are in a state where that is allowed, *and* the total number of processes 17978 // has gone down since last time. 17979 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17980 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17981 + " last=" + mLastNumProcesses); 17982 if (memFactor > mLastMemoryLevel) { 17983 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17984 memFactor = mLastMemoryLevel; 17985 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17986 } 17987 } 17988 mLastMemoryLevel = memFactor; 17989 mLastNumProcesses = mLruProcesses.size(); 17990 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17991 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17992 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17993 if (mLowRamStartTime == 0) { 17994 mLowRamStartTime = now; 17995 } 17996 int step = 0; 17997 int fgTrimLevel; 17998 switch (memFactor) { 17999 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18000 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18001 break; 18002 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18003 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18004 break; 18005 default: 18006 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18007 break; 18008 } 18009 int factor = numTrimming/3; 18010 int minFactor = 2; 18011 if (mHomeProcess != null) minFactor++; 18012 if (mPreviousProcess != null) minFactor++; 18013 if (factor < minFactor) factor = minFactor; 18014 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18015 for (int i=N-1; i>=0; i--) { 18016 ProcessRecord app = mLruProcesses.get(i); 18017 if (allChanged || app.procStateChanged) { 18018 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18019 app.procStateChanged = false; 18020 } 18021 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18022 && !app.killedByAm) { 18023 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18024 try { 18025 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18026 "Trimming memory of " + app.processName 18027 + " to " + curLevel); 18028 app.thread.scheduleTrimMemory(curLevel); 18029 } catch (RemoteException e) { 18030 } 18031 if (false) { 18032 // For now we won't do this; our memory trimming seems 18033 // to be good enough at this point that destroying 18034 // activities causes more harm than good. 18035 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18036 && app != mHomeProcess && app != mPreviousProcess) { 18037 // Need to do this on its own message because the stack may not 18038 // be in a consistent state at this point. 18039 // For these apps we will also finish their activities 18040 // to help them free memory. 18041 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18042 } 18043 } 18044 } 18045 app.trimMemoryLevel = curLevel; 18046 step++; 18047 if (step >= factor) { 18048 step = 0; 18049 switch (curLevel) { 18050 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18051 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18052 break; 18053 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18054 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18055 break; 18056 } 18057 } 18058 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18059 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18060 && app.thread != null) { 18061 try { 18062 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18063 "Trimming memory of heavy-weight " + app.processName 18064 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18065 app.thread.scheduleTrimMemory( 18066 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18067 } catch (RemoteException e) { 18068 } 18069 } 18070 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18071 } else { 18072 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18073 || app.systemNoUi) && app.pendingUiClean) { 18074 // If this application is now in the background and it 18075 // had done UI, then give it the special trim level to 18076 // have it free UI resources. 18077 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18078 if (app.trimMemoryLevel < level && app.thread != null) { 18079 try { 18080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18081 "Trimming memory of bg-ui " + app.processName 18082 + " to " + level); 18083 app.thread.scheduleTrimMemory(level); 18084 } catch (RemoteException e) { 18085 } 18086 } 18087 app.pendingUiClean = false; 18088 } 18089 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18090 try { 18091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18092 "Trimming memory of fg " + app.processName 18093 + " to " + fgTrimLevel); 18094 app.thread.scheduleTrimMemory(fgTrimLevel); 18095 } catch (RemoteException e) { 18096 } 18097 } 18098 app.trimMemoryLevel = fgTrimLevel; 18099 } 18100 } 18101 } else { 18102 if (mLowRamStartTime != 0) { 18103 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18104 mLowRamStartTime = 0; 18105 } 18106 for (int i=N-1; i>=0; i--) { 18107 ProcessRecord app = mLruProcesses.get(i); 18108 if (allChanged || app.procStateChanged) { 18109 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18110 app.procStateChanged = false; 18111 } 18112 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18113 || app.systemNoUi) && app.pendingUiClean) { 18114 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18115 && app.thread != null) { 18116 try { 18117 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18118 "Trimming memory of ui hidden " + app.processName 18119 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18120 app.thread.scheduleTrimMemory( 18121 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18122 } catch (RemoteException e) { 18123 } 18124 } 18125 app.pendingUiClean = false; 18126 } 18127 app.trimMemoryLevel = 0; 18128 } 18129 } 18130 18131 if (mAlwaysFinishActivities) { 18132 // Need to do this on its own message because the stack may not 18133 // be in a consistent state at this point. 18134 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18135 } 18136 18137 if (allChanged) { 18138 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18139 } 18140 18141 if (mProcessStats.shouldWriteNowLocked(now)) { 18142 mHandler.post(new Runnable() { 18143 @Override public void run() { 18144 synchronized (ActivityManagerService.this) { 18145 mProcessStats.writeStateAsyncLocked(); 18146 } 18147 } 18148 }); 18149 } 18150 18151 if (DEBUG_OOM_ADJ) { 18152 if (false) { 18153 RuntimeException here = new RuntimeException("here"); 18154 here.fillInStackTrace(); 18155 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18156 } else { 18157 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18158 } 18159 } 18160 } 18161 18162 final void trimApplications() { 18163 synchronized (this) { 18164 int i; 18165 18166 // First remove any unused application processes whose package 18167 // has been removed. 18168 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18169 final ProcessRecord app = mRemovedProcesses.get(i); 18170 if (app.activities.size() == 0 18171 && app.curReceiver == null && app.services.size() == 0) { 18172 Slog.i( 18173 TAG, "Exiting empty application process " 18174 + app.processName + " (" 18175 + (app.thread != null ? app.thread.asBinder() : null) 18176 + ")\n"); 18177 if (app.pid > 0 && app.pid != MY_PID) { 18178 app.kill("empty", false); 18179 } else { 18180 try { 18181 app.thread.scheduleExit(); 18182 } catch (Exception e) { 18183 // Ignore exceptions. 18184 } 18185 } 18186 cleanUpApplicationRecordLocked(app, false, true, -1); 18187 mRemovedProcesses.remove(i); 18188 18189 if (app.persistent) { 18190 addAppLocked(app.info, false, null /* ABI override */); 18191 } 18192 } 18193 } 18194 18195 // Now update the oom adj for all processes. 18196 updateOomAdjLocked(); 18197 } 18198 } 18199 18200 /** This method sends the specified signal to each of the persistent apps */ 18201 public void signalPersistentProcesses(int sig) throws RemoteException { 18202 if (sig != Process.SIGNAL_USR1) { 18203 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18204 } 18205 18206 synchronized (this) { 18207 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18208 != PackageManager.PERMISSION_GRANTED) { 18209 throw new SecurityException("Requires permission " 18210 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18211 } 18212 18213 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18214 ProcessRecord r = mLruProcesses.get(i); 18215 if (r.thread != null && r.persistent) { 18216 Process.sendSignal(r.pid, sig); 18217 } 18218 } 18219 } 18220 } 18221 18222 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18223 if (proc == null || proc == mProfileProc) { 18224 proc = mProfileProc; 18225 profileType = mProfileType; 18226 clearProfilerLocked(); 18227 } 18228 if (proc == null) { 18229 return; 18230 } 18231 try { 18232 proc.thread.profilerControl(false, null, profileType); 18233 } catch (RemoteException e) { 18234 throw new IllegalStateException("Process disappeared"); 18235 } 18236 } 18237 18238 private void clearProfilerLocked() { 18239 if (mProfileFd != null) { 18240 try { 18241 mProfileFd.close(); 18242 } catch (IOException e) { 18243 } 18244 } 18245 mProfileApp = null; 18246 mProfileProc = null; 18247 mProfileFile = null; 18248 mProfileType = 0; 18249 mAutoStopProfiler = false; 18250 mSamplingInterval = 0; 18251 } 18252 18253 public boolean profileControl(String process, int userId, boolean start, 18254 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18255 18256 try { 18257 synchronized (this) { 18258 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18259 // its own permission. 18260 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18261 != PackageManager.PERMISSION_GRANTED) { 18262 throw new SecurityException("Requires permission " 18263 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18264 } 18265 18266 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18267 throw new IllegalArgumentException("null profile info or fd"); 18268 } 18269 18270 ProcessRecord proc = null; 18271 if (process != null) { 18272 proc = findProcessLocked(process, userId, "profileControl"); 18273 } 18274 18275 if (start && (proc == null || proc.thread == null)) { 18276 throw new IllegalArgumentException("Unknown process: " + process); 18277 } 18278 18279 if (start) { 18280 stopProfilerLocked(null, 0); 18281 setProfileApp(proc.info, proc.processName, profilerInfo); 18282 mProfileProc = proc; 18283 mProfileType = profileType; 18284 ParcelFileDescriptor fd = profilerInfo.profileFd; 18285 try { 18286 fd = fd.dup(); 18287 } catch (IOException e) { 18288 fd = null; 18289 } 18290 profilerInfo.profileFd = fd; 18291 proc.thread.profilerControl(start, profilerInfo, profileType); 18292 fd = null; 18293 mProfileFd = null; 18294 } else { 18295 stopProfilerLocked(proc, profileType); 18296 if (profilerInfo != null && profilerInfo.profileFd != null) { 18297 try { 18298 profilerInfo.profileFd.close(); 18299 } catch (IOException e) { 18300 } 18301 } 18302 } 18303 18304 return true; 18305 } 18306 } catch (RemoteException e) { 18307 throw new IllegalStateException("Process disappeared"); 18308 } finally { 18309 if (profilerInfo != null && profilerInfo.profileFd != null) { 18310 try { 18311 profilerInfo.profileFd.close(); 18312 } catch (IOException e) { 18313 } 18314 } 18315 } 18316 } 18317 18318 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18319 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18320 userId, true, ALLOW_FULL_ONLY, callName, null); 18321 ProcessRecord proc = null; 18322 try { 18323 int pid = Integer.parseInt(process); 18324 synchronized (mPidsSelfLocked) { 18325 proc = mPidsSelfLocked.get(pid); 18326 } 18327 } catch (NumberFormatException e) { 18328 } 18329 18330 if (proc == null) { 18331 ArrayMap<String, SparseArray<ProcessRecord>> all 18332 = mProcessNames.getMap(); 18333 SparseArray<ProcessRecord> procs = all.get(process); 18334 if (procs != null && procs.size() > 0) { 18335 proc = procs.valueAt(0); 18336 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18337 for (int i=1; i<procs.size(); i++) { 18338 ProcessRecord thisProc = procs.valueAt(i); 18339 if (thisProc.userId == userId) { 18340 proc = thisProc; 18341 break; 18342 } 18343 } 18344 } 18345 } 18346 } 18347 18348 return proc; 18349 } 18350 18351 public boolean dumpHeap(String process, int userId, boolean managed, 18352 String path, ParcelFileDescriptor fd) throws RemoteException { 18353 18354 try { 18355 synchronized (this) { 18356 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18357 // its own permission (same as profileControl). 18358 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18359 != PackageManager.PERMISSION_GRANTED) { 18360 throw new SecurityException("Requires permission " 18361 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18362 } 18363 18364 if (fd == null) { 18365 throw new IllegalArgumentException("null fd"); 18366 } 18367 18368 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18369 if (proc == null || proc.thread == null) { 18370 throw new IllegalArgumentException("Unknown process: " + process); 18371 } 18372 18373 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18374 if (!isDebuggable) { 18375 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18376 throw new SecurityException("Process not debuggable: " + proc); 18377 } 18378 } 18379 18380 proc.thread.dumpHeap(managed, path, fd); 18381 fd = null; 18382 return true; 18383 } 18384 } catch (RemoteException e) { 18385 throw new IllegalStateException("Process disappeared"); 18386 } finally { 18387 if (fd != null) { 18388 try { 18389 fd.close(); 18390 } catch (IOException e) { 18391 } 18392 } 18393 } 18394 } 18395 18396 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18397 public void monitor() { 18398 synchronized (this) { } 18399 } 18400 18401 void onCoreSettingsChange(Bundle settings) { 18402 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18403 ProcessRecord processRecord = mLruProcesses.get(i); 18404 try { 18405 if (processRecord.thread != null) { 18406 processRecord.thread.setCoreSettings(settings); 18407 } 18408 } catch (RemoteException re) { 18409 /* ignore */ 18410 } 18411 } 18412 } 18413 18414 // Multi-user methods 18415 18416 /** 18417 * Start user, if its not already running, but don't bring it to foreground. 18418 */ 18419 @Override 18420 public boolean startUserInBackground(final int userId) { 18421 return startUser(userId, /* foreground */ false); 18422 } 18423 18424 /** 18425 * Start user, if its not already running, and bring it to foreground. 18426 */ 18427 boolean startUserInForeground(final int userId, Dialog dlg) { 18428 boolean result = startUser(userId, /* foreground */ true); 18429 dlg.dismiss(); 18430 return result; 18431 } 18432 18433 /** 18434 * Refreshes the list of users related to the current user when either a 18435 * user switch happens or when a new related user is started in the 18436 * background. 18437 */ 18438 private void updateCurrentProfileIdsLocked() { 18439 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18440 mCurrentUserId, false /* enabledOnly */); 18441 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18442 for (int i = 0; i < currentProfileIds.length; i++) { 18443 currentProfileIds[i] = profiles.get(i).id; 18444 } 18445 mCurrentProfileIds = currentProfileIds; 18446 18447 synchronized (mUserProfileGroupIdsSelfLocked) { 18448 mUserProfileGroupIdsSelfLocked.clear(); 18449 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18450 for (int i = 0; i < users.size(); i++) { 18451 UserInfo user = users.get(i); 18452 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18453 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18454 } 18455 } 18456 } 18457 } 18458 18459 private Set getProfileIdsLocked(int userId) { 18460 Set userIds = new HashSet<Integer>(); 18461 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18462 userId, false /* enabledOnly */); 18463 for (UserInfo user : profiles) { 18464 userIds.add(Integer.valueOf(user.id)); 18465 } 18466 return userIds; 18467 } 18468 18469 @Override 18470 public boolean switchUser(final int userId) { 18471 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18472 String userName; 18473 synchronized (this) { 18474 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18475 if (userInfo == null) { 18476 Slog.w(TAG, "No user info for user #" + userId); 18477 return false; 18478 } 18479 if (userInfo.isManagedProfile()) { 18480 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18481 return false; 18482 } 18483 userName = userInfo.name; 18484 mTargetUserId = userId; 18485 } 18486 mHandler.removeMessages(START_USER_SWITCH_MSG); 18487 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18488 return true; 18489 } 18490 18491 private void showUserSwitchDialog(int userId, String userName) { 18492 // The dialog will show and then initiate the user switch by calling startUserInForeground 18493 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18494 true /* above system */); 18495 d.show(); 18496 } 18497 18498 private boolean startUser(final int userId, final boolean foreground) { 18499 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18500 != PackageManager.PERMISSION_GRANTED) { 18501 String msg = "Permission Denial: switchUser() from pid=" 18502 + Binder.getCallingPid() 18503 + ", uid=" + Binder.getCallingUid() 18504 + " requires " + INTERACT_ACROSS_USERS_FULL; 18505 Slog.w(TAG, msg); 18506 throw new SecurityException(msg); 18507 } 18508 18509 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18510 18511 final long ident = Binder.clearCallingIdentity(); 18512 try { 18513 synchronized (this) { 18514 final int oldUserId = mCurrentUserId; 18515 if (oldUserId == userId) { 18516 return true; 18517 } 18518 18519 mStackSupervisor.setLockTaskModeLocked(null, false); 18520 18521 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18522 if (userInfo == null) { 18523 Slog.w(TAG, "No user info for user #" + userId); 18524 return false; 18525 } 18526 if (foreground && userInfo.isManagedProfile()) { 18527 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18528 return false; 18529 } 18530 18531 if (foreground) { 18532 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18533 R.anim.screen_user_enter); 18534 } 18535 18536 boolean needStart = false; 18537 18538 // If the user we are switching to is not currently started, then 18539 // we need to start it now. 18540 if (mStartedUsers.get(userId) == null) { 18541 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18542 updateStartedUserArrayLocked(); 18543 needStart = true; 18544 } 18545 18546 final Integer userIdInt = Integer.valueOf(userId); 18547 mUserLru.remove(userIdInt); 18548 mUserLru.add(userIdInt); 18549 18550 if (foreground) { 18551 mCurrentUserId = userId; 18552 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18553 updateCurrentProfileIdsLocked(); 18554 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18555 // Once the internal notion of the active user has switched, we lock the device 18556 // with the option to show the user switcher on the keyguard. 18557 mWindowManager.lockNow(null); 18558 } else { 18559 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18560 updateCurrentProfileIdsLocked(); 18561 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18562 mUserLru.remove(currentUserIdInt); 18563 mUserLru.add(currentUserIdInt); 18564 } 18565 18566 final UserStartedState uss = mStartedUsers.get(userId); 18567 18568 // Make sure user is in the started state. If it is currently 18569 // stopping, we need to knock that off. 18570 if (uss.mState == UserStartedState.STATE_STOPPING) { 18571 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18572 // so we can just fairly silently bring the user back from 18573 // the almost-dead. 18574 uss.mState = UserStartedState.STATE_RUNNING; 18575 updateStartedUserArrayLocked(); 18576 needStart = true; 18577 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18578 // This means ACTION_SHUTDOWN has been sent, so we will 18579 // need to treat this as a new boot of the user. 18580 uss.mState = UserStartedState.STATE_BOOTING; 18581 updateStartedUserArrayLocked(); 18582 needStart = true; 18583 } 18584 18585 if (uss.mState == UserStartedState.STATE_BOOTING) { 18586 // Booting up a new user, need to tell system services about it. 18587 // Note that this is on the same handler as scheduling of broadcasts, 18588 // which is important because it needs to go first. 18589 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18590 } 18591 18592 if (foreground) { 18593 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18594 oldUserId)); 18595 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18596 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18597 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18598 oldUserId, userId, uss)); 18599 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18600 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18601 } 18602 18603 if (needStart) { 18604 // Send USER_STARTED broadcast 18605 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18607 | Intent.FLAG_RECEIVER_FOREGROUND); 18608 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18609 broadcastIntentLocked(null, null, intent, 18610 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18611 false, false, MY_PID, Process.SYSTEM_UID, userId); 18612 } 18613 18614 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18615 if (userId != UserHandle.USER_OWNER) { 18616 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18617 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18618 broadcastIntentLocked(null, null, intent, null, 18619 new IIntentReceiver.Stub() { 18620 public void performReceive(Intent intent, int resultCode, 18621 String data, Bundle extras, boolean ordered, 18622 boolean sticky, int sendingUser) { 18623 onUserInitialized(uss, foreground, oldUserId, userId); 18624 } 18625 }, 0, null, null, null, AppOpsManager.OP_NONE, 18626 true, false, MY_PID, Process.SYSTEM_UID, 18627 userId); 18628 uss.initializing = true; 18629 } else { 18630 getUserManagerLocked().makeInitialized(userInfo.id); 18631 } 18632 } 18633 18634 if (foreground) { 18635 if (!uss.initializing) { 18636 moveUserToForeground(uss, oldUserId, userId); 18637 } 18638 } else { 18639 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18640 } 18641 18642 if (needStart) { 18643 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18644 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18645 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18646 broadcastIntentLocked(null, null, intent, 18647 null, new IIntentReceiver.Stub() { 18648 @Override 18649 public void performReceive(Intent intent, int resultCode, String data, 18650 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18651 throws RemoteException { 18652 } 18653 }, 0, null, null, 18654 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18655 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18656 } 18657 } 18658 } finally { 18659 Binder.restoreCallingIdentity(ident); 18660 } 18661 18662 return true; 18663 } 18664 18665 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18666 long ident = Binder.clearCallingIdentity(); 18667 try { 18668 Intent intent; 18669 if (oldUserId >= 0) { 18670 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18671 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18672 int count = profiles.size(); 18673 for (int i = 0; i < count; i++) { 18674 int profileUserId = profiles.get(i).id; 18675 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18676 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18677 | Intent.FLAG_RECEIVER_FOREGROUND); 18678 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18679 broadcastIntentLocked(null, null, intent, 18680 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18681 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18682 } 18683 } 18684 if (newUserId >= 0) { 18685 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18686 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18687 int count = profiles.size(); 18688 for (int i = 0; i < count; i++) { 18689 int profileUserId = profiles.get(i).id; 18690 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18692 | Intent.FLAG_RECEIVER_FOREGROUND); 18693 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18694 broadcastIntentLocked(null, null, intent, 18695 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18696 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18697 } 18698 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18700 | Intent.FLAG_RECEIVER_FOREGROUND); 18701 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18702 broadcastIntentLocked(null, null, intent, 18703 null, null, 0, null, null, 18704 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18705 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18706 } 18707 } finally { 18708 Binder.restoreCallingIdentity(ident); 18709 } 18710 } 18711 18712 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18713 final int newUserId) { 18714 final int N = mUserSwitchObservers.beginBroadcast(); 18715 if (N > 0) { 18716 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18717 int mCount = 0; 18718 @Override 18719 public void sendResult(Bundle data) throws RemoteException { 18720 synchronized (ActivityManagerService.this) { 18721 if (mCurUserSwitchCallback == this) { 18722 mCount++; 18723 if (mCount == N) { 18724 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18725 } 18726 } 18727 } 18728 } 18729 }; 18730 synchronized (this) { 18731 uss.switching = true; 18732 mCurUserSwitchCallback = callback; 18733 } 18734 for (int i=0; i<N; i++) { 18735 try { 18736 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18737 newUserId, callback); 18738 } catch (RemoteException e) { 18739 } 18740 } 18741 } else { 18742 synchronized (this) { 18743 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18744 } 18745 } 18746 mUserSwitchObservers.finishBroadcast(); 18747 } 18748 18749 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18750 synchronized (this) { 18751 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18752 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18753 } 18754 } 18755 18756 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18757 mCurUserSwitchCallback = null; 18758 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18759 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18760 oldUserId, newUserId, uss)); 18761 } 18762 18763 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18764 synchronized (this) { 18765 if (foreground) { 18766 moveUserToForeground(uss, oldUserId, newUserId); 18767 } 18768 } 18769 18770 completeSwitchAndInitalize(uss, newUserId, true, false); 18771 } 18772 18773 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18774 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18775 if (homeInFront) { 18776 startHomeActivityLocked(newUserId); 18777 } else { 18778 mStackSupervisor.resumeTopActivitiesLocked(); 18779 } 18780 EventLogTags.writeAmSwitchUser(newUserId); 18781 getUserManagerLocked().userForeground(newUserId); 18782 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18783 } 18784 18785 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18786 completeSwitchAndInitalize(uss, newUserId, false, true); 18787 } 18788 18789 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18790 boolean clearInitializing, boolean clearSwitching) { 18791 boolean unfrozen = false; 18792 synchronized (this) { 18793 if (clearInitializing) { 18794 uss.initializing = false; 18795 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18796 } 18797 if (clearSwitching) { 18798 uss.switching = false; 18799 } 18800 if (!uss.switching && !uss.initializing) { 18801 mWindowManager.stopFreezingScreen(); 18802 unfrozen = true; 18803 } 18804 } 18805 if (unfrozen) { 18806 final int N = mUserSwitchObservers.beginBroadcast(); 18807 for (int i=0; i<N; i++) { 18808 try { 18809 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18810 } catch (RemoteException e) { 18811 } 18812 } 18813 mUserSwitchObservers.finishBroadcast(); 18814 } 18815 } 18816 18817 void scheduleStartProfilesLocked() { 18818 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18819 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18820 DateUtils.SECOND_IN_MILLIS); 18821 } 18822 } 18823 18824 void startProfilesLocked() { 18825 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18826 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18827 mCurrentUserId, false /* enabledOnly */); 18828 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18829 for (UserInfo user : profiles) { 18830 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18831 && user.id != mCurrentUserId) { 18832 toStart.add(user); 18833 } 18834 } 18835 final int n = toStart.size(); 18836 int i = 0; 18837 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18838 startUserInBackground(toStart.get(i).id); 18839 } 18840 if (i < n) { 18841 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18842 } 18843 } 18844 18845 void finishUserBoot(UserStartedState uss) { 18846 synchronized (this) { 18847 if (uss.mState == UserStartedState.STATE_BOOTING 18848 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18849 uss.mState = UserStartedState.STATE_RUNNING; 18850 final int userId = uss.mHandle.getIdentifier(); 18851 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18852 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18853 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18854 broadcastIntentLocked(null, null, intent, 18855 null, null, 0, null, null, 18856 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18857 true, false, MY_PID, Process.SYSTEM_UID, userId); 18858 } 18859 } 18860 } 18861 18862 void finishUserSwitch(UserStartedState uss) { 18863 synchronized (this) { 18864 finishUserBoot(uss); 18865 18866 startProfilesLocked(); 18867 18868 int num = mUserLru.size(); 18869 int i = 0; 18870 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18871 Integer oldUserId = mUserLru.get(i); 18872 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18873 if (oldUss == null) { 18874 // Shouldn't happen, but be sane if it does. 18875 mUserLru.remove(i); 18876 num--; 18877 continue; 18878 } 18879 if (oldUss.mState == UserStartedState.STATE_STOPPING 18880 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18881 // This user is already stopping, doesn't count. 18882 num--; 18883 i++; 18884 continue; 18885 } 18886 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18887 // Owner and current can't be stopped, but count as running. 18888 i++; 18889 continue; 18890 } 18891 // This is a user to be stopped. 18892 stopUserLocked(oldUserId, null); 18893 num--; 18894 i++; 18895 } 18896 } 18897 } 18898 18899 @Override 18900 public int stopUser(final int userId, final IStopUserCallback callback) { 18901 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18902 != PackageManager.PERMISSION_GRANTED) { 18903 String msg = "Permission Denial: switchUser() from pid=" 18904 + Binder.getCallingPid() 18905 + ", uid=" + Binder.getCallingUid() 18906 + " requires " + INTERACT_ACROSS_USERS_FULL; 18907 Slog.w(TAG, msg); 18908 throw new SecurityException(msg); 18909 } 18910 if (userId <= 0) { 18911 throw new IllegalArgumentException("Can't stop primary user " + userId); 18912 } 18913 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18914 synchronized (this) { 18915 return stopUserLocked(userId, callback); 18916 } 18917 } 18918 18919 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18920 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18921 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18922 return ActivityManager.USER_OP_IS_CURRENT; 18923 } 18924 18925 final UserStartedState uss = mStartedUsers.get(userId); 18926 if (uss == null) { 18927 // User is not started, nothing to do... but we do need to 18928 // callback if requested. 18929 if (callback != null) { 18930 mHandler.post(new Runnable() { 18931 @Override 18932 public void run() { 18933 try { 18934 callback.userStopped(userId); 18935 } catch (RemoteException e) { 18936 } 18937 } 18938 }); 18939 } 18940 return ActivityManager.USER_OP_SUCCESS; 18941 } 18942 18943 if (callback != null) { 18944 uss.mStopCallbacks.add(callback); 18945 } 18946 18947 if (uss.mState != UserStartedState.STATE_STOPPING 18948 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18949 uss.mState = UserStartedState.STATE_STOPPING; 18950 updateStartedUserArrayLocked(); 18951 18952 long ident = Binder.clearCallingIdentity(); 18953 try { 18954 // We are going to broadcast ACTION_USER_STOPPING and then 18955 // once that is done send a final ACTION_SHUTDOWN and then 18956 // stop the user. 18957 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18958 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18959 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18960 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18961 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18962 // This is the result receiver for the final shutdown broadcast. 18963 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18964 @Override 18965 public void performReceive(Intent intent, int resultCode, String data, 18966 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18967 finishUserStop(uss); 18968 } 18969 }; 18970 // This is the result receiver for the initial stopping broadcast. 18971 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18972 @Override 18973 public void performReceive(Intent intent, int resultCode, String data, 18974 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18975 // On to the next. 18976 synchronized (ActivityManagerService.this) { 18977 if (uss.mState != UserStartedState.STATE_STOPPING) { 18978 // Whoops, we are being started back up. Abort, abort! 18979 return; 18980 } 18981 uss.mState = UserStartedState.STATE_SHUTDOWN; 18982 } 18983 mBatteryStatsService.noteEvent( 18984 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18985 Integer.toString(userId), userId); 18986 mSystemServiceManager.stopUser(userId); 18987 broadcastIntentLocked(null, null, shutdownIntent, 18988 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18989 true, false, MY_PID, Process.SYSTEM_UID, userId); 18990 } 18991 }; 18992 // Kick things off. 18993 broadcastIntentLocked(null, null, stoppingIntent, 18994 null, stoppingReceiver, 0, null, null, 18995 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18996 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18997 } finally { 18998 Binder.restoreCallingIdentity(ident); 18999 } 19000 } 19001 19002 return ActivityManager.USER_OP_SUCCESS; 19003 } 19004 19005 void finishUserStop(UserStartedState uss) { 19006 final int userId = uss.mHandle.getIdentifier(); 19007 boolean stopped; 19008 ArrayList<IStopUserCallback> callbacks; 19009 synchronized (this) { 19010 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19011 if (mStartedUsers.get(userId) != uss) { 19012 stopped = false; 19013 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19014 stopped = false; 19015 } else { 19016 stopped = true; 19017 // User can no longer run. 19018 mStartedUsers.remove(userId); 19019 mUserLru.remove(Integer.valueOf(userId)); 19020 updateStartedUserArrayLocked(); 19021 19022 // Clean up all state and processes associated with the user. 19023 // Kill all the processes for the user. 19024 forceStopUserLocked(userId, "finish user"); 19025 } 19026 19027 // Explicitly remove the old information in mRecentTasks. 19028 removeRecentTasksForUserLocked(userId); 19029 } 19030 19031 for (int i=0; i<callbacks.size(); i++) { 19032 try { 19033 if (stopped) callbacks.get(i).userStopped(userId); 19034 else callbacks.get(i).userStopAborted(userId); 19035 } catch (RemoteException e) { 19036 } 19037 } 19038 19039 if (stopped) { 19040 mSystemServiceManager.cleanupUser(userId); 19041 synchronized (this) { 19042 mStackSupervisor.removeUserLocked(userId); 19043 } 19044 } 19045 } 19046 19047 @Override 19048 public UserInfo getCurrentUser() { 19049 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19050 != PackageManager.PERMISSION_GRANTED) && ( 19051 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19052 != PackageManager.PERMISSION_GRANTED)) { 19053 String msg = "Permission Denial: getCurrentUser() from pid=" 19054 + Binder.getCallingPid() 19055 + ", uid=" + Binder.getCallingUid() 19056 + " requires " + INTERACT_ACROSS_USERS; 19057 Slog.w(TAG, msg); 19058 throw new SecurityException(msg); 19059 } 19060 synchronized (this) { 19061 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19062 return getUserManagerLocked().getUserInfo(userId); 19063 } 19064 } 19065 19066 int getCurrentUserIdLocked() { 19067 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19068 } 19069 19070 @Override 19071 public boolean isUserRunning(int userId, boolean orStopped) { 19072 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19073 != PackageManager.PERMISSION_GRANTED) { 19074 String msg = "Permission Denial: isUserRunning() from pid=" 19075 + Binder.getCallingPid() 19076 + ", uid=" + Binder.getCallingUid() 19077 + " requires " + INTERACT_ACROSS_USERS; 19078 Slog.w(TAG, msg); 19079 throw new SecurityException(msg); 19080 } 19081 synchronized (this) { 19082 return isUserRunningLocked(userId, orStopped); 19083 } 19084 } 19085 19086 boolean isUserRunningLocked(int userId, boolean orStopped) { 19087 UserStartedState state = mStartedUsers.get(userId); 19088 if (state == null) { 19089 return false; 19090 } 19091 if (orStopped) { 19092 return true; 19093 } 19094 return state.mState != UserStartedState.STATE_STOPPING 19095 && state.mState != UserStartedState.STATE_SHUTDOWN; 19096 } 19097 19098 @Override 19099 public int[] getRunningUserIds() { 19100 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19101 != PackageManager.PERMISSION_GRANTED) { 19102 String msg = "Permission Denial: isUserRunning() from pid=" 19103 + Binder.getCallingPid() 19104 + ", uid=" + Binder.getCallingUid() 19105 + " requires " + INTERACT_ACROSS_USERS; 19106 Slog.w(TAG, msg); 19107 throw new SecurityException(msg); 19108 } 19109 synchronized (this) { 19110 return mStartedUserArray; 19111 } 19112 } 19113 19114 private void updateStartedUserArrayLocked() { 19115 int num = 0; 19116 for (int i=0; i<mStartedUsers.size(); i++) { 19117 UserStartedState uss = mStartedUsers.valueAt(i); 19118 // This list does not include stopping users. 19119 if (uss.mState != UserStartedState.STATE_STOPPING 19120 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19121 num++; 19122 } 19123 } 19124 mStartedUserArray = new int[num]; 19125 num = 0; 19126 for (int i=0; i<mStartedUsers.size(); i++) { 19127 UserStartedState uss = mStartedUsers.valueAt(i); 19128 if (uss.mState != UserStartedState.STATE_STOPPING 19129 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19130 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19131 num++; 19132 } 19133 } 19134 } 19135 19136 @Override 19137 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19138 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19139 != PackageManager.PERMISSION_GRANTED) { 19140 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19141 + Binder.getCallingPid() 19142 + ", uid=" + Binder.getCallingUid() 19143 + " requires " + INTERACT_ACROSS_USERS_FULL; 19144 Slog.w(TAG, msg); 19145 throw new SecurityException(msg); 19146 } 19147 19148 mUserSwitchObservers.register(observer); 19149 } 19150 19151 @Override 19152 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19153 mUserSwitchObservers.unregister(observer); 19154 } 19155 19156 private boolean userExists(int userId) { 19157 if (userId == 0) { 19158 return true; 19159 } 19160 UserManagerService ums = getUserManagerLocked(); 19161 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19162 } 19163 19164 int[] getUsersLocked() { 19165 UserManagerService ums = getUserManagerLocked(); 19166 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19167 } 19168 19169 UserManagerService getUserManagerLocked() { 19170 if (mUserManager == null) { 19171 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19172 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19173 } 19174 return mUserManager; 19175 } 19176 19177 private int applyUserId(int uid, int userId) { 19178 return UserHandle.getUid(userId, uid); 19179 } 19180 19181 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19182 if (info == null) return null; 19183 ApplicationInfo newInfo = new ApplicationInfo(info); 19184 newInfo.uid = applyUserId(info.uid, userId); 19185 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19186 + info.packageName; 19187 return newInfo; 19188 } 19189 19190 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19191 if (aInfo == null 19192 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19193 return aInfo; 19194 } 19195 19196 ActivityInfo info = new ActivityInfo(aInfo); 19197 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19198 return info; 19199 } 19200 19201 private final class LocalService extends ActivityManagerInternal { 19202 @Override 19203 public void goingToSleep() { 19204 ActivityManagerService.this.goingToSleep(); 19205 } 19206 19207 @Override 19208 public void wakingUp() { 19209 ActivityManagerService.this.wakingUp(); 19210 } 19211 19212 @Override 19213 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19214 String processName, String abiOverride, int uid, Runnable crashHandler) { 19215 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19216 processName, abiOverride, uid, crashHandler); 19217 } 19218 } 19219 19220 /** 19221 * An implementation of IAppTask, that allows an app to manage its own tasks via 19222 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19223 * only the process that calls getAppTasks() can call the AppTask methods. 19224 */ 19225 class AppTaskImpl extends IAppTask.Stub { 19226 private int mTaskId; 19227 private int mCallingUid; 19228 19229 public AppTaskImpl(int taskId, int callingUid) { 19230 mTaskId = taskId; 19231 mCallingUid = callingUid; 19232 } 19233 19234 private void checkCaller() { 19235 if (mCallingUid != Binder.getCallingUid()) { 19236 throw new SecurityException("Caller " + mCallingUid 19237 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19238 } 19239 } 19240 19241 @Override 19242 public void finishAndRemoveTask() { 19243 checkCaller(); 19244 19245 synchronized (ActivityManagerService.this) { 19246 long origId = Binder.clearCallingIdentity(); 19247 try { 19248 if (!removeTaskByIdLocked(mTaskId, false)) { 19249 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19250 } 19251 } finally { 19252 Binder.restoreCallingIdentity(origId); 19253 } 19254 } 19255 } 19256 19257 @Override 19258 public ActivityManager.RecentTaskInfo getTaskInfo() { 19259 checkCaller(); 19260 19261 synchronized (ActivityManagerService.this) { 19262 long origId = Binder.clearCallingIdentity(); 19263 try { 19264 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19265 if (tr == null) { 19266 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19267 } 19268 return createRecentTaskInfoFromTaskRecord(tr); 19269 } finally { 19270 Binder.restoreCallingIdentity(origId); 19271 } 19272 } 19273 } 19274 19275 @Override 19276 public void moveToFront() { 19277 checkCaller(); 19278 19279 final TaskRecord tr; 19280 synchronized (ActivityManagerService.this) { 19281 tr = recentTaskForIdLocked(mTaskId); 19282 if (tr == null) { 19283 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19284 } 19285 if (tr.getRootActivity() != null) { 19286 moveTaskToFrontLocked(tr.taskId, 0, null); 19287 return; 19288 } 19289 } 19290 19291 startActivityFromRecentsInner(tr.taskId, null); 19292 } 19293 19294 @Override 19295 public int startActivity(IBinder whoThread, String callingPackage, 19296 Intent intent, String resolvedType, Bundle options) { 19297 checkCaller(); 19298 19299 int callingUser = UserHandle.getCallingUserId(); 19300 TaskRecord tr; 19301 IApplicationThread appThread; 19302 synchronized (ActivityManagerService.this) { 19303 tr = recentTaskForIdLocked(mTaskId); 19304 if (tr == null) { 19305 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19306 } 19307 appThread = ApplicationThreadNative.asInterface(whoThread); 19308 if (appThread == null) { 19309 throw new IllegalArgumentException("Bad app thread " + appThread); 19310 } 19311 } 19312 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19313 resolvedType, null, null, null, null, 0, 0, null, null, 19314 null, options, callingUser, null, tr); 19315 } 19316 19317 @Override 19318 public void setExcludeFromRecents(boolean exclude) { 19319 checkCaller(); 19320 19321 synchronized (ActivityManagerService.this) { 19322 long origId = Binder.clearCallingIdentity(); 19323 try { 19324 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19325 if (tr == null) { 19326 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19327 } 19328 Intent intent = tr.getBaseIntent(); 19329 if (exclude) { 19330 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19331 } else { 19332 intent.setFlags(intent.getFlags() 19333 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19334 } 19335 } finally { 19336 Binder.restoreCallingIdentity(origId); 19337 } 19338 } 19339 } 19340 } 19341} 19342