ActivityManagerService.java revision 0a41a578023fc3614f8888552b32fe9ea0d74eae
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 int pid; 838 public int uid; 839 840 Identity(int _pid, int _uid) { 841 pid = _pid; 842 uid = _uid; 843 } 844 } 845 846 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 847 848 /** 849 * All information we have collected about the runtime performance of 850 * any user id that can impact battery performance. 851 */ 852 final BatteryStatsService mBatteryStatsService; 853 854 /** 855 * Information about component usage 856 */ 857 UsageStatsManagerInternal mUsageStatsService; 858 859 /** 860 * Information about and control over application operations 861 */ 862 final AppOpsService mAppOpsService; 863 864 /** 865 * Save recent tasks information across reboots. 866 */ 867 final TaskPersister mTaskPersister; 868 869 /** 870 * Current configuration information. HistoryRecord objects are given 871 * a reference to this object to indicate which configuration they are 872 * currently running in, so this object must be kept immutable. 873 */ 874 Configuration mConfiguration = new Configuration(); 875 876 /** 877 * Current sequencing integer of the configuration, for skipping old 878 * configurations. 879 */ 880 int mConfigurationSeq = 0; 881 882 /** 883 * Hardware-reported OpenGLES version. 884 */ 885 final int GL_ES_VERSION; 886 887 /** 888 * List of initialization arguments to pass to all processes when binding applications to them. 889 * For example, references to the commonly used services. 890 */ 891 HashMap<String, IBinder> mAppBindArgs; 892 893 /** 894 * Temporary to avoid allocations. Protected by main lock. 895 */ 896 final StringBuilder mStringBuilder = new StringBuilder(256); 897 898 /** 899 * Used to control how we initialize the service. 900 */ 901 ComponentName mTopComponent; 902 String mTopAction = Intent.ACTION_MAIN; 903 String mTopData; 904 boolean mProcessesReady = false; 905 boolean mSystemReady = false; 906 boolean mBooting = false; 907 boolean mCallFinishBooting = false; 908 boolean mBootAnimationComplete = false; 909 boolean mWaitingUpdate = false; 910 boolean mDidUpdate = false; 911 boolean mOnBattery = false; 912 boolean mLaunchWarningShown = false; 913 914 Context mContext; 915 916 int mFactoryTest; 917 918 boolean mCheckedForSetup; 919 920 /** 921 * The time at which we will allow normal application switches again, 922 * after a call to {@link #stopAppSwitches()}. 923 */ 924 long mAppSwitchesAllowedTime; 925 926 /** 927 * This is set to true after the first switch after mAppSwitchesAllowedTime 928 * is set; any switches after that will clear the time. 929 */ 930 boolean mDidAppSwitch; 931 932 /** 933 * Last time (in realtime) at which we checked for power usage. 934 */ 935 long mLastPowerCheckRealtime; 936 937 /** 938 * Last time (in uptime) at which we checked for power usage. 939 */ 940 long mLastPowerCheckUptime; 941 942 /** 943 * Set while we are wanting to sleep, to prevent any 944 * activities from being started/resumed. 945 */ 946 private boolean mSleeping = false; 947 948 /** 949 * Set while we are running a voice interaction. This overrides 950 * sleeping while it is active. 951 */ 952 private boolean mRunningVoice = false; 953 954 /** 955 * State of external calls telling us if the device is asleep. 956 */ 957 private boolean mWentToSleep = false; 958 959 static final int LOCK_SCREEN_HIDDEN = 0; 960 static final int LOCK_SCREEN_LEAVING = 1; 961 static final int LOCK_SCREEN_SHOWN = 2; 962 /** 963 * State of external call telling us if the lock screen is shown. 964 */ 965 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 966 967 /** 968 * Set if we are shutting down the system, similar to sleeping. 969 */ 970 boolean mShuttingDown = false; 971 972 /** 973 * Current sequence id for oom_adj computation traversal. 974 */ 975 int mAdjSeq = 0; 976 977 /** 978 * Current sequence id for process LRU updating. 979 */ 980 int mLruSeq = 0; 981 982 /** 983 * Keep track of the non-cached/empty process we last found, to help 984 * determine how to distribute cached/empty processes next time. 985 */ 986 int mNumNonCachedProcs = 0; 987 988 /** 989 * Keep track of the number of cached hidden procs, to balance oom adj 990 * distribution between those and empty procs. 991 */ 992 int mNumCachedHiddenProcs = 0; 993 994 /** 995 * Keep track of the number of service processes we last found, to 996 * determine on the next iteration which should be B services. 997 */ 998 int mNumServiceProcs = 0; 999 int mNewNumAServiceProcs = 0; 1000 int mNewNumServiceProcs = 0; 1001 1002 /** 1003 * Allow the current computed overall memory level of the system to go down? 1004 * This is set to false when we are killing processes for reasons other than 1005 * memory management, so that the now smaller process list will not be taken as 1006 * an indication that memory is tighter. 1007 */ 1008 boolean mAllowLowerMemLevel = false; 1009 1010 /** 1011 * The last computed memory level, for holding when we are in a state that 1012 * processes are going away for other reasons. 1013 */ 1014 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1015 1016 /** 1017 * The last total number of process we have, to determine if changes actually look 1018 * like a shrinking number of process due to lower RAM. 1019 */ 1020 int mLastNumProcesses; 1021 1022 /** 1023 * The uptime of the last time we performed idle maintenance. 1024 */ 1025 long mLastIdleTime = SystemClock.uptimeMillis(); 1026 1027 /** 1028 * Total time spent with RAM that has been added in the past since the last idle time. 1029 */ 1030 long mLowRamTimeSinceLastIdle = 0; 1031 1032 /** 1033 * If RAM is currently low, when that horrible situation started. 1034 */ 1035 long mLowRamStartTime = 0; 1036 1037 /** 1038 * For reporting to battery stats the current top application. 1039 */ 1040 private String mCurResumedPackage = null; 1041 private int mCurResumedUid = -1; 1042 1043 /** 1044 * For reporting to battery stats the apps currently running foreground 1045 * service. The ProcessMap is package/uid tuples; each of these contain 1046 * an array of the currently foreground processes. 1047 */ 1048 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1049 = new ProcessMap<ArrayList<ProcessRecord>>(); 1050 1051 /** 1052 * This is set if we had to do a delayed dexopt of an app before launching 1053 * it, to increase the ANR timeouts in that case. 1054 */ 1055 boolean mDidDexOpt; 1056 1057 /** 1058 * Set if the systemServer made a call to enterSafeMode. 1059 */ 1060 boolean mSafeMode; 1061 1062 String mDebugApp = null; 1063 boolean mWaitForDebugger = false; 1064 boolean mDebugTransient = false; 1065 String mOrigDebugApp = null; 1066 boolean mOrigWaitForDebugger = false; 1067 boolean mAlwaysFinishActivities = false; 1068 IActivityController mController = null; 1069 String mProfileApp = null; 1070 ProcessRecord mProfileProc = null; 1071 String mProfileFile; 1072 ParcelFileDescriptor mProfileFd; 1073 int mSamplingInterval = 0; 1074 boolean mAutoStopProfiler = false; 1075 int mProfileType = 0; 1076 String mOpenGlTraceApp = null; 1077 1078 static class ProcessChangeItem { 1079 static final int CHANGE_ACTIVITIES = 1<<0; 1080 static final int CHANGE_PROCESS_STATE = 1<<1; 1081 int changes; 1082 int uid; 1083 int pid; 1084 int processState; 1085 boolean foregroundActivities; 1086 } 1087 1088 final RemoteCallbackList<IProcessObserver> mProcessObservers 1089 = new RemoteCallbackList<IProcessObserver>(); 1090 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1091 1092 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1093 = new ArrayList<ProcessChangeItem>(); 1094 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1095 = new ArrayList<ProcessChangeItem>(); 1096 1097 /** 1098 * Runtime CPU use collection thread. This object's lock is used to 1099 * perform synchronization with the thread (notifying it to run). 1100 */ 1101 final Thread mProcessCpuThread; 1102 1103 /** 1104 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1105 * Must acquire this object's lock when accessing it. 1106 * NOTE: this lock will be held while doing long operations (trawling 1107 * through all processes in /proc), so it should never be acquired by 1108 * any critical paths such as when holding the main activity manager lock. 1109 */ 1110 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1111 MONITOR_THREAD_CPU_USAGE); 1112 final AtomicLong mLastCpuTime = new AtomicLong(0); 1113 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1114 1115 long mLastWriteTime = 0; 1116 1117 /** 1118 * Used to retain an update lock when the foreground activity is in 1119 * immersive mode. 1120 */ 1121 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1122 1123 /** 1124 * Set to true after the system has finished booting. 1125 */ 1126 boolean mBooted = false; 1127 1128 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1129 int mProcessLimitOverride = -1; 1130 1131 WindowManagerService mWindowManager; 1132 1133 final ActivityThread mSystemThread; 1134 1135 // Holds the current foreground user's id 1136 int mCurrentUserId = 0; 1137 // Holds the target user's id during a user switch 1138 int mTargetUserId = UserHandle.USER_NULL; 1139 // If there are multiple profiles for the current user, their ids are here 1140 // Currently only the primary user can have managed profiles 1141 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1142 1143 /** 1144 * Mapping from each known user ID to the profile group ID it is associated with. 1145 */ 1146 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1147 1148 private UserManagerService mUserManager; 1149 1150 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1151 final ProcessRecord mApp; 1152 final int mPid; 1153 final IApplicationThread mAppThread; 1154 1155 AppDeathRecipient(ProcessRecord app, int pid, 1156 IApplicationThread thread) { 1157 if (localLOGV) Slog.v( 1158 TAG, "New death recipient " + this 1159 + " for thread " + thread.asBinder()); 1160 mApp = app; 1161 mPid = pid; 1162 mAppThread = thread; 1163 } 1164 1165 @Override 1166 public void binderDied() { 1167 if (localLOGV) Slog.v( 1168 TAG, "Death received in " + this 1169 + " for thread " + mAppThread.asBinder()); 1170 synchronized(ActivityManagerService.this) { 1171 appDiedLocked(mApp, mPid, mAppThread); 1172 } 1173 } 1174 } 1175 1176 static final int SHOW_ERROR_MSG = 1; 1177 static final int SHOW_NOT_RESPONDING_MSG = 2; 1178 static final int SHOW_FACTORY_ERROR_MSG = 3; 1179 static final int UPDATE_CONFIGURATION_MSG = 4; 1180 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1181 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1182 static final int SERVICE_TIMEOUT_MSG = 12; 1183 static final int UPDATE_TIME_ZONE = 13; 1184 static final int SHOW_UID_ERROR_MSG = 14; 1185 static final int IM_FEELING_LUCKY_MSG = 15; 1186 static final int PROC_START_TIMEOUT_MSG = 20; 1187 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1188 static final int KILL_APPLICATION_MSG = 22; 1189 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1190 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1191 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1192 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1193 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1194 static final int CLEAR_DNS_CACHE_MSG = 28; 1195 static final int UPDATE_HTTP_PROXY_MSG = 29; 1196 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1197 static final int DISPATCH_PROCESSES_CHANGED = 31; 1198 static final int DISPATCH_PROCESS_DIED = 32; 1199 static final int REPORT_MEM_USAGE_MSG = 33; 1200 static final int REPORT_USER_SWITCH_MSG = 34; 1201 static final int CONTINUE_USER_SWITCH_MSG = 35; 1202 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1203 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1204 static final int PERSIST_URI_GRANTS_MSG = 38; 1205 static final int REQUEST_ALL_PSS_MSG = 39; 1206 static final int START_PROFILES_MSG = 40; 1207 static final int UPDATE_TIME = 41; 1208 static final int SYSTEM_USER_START_MSG = 42; 1209 static final int SYSTEM_USER_CURRENT_MSG = 43; 1210 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1211 static final int FINISH_BOOTING_MSG = 45; 1212 static final int START_USER_SWITCH_MSG = 46; 1213 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1214 1215 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1216 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1217 static final int FIRST_COMPAT_MODE_MSG = 300; 1218 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1219 1220 AlertDialog mUidAlert; 1221 CompatModeDialog mCompatModeDialog; 1222 long mLastMemUsageReportTime = 0; 1223 1224 /** 1225 * Flag whether the current user is a "monkey", i.e. whether 1226 * the UI is driven by a UI automation tool. 1227 */ 1228 private boolean mUserIsMonkey; 1229 1230 /** Flag whether the device has a Recents UI */ 1231 boolean mHasRecents; 1232 1233 /** The dimensions of the thumbnails in the Recents UI. */ 1234 int mThumbnailWidth; 1235 int mThumbnailHeight; 1236 1237 final ServiceThread mHandlerThread; 1238 final MainHandler mHandler; 1239 1240 final class MainHandler extends Handler { 1241 public MainHandler(Looper looper) { 1242 super(looper, null, true); 1243 } 1244 1245 @Override 1246 public void handleMessage(Message msg) { 1247 switch (msg.what) { 1248 case SHOW_ERROR_MSG: { 1249 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1250 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1251 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1252 synchronized (ActivityManagerService.this) { 1253 ProcessRecord proc = (ProcessRecord)data.get("app"); 1254 AppErrorResult res = (AppErrorResult) data.get("result"); 1255 if (proc != null && proc.crashDialog != null) { 1256 Slog.e(TAG, "App already has crash dialog: " + proc); 1257 if (res != null) { 1258 res.set(0); 1259 } 1260 return; 1261 } 1262 boolean isBackground = (UserHandle.getAppId(proc.uid) 1263 >= Process.FIRST_APPLICATION_UID 1264 && proc.pid != MY_PID); 1265 for (int userId : mCurrentProfileIds) { 1266 isBackground &= (proc.userId != userId); 1267 } 1268 if (isBackground && !showBackground) { 1269 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1270 if (res != null) { 1271 res.set(0); 1272 } 1273 return; 1274 } 1275 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1276 Dialog d = new AppErrorDialog(mContext, 1277 ActivityManagerService.this, res, proc); 1278 d.show(); 1279 proc.crashDialog = d; 1280 } else { 1281 // The device is asleep, so just pretend that the user 1282 // saw a crash dialog and hit "force quit". 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 } 1287 } 1288 1289 ensureBootCompleted(); 1290 } break; 1291 case SHOW_NOT_RESPONDING_MSG: { 1292 synchronized (ActivityManagerService.this) { 1293 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1294 ProcessRecord proc = (ProcessRecord)data.get("app"); 1295 if (proc != null && proc.anrDialog != null) { 1296 Slog.e(TAG, "App already has anr dialog: " + proc); 1297 return; 1298 } 1299 1300 Intent intent = new Intent("android.intent.action.ANR"); 1301 if (!mProcessesReady) { 1302 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1303 | Intent.FLAG_RECEIVER_FOREGROUND); 1304 } 1305 broadcastIntentLocked(null, null, intent, 1306 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1307 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1308 1309 if (mShowDialogs) { 1310 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1311 mContext, proc, (ActivityRecord)data.get("activity"), 1312 msg.arg1 != 0); 1313 d.show(); 1314 proc.anrDialog = d; 1315 } else { 1316 // Just kill the app if there is no dialog to be shown. 1317 killAppAtUsersRequest(proc, null); 1318 } 1319 } 1320 1321 ensureBootCompleted(); 1322 } break; 1323 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1324 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1325 synchronized (ActivityManagerService.this) { 1326 ProcessRecord proc = (ProcessRecord) data.get("app"); 1327 if (proc == null) { 1328 Slog.e(TAG, "App not found when showing strict mode dialog."); 1329 break; 1330 } 1331 if (proc.crashDialog != null) { 1332 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1333 return; 1334 } 1335 AppErrorResult res = (AppErrorResult) data.get("result"); 1336 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1337 Dialog d = new StrictModeViolationDialog(mContext, 1338 ActivityManagerService.this, res, proc); 1339 d.show(); 1340 proc.crashDialog = d; 1341 } else { 1342 // The device is asleep, so just pretend that the user 1343 // saw a crash dialog and hit "force quit". 1344 res.set(0); 1345 } 1346 } 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_FACTORY_ERROR_MSG: { 1350 Dialog d = new FactoryErrorDialog( 1351 mContext, msg.getData().getCharSequence("msg")); 1352 d.show(); 1353 ensureBootCompleted(); 1354 } break; 1355 case UPDATE_CONFIGURATION_MSG: { 1356 final ContentResolver resolver = mContext.getContentResolver(); 1357 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1358 } break; 1359 case GC_BACKGROUND_PROCESSES_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 performAppGcsIfAppropriateLocked(); 1362 } 1363 } break; 1364 case WAIT_FOR_DEBUGGER_MSG: { 1365 synchronized (ActivityManagerService.this) { 1366 ProcessRecord app = (ProcessRecord)msg.obj; 1367 if (msg.arg1 != 0) { 1368 if (!app.waitedForDebugger) { 1369 Dialog d = new AppWaitingForDebuggerDialog( 1370 ActivityManagerService.this, 1371 mContext, app); 1372 app.waitDialog = d; 1373 app.waitedForDebugger = true; 1374 d.show(); 1375 } 1376 } else { 1377 if (app.waitDialog != null) { 1378 app.waitDialog.dismiss(); 1379 app.waitDialog = null; 1380 } 1381 } 1382 } 1383 } break; 1384 case SERVICE_TIMEOUT_MSG: { 1385 if (mDidDexOpt) { 1386 mDidDexOpt = false; 1387 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1388 nmsg.obj = msg.obj; 1389 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1390 return; 1391 } 1392 mServices.serviceTimeout((ProcessRecord)msg.obj); 1393 } break; 1394 case UPDATE_TIME_ZONE: { 1395 synchronized (ActivityManagerService.this) { 1396 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1397 ProcessRecord r = mLruProcesses.get(i); 1398 if (r.thread != null) { 1399 try { 1400 r.thread.updateTimeZone(); 1401 } catch (RemoteException ex) { 1402 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1403 } 1404 } 1405 } 1406 } 1407 } break; 1408 case CLEAR_DNS_CACHE_MSG: { 1409 synchronized (ActivityManagerService.this) { 1410 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1411 ProcessRecord r = mLruProcesses.get(i); 1412 if (r.thread != null) { 1413 try { 1414 r.thread.clearDnsCache(); 1415 } catch (RemoteException ex) { 1416 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1417 } 1418 } 1419 } 1420 } 1421 } break; 1422 case UPDATE_HTTP_PROXY_MSG: { 1423 ProxyInfo proxy = (ProxyInfo)msg.obj; 1424 String host = ""; 1425 String port = ""; 1426 String exclList = ""; 1427 Uri pacFileUrl = Uri.EMPTY; 1428 if (proxy != null) { 1429 host = proxy.getHost(); 1430 port = Integer.toString(proxy.getPort()); 1431 exclList = proxy.getExclusionListAsString(); 1432 pacFileUrl = proxy.getPacFileUrl(); 1433 } 1434 synchronized (ActivityManagerService.this) { 1435 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1436 ProcessRecord r = mLruProcesses.get(i); 1437 if (r.thread != null) { 1438 try { 1439 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1440 } catch (RemoteException ex) { 1441 Slog.w(TAG, "Failed to update http proxy for: " + 1442 r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case SHOW_UID_ERROR_MSG: { 1449 String title = "System UIDs Inconsistent"; 1450 String text = "UIDs on the system are inconsistent, you need to wipe your" 1451 + " data partition or your device will be unstable."; 1452 Log.e(TAG, title + ": " + text); 1453 if (mShowDialogs) { 1454 // XXX This is a temporary dialog, no need to localize. 1455 AlertDialog d = new BaseErrorDialog(mContext); 1456 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1457 d.setCancelable(false); 1458 d.setTitle(title); 1459 d.setMessage(text); 1460 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1461 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1462 mUidAlert = d; 1463 d.show(); 1464 } 1465 } break; 1466 case IM_FEELING_LUCKY_MSG: { 1467 if (mUidAlert != null) { 1468 mUidAlert.dismiss(); 1469 mUidAlert = null; 1470 } 1471 } break; 1472 case PROC_START_TIMEOUT_MSG: { 1473 if (mDidDexOpt) { 1474 mDidDexOpt = false; 1475 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1476 nmsg.obj = msg.obj; 1477 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1478 return; 1479 } 1480 ProcessRecord app = (ProcessRecord)msg.obj; 1481 synchronized (ActivityManagerService.this) { 1482 processStartTimedOutLocked(app); 1483 } 1484 } break; 1485 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1488 } 1489 } break; 1490 case KILL_APPLICATION_MSG: { 1491 synchronized (ActivityManagerService.this) { 1492 int appid = msg.arg1; 1493 boolean restart = (msg.arg2 == 1); 1494 Bundle bundle = (Bundle)msg.obj; 1495 String pkg = bundle.getString("pkg"); 1496 String reason = bundle.getString("reason"); 1497 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1498 false, UserHandle.USER_ALL, reason); 1499 } 1500 } break; 1501 case FINALIZE_PENDING_INTENT_MSG: { 1502 ((PendingIntentRecord)msg.obj).completeFinalize(); 1503 } break; 1504 case POST_HEAVY_NOTIFICATION_MSG: { 1505 INotificationManager inm = NotificationManager.getService(); 1506 if (inm == null) { 1507 return; 1508 } 1509 1510 ActivityRecord root = (ActivityRecord)msg.obj; 1511 ProcessRecord process = root.app; 1512 if (process == null) { 1513 return; 1514 } 1515 1516 try { 1517 Context context = mContext.createPackageContext(process.info.packageName, 0); 1518 String text = mContext.getString(R.string.heavy_weight_notification, 1519 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1520 Notification notification = new Notification(); 1521 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1522 notification.when = 0; 1523 notification.flags = Notification.FLAG_ONGOING_EVENT; 1524 notification.tickerText = text; 1525 notification.defaults = 0; // please be quiet 1526 notification.sound = null; 1527 notification.vibrate = null; 1528 notification.color = mContext.getResources().getColor( 1529 com.android.internal.R.color.system_notification_accent_color); 1530 notification.setLatestEventInfo(context, text, 1531 mContext.getText(R.string.heavy_weight_notification_detail), 1532 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1533 PendingIntent.FLAG_CANCEL_CURRENT, null, 1534 new UserHandle(root.userId))); 1535 1536 try { 1537 int[] outId = new int[1]; 1538 inm.enqueueNotificationWithTag("android", "android", null, 1539 R.string.heavy_weight_notification, 1540 notification, outId, root.userId); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error showing notification for heavy-weight app", e); 1544 } catch (RemoteException e) { 1545 } 1546 } catch (NameNotFoundException e) { 1547 Slog.w(TAG, "Unable to create context for heavy notification", e); 1548 } 1549 } break; 1550 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1551 INotificationManager inm = NotificationManager.getService(); 1552 if (inm == null) { 1553 return; 1554 } 1555 try { 1556 inm.cancelNotificationWithTag("android", null, 1557 R.string.heavy_weight_notification, msg.arg1); 1558 } catch (RuntimeException e) { 1559 Slog.w(ActivityManagerService.TAG, 1560 "Error canceling notification for service", e); 1561 } catch (RemoteException e) { 1562 } 1563 } break; 1564 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1565 synchronized (ActivityManagerService.this) { 1566 checkExcessivePowerUsageLocked(true); 1567 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1568 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1569 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1570 } 1571 } break; 1572 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1573 synchronized (ActivityManagerService.this) { 1574 ActivityRecord ar = (ActivityRecord)msg.obj; 1575 if (mCompatModeDialog != null) { 1576 if (mCompatModeDialog.mAppInfo.packageName.equals( 1577 ar.info.applicationInfo.packageName)) { 1578 return; 1579 } 1580 mCompatModeDialog.dismiss(); 1581 mCompatModeDialog = null; 1582 } 1583 if (ar != null && false) { 1584 if (mCompatModePackages.getPackageAskCompatModeLocked( 1585 ar.packageName)) { 1586 int mode = mCompatModePackages.computeCompatModeLocked( 1587 ar.info.applicationInfo); 1588 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1589 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1590 mCompatModeDialog = new CompatModeDialog( 1591 ActivityManagerService.this, mContext, 1592 ar.info.applicationInfo); 1593 mCompatModeDialog.show(); 1594 } 1595 } 1596 } 1597 } 1598 break; 1599 } 1600 case DISPATCH_PROCESSES_CHANGED: { 1601 dispatchProcessesChanged(); 1602 break; 1603 } 1604 case DISPATCH_PROCESS_DIED: { 1605 final int pid = msg.arg1; 1606 final int uid = msg.arg2; 1607 dispatchProcessDied(pid, uid); 1608 break; 1609 } 1610 case REPORT_MEM_USAGE_MSG: { 1611 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1612 Thread thread = new Thread() { 1613 @Override public void run() { 1614 reportMemUsage(memInfos); 1615 } 1616 }; 1617 thread.start(); 1618 break; 1619 } 1620 case START_USER_SWITCH_MSG: { 1621 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1622 break; 1623 } 1624 case REPORT_USER_SWITCH_MSG: { 1625 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1626 break; 1627 } 1628 case CONTINUE_USER_SWITCH_MSG: { 1629 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1630 break; 1631 } 1632 case USER_SWITCH_TIMEOUT_MSG: { 1633 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1634 break; 1635 } 1636 case IMMERSIVE_MODE_LOCK_MSG: { 1637 final boolean nextState = (msg.arg1 != 0); 1638 if (mUpdateLock.isHeld() != nextState) { 1639 if (DEBUG_IMMERSIVE) { 1640 final ActivityRecord r = (ActivityRecord) msg.obj; 1641 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1642 } 1643 if (nextState) { 1644 mUpdateLock.acquire(); 1645 } else { 1646 mUpdateLock.release(); 1647 } 1648 } 1649 break; 1650 } 1651 case PERSIST_URI_GRANTS_MSG: { 1652 writeGrantedUriPermissions(); 1653 break; 1654 } 1655 case REQUEST_ALL_PSS_MSG: { 1656 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1657 break; 1658 } 1659 case START_PROFILES_MSG: { 1660 synchronized (ActivityManagerService.this) { 1661 startProfilesLocked(); 1662 } 1663 break; 1664 } 1665 case UPDATE_TIME: { 1666 synchronized (ActivityManagerService.this) { 1667 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1668 ProcessRecord r = mLruProcesses.get(i); 1669 if (r.thread != null) { 1670 try { 1671 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1672 } catch (RemoteException ex) { 1673 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1674 } 1675 } 1676 } 1677 } 1678 break; 1679 } 1680 case SYSTEM_USER_START_MSG: { 1681 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1682 Integer.toString(msg.arg1), msg.arg1); 1683 mSystemServiceManager.startUser(msg.arg1); 1684 break; 1685 } 1686 case SYSTEM_USER_CURRENT_MSG: { 1687 mBatteryStatsService.noteEvent( 1688 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1689 Integer.toString(msg.arg2), msg.arg2); 1690 mBatteryStatsService.noteEvent( 1691 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1692 Integer.toString(msg.arg1), msg.arg1); 1693 mSystemServiceManager.switchUser(msg.arg1); 1694 break; 1695 } 1696 case ENTER_ANIMATION_COMPLETE_MSG: { 1697 synchronized (ActivityManagerService.this) { 1698 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1699 if (r != null && r.app != null && r.app.thread != null) { 1700 try { 1701 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1702 } catch (RemoteException e) { 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case FINISH_BOOTING_MSG: { 1709 if (msg.arg1 != 0) { 1710 finishBooting(); 1711 } 1712 if (msg.arg2 != 0) { 1713 enableScreenAfterBoot(); 1714 } 1715 break; 1716 } 1717 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1718 try { 1719 Locale l = (Locale) msg.obj; 1720 IBinder service = ServiceManager.getService("mount"); 1721 IMountService mountService = IMountService.Stub.asInterface(service); 1722 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1723 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1724 } catch (RemoteException e) { 1725 Log.e(TAG, "Error storing locale for decryption UI", e); 1726 } 1727 break; 1728 } 1729 } 1730 } 1731 }; 1732 1733 static final int COLLECT_PSS_BG_MSG = 1; 1734 1735 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1736 @Override 1737 public void handleMessage(Message msg) { 1738 switch (msg.what) { 1739 case COLLECT_PSS_BG_MSG: { 1740 long start = SystemClock.uptimeMillis(); 1741 MemInfoReader memInfo = null; 1742 synchronized (ActivityManagerService.this) { 1743 if (mFullPssPending) { 1744 mFullPssPending = false; 1745 memInfo = new MemInfoReader(); 1746 } 1747 } 1748 if (memInfo != null) { 1749 updateCpuStatsNow(); 1750 long nativeTotalPss = 0; 1751 synchronized (mProcessCpuTracker) { 1752 final int N = mProcessCpuTracker.countStats(); 1753 for (int j=0; j<N; j++) { 1754 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1755 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1756 // This is definitely an application process; skip it. 1757 continue; 1758 } 1759 synchronized (mPidsSelfLocked) { 1760 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1761 // This is one of our own processes; skip it. 1762 continue; 1763 } 1764 } 1765 nativeTotalPss += Debug.getPss(st.pid, null); 1766 } 1767 } 1768 memInfo.readMemInfo(); 1769 synchronized (ActivityManagerService.this) { 1770 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1771 + (SystemClock.uptimeMillis()-start) + "ms"); 1772 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1773 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1774 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1775 } 1776 } 1777 1778 int i=0, num=0; 1779 long[] tmp = new long[1]; 1780 do { 1781 ProcessRecord proc; 1782 int procState; 1783 int pid; 1784 synchronized (ActivityManagerService.this) { 1785 if (i >= mPendingPssProcesses.size()) { 1786 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1787 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1788 mPendingPssProcesses.clear(); 1789 return; 1790 } 1791 proc = mPendingPssProcesses.get(i); 1792 procState = proc.pssProcState; 1793 if (proc.thread != null && procState == proc.setProcState) { 1794 pid = proc.pid; 1795 } else { 1796 proc = null; 1797 pid = 0; 1798 } 1799 i++; 1800 } 1801 if (proc != null) { 1802 long pss = Debug.getPss(pid, tmp); 1803 synchronized (ActivityManagerService.this) { 1804 if (proc.thread != null && proc.setProcState == procState 1805 && proc.pid == pid) { 1806 num++; 1807 proc.lastPssTime = SystemClock.uptimeMillis(); 1808 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1809 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1810 + ": " + pss + " lastPss=" + proc.lastPss 1811 + " state=" + ProcessList.makeProcStateString(procState)); 1812 if (proc.initialIdlePss == 0) { 1813 proc.initialIdlePss = pss; 1814 } 1815 proc.lastPss = pss; 1816 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1817 proc.lastCachedPss = pss; 1818 } 1819 } 1820 } 1821 } 1822 } while (true); 1823 } 1824 } 1825 } 1826 }; 1827 1828 public void setSystemProcess() { 1829 try { 1830 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1831 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1832 ServiceManager.addService("meminfo", new MemBinder(this)); 1833 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1834 ServiceManager.addService("dbinfo", new DbBinder(this)); 1835 if (MONITOR_CPU_USAGE) { 1836 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1837 } 1838 ServiceManager.addService("permission", new PermissionController(this)); 1839 1840 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1841 "android", STOCK_PM_FLAGS); 1842 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1843 1844 synchronized (this) { 1845 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1846 app.persistent = true; 1847 app.pid = MY_PID; 1848 app.maxAdj = ProcessList.SYSTEM_ADJ; 1849 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1850 mProcessNames.put(app.processName, app.uid, app); 1851 synchronized (mPidsSelfLocked) { 1852 mPidsSelfLocked.put(app.pid, app); 1853 } 1854 updateLruProcessLocked(app, false, null); 1855 updateOomAdjLocked(); 1856 } 1857 } catch (PackageManager.NameNotFoundException e) { 1858 throw new RuntimeException( 1859 "Unable to find android system package", e); 1860 } 1861 } 1862 1863 public void setWindowManager(WindowManagerService wm) { 1864 mWindowManager = wm; 1865 mStackSupervisor.setWindowManager(wm); 1866 } 1867 1868 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1869 mUsageStatsService = usageStatsManager; 1870 } 1871 1872 public void startObservingNativeCrashes() { 1873 final NativeCrashListener ncl = new NativeCrashListener(this); 1874 ncl.start(); 1875 } 1876 1877 public IAppOpsService getAppOpsService() { 1878 return mAppOpsService; 1879 } 1880 1881 static class MemBinder extends Binder { 1882 ActivityManagerService mActivityManagerService; 1883 MemBinder(ActivityManagerService activityManagerService) { 1884 mActivityManagerService = activityManagerService; 1885 } 1886 1887 @Override 1888 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1889 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1890 != PackageManager.PERMISSION_GRANTED) { 1891 pw.println("Permission Denial: can't dump meminfo from from pid=" 1892 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1893 + " without permission " + android.Manifest.permission.DUMP); 1894 return; 1895 } 1896 1897 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1898 } 1899 } 1900 1901 static class GraphicsBinder extends Binder { 1902 ActivityManagerService mActivityManagerService; 1903 GraphicsBinder(ActivityManagerService activityManagerService) { 1904 mActivityManagerService = activityManagerService; 1905 } 1906 1907 @Override 1908 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1909 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1910 != PackageManager.PERMISSION_GRANTED) { 1911 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1912 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1913 + " without permission " + android.Manifest.permission.DUMP); 1914 return; 1915 } 1916 1917 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1918 } 1919 } 1920 1921 static class DbBinder extends Binder { 1922 ActivityManagerService mActivityManagerService; 1923 DbBinder(ActivityManagerService activityManagerService) { 1924 mActivityManagerService = activityManagerService; 1925 } 1926 1927 @Override 1928 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1929 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1930 != PackageManager.PERMISSION_GRANTED) { 1931 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1932 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1933 + " without permission " + android.Manifest.permission.DUMP); 1934 return; 1935 } 1936 1937 mActivityManagerService.dumpDbInfo(fd, pw, args); 1938 } 1939 } 1940 1941 static class CpuBinder extends Binder { 1942 ActivityManagerService mActivityManagerService; 1943 CpuBinder(ActivityManagerService activityManagerService) { 1944 mActivityManagerService = activityManagerService; 1945 } 1946 1947 @Override 1948 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1949 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1950 != PackageManager.PERMISSION_GRANTED) { 1951 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1952 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1953 + " without permission " + android.Manifest.permission.DUMP); 1954 return; 1955 } 1956 1957 synchronized (mActivityManagerService.mProcessCpuTracker) { 1958 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1959 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1960 SystemClock.uptimeMillis())); 1961 } 1962 } 1963 } 1964 1965 public static final class Lifecycle extends SystemService { 1966 private final ActivityManagerService mService; 1967 1968 public Lifecycle(Context context) { 1969 super(context); 1970 mService = new ActivityManagerService(context); 1971 } 1972 1973 @Override 1974 public void onStart() { 1975 mService.start(); 1976 } 1977 1978 public ActivityManagerService getService() { 1979 return mService; 1980 } 1981 } 1982 1983 // Note: This method is invoked on the main thread but may need to attach various 1984 // handlers to other threads. So take care to be explicit about the looper. 1985 public ActivityManagerService(Context systemContext) { 1986 mContext = systemContext; 1987 mFactoryTest = FactoryTest.getMode(); 1988 mSystemThread = ActivityThread.currentActivityThread(); 1989 1990 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1991 1992 mHandlerThread = new ServiceThread(TAG, 1993 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1994 mHandlerThread.start(); 1995 mHandler = new MainHandler(mHandlerThread.getLooper()); 1996 1997 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1998 "foreground", BROADCAST_FG_TIMEOUT, false); 1999 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2000 "background", BROADCAST_BG_TIMEOUT, true); 2001 mBroadcastQueues[0] = mFgBroadcastQueue; 2002 mBroadcastQueues[1] = mBgBroadcastQueue; 2003 2004 mServices = new ActiveServices(this); 2005 mProviderMap = new ProviderMap(this); 2006 2007 // TODO: Move creation of battery stats service outside of activity manager service. 2008 File dataDir = Environment.getDataDirectory(); 2009 File systemDir = new File(dataDir, "system"); 2010 systemDir.mkdirs(); 2011 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2012 mBatteryStatsService.getActiveStatistics().readLocked(); 2013 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2014 mOnBattery = DEBUG_POWER ? true 2015 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2016 mBatteryStatsService.getActiveStatistics().setCallback(this); 2017 2018 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2019 2020 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2021 2022 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2023 2024 // User 0 is the first and only user that runs at boot. 2025 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2026 mUserLru.add(Integer.valueOf(0)); 2027 updateStartedUserArrayLocked(); 2028 2029 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2030 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2031 2032 mConfiguration.setToDefaults(); 2033 mConfiguration.setLocale(Locale.getDefault()); 2034 2035 mConfigurationSeq = mConfiguration.seq = 1; 2036 mProcessCpuTracker.init(); 2037 2038 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2039 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2040 mStackSupervisor = new ActivityStackSupervisor(this); 2041 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2042 2043 mProcessCpuThread = new Thread("CpuTracker") { 2044 @Override 2045 public void run() { 2046 while (true) { 2047 try { 2048 try { 2049 synchronized(this) { 2050 final long now = SystemClock.uptimeMillis(); 2051 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2052 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2053 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2054 // + ", write delay=" + nextWriteDelay); 2055 if (nextWriteDelay < nextCpuDelay) { 2056 nextCpuDelay = nextWriteDelay; 2057 } 2058 if (nextCpuDelay > 0) { 2059 mProcessCpuMutexFree.set(true); 2060 this.wait(nextCpuDelay); 2061 } 2062 } 2063 } catch (InterruptedException e) { 2064 } 2065 updateCpuStatsNow(); 2066 } catch (Exception e) { 2067 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2068 } 2069 } 2070 } 2071 }; 2072 2073 Watchdog.getInstance().addMonitor(this); 2074 Watchdog.getInstance().addThread(mHandler); 2075 } 2076 2077 public void setSystemServiceManager(SystemServiceManager mgr) { 2078 mSystemServiceManager = mgr; 2079 } 2080 2081 public void setInstaller(Installer installer) { 2082 mInstaller = installer; 2083 } 2084 2085 private void start() { 2086 Process.removeAllProcessGroups(); 2087 mProcessCpuThread.start(); 2088 2089 mBatteryStatsService.publish(mContext); 2090 mAppOpsService.publish(mContext); 2091 Slog.d("AppOps", "AppOpsService published"); 2092 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2093 } 2094 2095 public void initPowerManagement() { 2096 mStackSupervisor.initPowerManagement(); 2097 mBatteryStatsService.initPowerManagement(); 2098 } 2099 2100 @Override 2101 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2102 throws RemoteException { 2103 if (code == SYSPROPS_TRANSACTION) { 2104 // We need to tell all apps about the system property change. 2105 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2106 synchronized(this) { 2107 final int NP = mProcessNames.getMap().size(); 2108 for (int ip=0; ip<NP; ip++) { 2109 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2110 final int NA = apps.size(); 2111 for (int ia=0; ia<NA; ia++) { 2112 ProcessRecord app = apps.valueAt(ia); 2113 if (app.thread != null) { 2114 procs.add(app.thread.asBinder()); 2115 } 2116 } 2117 } 2118 } 2119 2120 int N = procs.size(); 2121 for (int i=0; i<N; i++) { 2122 Parcel data2 = Parcel.obtain(); 2123 try { 2124 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2125 } catch (RemoteException e) { 2126 } 2127 data2.recycle(); 2128 } 2129 } 2130 try { 2131 return super.onTransact(code, data, reply, flags); 2132 } catch (RuntimeException e) { 2133 // The activity manager only throws security exceptions, so let's 2134 // log all others. 2135 if (!(e instanceof SecurityException)) { 2136 Slog.wtf(TAG, "Activity Manager Crash", e); 2137 } 2138 throw e; 2139 } 2140 } 2141 2142 void updateCpuStats() { 2143 final long now = SystemClock.uptimeMillis(); 2144 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2145 return; 2146 } 2147 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2148 synchronized (mProcessCpuThread) { 2149 mProcessCpuThread.notify(); 2150 } 2151 } 2152 } 2153 2154 void updateCpuStatsNow() { 2155 synchronized (mProcessCpuTracker) { 2156 mProcessCpuMutexFree.set(false); 2157 final long now = SystemClock.uptimeMillis(); 2158 boolean haveNewCpuStats = false; 2159 2160 if (MONITOR_CPU_USAGE && 2161 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2162 mLastCpuTime.set(now); 2163 haveNewCpuStats = true; 2164 mProcessCpuTracker.update(); 2165 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2166 //Slog.i(TAG, "Total CPU usage: " 2167 // + mProcessCpu.getTotalCpuPercent() + "%"); 2168 2169 // Slog the cpu usage if the property is set. 2170 if ("true".equals(SystemProperties.get("events.cpu"))) { 2171 int user = mProcessCpuTracker.getLastUserTime(); 2172 int system = mProcessCpuTracker.getLastSystemTime(); 2173 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2174 int irq = mProcessCpuTracker.getLastIrqTime(); 2175 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2176 int idle = mProcessCpuTracker.getLastIdleTime(); 2177 2178 int total = user + system + iowait + irq + softIrq + idle; 2179 if (total == 0) total = 1; 2180 2181 EventLog.writeEvent(EventLogTags.CPU, 2182 ((user+system+iowait+irq+softIrq) * 100) / total, 2183 (user * 100) / total, 2184 (system * 100) / total, 2185 (iowait * 100) / total, 2186 (irq * 100) / total, 2187 (softIrq * 100) / total); 2188 } 2189 } 2190 2191 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2192 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2193 synchronized(bstats) { 2194 synchronized(mPidsSelfLocked) { 2195 if (haveNewCpuStats) { 2196 if (mOnBattery) { 2197 int perc = bstats.startAddingCpuLocked(); 2198 int totalUTime = 0; 2199 int totalSTime = 0; 2200 final int N = mProcessCpuTracker.countStats(); 2201 for (int i=0; i<N; i++) { 2202 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2203 if (!st.working) { 2204 continue; 2205 } 2206 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2207 int otherUTime = (st.rel_utime*perc)/100; 2208 int otherSTime = (st.rel_stime*perc)/100; 2209 totalUTime += otherUTime; 2210 totalSTime += otherSTime; 2211 if (pr != null) { 2212 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2213 if (ps == null || !ps.isActive()) { 2214 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2215 pr.info.uid, pr.processName); 2216 } 2217 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2218 st.rel_stime-otherSTime); 2219 ps.addSpeedStepTimes(cpuSpeedTimes); 2220 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2221 } else { 2222 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2223 if (ps == null || !ps.isActive()) { 2224 st.batteryStats = ps = bstats.getProcessStatsLocked( 2225 bstats.mapUid(st.uid), st.name); 2226 } 2227 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2228 st.rel_stime-otherSTime); 2229 ps.addSpeedStepTimes(cpuSpeedTimes); 2230 } 2231 } 2232 bstats.finishAddingCpuLocked(perc, totalUTime, 2233 totalSTime, cpuSpeedTimes); 2234 } 2235 } 2236 } 2237 2238 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2239 mLastWriteTime = now; 2240 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2241 } 2242 } 2243 } 2244 } 2245 2246 @Override 2247 public void batteryNeedsCpuUpdate() { 2248 updateCpuStatsNow(); 2249 } 2250 2251 @Override 2252 public void batteryPowerChanged(boolean onBattery) { 2253 // When plugging in, update the CPU stats first before changing 2254 // the plug state. 2255 updateCpuStatsNow(); 2256 synchronized (this) { 2257 synchronized(mPidsSelfLocked) { 2258 mOnBattery = DEBUG_POWER ? true : onBattery; 2259 } 2260 } 2261 } 2262 2263 /** 2264 * Initialize the application bind args. These are passed to each 2265 * process when the bindApplication() IPC is sent to the process. They're 2266 * lazily setup to make sure the services are running when they're asked for. 2267 */ 2268 private HashMap<String, IBinder> getCommonServicesLocked() { 2269 if (mAppBindArgs == null) { 2270 mAppBindArgs = new HashMap<String, IBinder>(); 2271 2272 // Setup the application init args 2273 mAppBindArgs.put("package", ServiceManager.getService("package")); 2274 mAppBindArgs.put("window", ServiceManager.getService("window")); 2275 mAppBindArgs.put(Context.ALARM_SERVICE, 2276 ServiceManager.getService(Context.ALARM_SERVICE)); 2277 } 2278 return mAppBindArgs; 2279 } 2280 2281 final void setFocusedActivityLocked(ActivityRecord r) { 2282 if (mFocusedActivity != r) { 2283 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2284 mFocusedActivity = r; 2285 if (r.task != null && r.task.voiceInteractor != null) { 2286 startRunningVoiceLocked(); 2287 } else { 2288 finishRunningVoiceLocked(); 2289 } 2290 mStackSupervisor.setFocusedStack(r); 2291 if (r != null) { 2292 mWindowManager.setFocusedApp(r.appToken, true); 2293 } 2294 applyUpdateLockStateLocked(r); 2295 } 2296 } 2297 2298 final void clearFocusedActivity(ActivityRecord r) { 2299 if (mFocusedActivity == r) { 2300 mFocusedActivity = null; 2301 } 2302 } 2303 2304 @Override 2305 public void setFocusedStack(int stackId) { 2306 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2307 synchronized (ActivityManagerService.this) { 2308 ActivityStack stack = mStackSupervisor.getStack(stackId); 2309 if (stack != null) { 2310 ActivityRecord r = stack.topRunningActivityLocked(null); 2311 if (r != null) { 2312 setFocusedActivityLocked(r); 2313 } 2314 } 2315 } 2316 } 2317 2318 @Override 2319 public void notifyActivityDrawn(IBinder token) { 2320 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2321 synchronized (this) { 2322 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2323 if (r != null) { 2324 r.task.stack.notifyActivityDrawnLocked(r); 2325 } 2326 } 2327 } 2328 2329 final void applyUpdateLockStateLocked(ActivityRecord r) { 2330 // Modifications to the UpdateLock state are done on our handler, outside 2331 // the activity manager's locks. The new state is determined based on the 2332 // state *now* of the relevant activity record. The object is passed to 2333 // the handler solely for logging detail, not to be consulted/modified. 2334 final boolean nextState = r != null && r.immersive; 2335 mHandler.sendMessage( 2336 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2337 } 2338 2339 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2340 Message msg = Message.obtain(); 2341 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2342 msg.obj = r.task.askedCompatMode ? null : r; 2343 mHandler.sendMessage(msg); 2344 } 2345 2346 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2347 String what, Object obj, ProcessRecord srcApp) { 2348 app.lastActivityTime = now; 2349 2350 if (app.activities.size() > 0) { 2351 // Don't want to touch dependent processes that are hosting activities. 2352 return index; 2353 } 2354 2355 int lrui = mLruProcesses.lastIndexOf(app); 2356 if (lrui < 0) { 2357 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2358 + what + " " + obj + " from " + srcApp); 2359 return index; 2360 } 2361 2362 if (lrui >= index) { 2363 // Don't want to cause this to move dependent processes *back* in the 2364 // list as if they were less frequently used. 2365 return index; 2366 } 2367 2368 if (lrui >= mLruProcessActivityStart) { 2369 // Don't want to touch dependent processes that are hosting activities. 2370 return index; 2371 } 2372 2373 mLruProcesses.remove(lrui); 2374 if (index > 0) { 2375 index--; 2376 } 2377 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2378 + " in LRU list: " + app); 2379 mLruProcesses.add(index, app); 2380 return index; 2381 } 2382 2383 final void removeLruProcessLocked(ProcessRecord app) { 2384 int lrui = mLruProcesses.lastIndexOf(app); 2385 if (lrui >= 0) { 2386 if (!app.killed) { 2387 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2388 Process.killProcessQuiet(app.pid); 2389 Process.killProcessGroup(app.info.uid, app.pid); 2390 } 2391 if (lrui <= mLruProcessActivityStart) { 2392 mLruProcessActivityStart--; 2393 } 2394 if (lrui <= mLruProcessServiceStart) { 2395 mLruProcessServiceStart--; 2396 } 2397 mLruProcesses.remove(lrui); 2398 } 2399 } 2400 2401 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2402 ProcessRecord client) { 2403 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2404 || app.treatLikeActivity; 2405 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2406 if (!activityChange && hasActivity) { 2407 // The process has activities, so we are only allowing activity-based adjustments 2408 // to move it. It should be kept in the front of the list with other 2409 // processes that have activities, and we don't want those to change their 2410 // order except due to activity operations. 2411 return; 2412 } 2413 2414 mLruSeq++; 2415 final long now = SystemClock.uptimeMillis(); 2416 app.lastActivityTime = now; 2417 2418 // First a quick reject: if the app is already at the position we will 2419 // put it, then there is nothing to do. 2420 if (hasActivity) { 2421 final int N = mLruProcesses.size(); 2422 if (N > 0 && mLruProcesses.get(N-1) == app) { 2423 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2424 return; 2425 } 2426 } else { 2427 if (mLruProcessServiceStart > 0 2428 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2429 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2430 return; 2431 } 2432 } 2433 2434 int lrui = mLruProcesses.lastIndexOf(app); 2435 2436 if (app.persistent && lrui >= 0) { 2437 // We don't care about the position of persistent processes, as long as 2438 // they are in the list. 2439 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2440 return; 2441 } 2442 2443 /* In progress: compute new position first, so we can avoid doing work 2444 if the process is not actually going to move. Not yet working. 2445 int addIndex; 2446 int nextIndex; 2447 boolean inActivity = false, inService = false; 2448 if (hasActivity) { 2449 // Process has activities, put it at the very tipsy-top. 2450 addIndex = mLruProcesses.size(); 2451 nextIndex = mLruProcessServiceStart; 2452 inActivity = true; 2453 } else if (hasService) { 2454 // Process has services, put it at the top of the service list. 2455 addIndex = mLruProcessActivityStart; 2456 nextIndex = mLruProcessServiceStart; 2457 inActivity = true; 2458 inService = true; 2459 } else { 2460 // Process not otherwise of interest, it goes to the top of the non-service area. 2461 addIndex = mLruProcessServiceStart; 2462 if (client != null) { 2463 int clientIndex = mLruProcesses.lastIndexOf(client); 2464 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2465 + app); 2466 if (clientIndex >= 0 && addIndex > clientIndex) { 2467 addIndex = clientIndex; 2468 } 2469 } 2470 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2471 } 2472 2473 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2474 + mLruProcessActivityStart + "): " + app); 2475 */ 2476 2477 if (lrui >= 0) { 2478 if (lrui < mLruProcessActivityStart) { 2479 mLruProcessActivityStart--; 2480 } 2481 if (lrui < mLruProcessServiceStart) { 2482 mLruProcessServiceStart--; 2483 } 2484 /* 2485 if (addIndex > lrui) { 2486 addIndex--; 2487 } 2488 if (nextIndex > lrui) { 2489 nextIndex--; 2490 } 2491 */ 2492 mLruProcesses.remove(lrui); 2493 } 2494 2495 /* 2496 mLruProcesses.add(addIndex, app); 2497 if (inActivity) { 2498 mLruProcessActivityStart++; 2499 } 2500 if (inService) { 2501 mLruProcessActivityStart++; 2502 } 2503 */ 2504 2505 int nextIndex; 2506 if (hasActivity) { 2507 final int N = mLruProcesses.size(); 2508 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2509 // Process doesn't have activities, but has clients with 2510 // activities... move it up, but one below the top (the top 2511 // should always have a real activity). 2512 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2513 mLruProcesses.add(N-1, app); 2514 // To keep it from spamming the LRU list (by making a bunch of clients), 2515 // we will push down any other entries owned by the app. 2516 final int uid = app.info.uid; 2517 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2518 ProcessRecord subProc = mLruProcesses.get(i); 2519 if (subProc.info.uid == uid) { 2520 // We want to push this one down the list. If the process after 2521 // it is for the same uid, however, don't do so, because we don't 2522 // want them internally to be re-ordered. 2523 if (mLruProcesses.get(i-1).info.uid != uid) { 2524 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2525 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2526 ProcessRecord tmp = mLruProcesses.get(i); 2527 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2528 mLruProcesses.set(i-1, tmp); 2529 i--; 2530 } 2531 } else { 2532 // A gap, we can stop here. 2533 break; 2534 } 2535 } 2536 } else { 2537 // Process has activities, put it at the very tipsy-top. 2538 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2539 mLruProcesses.add(app); 2540 } 2541 nextIndex = mLruProcessServiceStart; 2542 } else if (hasService) { 2543 // Process has services, put it at the top of the service list. 2544 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2545 mLruProcesses.add(mLruProcessActivityStart, app); 2546 nextIndex = mLruProcessServiceStart; 2547 mLruProcessActivityStart++; 2548 } else { 2549 // Process not otherwise of interest, it goes to the top of the non-service area. 2550 int index = mLruProcessServiceStart; 2551 if (client != null) { 2552 // If there is a client, don't allow the process to be moved up higher 2553 // in the list than that client. 2554 int clientIndex = mLruProcesses.lastIndexOf(client); 2555 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2556 + " when updating " + app); 2557 if (clientIndex <= lrui) { 2558 // Don't allow the client index restriction to push it down farther in the 2559 // list than it already is. 2560 clientIndex = lrui; 2561 } 2562 if (clientIndex >= 0 && index > clientIndex) { 2563 index = clientIndex; 2564 } 2565 } 2566 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2567 mLruProcesses.add(index, app); 2568 nextIndex = index-1; 2569 mLruProcessActivityStart++; 2570 mLruProcessServiceStart++; 2571 } 2572 2573 // If the app is currently using a content provider or service, 2574 // bump those processes as well. 2575 for (int j=app.connections.size()-1; j>=0; j--) { 2576 ConnectionRecord cr = app.connections.valueAt(j); 2577 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2578 && cr.binding.service.app != null 2579 && cr.binding.service.app.lruSeq != mLruSeq 2580 && !cr.binding.service.app.persistent) { 2581 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2582 "service connection", cr, app); 2583 } 2584 } 2585 for (int j=app.conProviders.size()-1; j>=0; j--) { 2586 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2587 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2588 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2589 "provider reference", cpr, app); 2590 } 2591 } 2592 } 2593 2594 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2595 if (uid == Process.SYSTEM_UID) { 2596 // The system gets to run in any process. If there are multiple 2597 // processes with the same uid, just pick the first (this 2598 // should never happen). 2599 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2600 if (procs == null) return null; 2601 final int N = procs.size(); 2602 for (int i = 0; i < N; i++) { 2603 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2604 } 2605 } 2606 ProcessRecord proc = mProcessNames.get(processName, uid); 2607 if (false && proc != null && !keepIfLarge 2608 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2609 && proc.lastCachedPss >= 4000) { 2610 // Turn this condition on to cause killing to happen regularly, for testing. 2611 if (proc.baseProcessTracker != null) { 2612 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2613 } 2614 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2615 } else if (proc != null && !keepIfLarge 2616 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2617 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2618 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2619 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2620 if (proc.baseProcessTracker != null) { 2621 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2622 } 2623 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2624 } 2625 } 2626 return proc; 2627 } 2628 2629 void ensurePackageDexOpt(String packageName) { 2630 IPackageManager pm = AppGlobals.getPackageManager(); 2631 try { 2632 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2633 mDidDexOpt = true; 2634 } 2635 } catch (RemoteException e) { 2636 } 2637 } 2638 2639 boolean isNextTransitionForward() { 2640 int transit = mWindowManager.getPendingAppTransition(); 2641 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2642 || transit == AppTransition.TRANSIT_TASK_OPEN 2643 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2644 } 2645 2646 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2647 String processName, String abiOverride, int uid, Runnable crashHandler) { 2648 synchronized(this) { 2649 ApplicationInfo info = new ApplicationInfo(); 2650 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2651 // For isolated processes, the former contains the parent's uid and the latter the 2652 // actual uid of the isolated process. 2653 // In the special case introduced by this method (which is, starting an isolated 2654 // process directly from the SystemServer without an actual parent app process) the 2655 // closest thing to a parent's uid is SYSTEM_UID. 2656 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2657 // the |isolated| logic in the ProcessRecord constructor. 2658 info.uid = Process.SYSTEM_UID; 2659 info.processName = processName; 2660 info.className = entryPoint; 2661 info.packageName = "android"; 2662 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2663 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2664 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2665 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2666 crashHandler); 2667 return proc != null ? proc.pid : 0; 2668 } 2669 } 2670 2671 final ProcessRecord startProcessLocked(String processName, 2672 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2673 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2674 boolean isolated, boolean keepIfLarge) { 2675 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2676 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2677 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2678 null /* crashHandler */); 2679 } 2680 2681 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2682 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2683 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2684 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2685 long startTime = SystemClock.elapsedRealtime(); 2686 ProcessRecord app; 2687 if (!isolated) { 2688 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2689 checkTime(startTime, "startProcess: after getProcessRecord"); 2690 } else { 2691 // If this is an isolated process, it can't re-use an existing process. 2692 app = null; 2693 } 2694 // We don't have to do anything more if: 2695 // (1) There is an existing application record; and 2696 // (2) The caller doesn't think it is dead, OR there is no thread 2697 // object attached to it so we know it couldn't have crashed; and 2698 // (3) There is a pid assigned to it, so it is either starting or 2699 // already running. 2700 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2701 + " app=" + app + " knownToBeDead=" + knownToBeDead 2702 + " thread=" + (app != null ? app.thread : null) 2703 + " pid=" + (app != null ? app.pid : -1)); 2704 if (app != null && app.pid > 0) { 2705 if (!knownToBeDead || app.thread == null) { 2706 // We already have the app running, or are waiting for it to 2707 // come up (we have a pid but not yet its thread), so keep it. 2708 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2709 // If this is a new package in the process, add the package to the list 2710 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2711 checkTime(startTime, "startProcess: done, added package to proc"); 2712 return app; 2713 } 2714 2715 // An application record is attached to a previous process, 2716 // clean it up now. 2717 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2718 checkTime(startTime, "startProcess: bad proc running, killing"); 2719 Process.killProcessGroup(app.info.uid, app.pid); 2720 handleAppDiedLocked(app, true, true); 2721 checkTime(startTime, "startProcess: done killing old proc"); 2722 } 2723 2724 String hostingNameStr = hostingName != null 2725 ? hostingName.flattenToShortString() : null; 2726 2727 if (!isolated) { 2728 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2729 // If we are in the background, then check to see if this process 2730 // is bad. If so, we will just silently fail. 2731 if (mBadProcesses.get(info.processName, info.uid) != null) { 2732 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2733 + "/" + info.processName); 2734 return null; 2735 } 2736 } else { 2737 // When the user is explicitly starting a process, then clear its 2738 // crash count so that we won't make it bad until they see at 2739 // least one crash dialog again, and make the process good again 2740 // if it had been bad. 2741 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2742 + "/" + info.processName); 2743 mProcessCrashTimes.remove(info.processName, info.uid); 2744 if (mBadProcesses.get(info.processName, info.uid) != null) { 2745 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2746 UserHandle.getUserId(info.uid), info.uid, 2747 info.processName); 2748 mBadProcesses.remove(info.processName, info.uid); 2749 if (app != null) { 2750 app.bad = false; 2751 } 2752 } 2753 } 2754 } 2755 2756 if (app == null) { 2757 checkTime(startTime, "startProcess: creating new process record"); 2758 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2759 app.crashHandler = crashHandler; 2760 if (app == null) { 2761 Slog.w(TAG, "Failed making new process record for " 2762 + processName + "/" + info.uid + " isolated=" + isolated); 2763 return null; 2764 } 2765 mProcessNames.put(processName, app.uid, app); 2766 if (isolated) { 2767 mIsolatedProcesses.put(app.uid, app); 2768 } 2769 checkTime(startTime, "startProcess: done creating new process record"); 2770 } else { 2771 // If this is a new package in the process, add the package to the list 2772 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2773 checkTime(startTime, "startProcess: added package to existing proc"); 2774 } 2775 2776 // If the system is not ready yet, then hold off on starting this 2777 // process until it is. 2778 if (!mProcessesReady 2779 && !isAllowedWhileBooting(info) 2780 && !allowWhileBooting) { 2781 if (!mProcessesOnHold.contains(app)) { 2782 mProcessesOnHold.add(app); 2783 } 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2785 checkTime(startTime, "startProcess: returning with proc on hold"); 2786 return app; 2787 } 2788 2789 checkTime(startTime, "startProcess: stepping in to startProcess"); 2790 startProcessLocked( 2791 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2792 checkTime(startTime, "startProcess: done starting proc!"); 2793 return (app.pid != 0) ? app : null; 2794 } 2795 2796 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2797 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2798 } 2799 2800 private final void startProcessLocked(ProcessRecord app, 2801 String hostingType, String hostingNameStr) { 2802 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2803 null /* entryPoint */, null /* entryPointArgs */); 2804 } 2805 2806 private final void startProcessLocked(ProcessRecord app, String hostingType, 2807 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2808 long startTime = SystemClock.elapsedRealtime(); 2809 if (app.pid > 0 && app.pid != MY_PID) { 2810 checkTime(startTime, "startProcess: removing from pids map"); 2811 synchronized (mPidsSelfLocked) { 2812 mPidsSelfLocked.remove(app.pid); 2813 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2814 } 2815 checkTime(startTime, "startProcess: done removing from pids map"); 2816 app.setPid(0); 2817 } 2818 2819 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2820 "startProcessLocked removing on hold: " + app); 2821 mProcessesOnHold.remove(app); 2822 2823 checkTime(startTime, "startProcess: starting to update cpu stats"); 2824 updateCpuStats(); 2825 checkTime(startTime, "startProcess: done updating cpu stats"); 2826 2827 try { 2828 int uid = app.uid; 2829 2830 int[] gids = null; 2831 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2832 if (!app.isolated) { 2833 int[] permGids = null; 2834 try { 2835 checkTime(startTime, "startProcess: getting gids from package manager"); 2836 final PackageManager pm = mContext.getPackageManager(); 2837 permGids = pm.getPackageGids(app.info.packageName); 2838 2839 if (Environment.isExternalStorageEmulated()) { 2840 checkTime(startTime, "startProcess: checking external storage perm"); 2841 if (pm.checkPermission( 2842 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2843 app.info.packageName) == PERMISSION_GRANTED) { 2844 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2845 } else { 2846 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2847 } 2848 } 2849 } catch (PackageManager.NameNotFoundException e) { 2850 Slog.w(TAG, "Unable to retrieve gids", e); 2851 } 2852 2853 /* 2854 * Add shared application and profile GIDs so applications can share some 2855 * resources like shared libraries and access user-wide resources 2856 */ 2857 if (permGids == null) { 2858 gids = new int[2]; 2859 } else { 2860 gids = new int[permGids.length + 2]; 2861 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2862 } 2863 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2864 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2865 } 2866 checkTime(startTime, "startProcess: building args"); 2867 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2868 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2869 && mTopComponent != null 2870 && app.processName.equals(mTopComponent.getPackageName())) { 2871 uid = 0; 2872 } 2873 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2874 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2875 uid = 0; 2876 } 2877 } 2878 int debugFlags = 0; 2879 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2880 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2881 // Also turn on CheckJNI for debuggable apps. It's quite 2882 // awkward to turn on otherwise. 2883 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2884 } 2885 // Run the app in safe mode if its manifest requests so or the 2886 // system is booted in safe mode. 2887 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2888 mSafeMode == true) { 2889 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2890 } 2891 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2892 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2893 } 2894 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2895 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2896 } 2897 if ("1".equals(SystemProperties.get("debug.assert"))) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2899 } 2900 2901 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2902 if (requiredAbi == null) { 2903 requiredAbi = Build.SUPPORTED_ABIS[0]; 2904 } 2905 2906 String instructionSet = null; 2907 if (app.info.primaryCpuAbi != null) { 2908 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2909 } 2910 2911 // Start the process. It will either succeed and return a result containing 2912 // the PID of the new process, or else throw a RuntimeException. 2913 boolean isActivityProcess = (entryPoint == null); 2914 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2915 checkTime(startTime, "startProcess: asking zygote to start proc"); 2916 Process.ProcessStartResult startResult = Process.start(entryPoint, 2917 app.processName, uid, uid, gids, debugFlags, mountExternal, 2918 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2919 app.info.dataDir, entryPointArgs); 2920 checkTime(startTime, "startProcess: returned from zygote!"); 2921 2922 if (app.isolated) { 2923 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2924 } 2925 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2926 checkTime(startTime, "startProcess: done updating battery stats"); 2927 2928 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2929 UserHandle.getUserId(uid), startResult.pid, uid, 2930 app.processName, hostingType, 2931 hostingNameStr != null ? hostingNameStr : ""); 2932 2933 if (app.persistent) { 2934 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2935 } 2936 2937 checkTime(startTime, "startProcess: building log message"); 2938 StringBuilder buf = mStringBuilder; 2939 buf.setLength(0); 2940 buf.append("Start proc "); 2941 buf.append(app.processName); 2942 if (!isActivityProcess) { 2943 buf.append(" ["); 2944 buf.append(entryPoint); 2945 buf.append("]"); 2946 } 2947 buf.append(" for "); 2948 buf.append(hostingType); 2949 if (hostingNameStr != null) { 2950 buf.append(" "); 2951 buf.append(hostingNameStr); 2952 } 2953 buf.append(": pid="); 2954 buf.append(startResult.pid); 2955 buf.append(" uid="); 2956 buf.append(uid); 2957 buf.append(" gids={"); 2958 if (gids != null) { 2959 for (int gi=0; gi<gids.length; gi++) { 2960 if (gi != 0) buf.append(", "); 2961 buf.append(gids[gi]); 2962 2963 } 2964 } 2965 buf.append("}"); 2966 if (requiredAbi != null) { 2967 buf.append(" abi="); 2968 buf.append(requiredAbi); 2969 } 2970 Slog.i(TAG, buf.toString()); 2971 app.setPid(startResult.pid); 2972 app.usingWrapper = startResult.usingWrapper; 2973 app.removed = false; 2974 app.killed = false; 2975 app.killedByAm = false; 2976 checkTime(startTime, "startProcess: starting to update pids map"); 2977 synchronized (mPidsSelfLocked) { 2978 this.mPidsSelfLocked.put(startResult.pid, app); 2979 if (isActivityProcess) { 2980 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2981 msg.obj = app; 2982 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2983 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2984 } 2985 } 2986 checkTime(startTime, "startProcess: done updating pids map"); 2987 } catch (RuntimeException e) { 2988 // XXX do better error recovery. 2989 app.setPid(0); 2990 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 2991 if (app.isolated) { 2992 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 2993 } 2994 Slog.e(TAG, "Failure starting process " + app.processName, e); 2995 } 2996 } 2997 2998 void updateUsageStats(ActivityRecord component, boolean resumed) { 2999 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3000 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3001 if (resumed) { 3002 if (mUsageStatsService != null) { 3003 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3004 UsageEvents.Event.MOVE_TO_FOREGROUND); 3005 } 3006 synchronized (stats) { 3007 stats.noteActivityResumedLocked(component.app.uid); 3008 } 3009 } else { 3010 if (mUsageStatsService != null) { 3011 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3012 UsageEvents.Event.MOVE_TO_BACKGROUND); 3013 } 3014 synchronized (stats) { 3015 stats.noteActivityPausedLocked(component.app.uid); 3016 } 3017 } 3018 } 3019 3020 Intent getHomeIntent() { 3021 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3022 intent.setComponent(mTopComponent); 3023 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3024 intent.addCategory(Intent.CATEGORY_HOME); 3025 } 3026 return intent; 3027 } 3028 3029 boolean startHomeActivityLocked(int userId) { 3030 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3031 && mTopAction == null) { 3032 // We are running in factory test mode, but unable to find 3033 // the factory test app, so just sit around displaying the 3034 // error message and don't try to start anything. 3035 return false; 3036 } 3037 Intent intent = getHomeIntent(); 3038 ActivityInfo aInfo = 3039 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3040 if (aInfo != null) { 3041 intent.setComponent(new ComponentName( 3042 aInfo.applicationInfo.packageName, aInfo.name)); 3043 // Don't do this if the home app is currently being 3044 // instrumented. 3045 aInfo = new ActivityInfo(aInfo); 3046 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3047 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3048 aInfo.applicationInfo.uid, true); 3049 if (app == null || app.instrumentationClass == null) { 3050 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3051 mStackSupervisor.startHomeActivity(intent, aInfo); 3052 } 3053 } 3054 3055 return true; 3056 } 3057 3058 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3059 ActivityInfo ai = null; 3060 ComponentName comp = intent.getComponent(); 3061 try { 3062 if (comp != null) { 3063 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3064 } else { 3065 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3066 intent, 3067 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3068 flags, userId); 3069 3070 if (info != null) { 3071 ai = info.activityInfo; 3072 } 3073 } 3074 } catch (RemoteException e) { 3075 // ignore 3076 } 3077 3078 return ai; 3079 } 3080 3081 /** 3082 * Starts the "new version setup screen" if appropriate. 3083 */ 3084 void startSetupActivityLocked() { 3085 // Only do this once per boot. 3086 if (mCheckedForSetup) { 3087 return; 3088 } 3089 3090 // We will show this screen if the current one is a different 3091 // version than the last one shown, and we are not running in 3092 // low-level factory test mode. 3093 final ContentResolver resolver = mContext.getContentResolver(); 3094 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3095 Settings.Global.getInt(resolver, 3096 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3097 mCheckedForSetup = true; 3098 3099 // See if we should be showing the platform update setup UI. 3100 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3101 List<ResolveInfo> ris = mContext.getPackageManager() 3102 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3103 3104 // We don't allow third party apps to replace this. 3105 ResolveInfo ri = null; 3106 for (int i=0; ris != null && i<ris.size(); i++) { 3107 if ((ris.get(i).activityInfo.applicationInfo.flags 3108 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3109 ri = ris.get(i); 3110 break; 3111 } 3112 } 3113 3114 if (ri != null) { 3115 String vers = ri.activityInfo.metaData != null 3116 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3117 : null; 3118 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3119 vers = ri.activityInfo.applicationInfo.metaData.getString( 3120 Intent.METADATA_SETUP_VERSION); 3121 } 3122 String lastVers = Settings.Secure.getString( 3123 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3124 if (vers != null && !vers.equals(lastVers)) { 3125 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3126 intent.setComponent(new ComponentName( 3127 ri.activityInfo.packageName, ri.activityInfo.name)); 3128 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3129 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3130 null); 3131 } 3132 } 3133 } 3134 } 3135 3136 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3137 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3138 } 3139 3140 void enforceNotIsolatedCaller(String caller) { 3141 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3142 throw new SecurityException("Isolated process not allowed to call " + caller); 3143 } 3144 } 3145 3146 void enforceShellRestriction(String restriction, int userHandle) { 3147 if (Binder.getCallingUid() == Process.SHELL_UID) { 3148 if (userHandle < 0 3149 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3150 throw new SecurityException("Shell does not have permission to access user " 3151 + userHandle); 3152 } 3153 } 3154 } 3155 3156 @Override 3157 public int getFrontActivityScreenCompatMode() { 3158 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3159 synchronized (this) { 3160 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3161 } 3162 } 3163 3164 @Override 3165 public void setFrontActivityScreenCompatMode(int mode) { 3166 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3167 "setFrontActivityScreenCompatMode"); 3168 synchronized (this) { 3169 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3170 } 3171 } 3172 3173 @Override 3174 public int getPackageScreenCompatMode(String packageName) { 3175 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3176 synchronized (this) { 3177 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3178 } 3179 } 3180 3181 @Override 3182 public void setPackageScreenCompatMode(String packageName, int mode) { 3183 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3184 "setPackageScreenCompatMode"); 3185 synchronized (this) { 3186 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3187 } 3188 } 3189 3190 @Override 3191 public boolean getPackageAskScreenCompat(String packageName) { 3192 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3193 synchronized (this) { 3194 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3195 } 3196 } 3197 3198 @Override 3199 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3200 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3201 "setPackageAskScreenCompat"); 3202 synchronized (this) { 3203 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3204 } 3205 } 3206 3207 private void dispatchProcessesChanged() { 3208 int N; 3209 synchronized (this) { 3210 N = mPendingProcessChanges.size(); 3211 if (mActiveProcessChanges.length < N) { 3212 mActiveProcessChanges = new ProcessChangeItem[N]; 3213 } 3214 mPendingProcessChanges.toArray(mActiveProcessChanges); 3215 mAvailProcessChanges.addAll(mPendingProcessChanges); 3216 mPendingProcessChanges.clear(); 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3218 } 3219 3220 int i = mProcessObservers.beginBroadcast(); 3221 while (i > 0) { 3222 i--; 3223 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3224 if (observer != null) { 3225 try { 3226 for (int j=0; j<N; j++) { 3227 ProcessChangeItem item = mActiveProcessChanges[j]; 3228 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3229 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3230 + item.pid + " uid=" + item.uid + ": " 3231 + item.foregroundActivities); 3232 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3233 item.foregroundActivities); 3234 } 3235 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3236 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3237 + item.pid + " uid=" + item.uid + ": " + item.processState); 3238 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3239 } 3240 } 3241 } catch (RemoteException e) { 3242 } 3243 } 3244 } 3245 mProcessObservers.finishBroadcast(); 3246 } 3247 3248 private void dispatchProcessDied(int pid, int uid) { 3249 int i = mProcessObservers.beginBroadcast(); 3250 while (i > 0) { 3251 i--; 3252 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3253 if (observer != null) { 3254 try { 3255 observer.onProcessDied(pid, uid); 3256 } catch (RemoteException e) { 3257 } 3258 } 3259 } 3260 mProcessObservers.finishBroadcast(); 3261 } 3262 3263 @Override 3264 public final int startActivity(IApplicationThread caller, String callingPackage, 3265 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3266 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3267 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3268 resultWho, requestCode, startFlags, profilerInfo, options, 3269 UserHandle.getCallingUserId()); 3270 } 3271 3272 @Override 3273 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3274 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3275 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3276 enforceNotIsolatedCaller("startActivity"); 3277 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3278 false, ALLOW_FULL_ONLY, "startActivity", null); 3279 // TODO: Switch to user app stacks here. 3280 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3281 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3282 profilerInfo, null, null, options, userId, null, null); 3283 } 3284 3285 @Override 3286 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3287 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3288 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3289 3290 // This is very dangerous -- it allows you to perform a start activity (including 3291 // permission grants) as any app that may launch one of your own activities. So 3292 // we will only allow this to be done from activities that are part of the core framework, 3293 // and then only when they are running as the system. 3294 final ActivityRecord sourceRecord; 3295 final int targetUid; 3296 final String targetPackage; 3297 synchronized (this) { 3298 if (resultTo == null) { 3299 throw new SecurityException("Must be called from an activity"); 3300 } 3301 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3302 if (sourceRecord == null) { 3303 throw new SecurityException("Called with bad activity token: " + resultTo); 3304 } 3305 if (!sourceRecord.info.packageName.equals("android")) { 3306 throw new SecurityException( 3307 "Must be called from an activity that is declared in the android package"); 3308 } 3309 if (sourceRecord.app == null) { 3310 throw new SecurityException("Called without a process attached to activity"); 3311 } 3312 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3313 // This is still okay, as long as this activity is running under the 3314 // uid of the original calling activity. 3315 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3316 throw new SecurityException( 3317 "Calling activity in uid " + sourceRecord.app.uid 3318 + " must be system uid or original calling uid " 3319 + sourceRecord.launchedFromUid); 3320 } 3321 } 3322 targetUid = sourceRecord.launchedFromUid; 3323 targetPackage = sourceRecord.launchedFromPackage; 3324 } 3325 3326 if (userId == UserHandle.USER_NULL) { 3327 userId = UserHandle.getUserId(sourceRecord.app.uid); 3328 } 3329 3330 // TODO: Switch to user app stacks here. 3331 try { 3332 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3333 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3334 null, null, options, userId, null, null); 3335 return ret; 3336 } catch (SecurityException e) { 3337 // XXX need to figure out how to propagate to original app. 3338 // A SecurityException here is generally actually a fault of the original 3339 // calling activity (such as a fairly granting permissions), so propagate it 3340 // back to them. 3341 /* 3342 StringBuilder msg = new StringBuilder(); 3343 msg.append("While launching"); 3344 msg.append(intent.toString()); 3345 msg.append(": "); 3346 msg.append(e.getMessage()); 3347 */ 3348 throw e; 3349 } 3350 } 3351 3352 @Override 3353 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3355 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3356 enforceNotIsolatedCaller("startActivityAndWait"); 3357 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3358 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3359 WaitResult res = new WaitResult(); 3360 // TODO: Switch to user app stacks here. 3361 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3362 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3363 options, userId, null, null); 3364 return res; 3365 } 3366 3367 @Override 3368 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3369 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3370 int startFlags, Configuration config, Bundle options, int userId) { 3371 enforceNotIsolatedCaller("startActivityWithConfig"); 3372 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3373 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3374 // TODO: Switch to user app stacks here. 3375 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3376 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3377 null, null, config, options, userId, null, null); 3378 return ret; 3379 } 3380 3381 @Override 3382 public int startActivityIntentSender(IApplicationThread caller, 3383 IntentSender intent, Intent fillInIntent, String resolvedType, 3384 IBinder resultTo, String resultWho, int requestCode, 3385 int flagsMask, int flagsValues, Bundle options) { 3386 enforceNotIsolatedCaller("startActivityIntentSender"); 3387 // Refuse possible leaked file descriptors 3388 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3389 throw new IllegalArgumentException("File descriptors passed in Intent"); 3390 } 3391 3392 IIntentSender sender = intent.getTarget(); 3393 if (!(sender instanceof PendingIntentRecord)) { 3394 throw new IllegalArgumentException("Bad PendingIntent object"); 3395 } 3396 3397 PendingIntentRecord pir = (PendingIntentRecord)sender; 3398 3399 synchronized (this) { 3400 // If this is coming from the currently resumed activity, it is 3401 // effectively saying that app switches are allowed at this point. 3402 final ActivityStack stack = getFocusedStack(); 3403 if (stack.mResumedActivity != null && 3404 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3405 mAppSwitchesAllowedTime = 0; 3406 } 3407 } 3408 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3409 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3410 return ret; 3411 } 3412 3413 @Override 3414 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3415 Intent intent, String resolvedType, IVoiceInteractionSession session, 3416 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3417 Bundle options, int userId) { 3418 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3419 != PackageManager.PERMISSION_GRANTED) { 3420 String msg = "Permission Denial: startVoiceActivity() from pid=" 3421 + Binder.getCallingPid() 3422 + ", uid=" + Binder.getCallingUid() 3423 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3424 Slog.w(TAG, msg); 3425 throw new SecurityException(msg); 3426 } 3427 if (session == null || interactor == null) { 3428 throw new NullPointerException("null session or interactor"); 3429 } 3430 userId = handleIncomingUser(callingPid, callingUid, userId, 3431 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3432 // TODO: Switch to user app stacks here. 3433 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3434 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3435 null, options, userId, null, null); 3436 } 3437 3438 @Override 3439 public boolean startNextMatchingActivity(IBinder callingActivity, 3440 Intent intent, Bundle options) { 3441 // Refuse possible leaked file descriptors 3442 if (intent != null && intent.hasFileDescriptors() == true) { 3443 throw new IllegalArgumentException("File descriptors passed in Intent"); 3444 } 3445 3446 synchronized (this) { 3447 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3448 if (r == null) { 3449 ActivityOptions.abort(options); 3450 return false; 3451 } 3452 if (r.app == null || r.app.thread == null) { 3453 // The caller is not running... d'oh! 3454 ActivityOptions.abort(options); 3455 return false; 3456 } 3457 intent = new Intent(intent); 3458 // The caller is not allowed to change the data. 3459 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3460 // And we are resetting to find the next component... 3461 intent.setComponent(null); 3462 3463 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3464 3465 ActivityInfo aInfo = null; 3466 try { 3467 List<ResolveInfo> resolves = 3468 AppGlobals.getPackageManager().queryIntentActivities( 3469 intent, r.resolvedType, 3470 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3471 UserHandle.getCallingUserId()); 3472 3473 // Look for the original activity in the list... 3474 final int N = resolves != null ? resolves.size() : 0; 3475 for (int i=0; i<N; i++) { 3476 ResolveInfo rInfo = resolves.get(i); 3477 if (rInfo.activityInfo.packageName.equals(r.packageName) 3478 && rInfo.activityInfo.name.equals(r.info.name)) { 3479 // We found the current one... the next matching is 3480 // after it. 3481 i++; 3482 if (i<N) { 3483 aInfo = resolves.get(i).activityInfo; 3484 } 3485 if (debug) { 3486 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3487 + "/" + r.info.name); 3488 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3489 + "/" + aInfo.name); 3490 } 3491 break; 3492 } 3493 } 3494 } catch (RemoteException e) { 3495 } 3496 3497 if (aInfo == null) { 3498 // Nobody who is next! 3499 ActivityOptions.abort(options); 3500 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3501 return false; 3502 } 3503 3504 intent.setComponent(new ComponentName( 3505 aInfo.applicationInfo.packageName, aInfo.name)); 3506 intent.setFlags(intent.getFlags()&~( 3507 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3508 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3509 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3510 Intent.FLAG_ACTIVITY_NEW_TASK)); 3511 3512 // Okay now we need to start the new activity, replacing the 3513 // currently running activity. This is a little tricky because 3514 // we want to start the new one as if the current one is finished, 3515 // but not finish the current one first so that there is no flicker. 3516 // And thus... 3517 final boolean wasFinishing = r.finishing; 3518 r.finishing = true; 3519 3520 // Propagate reply information over to the new activity. 3521 final ActivityRecord resultTo = r.resultTo; 3522 final String resultWho = r.resultWho; 3523 final int requestCode = r.requestCode; 3524 r.resultTo = null; 3525 if (resultTo != null) { 3526 resultTo.removeResultsLocked(r, resultWho, requestCode); 3527 } 3528 3529 final long origId = Binder.clearCallingIdentity(); 3530 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3531 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3532 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3533 -1, r.launchedFromUid, 0, options, false, null, null, null); 3534 Binder.restoreCallingIdentity(origId); 3535 3536 r.finishing = wasFinishing; 3537 if (res != ActivityManager.START_SUCCESS) { 3538 return false; 3539 } 3540 return true; 3541 } 3542 } 3543 3544 @Override 3545 public final int startActivityFromRecents(int taskId, Bundle options) { 3546 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3547 String msg = "Permission Denial: startActivityFromRecents called without " + 3548 START_TASKS_FROM_RECENTS; 3549 Slog.w(TAG, msg); 3550 throw new SecurityException(msg); 3551 } 3552 return startActivityFromRecentsInner(taskId, options); 3553 } 3554 3555 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3556 final TaskRecord task; 3557 final int callingUid; 3558 final String callingPackage; 3559 final Intent intent; 3560 final int userId; 3561 synchronized (this) { 3562 task = recentTaskForIdLocked(taskId); 3563 if (task == null) { 3564 throw new IllegalArgumentException("Task " + taskId + " not found."); 3565 } 3566 callingUid = task.mCallingUid; 3567 callingPackage = task.mCallingPackage; 3568 intent = task.intent; 3569 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3570 userId = task.userId; 3571 } 3572 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3573 options, userId, null, task); 3574 } 3575 3576 final int startActivityInPackage(int uid, String callingPackage, 3577 Intent intent, String resolvedType, IBinder resultTo, 3578 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3579 IActivityContainer container, TaskRecord inTask) { 3580 3581 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3582 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3583 3584 // TODO: Switch to user app stacks here. 3585 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3586 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3587 null, null, null, options, userId, container, inTask); 3588 return ret; 3589 } 3590 3591 @Override 3592 public final int startActivities(IApplicationThread caller, String callingPackage, 3593 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3594 int userId) { 3595 enforceNotIsolatedCaller("startActivities"); 3596 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3597 false, ALLOW_FULL_ONLY, "startActivity", null); 3598 // TODO: Switch to user app stacks here. 3599 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3600 resolvedTypes, resultTo, options, userId); 3601 return ret; 3602 } 3603 3604 final int startActivitiesInPackage(int uid, String callingPackage, 3605 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3606 Bundle options, int userId) { 3607 3608 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3609 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3610 // TODO: Switch to user app stacks here. 3611 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3612 resultTo, options, userId); 3613 return ret; 3614 } 3615 3616 //explicitly remove thd old information in mRecentTasks when removing existing user. 3617 private void removeRecentTasksForUserLocked(int userId) { 3618 if(userId <= 0) { 3619 Slog.i(TAG, "Can't remove recent task on user " + userId); 3620 return; 3621 } 3622 3623 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3624 TaskRecord tr = mRecentTasks.get(i); 3625 if (tr.userId == userId) { 3626 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3627 + " when finishing user" + userId); 3628 mRecentTasks.remove(i); 3629 tr.removedFromRecents(mTaskPersister); 3630 } 3631 } 3632 3633 // Remove tasks from persistent storage. 3634 mTaskPersister.wakeup(null, true); 3635 } 3636 3637 // Sort by taskId 3638 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3639 @Override 3640 public int compare(TaskRecord lhs, TaskRecord rhs) { 3641 return rhs.taskId - lhs.taskId; 3642 } 3643 }; 3644 3645 // Extract the affiliates of the chain containing mRecentTasks[start]. 3646 private int processNextAffiliateChain(int start) { 3647 final TaskRecord startTask = mRecentTasks.get(start); 3648 final int affiliateId = startTask.mAffiliatedTaskId; 3649 3650 // Quick identification of isolated tasks. I.e. those not launched behind. 3651 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3652 startTask.mNextAffiliate == null) { 3653 // There is still a slim chance that there are other tasks that point to this task 3654 // and that the chain is so messed up that this task no longer points to them but 3655 // the gain of this optimization outweighs the risk. 3656 startTask.inRecents = true; 3657 return start + 1; 3658 } 3659 3660 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3661 mTmpRecents.clear(); 3662 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3663 final TaskRecord task = mRecentTasks.get(i); 3664 if (task.mAffiliatedTaskId == affiliateId) { 3665 mRecentTasks.remove(i); 3666 mTmpRecents.add(task); 3667 } 3668 } 3669 3670 // Sort them all by taskId. That is the order they were create in and that order will 3671 // always be correct. 3672 Collections.sort(mTmpRecents, mTaskRecordComparator); 3673 3674 // Go through and fix up the linked list. 3675 // The first one is the end of the chain and has no next. 3676 final TaskRecord first = mTmpRecents.get(0); 3677 first.inRecents = true; 3678 if (first.mNextAffiliate != null) { 3679 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3680 first.setNextAffiliate(null); 3681 mTaskPersister.wakeup(first, false); 3682 } 3683 // Everything in the middle is doubly linked from next to prev. 3684 final int tmpSize = mTmpRecents.size(); 3685 for (int i = 0; i < tmpSize - 1; ++i) { 3686 final TaskRecord next = mTmpRecents.get(i); 3687 final TaskRecord prev = mTmpRecents.get(i + 1); 3688 if (next.mPrevAffiliate != prev) { 3689 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3690 " setting prev=" + prev); 3691 next.setPrevAffiliate(prev); 3692 mTaskPersister.wakeup(next, false); 3693 } 3694 if (prev.mNextAffiliate != next) { 3695 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3696 " setting next=" + next); 3697 prev.setNextAffiliate(next); 3698 mTaskPersister.wakeup(prev, false); 3699 } 3700 prev.inRecents = true; 3701 } 3702 // The last one is the beginning of the list and has no prev. 3703 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3704 if (last.mPrevAffiliate != null) { 3705 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3706 last.setPrevAffiliate(null); 3707 mTaskPersister.wakeup(last, false); 3708 } 3709 3710 // Insert the group back into mRecentTasks at start. 3711 mRecentTasks.addAll(start, mTmpRecents); 3712 3713 // Let the caller know where we left off. 3714 return start + tmpSize; 3715 } 3716 3717 /** 3718 * Update the recent tasks lists: make sure tasks should still be here (their 3719 * applications / activities still exist), update their availability, fixup ordering 3720 * of affiliations. 3721 */ 3722 void cleanupRecentTasksLocked(int userId) { 3723 if (mRecentTasks == null) { 3724 // Happens when called from the packagemanager broadcast before boot. 3725 return; 3726 } 3727 3728 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3729 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3730 final IPackageManager pm = AppGlobals.getPackageManager(); 3731 final ActivityInfo dummyAct = new ActivityInfo(); 3732 final ApplicationInfo dummyApp = new ApplicationInfo(); 3733 3734 int N = mRecentTasks.size(); 3735 3736 int[] users = userId == UserHandle.USER_ALL 3737 ? getUsersLocked() : new int[] { userId }; 3738 for (int user : users) { 3739 for (int i = 0; i < N; i++) { 3740 TaskRecord task = mRecentTasks.get(i); 3741 if (task.userId != user) { 3742 // Only look at tasks for the user ID of interest. 3743 continue; 3744 } 3745 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3746 // This situation is broken, and we should just get rid of it now. 3747 mRecentTasks.remove(i); 3748 task.removedFromRecents(mTaskPersister); 3749 i--; 3750 N--; 3751 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3752 continue; 3753 } 3754 // Check whether this activity is currently available. 3755 if (task.realActivity != null) { 3756 ActivityInfo ai = availActCache.get(task.realActivity); 3757 if (ai == null) { 3758 try { 3759 ai = pm.getActivityInfo(task.realActivity, 3760 PackageManager.GET_UNINSTALLED_PACKAGES 3761 | PackageManager.GET_DISABLED_COMPONENTS, user); 3762 } catch (RemoteException e) { 3763 // Will never happen. 3764 continue; 3765 } 3766 if (ai == null) { 3767 ai = dummyAct; 3768 } 3769 availActCache.put(task.realActivity, ai); 3770 } 3771 if (ai == dummyAct) { 3772 // This could be either because the activity no longer exists, or the 3773 // app is temporarily gone. For the former we want to remove the recents 3774 // entry; for the latter we want to mark it as unavailable. 3775 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3776 if (app == null) { 3777 try { 3778 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3779 PackageManager.GET_UNINSTALLED_PACKAGES 3780 | PackageManager.GET_DISABLED_COMPONENTS, user); 3781 } catch (RemoteException e) { 3782 // Will never happen. 3783 continue; 3784 } 3785 if (app == null) { 3786 app = dummyApp; 3787 } 3788 availAppCache.put(task.realActivity.getPackageName(), app); 3789 } 3790 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3791 // Doesn't exist any more! Good-bye. 3792 mRecentTasks.remove(i); 3793 task.removedFromRecents(mTaskPersister); 3794 i--; 3795 N--; 3796 Slog.w(TAG, "Removing no longer valid recent: " + task); 3797 continue; 3798 } else { 3799 // Otherwise just not available for now. 3800 if (task.isAvailable) { 3801 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3802 + task); 3803 } 3804 task.isAvailable = false; 3805 } 3806 } else { 3807 if (!ai.enabled || !ai.applicationInfo.enabled 3808 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3809 if (task.isAvailable) { 3810 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3811 + task + " (enabled=" + ai.enabled + "/" 3812 + ai.applicationInfo.enabled + " flags=" 3813 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3814 } 3815 task.isAvailable = false; 3816 } else { 3817 if (!task.isAvailable) { 3818 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3819 + task); 3820 } 3821 task.isAvailable = true; 3822 } 3823 } 3824 } 3825 } 3826 } 3827 3828 // Verify the affiliate chain for each task. 3829 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3830 } 3831 3832 mTmpRecents.clear(); 3833 // mRecentTasks is now in sorted, affiliated order. 3834 } 3835 3836 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3837 int N = mRecentTasks.size(); 3838 TaskRecord top = task; 3839 int topIndex = taskIndex; 3840 while (top.mNextAffiliate != null && topIndex > 0) { 3841 top = top.mNextAffiliate; 3842 topIndex--; 3843 } 3844 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3845 + topIndex + " from intial " + taskIndex); 3846 // Find the end of the chain, doing a sanity check along the way. 3847 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3848 int endIndex = topIndex; 3849 TaskRecord prev = top; 3850 while (endIndex < N) { 3851 TaskRecord cur = mRecentTasks.get(endIndex); 3852 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3853 + endIndex + " " + cur); 3854 if (cur == top) { 3855 // Verify start of the chain. 3856 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3857 Slog.wtf(TAG, "Bad chain @" + endIndex 3858 + ": first task has next affiliate: " + prev); 3859 sane = false; 3860 break; 3861 } 3862 } else { 3863 // Verify middle of the chain's next points back to the one before. 3864 if (cur.mNextAffiliate != prev 3865 || cur.mNextAffiliateTaskId != prev.taskId) { 3866 Slog.wtf(TAG, "Bad chain @" + endIndex 3867 + ": middle task " + cur + " @" + endIndex 3868 + " has bad next affiliate " 3869 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3870 + ", expected " + prev); 3871 sane = false; 3872 break; 3873 } 3874 } 3875 if (cur.mPrevAffiliateTaskId == -1) { 3876 // Chain ends here. 3877 if (cur.mPrevAffiliate != null) { 3878 Slog.wtf(TAG, "Bad chain @" + endIndex 3879 + ": last task " + cur + " has previous affiliate " 3880 + cur.mPrevAffiliate); 3881 sane = false; 3882 } 3883 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3884 break; 3885 } else { 3886 // Verify middle of the chain's prev points to a valid item. 3887 if (cur.mPrevAffiliate == null) { 3888 Slog.wtf(TAG, "Bad chain @" + endIndex 3889 + ": task " + cur + " has previous affiliate " 3890 + cur.mPrevAffiliate + " but should be id " 3891 + cur.mPrevAffiliate); 3892 sane = false; 3893 break; 3894 } 3895 } 3896 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3897 Slog.wtf(TAG, "Bad chain @" + endIndex 3898 + ": task " + cur + " has affiliated id " 3899 + cur.mAffiliatedTaskId + " but should be " 3900 + task.mAffiliatedTaskId); 3901 sane = false; 3902 break; 3903 } 3904 prev = cur; 3905 endIndex++; 3906 if (endIndex >= N) { 3907 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3908 + ": last task " + prev); 3909 sane = false; 3910 break; 3911 } 3912 } 3913 if (sane) { 3914 if (endIndex < taskIndex) { 3915 Slog.wtf(TAG, "Bad chain @" + endIndex 3916 + ": did not extend to task " + task + " @" + taskIndex); 3917 sane = false; 3918 } 3919 } 3920 if (sane) { 3921 // All looks good, we can just move all of the affiliated tasks 3922 // to the top. 3923 for (int i=topIndex; i<=endIndex; i++) { 3924 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3925 + " from " + i + " to " + (i-topIndex)); 3926 TaskRecord cur = mRecentTasks.remove(i); 3927 mRecentTasks.add(i-topIndex, cur); 3928 } 3929 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3930 + " to " + endIndex); 3931 return true; 3932 } 3933 3934 // Whoops, couldn't do it. 3935 return false; 3936 } 3937 3938 final void addRecentTaskLocked(TaskRecord task) { 3939 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3940 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3941 3942 int N = mRecentTasks.size(); 3943 // Quick case: check if the top-most recent task is the same. 3944 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3945 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3946 return; 3947 } 3948 // Another quick case: check if this is part of a set of affiliated 3949 // tasks that are at the top. 3950 if (isAffiliated && N > 0 && task.inRecents 3951 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3952 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3953 + " at top when adding " + task); 3954 return; 3955 } 3956 // Another quick case: never add voice sessions. 3957 if (task.voiceSession != null) { 3958 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3959 return; 3960 } 3961 3962 boolean needAffiliationFix = false; 3963 3964 // Slightly less quick case: the task is already in recents, so all we need 3965 // to do is move it. 3966 if (task.inRecents) { 3967 int taskIndex = mRecentTasks.indexOf(task); 3968 if (taskIndex >= 0) { 3969 if (!isAffiliated) { 3970 // Simple case: this is not an affiliated task, so we just move it to the front. 3971 mRecentTasks.remove(taskIndex); 3972 mRecentTasks.add(0, task); 3973 notifyTaskPersisterLocked(task, false); 3974 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3975 + " from " + taskIndex); 3976 return; 3977 } else { 3978 // More complicated: need to keep all affiliated tasks together. 3979 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3980 // All went well. 3981 return; 3982 } 3983 3984 // Uh oh... something bad in the affiliation chain, try to rebuild 3985 // everything and then go through our general path of adding a new task. 3986 needAffiliationFix = true; 3987 } 3988 } else { 3989 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 3990 needAffiliationFix = true; 3991 } 3992 } 3993 3994 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 3995 trimRecentsForTask(task, true); 3996 3997 N = mRecentTasks.size(); 3998 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 3999 final TaskRecord tr = mRecentTasks.remove(N - 1); 4000 tr.removedFromRecents(mTaskPersister); 4001 N--; 4002 } 4003 task.inRecents = true; 4004 if (!isAffiliated || needAffiliationFix) { 4005 // If this is a simple non-affiliated task, or we had some failure trying to 4006 // handle it as part of an affilated task, then just place it at the top. 4007 mRecentTasks.add(0, task); 4008 } else if (isAffiliated) { 4009 // If this is a new affiliated task, then move all of the affiliated tasks 4010 // to the front and insert this new one. 4011 TaskRecord other = task.mNextAffiliate; 4012 if (other == null) { 4013 other = task.mPrevAffiliate; 4014 } 4015 if (other != null) { 4016 int otherIndex = mRecentTasks.indexOf(other); 4017 if (otherIndex >= 0) { 4018 // Insert new task at appropriate location. 4019 int taskIndex; 4020 if (other == task.mNextAffiliate) { 4021 // We found the index of our next affiliation, which is who is 4022 // before us in the list, so add after that point. 4023 taskIndex = otherIndex+1; 4024 } else { 4025 // We found the index of our previous affiliation, which is who is 4026 // after us in the list, so add at their position. 4027 taskIndex = otherIndex; 4028 } 4029 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4030 + taskIndex + ": " + task); 4031 mRecentTasks.add(taskIndex, task); 4032 4033 // Now move everything to the front. 4034 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4035 // All went well. 4036 return; 4037 } 4038 4039 // Uh oh... something bad in the affiliation chain, try to rebuild 4040 // everything and then go through our general path of adding a new task. 4041 needAffiliationFix = true; 4042 } else { 4043 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4044 + other); 4045 needAffiliationFix = true; 4046 } 4047 } else { 4048 if (DEBUG_RECENTS) Slog.d(TAG, 4049 "addRecent: adding affiliated task without next/prev:" + task); 4050 needAffiliationFix = true; 4051 } 4052 } 4053 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4054 4055 if (needAffiliationFix) { 4056 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4057 cleanupRecentTasksLocked(task.userId); 4058 } 4059 } 4060 4061 /** 4062 * If needed, remove oldest existing entries in recents that are for the same kind 4063 * of task as the given one. 4064 */ 4065 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4066 int N = mRecentTasks.size(); 4067 final Intent intent = task.intent; 4068 final boolean document = intent != null && intent.isDocument(); 4069 4070 int maxRecents = task.maxRecents - 1; 4071 for (int i=0; i<N; i++) { 4072 final TaskRecord tr = mRecentTasks.get(i); 4073 if (task != tr) { 4074 if (task.userId != tr.userId) { 4075 continue; 4076 } 4077 if (i > MAX_RECENT_BITMAPS) { 4078 tr.freeLastThumbnail(); 4079 } 4080 final Intent trIntent = tr.intent; 4081 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4082 (intent == null || !intent.filterEquals(trIntent))) { 4083 continue; 4084 } 4085 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4086 if (document && trIsDocument) { 4087 // These are the same document activity (not necessarily the same doc). 4088 if (maxRecents > 0) { 4089 --maxRecents; 4090 continue; 4091 } 4092 // Hit the maximum number of documents for this task. Fall through 4093 // and remove this document from recents. 4094 } else if (document || trIsDocument) { 4095 // Only one of these is a document. Not the droid we're looking for. 4096 continue; 4097 } 4098 } 4099 4100 if (!doTrim) { 4101 // If the caller is not actually asking for a trim, just tell them we reached 4102 // a point where the trim would happen. 4103 return i; 4104 } 4105 4106 // Either task and tr are the same or, their affinities match or their intents match 4107 // and neither of them is a document, or they are documents using the same activity 4108 // and their maxRecents has been reached. 4109 tr.disposeThumbnail(); 4110 mRecentTasks.remove(i); 4111 if (task != tr) { 4112 tr.removedFromRecents(mTaskPersister); 4113 } 4114 i--; 4115 N--; 4116 if (task.intent == null) { 4117 // If the new recent task we are adding is not fully 4118 // specified, then replace it with the existing recent task. 4119 task = tr; 4120 } 4121 notifyTaskPersisterLocked(tr, false); 4122 } 4123 4124 return -1; 4125 } 4126 4127 @Override 4128 public void reportActivityFullyDrawn(IBinder token) { 4129 synchronized (this) { 4130 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4131 if (r == null) { 4132 return; 4133 } 4134 r.reportFullyDrawnLocked(); 4135 } 4136 } 4137 4138 @Override 4139 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4140 synchronized (this) { 4141 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4142 if (r == null) { 4143 return; 4144 } 4145 final long origId = Binder.clearCallingIdentity(); 4146 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4147 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4148 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4149 if (config != null) { 4150 r.frozenBeforeDestroy = true; 4151 if (!updateConfigurationLocked(config, r, false, false)) { 4152 mStackSupervisor.resumeTopActivitiesLocked(); 4153 } 4154 } 4155 Binder.restoreCallingIdentity(origId); 4156 } 4157 } 4158 4159 @Override 4160 public int getRequestedOrientation(IBinder token) { 4161 synchronized (this) { 4162 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4163 if (r == null) { 4164 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4165 } 4166 return mWindowManager.getAppOrientation(r.appToken); 4167 } 4168 } 4169 4170 /** 4171 * This is the internal entry point for handling Activity.finish(). 4172 * 4173 * @param token The Binder token referencing the Activity we want to finish. 4174 * @param resultCode Result code, if any, from this Activity. 4175 * @param resultData Result data (Intent), if any, from this Activity. 4176 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4177 * the root Activity in the task. 4178 * 4179 * @return Returns true if the activity successfully finished, or false if it is still running. 4180 */ 4181 @Override 4182 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4183 boolean finishTask) { 4184 // Refuse possible leaked file descriptors 4185 if (resultData != null && resultData.hasFileDescriptors() == true) { 4186 throw new IllegalArgumentException("File descriptors passed in Intent"); 4187 } 4188 4189 synchronized(this) { 4190 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4191 if (r == null) { 4192 return true; 4193 } 4194 // Keep track of the root activity of the task before we finish it 4195 TaskRecord tr = r.task; 4196 ActivityRecord rootR = tr.getRootActivity(); 4197 if (rootR == null) { 4198 Slog.w(TAG, "Finishing task with all activities already finished"); 4199 } 4200 // Do not allow task to finish in Lock Task mode. 4201 if (tr == mStackSupervisor.mLockTaskModeTask) { 4202 if (rootR == r) { 4203 Slog.i(TAG, "Not finishing task in lock task mode"); 4204 mStackSupervisor.showLockTaskToast(); 4205 return false; 4206 } 4207 } 4208 if (mController != null) { 4209 // Find the first activity that is not finishing. 4210 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4211 if (next != null) { 4212 // ask watcher if this is allowed 4213 boolean resumeOK = true; 4214 try { 4215 resumeOK = mController.activityResuming(next.packageName); 4216 } catch (RemoteException e) { 4217 mController = null; 4218 Watchdog.getInstance().setActivityController(null); 4219 } 4220 4221 if (!resumeOK) { 4222 Slog.i(TAG, "Not finishing activity because controller resumed"); 4223 return false; 4224 } 4225 } 4226 } 4227 final long origId = Binder.clearCallingIdentity(); 4228 try { 4229 boolean res; 4230 if (finishTask && r == rootR) { 4231 // If requested, remove the task that is associated to this activity only if it 4232 // was the root activity in the task. The result code and data is ignored 4233 // because we don't support returning them across task boundaries. 4234 res = removeTaskByIdLocked(tr.taskId, false); 4235 if (!res) { 4236 Slog.i(TAG, "Removing task failed to finish activity"); 4237 } 4238 } else { 4239 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4240 resultData, "app-request", true); 4241 if (!res) { 4242 Slog.i(TAG, "Failed to finish by app-request"); 4243 } 4244 } 4245 return res; 4246 } finally { 4247 Binder.restoreCallingIdentity(origId); 4248 } 4249 } 4250 } 4251 4252 @Override 4253 public final void finishHeavyWeightApp() { 4254 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4255 != PackageManager.PERMISSION_GRANTED) { 4256 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4257 + Binder.getCallingPid() 4258 + ", uid=" + Binder.getCallingUid() 4259 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4260 Slog.w(TAG, msg); 4261 throw new SecurityException(msg); 4262 } 4263 4264 synchronized(this) { 4265 if (mHeavyWeightProcess == null) { 4266 return; 4267 } 4268 4269 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4270 mHeavyWeightProcess.activities); 4271 for (int i=0; i<activities.size(); i++) { 4272 ActivityRecord r = activities.get(i); 4273 if (!r.finishing) { 4274 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4275 null, "finish-heavy", true); 4276 } 4277 } 4278 4279 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4280 mHeavyWeightProcess.userId, 0)); 4281 mHeavyWeightProcess = null; 4282 } 4283 } 4284 4285 @Override 4286 public void crashApplication(int uid, int initialPid, String packageName, 4287 String message) { 4288 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4289 != PackageManager.PERMISSION_GRANTED) { 4290 String msg = "Permission Denial: crashApplication() from pid=" 4291 + Binder.getCallingPid() 4292 + ", uid=" + Binder.getCallingUid() 4293 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4294 Slog.w(TAG, msg); 4295 throw new SecurityException(msg); 4296 } 4297 4298 synchronized(this) { 4299 ProcessRecord proc = null; 4300 4301 // Figure out which process to kill. We don't trust that initialPid 4302 // still has any relation to current pids, so must scan through the 4303 // list. 4304 synchronized (mPidsSelfLocked) { 4305 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4306 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4307 if (p.uid != uid) { 4308 continue; 4309 } 4310 if (p.pid == initialPid) { 4311 proc = p; 4312 break; 4313 } 4314 if (p.pkgList.containsKey(packageName)) { 4315 proc = p; 4316 } 4317 } 4318 } 4319 4320 if (proc == null) { 4321 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4322 + " initialPid=" + initialPid 4323 + " packageName=" + packageName); 4324 return; 4325 } 4326 4327 if (proc.thread != null) { 4328 if (proc.pid == Process.myPid()) { 4329 Log.w(TAG, "crashApplication: trying to crash self!"); 4330 return; 4331 } 4332 long ident = Binder.clearCallingIdentity(); 4333 try { 4334 proc.thread.scheduleCrash(message); 4335 } catch (RemoteException e) { 4336 } 4337 Binder.restoreCallingIdentity(ident); 4338 } 4339 } 4340 } 4341 4342 @Override 4343 public final void finishSubActivity(IBinder token, String resultWho, 4344 int requestCode) { 4345 synchronized(this) { 4346 final long origId = Binder.clearCallingIdentity(); 4347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4348 if (r != null) { 4349 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4350 } 4351 Binder.restoreCallingIdentity(origId); 4352 } 4353 } 4354 4355 @Override 4356 public boolean finishActivityAffinity(IBinder token) { 4357 synchronized(this) { 4358 final long origId = Binder.clearCallingIdentity(); 4359 try { 4360 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4361 4362 ActivityRecord rootR = r.task.getRootActivity(); 4363 // Do not allow task to finish in Lock Task mode. 4364 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4365 if (rootR == r) { 4366 mStackSupervisor.showLockTaskToast(); 4367 return false; 4368 } 4369 } 4370 boolean res = false; 4371 if (r != null) { 4372 res = r.task.stack.finishActivityAffinityLocked(r); 4373 } 4374 return res; 4375 } finally { 4376 Binder.restoreCallingIdentity(origId); 4377 } 4378 } 4379 } 4380 4381 @Override 4382 public void finishVoiceTask(IVoiceInteractionSession session) { 4383 synchronized(this) { 4384 final long origId = Binder.clearCallingIdentity(); 4385 try { 4386 mStackSupervisor.finishVoiceTask(session); 4387 } finally { 4388 Binder.restoreCallingIdentity(origId); 4389 } 4390 } 4391 4392 } 4393 4394 @Override 4395 public boolean releaseActivityInstance(IBinder token) { 4396 synchronized(this) { 4397 final long origId = Binder.clearCallingIdentity(); 4398 try { 4399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4400 if (r.task == null || r.task.stack == null) { 4401 return false; 4402 } 4403 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4404 } finally { 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 } 4409 4410 @Override 4411 public void releaseSomeActivities(IApplicationThread appInt) { 4412 synchronized(this) { 4413 final long origId = Binder.clearCallingIdentity(); 4414 try { 4415 ProcessRecord app = getRecordForAppLocked(appInt); 4416 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4417 } finally { 4418 Binder.restoreCallingIdentity(origId); 4419 } 4420 } 4421 } 4422 4423 @Override 4424 public boolean willActivityBeVisible(IBinder token) { 4425 synchronized(this) { 4426 ActivityStack stack = ActivityRecord.getStackLocked(token); 4427 if (stack != null) { 4428 return stack.willActivityBeVisibleLocked(token); 4429 } 4430 return false; 4431 } 4432 } 4433 4434 @Override 4435 public void overridePendingTransition(IBinder token, String packageName, 4436 int enterAnim, int exitAnim) { 4437 synchronized(this) { 4438 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4439 if (self == null) { 4440 return; 4441 } 4442 4443 final long origId = Binder.clearCallingIdentity(); 4444 4445 if (self.state == ActivityState.RESUMED 4446 || self.state == ActivityState.PAUSING) { 4447 mWindowManager.overridePendingAppTransition(packageName, 4448 enterAnim, exitAnim, null); 4449 } 4450 4451 Binder.restoreCallingIdentity(origId); 4452 } 4453 } 4454 4455 /** 4456 * Main function for removing an existing process from the activity manager 4457 * as a result of that process going away. Clears out all connections 4458 * to the process. 4459 */ 4460 private final void handleAppDiedLocked(ProcessRecord app, 4461 boolean restarting, boolean allowRestart) { 4462 int pid = app.pid; 4463 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4464 if (!kept && !restarting) { 4465 removeLruProcessLocked(app); 4466 if (pid > 0) { 4467 ProcessList.remove(pid); 4468 } 4469 } 4470 4471 if (mProfileProc == app) { 4472 clearProfilerLocked(); 4473 } 4474 4475 // Remove this application's activities from active lists. 4476 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4477 4478 app.activities.clear(); 4479 4480 if (app.instrumentationClass != null) { 4481 Slog.w(TAG, "Crash of app " + app.processName 4482 + " running instrumentation " + app.instrumentationClass); 4483 Bundle info = new Bundle(); 4484 info.putString("shortMsg", "Process crashed."); 4485 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4486 } 4487 4488 if (!restarting) { 4489 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4490 // If there was nothing to resume, and we are not already 4491 // restarting this process, but there is a visible activity that 4492 // is hosted by the process... then make sure all visible 4493 // activities are running, taking care of restarting this 4494 // process. 4495 if (hasVisibleActivities) { 4496 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4497 } 4498 } 4499 } 4500 } 4501 4502 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4503 IBinder threadBinder = thread.asBinder(); 4504 // Find the application record. 4505 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4506 ProcessRecord rec = mLruProcesses.get(i); 4507 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4508 return i; 4509 } 4510 } 4511 return -1; 4512 } 4513 4514 final ProcessRecord getRecordForAppLocked( 4515 IApplicationThread thread) { 4516 if (thread == null) { 4517 return null; 4518 } 4519 4520 int appIndex = getLRURecordIndexForAppLocked(thread); 4521 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4522 } 4523 4524 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4525 // If there are no longer any background processes running, 4526 // and the app that died was not running instrumentation, 4527 // then tell everyone we are now low on memory. 4528 boolean haveBg = false; 4529 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4530 ProcessRecord rec = mLruProcesses.get(i); 4531 if (rec.thread != null 4532 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4533 haveBg = true; 4534 break; 4535 } 4536 } 4537 4538 if (!haveBg) { 4539 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4540 if (doReport) { 4541 long now = SystemClock.uptimeMillis(); 4542 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4543 doReport = false; 4544 } else { 4545 mLastMemUsageReportTime = now; 4546 } 4547 } 4548 final ArrayList<ProcessMemInfo> memInfos 4549 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4550 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4551 long now = SystemClock.uptimeMillis(); 4552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4553 ProcessRecord rec = mLruProcesses.get(i); 4554 if (rec == dyingProc || rec.thread == null) { 4555 continue; 4556 } 4557 if (doReport) { 4558 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4559 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4560 } 4561 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4562 // The low memory report is overriding any current 4563 // state for a GC request. Make sure to do 4564 // heavy/important/visible/foreground processes first. 4565 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4566 rec.lastRequestedGc = 0; 4567 } else { 4568 rec.lastRequestedGc = rec.lastLowMemory; 4569 } 4570 rec.reportLowMemory = true; 4571 rec.lastLowMemory = now; 4572 mProcessesToGc.remove(rec); 4573 addProcessToGcListLocked(rec); 4574 } 4575 } 4576 if (doReport) { 4577 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4578 mHandler.sendMessage(msg); 4579 } 4580 scheduleAppGcsLocked(); 4581 } 4582 } 4583 4584 final void appDiedLocked(ProcessRecord app) { 4585 appDiedLocked(app, app.pid, app.thread); 4586 } 4587 4588 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4589 // First check if this ProcessRecord is actually active for the pid. 4590 synchronized (mPidsSelfLocked) { 4591 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4592 if (curProc != app) { 4593 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4594 return; 4595 } 4596 } 4597 4598 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4599 synchronized (stats) { 4600 stats.noteProcessDiedLocked(app.info.uid, pid); 4601 } 4602 4603 Process.killProcessQuiet(pid); 4604 Process.killProcessGroup(app.info.uid, pid); 4605 app.killed = true; 4606 4607 // Clean up already done if the process has been re-started. 4608 if (app.pid == pid && app.thread != null && 4609 app.thread.asBinder() == thread.asBinder()) { 4610 boolean doLowMem = app.instrumentationClass == null; 4611 boolean doOomAdj = doLowMem; 4612 if (!app.killedByAm) { 4613 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4614 + ") has died"); 4615 mAllowLowerMemLevel = true; 4616 } else { 4617 // Note that we always want to do oom adj to update our state with the 4618 // new number of procs. 4619 mAllowLowerMemLevel = false; 4620 doLowMem = false; 4621 } 4622 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4623 if (DEBUG_CLEANUP) Slog.v( 4624 TAG, "Dying app: " + app + ", pid: " + pid 4625 + ", thread: " + thread.asBinder()); 4626 handleAppDiedLocked(app, false, true); 4627 4628 if (doOomAdj) { 4629 updateOomAdjLocked(); 4630 } 4631 if (doLowMem) { 4632 doLowMemReportIfNeededLocked(app); 4633 } 4634 } else if (app.pid != pid) { 4635 // A new process has already been started. 4636 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4637 + ") has died and restarted (pid " + app.pid + ")."); 4638 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4639 } else if (DEBUG_PROCESSES) { 4640 Slog.d(TAG, "Received spurious death notification for thread " 4641 + thread.asBinder()); 4642 } 4643 } 4644 4645 /** 4646 * If a stack trace dump file is configured, dump process stack traces. 4647 * @param clearTraces causes the dump file to be erased prior to the new 4648 * traces being written, if true; when false, the new traces will be 4649 * appended to any existing file content. 4650 * @param firstPids of dalvik VM processes to dump stack traces for first 4651 * @param lastPids of dalvik VM processes to dump stack traces for last 4652 * @param nativeProcs optional list of native process names to dump stack crawls 4653 * @return file containing stack traces, or null if no dump file is configured 4654 */ 4655 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4656 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4657 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4658 if (tracesPath == null || tracesPath.length() == 0) { 4659 return null; 4660 } 4661 4662 File tracesFile = new File(tracesPath); 4663 try { 4664 File tracesDir = tracesFile.getParentFile(); 4665 if (!tracesDir.exists()) { 4666 tracesDir.mkdirs(); 4667 if (!SELinux.restorecon(tracesDir)) { 4668 return null; 4669 } 4670 } 4671 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4672 4673 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4674 tracesFile.createNewFile(); 4675 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4676 } catch (IOException e) { 4677 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4678 return null; 4679 } 4680 4681 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4682 return tracesFile; 4683 } 4684 4685 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4686 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4687 // Use a FileObserver to detect when traces finish writing. 4688 // The order of traces is considered important to maintain for legibility. 4689 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4690 @Override 4691 public synchronized void onEvent(int event, String path) { notify(); } 4692 }; 4693 4694 try { 4695 observer.startWatching(); 4696 4697 // First collect all of the stacks of the most important pids. 4698 if (firstPids != null) { 4699 try { 4700 int num = firstPids.size(); 4701 for (int i = 0; i < num; i++) { 4702 synchronized (observer) { 4703 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4704 observer.wait(200); // Wait for write-close, give up after 200msec 4705 } 4706 } 4707 } catch (InterruptedException e) { 4708 Slog.wtf(TAG, e); 4709 } 4710 } 4711 4712 // Next collect the stacks of the native pids 4713 if (nativeProcs != null) { 4714 int[] pids = Process.getPidsForCommands(nativeProcs); 4715 if (pids != null) { 4716 for (int pid : pids) { 4717 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4718 } 4719 } 4720 } 4721 4722 // Lastly, measure CPU usage. 4723 if (processCpuTracker != null) { 4724 processCpuTracker.init(); 4725 System.gc(); 4726 processCpuTracker.update(); 4727 try { 4728 synchronized (processCpuTracker) { 4729 processCpuTracker.wait(500); // measure over 1/2 second. 4730 } 4731 } catch (InterruptedException e) { 4732 } 4733 processCpuTracker.update(); 4734 4735 // We'll take the stack crawls of just the top apps using CPU. 4736 final int N = processCpuTracker.countWorkingStats(); 4737 int numProcs = 0; 4738 for (int i=0; i<N && numProcs<5; i++) { 4739 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4740 if (lastPids.indexOfKey(stats.pid) >= 0) { 4741 numProcs++; 4742 try { 4743 synchronized (observer) { 4744 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4745 observer.wait(200); // Wait for write-close, give up after 200msec 4746 } 4747 } catch (InterruptedException e) { 4748 Slog.wtf(TAG, e); 4749 } 4750 4751 } 4752 } 4753 } 4754 } finally { 4755 observer.stopWatching(); 4756 } 4757 } 4758 4759 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4760 if (true || IS_USER_BUILD) { 4761 return; 4762 } 4763 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4764 if (tracesPath == null || tracesPath.length() == 0) { 4765 return; 4766 } 4767 4768 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4769 StrictMode.allowThreadDiskWrites(); 4770 try { 4771 final File tracesFile = new File(tracesPath); 4772 final File tracesDir = tracesFile.getParentFile(); 4773 final File tracesTmp = new File(tracesDir, "__tmp__"); 4774 try { 4775 if (!tracesDir.exists()) { 4776 tracesDir.mkdirs(); 4777 if (!SELinux.restorecon(tracesDir.getPath())) { 4778 return; 4779 } 4780 } 4781 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4782 4783 if (tracesFile.exists()) { 4784 tracesTmp.delete(); 4785 tracesFile.renameTo(tracesTmp); 4786 } 4787 StringBuilder sb = new StringBuilder(); 4788 Time tobj = new Time(); 4789 tobj.set(System.currentTimeMillis()); 4790 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4791 sb.append(": "); 4792 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4793 sb.append(" since "); 4794 sb.append(msg); 4795 FileOutputStream fos = new FileOutputStream(tracesFile); 4796 fos.write(sb.toString().getBytes()); 4797 if (app == null) { 4798 fos.write("\n*** No application process!".getBytes()); 4799 } 4800 fos.close(); 4801 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4802 } catch (IOException e) { 4803 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4804 return; 4805 } 4806 4807 if (app != null) { 4808 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4809 firstPids.add(app.pid); 4810 dumpStackTraces(tracesPath, firstPids, null, null, null); 4811 } 4812 4813 File lastTracesFile = null; 4814 File curTracesFile = null; 4815 for (int i=9; i>=0; i--) { 4816 String name = String.format(Locale.US, "slow%02d.txt", i); 4817 curTracesFile = new File(tracesDir, name); 4818 if (curTracesFile.exists()) { 4819 if (lastTracesFile != null) { 4820 curTracesFile.renameTo(lastTracesFile); 4821 } else { 4822 curTracesFile.delete(); 4823 } 4824 } 4825 lastTracesFile = curTracesFile; 4826 } 4827 tracesFile.renameTo(curTracesFile); 4828 if (tracesTmp.exists()) { 4829 tracesTmp.renameTo(tracesFile); 4830 } 4831 } finally { 4832 StrictMode.setThreadPolicy(oldPolicy); 4833 } 4834 } 4835 4836 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4837 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4838 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4839 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4840 4841 if (mController != null) { 4842 try { 4843 // 0 == continue, -1 = kill process immediately 4844 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4845 if (res < 0 && app.pid != MY_PID) { 4846 app.kill("anr", true); 4847 } 4848 } catch (RemoteException e) { 4849 mController = null; 4850 Watchdog.getInstance().setActivityController(null); 4851 } 4852 } 4853 4854 long anrTime = SystemClock.uptimeMillis(); 4855 if (MONITOR_CPU_USAGE) { 4856 updateCpuStatsNow(); 4857 } 4858 4859 synchronized (this) { 4860 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4861 if (mShuttingDown) { 4862 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4863 return; 4864 } else if (app.notResponding) { 4865 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4866 return; 4867 } else if (app.crashing) { 4868 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4869 return; 4870 } 4871 4872 // In case we come through here for the same app before completing 4873 // this one, mark as anring now so we will bail out. 4874 app.notResponding = true; 4875 4876 // Log the ANR to the event log. 4877 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4878 app.processName, app.info.flags, annotation); 4879 4880 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4881 firstPids.add(app.pid); 4882 4883 int parentPid = app.pid; 4884 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4885 if (parentPid != app.pid) firstPids.add(parentPid); 4886 4887 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4888 4889 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4890 ProcessRecord r = mLruProcesses.get(i); 4891 if (r != null && r.thread != null) { 4892 int pid = r.pid; 4893 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4894 if (r.persistent) { 4895 firstPids.add(pid); 4896 } else { 4897 lastPids.put(pid, Boolean.TRUE); 4898 } 4899 } 4900 } 4901 } 4902 } 4903 4904 // Log the ANR to the main log. 4905 StringBuilder info = new StringBuilder(); 4906 info.setLength(0); 4907 info.append("ANR in ").append(app.processName); 4908 if (activity != null && activity.shortComponentName != null) { 4909 info.append(" (").append(activity.shortComponentName).append(")"); 4910 } 4911 info.append("\n"); 4912 info.append("PID: ").append(app.pid).append("\n"); 4913 if (annotation != null) { 4914 info.append("Reason: ").append(annotation).append("\n"); 4915 } 4916 if (parent != null && parent != activity) { 4917 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4918 } 4919 4920 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4921 4922 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4923 NATIVE_STACKS_OF_INTEREST); 4924 4925 String cpuInfo = null; 4926 if (MONITOR_CPU_USAGE) { 4927 updateCpuStatsNow(); 4928 synchronized (mProcessCpuTracker) { 4929 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4930 } 4931 info.append(processCpuTracker.printCurrentLoad()); 4932 info.append(cpuInfo); 4933 } 4934 4935 info.append(processCpuTracker.printCurrentState(anrTime)); 4936 4937 Slog.e(TAG, info.toString()); 4938 if (tracesFile == null) { 4939 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4940 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4941 } 4942 4943 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4944 cpuInfo, tracesFile, null); 4945 4946 if (mController != null) { 4947 try { 4948 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4949 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4950 if (res != 0) { 4951 if (res < 0 && app.pid != MY_PID) { 4952 app.kill("anr", true); 4953 } else { 4954 synchronized (this) { 4955 mServices.scheduleServiceTimeoutLocked(app); 4956 } 4957 } 4958 return; 4959 } 4960 } catch (RemoteException e) { 4961 mController = null; 4962 Watchdog.getInstance().setActivityController(null); 4963 } 4964 } 4965 4966 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4967 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4968 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4969 4970 synchronized (this) { 4971 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4972 app.kill("bg anr", true); 4973 return; 4974 } 4975 4976 // Set the app's notResponding state, and look up the errorReportReceiver 4977 makeAppNotRespondingLocked(app, 4978 activity != null ? activity.shortComponentName : null, 4979 annotation != null ? "ANR " + annotation : "ANR", 4980 info.toString()); 4981 4982 // Bring up the infamous App Not Responding dialog 4983 Message msg = Message.obtain(); 4984 HashMap<String, Object> map = new HashMap<String, Object>(); 4985 msg.what = SHOW_NOT_RESPONDING_MSG; 4986 msg.obj = map; 4987 msg.arg1 = aboveSystem ? 1 : 0; 4988 map.put("app", app); 4989 if (activity != null) { 4990 map.put("activity", activity); 4991 } 4992 4993 mHandler.sendMessage(msg); 4994 } 4995 } 4996 4997 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4998 if (!mLaunchWarningShown) { 4999 mLaunchWarningShown = true; 5000 mHandler.post(new Runnable() { 5001 @Override 5002 public void run() { 5003 synchronized (ActivityManagerService.this) { 5004 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5005 d.show(); 5006 mHandler.postDelayed(new Runnable() { 5007 @Override 5008 public void run() { 5009 synchronized (ActivityManagerService.this) { 5010 d.dismiss(); 5011 mLaunchWarningShown = false; 5012 } 5013 } 5014 }, 4000); 5015 } 5016 } 5017 }); 5018 } 5019 } 5020 5021 @Override 5022 public boolean clearApplicationUserData(final String packageName, 5023 final IPackageDataObserver observer, int userId) { 5024 enforceNotIsolatedCaller("clearApplicationUserData"); 5025 int uid = Binder.getCallingUid(); 5026 int pid = Binder.getCallingPid(); 5027 userId = handleIncomingUser(pid, uid, 5028 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5029 long callingId = Binder.clearCallingIdentity(); 5030 try { 5031 IPackageManager pm = AppGlobals.getPackageManager(); 5032 int pkgUid = -1; 5033 synchronized(this) { 5034 try { 5035 pkgUid = pm.getPackageUid(packageName, userId); 5036 } catch (RemoteException e) { 5037 } 5038 if (pkgUid == -1) { 5039 Slog.w(TAG, "Invalid packageName: " + packageName); 5040 if (observer != null) { 5041 try { 5042 observer.onRemoveCompleted(packageName, false); 5043 } catch (RemoteException e) { 5044 Slog.i(TAG, "Observer no longer exists."); 5045 } 5046 } 5047 return false; 5048 } 5049 if (uid == pkgUid || checkComponentPermission( 5050 android.Manifest.permission.CLEAR_APP_USER_DATA, 5051 pid, uid, -1, true) 5052 == PackageManager.PERMISSION_GRANTED) { 5053 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5054 } else { 5055 throw new SecurityException("PID " + pid + " does not have permission " 5056 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5057 + " of package " + packageName); 5058 } 5059 5060 // Remove all tasks match the cleared application package and user 5061 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5062 final TaskRecord tr = mRecentTasks.get(i); 5063 final String taskPackageName = 5064 tr.getBaseIntent().getComponent().getPackageName(); 5065 if (tr.userId != userId) continue; 5066 if (!taskPackageName.equals(packageName)) continue; 5067 removeTaskByIdLocked(tr.taskId, false); 5068 } 5069 } 5070 5071 try { 5072 // Clear application user data 5073 pm.clearApplicationUserData(packageName, observer, userId); 5074 5075 synchronized(this) { 5076 // Remove all permissions granted from/to this package 5077 removeUriPermissionsForPackageLocked(packageName, userId, true); 5078 } 5079 5080 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5081 Uri.fromParts("package", packageName, null)); 5082 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5083 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5084 null, null, 0, null, null, null, false, false, userId); 5085 } catch (RemoteException e) { 5086 } 5087 } finally { 5088 Binder.restoreCallingIdentity(callingId); 5089 } 5090 return true; 5091 } 5092 5093 @Override 5094 public void killBackgroundProcesses(final String packageName, int userId) { 5095 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5096 != PackageManager.PERMISSION_GRANTED && 5097 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5098 != PackageManager.PERMISSION_GRANTED) { 5099 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5100 + Binder.getCallingPid() 5101 + ", uid=" + Binder.getCallingUid() 5102 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5103 Slog.w(TAG, msg); 5104 throw new SecurityException(msg); 5105 } 5106 5107 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5108 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5109 long callingId = Binder.clearCallingIdentity(); 5110 try { 5111 IPackageManager pm = AppGlobals.getPackageManager(); 5112 synchronized(this) { 5113 int appId = -1; 5114 try { 5115 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5116 } catch (RemoteException e) { 5117 } 5118 if (appId == -1) { 5119 Slog.w(TAG, "Invalid packageName: " + packageName); 5120 return; 5121 } 5122 killPackageProcessesLocked(packageName, appId, userId, 5123 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5124 } 5125 } finally { 5126 Binder.restoreCallingIdentity(callingId); 5127 } 5128 } 5129 5130 @Override 5131 public void killAllBackgroundProcesses() { 5132 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5133 != PackageManager.PERMISSION_GRANTED) { 5134 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5135 + Binder.getCallingPid() 5136 + ", uid=" + Binder.getCallingUid() 5137 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5138 Slog.w(TAG, msg); 5139 throw new SecurityException(msg); 5140 } 5141 5142 long callingId = Binder.clearCallingIdentity(); 5143 try { 5144 synchronized(this) { 5145 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5146 final int NP = mProcessNames.getMap().size(); 5147 for (int ip=0; ip<NP; ip++) { 5148 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5149 final int NA = apps.size(); 5150 for (int ia=0; ia<NA; ia++) { 5151 ProcessRecord app = apps.valueAt(ia); 5152 if (app.persistent) { 5153 // we don't kill persistent processes 5154 continue; 5155 } 5156 if (app.removed) { 5157 procs.add(app); 5158 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5159 app.removed = true; 5160 procs.add(app); 5161 } 5162 } 5163 } 5164 5165 int N = procs.size(); 5166 for (int i=0; i<N; i++) { 5167 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5168 } 5169 mAllowLowerMemLevel = true; 5170 updateOomAdjLocked(); 5171 doLowMemReportIfNeededLocked(null); 5172 } 5173 } finally { 5174 Binder.restoreCallingIdentity(callingId); 5175 } 5176 } 5177 5178 @Override 5179 public void forceStopPackage(final String packageName, int userId) { 5180 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5181 != PackageManager.PERMISSION_GRANTED) { 5182 String msg = "Permission Denial: forceStopPackage() from pid=" 5183 + Binder.getCallingPid() 5184 + ", uid=" + Binder.getCallingUid() 5185 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5186 Slog.w(TAG, msg); 5187 throw new SecurityException(msg); 5188 } 5189 final int callingPid = Binder.getCallingPid(); 5190 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5191 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5192 long callingId = Binder.clearCallingIdentity(); 5193 try { 5194 IPackageManager pm = AppGlobals.getPackageManager(); 5195 synchronized(this) { 5196 int[] users = userId == UserHandle.USER_ALL 5197 ? getUsersLocked() : new int[] { userId }; 5198 for (int user : users) { 5199 int pkgUid = -1; 5200 try { 5201 pkgUid = pm.getPackageUid(packageName, user); 5202 } catch (RemoteException e) { 5203 } 5204 if (pkgUid == -1) { 5205 Slog.w(TAG, "Invalid packageName: " + packageName); 5206 continue; 5207 } 5208 try { 5209 pm.setPackageStoppedState(packageName, true, user); 5210 } catch (RemoteException e) { 5211 } catch (IllegalArgumentException e) { 5212 Slog.w(TAG, "Failed trying to unstop package " 5213 + packageName + ": " + e); 5214 } 5215 if (isUserRunningLocked(user, false)) { 5216 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5217 } 5218 } 5219 } 5220 } finally { 5221 Binder.restoreCallingIdentity(callingId); 5222 } 5223 } 5224 5225 @Override 5226 public void addPackageDependency(String packageName) { 5227 synchronized (this) { 5228 int callingPid = Binder.getCallingPid(); 5229 if (callingPid == Process.myPid()) { 5230 // Yeah, um, no. 5231 Slog.w(TAG, "Can't addPackageDependency on system process"); 5232 return; 5233 } 5234 ProcessRecord proc; 5235 synchronized (mPidsSelfLocked) { 5236 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5237 } 5238 if (proc != null) { 5239 if (proc.pkgDeps == null) { 5240 proc.pkgDeps = new ArraySet<String>(1); 5241 } 5242 proc.pkgDeps.add(packageName); 5243 } 5244 } 5245 } 5246 5247 /* 5248 * The pkg name and app id have to be specified. 5249 */ 5250 @Override 5251 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5252 if (pkg == null) { 5253 return; 5254 } 5255 // Make sure the uid is valid. 5256 if (appid < 0) { 5257 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5258 return; 5259 } 5260 int callerUid = Binder.getCallingUid(); 5261 // Only the system server can kill an application 5262 if (callerUid == Process.SYSTEM_UID) { 5263 // Post an aysnc message to kill the application 5264 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5265 msg.arg1 = appid; 5266 msg.arg2 = 0; 5267 Bundle bundle = new Bundle(); 5268 bundle.putString("pkg", pkg); 5269 bundle.putString("reason", reason); 5270 msg.obj = bundle; 5271 mHandler.sendMessage(msg); 5272 } else { 5273 throw new SecurityException(callerUid + " cannot kill pkg: " + 5274 pkg); 5275 } 5276 } 5277 5278 @Override 5279 public void closeSystemDialogs(String reason) { 5280 enforceNotIsolatedCaller("closeSystemDialogs"); 5281 5282 final int pid = Binder.getCallingPid(); 5283 final int uid = Binder.getCallingUid(); 5284 final long origId = Binder.clearCallingIdentity(); 5285 try { 5286 synchronized (this) { 5287 // Only allow this from foreground processes, so that background 5288 // applications can't abuse it to prevent system UI from being shown. 5289 if (uid >= Process.FIRST_APPLICATION_UID) { 5290 ProcessRecord proc; 5291 synchronized (mPidsSelfLocked) { 5292 proc = mPidsSelfLocked.get(pid); 5293 } 5294 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5295 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5296 + " from background process " + proc); 5297 return; 5298 } 5299 } 5300 closeSystemDialogsLocked(reason); 5301 } 5302 } finally { 5303 Binder.restoreCallingIdentity(origId); 5304 } 5305 } 5306 5307 void closeSystemDialogsLocked(String reason) { 5308 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5310 | Intent.FLAG_RECEIVER_FOREGROUND); 5311 if (reason != null) { 5312 intent.putExtra("reason", reason); 5313 } 5314 mWindowManager.closeSystemDialogs(reason); 5315 5316 mStackSupervisor.closeSystemDialogsLocked(); 5317 5318 broadcastIntentLocked(null, null, intent, null, 5319 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5320 Process.SYSTEM_UID, UserHandle.USER_ALL); 5321 } 5322 5323 @Override 5324 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5325 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5326 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5327 for (int i=pids.length-1; i>=0; i--) { 5328 ProcessRecord proc; 5329 int oomAdj; 5330 synchronized (this) { 5331 synchronized (mPidsSelfLocked) { 5332 proc = mPidsSelfLocked.get(pids[i]); 5333 oomAdj = proc != null ? proc.setAdj : 0; 5334 } 5335 } 5336 infos[i] = new Debug.MemoryInfo(); 5337 Debug.getMemoryInfo(pids[i], infos[i]); 5338 if (proc != null) { 5339 synchronized (this) { 5340 if (proc.thread != null && proc.setAdj == oomAdj) { 5341 // Record this for posterity if the process has been stable. 5342 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5343 infos[i].getTotalUss(), false, proc.pkgList); 5344 } 5345 } 5346 } 5347 } 5348 return infos; 5349 } 5350 5351 @Override 5352 public long[] getProcessPss(int[] pids) { 5353 enforceNotIsolatedCaller("getProcessPss"); 5354 long[] pss = new long[pids.length]; 5355 for (int i=pids.length-1; i>=0; i--) { 5356 ProcessRecord proc; 5357 int oomAdj; 5358 synchronized (this) { 5359 synchronized (mPidsSelfLocked) { 5360 proc = mPidsSelfLocked.get(pids[i]); 5361 oomAdj = proc != null ? proc.setAdj : 0; 5362 } 5363 } 5364 long[] tmpUss = new long[1]; 5365 pss[i] = Debug.getPss(pids[i], tmpUss); 5366 if (proc != null) { 5367 synchronized (this) { 5368 if (proc.thread != null && proc.setAdj == oomAdj) { 5369 // Record this for posterity if the process has been stable. 5370 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5371 } 5372 } 5373 } 5374 } 5375 return pss; 5376 } 5377 5378 @Override 5379 public void killApplicationProcess(String processName, int uid) { 5380 if (processName == null) { 5381 return; 5382 } 5383 5384 int callerUid = Binder.getCallingUid(); 5385 // Only the system server can kill an application 5386 if (callerUid == Process.SYSTEM_UID) { 5387 synchronized (this) { 5388 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5389 if (app != null && app.thread != null) { 5390 try { 5391 app.thread.scheduleSuicide(); 5392 } catch (RemoteException e) { 5393 // If the other end already died, then our work here is done. 5394 } 5395 } else { 5396 Slog.w(TAG, "Process/uid not found attempting kill of " 5397 + processName + " / " + uid); 5398 } 5399 } 5400 } else { 5401 throw new SecurityException(callerUid + " cannot kill app process: " + 5402 processName); 5403 } 5404 } 5405 5406 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5407 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5408 false, true, false, false, UserHandle.getUserId(uid), reason); 5409 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5410 Uri.fromParts("package", packageName, null)); 5411 if (!mProcessesReady) { 5412 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5413 | Intent.FLAG_RECEIVER_FOREGROUND); 5414 } 5415 intent.putExtra(Intent.EXTRA_UID, uid); 5416 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5417 broadcastIntentLocked(null, null, intent, 5418 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5419 false, false, 5420 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5421 } 5422 5423 private void forceStopUserLocked(int userId, String reason) { 5424 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5425 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5427 | Intent.FLAG_RECEIVER_FOREGROUND); 5428 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 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.USER_ALL); 5433 } 5434 5435 private final boolean killPackageProcessesLocked(String packageName, int appId, 5436 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5437 boolean doit, boolean evenPersistent, String reason) { 5438 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5439 5440 // Remove all processes this package may have touched: all with the 5441 // same UID (except for the system or root user), and all whose name 5442 // matches the package name. 5443 final int NP = mProcessNames.getMap().size(); 5444 for (int ip=0; ip<NP; ip++) { 5445 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5446 final int NA = apps.size(); 5447 for (int ia=0; ia<NA; ia++) { 5448 ProcessRecord app = apps.valueAt(ia); 5449 if (app.persistent && !evenPersistent) { 5450 // we don't kill persistent processes 5451 continue; 5452 } 5453 if (app.removed) { 5454 if (doit) { 5455 procs.add(app); 5456 } 5457 continue; 5458 } 5459 5460 // Skip process if it doesn't meet our oom adj requirement. 5461 if (app.setAdj < minOomAdj) { 5462 continue; 5463 } 5464 5465 // If no package is specified, we call all processes under the 5466 // give user id. 5467 if (packageName == null) { 5468 if (app.userId != userId) { 5469 continue; 5470 } 5471 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5472 continue; 5473 } 5474 // Package has been specified, we want to hit all processes 5475 // that match it. We need to qualify this by the processes 5476 // that are running under the specified app and user ID. 5477 } else { 5478 final boolean isDep = app.pkgDeps != null 5479 && app.pkgDeps.contains(packageName); 5480 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5481 continue; 5482 } 5483 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5484 continue; 5485 } 5486 if (!app.pkgList.containsKey(packageName) && !isDep) { 5487 continue; 5488 } 5489 } 5490 5491 // Process has passed all conditions, kill it! 5492 if (!doit) { 5493 return true; 5494 } 5495 app.removed = true; 5496 procs.add(app); 5497 } 5498 } 5499 5500 int N = procs.size(); 5501 for (int i=0; i<N; i++) { 5502 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5503 } 5504 updateOomAdjLocked(); 5505 return N > 0; 5506 } 5507 5508 private final boolean forceStopPackageLocked(String name, int appId, 5509 boolean callerWillRestart, boolean purgeCache, boolean doit, 5510 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5511 int i; 5512 int N; 5513 5514 if (userId == UserHandle.USER_ALL && name == null) { 5515 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5516 } 5517 5518 if (appId < 0 && name != null) { 5519 try { 5520 appId = UserHandle.getAppId( 5521 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5522 } catch (RemoteException e) { 5523 } 5524 } 5525 5526 if (doit) { 5527 if (name != null) { 5528 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5529 + " user=" + userId + ": " + reason); 5530 } else { 5531 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5532 } 5533 5534 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5535 for (int ip=pmap.size()-1; ip>=0; ip--) { 5536 SparseArray<Long> ba = pmap.valueAt(ip); 5537 for (i=ba.size()-1; i>=0; i--) { 5538 boolean remove = false; 5539 final int entUid = ba.keyAt(i); 5540 if (name != null) { 5541 if (userId == UserHandle.USER_ALL) { 5542 if (UserHandle.getAppId(entUid) == appId) { 5543 remove = true; 5544 } 5545 } else { 5546 if (entUid == UserHandle.getUid(userId, appId)) { 5547 remove = true; 5548 } 5549 } 5550 } else if (UserHandle.getUserId(entUid) == userId) { 5551 remove = true; 5552 } 5553 if (remove) { 5554 ba.removeAt(i); 5555 } 5556 } 5557 if (ba.size() == 0) { 5558 pmap.removeAt(ip); 5559 } 5560 } 5561 } 5562 5563 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5564 -100, callerWillRestart, true, doit, evenPersistent, 5565 name == null ? ("stop user " + userId) : ("stop " + name)); 5566 5567 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5568 if (!doit) { 5569 return true; 5570 } 5571 didSomething = true; 5572 } 5573 5574 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5575 if (!doit) { 5576 return true; 5577 } 5578 didSomething = true; 5579 } 5580 5581 if (name == null) { 5582 // Remove all sticky broadcasts from this user. 5583 mStickyBroadcasts.remove(userId); 5584 } 5585 5586 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5587 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5588 userId, providers)) { 5589 if (!doit) { 5590 return true; 5591 } 5592 didSomething = true; 5593 } 5594 N = providers.size(); 5595 for (i=0; i<N; i++) { 5596 removeDyingProviderLocked(null, providers.get(i), true); 5597 } 5598 5599 // Remove transient permissions granted from/to this package/user 5600 removeUriPermissionsForPackageLocked(name, userId, false); 5601 5602 if (name == null || uninstalling) { 5603 // Remove pending intents. For now we only do this when force 5604 // stopping users, because we have some problems when doing this 5605 // for packages -- app widgets are not currently cleaned up for 5606 // such packages, so they can be left with bad pending intents. 5607 if (mIntentSenderRecords.size() > 0) { 5608 Iterator<WeakReference<PendingIntentRecord>> it 5609 = mIntentSenderRecords.values().iterator(); 5610 while (it.hasNext()) { 5611 WeakReference<PendingIntentRecord> wpir = it.next(); 5612 if (wpir == null) { 5613 it.remove(); 5614 continue; 5615 } 5616 PendingIntentRecord pir = wpir.get(); 5617 if (pir == null) { 5618 it.remove(); 5619 continue; 5620 } 5621 if (name == null) { 5622 // Stopping user, remove all objects for the user. 5623 if (pir.key.userId != userId) { 5624 // Not the same user, skip it. 5625 continue; 5626 } 5627 } else { 5628 if (UserHandle.getAppId(pir.uid) != appId) { 5629 // Different app id, skip it. 5630 continue; 5631 } 5632 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5633 // Different user, skip it. 5634 continue; 5635 } 5636 if (!pir.key.packageName.equals(name)) { 5637 // Different package, skip it. 5638 continue; 5639 } 5640 } 5641 if (!doit) { 5642 return true; 5643 } 5644 didSomething = true; 5645 it.remove(); 5646 pir.canceled = true; 5647 if (pir.key.activity != null) { 5648 pir.key.activity.pendingResults.remove(pir.ref); 5649 } 5650 } 5651 } 5652 } 5653 5654 if (doit) { 5655 if (purgeCache && name != null) { 5656 AttributeCache ac = AttributeCache.instance(); 5657 if (ac != null) { 5658 ac.removePackage(name); 5659 } 5660 } 5661 if (mBooted) { 5662 mStackSupervisor.resumeTopActivitiesLocked(); 5663 mStackSupervisor.scheduleIdleLocked(); 5664 } 5665 } 5666 5667 return didSomething; 5668 } 5669 5670 private final boolean removeProcessLocked(ProcessRecord app, 5671 boolean callerWillRestart, boolean allowRestart, String reason) { 5672 final String name = app.processName; 5673 final int uid = app.uid; 5674 if (DEBUG_PROCESSES) Slog.d( 5675 TAG, "Force removing proc " + app.toShortString() + " (" + name 5676 + "/" + uid + ")"); 5677 5678 mProcessNames.remove(name, uid); 5679 mIsolatedProcesses.remove(app.uid); 5680 if (mHeavyWeightProcess == app) { 5681 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5682 mHeavyWeightProcess.userId, 0)); 5683 mHeavyWeightProcess = null; 5684 } 5685 boolean needRestart = false; 5686 if (app.pid > 0 && app.pid != MY_PID) { 5687 int pid = app.pid; 5688 synchronized (mPidsSelfLocked) { 5689 mPidsSelfLocked.remove(pid); 5690 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5691 } 5692 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5693 if (app.isolated) { 5694 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5695 } 5696 app.kill(reason, true); 5697 handleAppDiedLocked(app, true, allowRestart); 5698 removeLruProcessLocked(app); 5699 5700 if (app.persistent && !app.isolated) { 5701 if (!callerWillRestart) { 5702 addAppLocked(app.info, false, null /* ABI override */); 5703 } else { 5704 needRestart = true; 5705 } 5706 } 5707 } else { 5708 mRemovedProcesses.add(app); 5709 } 5710 5711 return needRestart; 5712 } 5713 5714 private final void processStartTimedOutLocked(ProcessRecord app) { 5715 final int pid = app.pid; 5716 boolean gone = false; 5717 synchronized (mPidsSelfLocked) { 5718 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5719 if (knownApp != null && knownApp.thread == null) { 5720 mPidsSelfLocked.remove(pid); 5721 gone = true; 5722 } 5723 } 5724 5725 if (gone) { 5726 Slog.w(TAG, "Process " + app + " failed to attach"); 5727 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5728 pid, app.uid, app.processName); 5729 mProcessNames.remove(app.processName, app.uid); 5730 mIsolatedProcesses.remove(app.uid); 5731 if (mHeavyWeightProcess == app) { 5732 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5733 mHeavyWeightProcess.userId, 0)); 5734 mHeavyWeightProcess = null; 5735 } 5736 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5737 if (app.isolated) { 5738 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5739 } 5740 // Take care of any launching providers waiting for this process. 5741 checkAppInLaunchingProvidersLocked(app, true); 5742 // Take care of any services that are waiting for the process. 5743 mServices.processStartTimedOutLocked(app); 5744 app.kill("start timeout", true); 5745 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5746 Slog.w(TAG, "Unattached app died before backup, skipping"); 5747 try { 5748 IBackupManager bm = IBackupManager.Stub.asInterface( 5749 ServiceManager.getService(Context.BACKUP_SERVICE)); 5750 bm.agentDisconnected(app.info.packageName); 5751 } catch (RemoteException e) { 5752 // Can't happen; the backup manager is local 5753 } 5754 } 5755 if (isPendingBroadcastProcessLocked(pid)) { 5756 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5757 skipPendingBroadcastLocked(pid); 5758 } 5759 } else { 5760 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5761 } 5762 } 5763 5764 private final boolean attachApplicationLocked(IApplicationThread thread, 5765 int pid) { 5766 5767 // Find the application record that is being attached... either via 5768 // the pid if we are running in multiple processes, or just pull the 5769 // next app record if we are emulating process with anonymous threads. 5770 ProcessRecord app; 5771 if (pid != MY_PID && pid >= 0) { 5772 synchronized (mPidsSelfLocked) { 5773 app = mPidsSelfLocked.get(pid); 5774 } 5775 } else { 5776 app = null; 5777 } 5778 5779 if (app == null) { 5780 Slog.w(TAG, "No pending application record for pid " + pid 5781 + " (IApplicationThread " + thread + "); dropping process"); 5782 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5783 if (pid > 0 && pid != MY_PID) { 5784 Process.killProcessQuiet(pid); 5785 //TODO: Process.killProcessGroup(app.info.uid, pid); 5786 } else { 5787 try { 5788 thread.scheduleExit(); 5789 } catch (Exception e) { 5790 // Ignore exceptions. 5791 } 5792 } 5793 return false; 5794 } 5795 5796 // If this application record is still attached to a previous 5797 // process, clean it up now. 5798 if (app.thread != null) { 5799 handleAppDiedLocked(app, true, true); 5800 } 5801 5802 // Tell the process all about itself. 5803 5804 if (localLOGV) Slog.v( 5805 TAG, "Binding process pid " + pid + " to record " + app); 5806 5807 final String processName = app.processName; 5808 try { 5809 AppDeathRecipient adr = new AppDeathRecipient( 5810 app, pid, thread); 5811 thread.asBinder().linkToDeath(adr, 0); 5812 app.deathRecipient = adr; 5813 } catch (RemoteException e) { 5814 app.resetPackageList(mProcessStats); 5815 startProcessLocked(app, "link fail", processName); 5816 return false; 5817 } 5818 5819 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5820 5821 app.makeActive(thread, mProcessStats); 5822 app.curAdj = app.setAdj = -100; 5823 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5824 app.forcingToForeground = null; 5825 updateProcessForegroundLocked(app, false, false); 5826 app.hasShownUi = false; 5827 app.debugging = false; 5828 app.cached = false; 5829 5830 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5831 5832 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5833 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5834 5835 if (!normalMode) { 5836 Slog.i(TAG, "Launching preboot mode app: " + app); 5837 } 5838 5839 if (localLOGV) Slog.v( 5840 TAG, "New app record " + app 5841 + " thread=" + thread.asBinder() + " pid=" + pid); 5842 try { 5843 int testMode = IApplicationThread.DEBUG_OFF; 5844 if (mDebugApp != null && mDebugApp.equals(processName)) { 5845 testMode = mWaitForDebugger 5846 ? IApplicationThread.DEBUG_WAIT 5847 : IApplicationThread.DEBUG_ON; 5848 app.debugging = true; 5849 if (mDebugTransient) { 5850 mDebugApp = mOrigDebugApp; 5851 mWaitForDebugger = mOrigWaitForDebugger; 5852 } 5853 } 5854 String profileFile = app.instrumentationProfileFile; 5855 ParcelFileDescriptor profileFd = null; 5856 int samplingInterval = 0; 5857 boolean profileAutoStop = false; 5858 if (mProfileApp != null && mProfileApp.equals(processName)) { 5859 mProfileProc = app; 5860 profileFile = mProfileFile; 5861 profileFd = mProfileFd; 5862 samplingInterval = mSamplingInterval; 5863 profileAutoStop = mAutoStopProfiler; 5864 } 5865 boolean enableOpenGlTrace = false; 5866 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5867 enableOpenGlTrace = true; 5868 mOpenGlTraceApp = null; 5869 } 5870 5871 // If the app is being launched for restore or full backup, set it up specially 5872 boolean isRestrictedBackupMode = false; 5873 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5874 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5875 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5876 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5877 } 5878 5879 ensurePackageDexOpt(app.instrumentationInfo != null 5880 ? app.instrumentationInfo.packageName 5881 : app.info.packageName); 5882 if (app.instrumentationClass != null) { 5883 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5884 } 5885 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5886 + processName + " with config " + mConfiguration); 5887 ApplicationInfo appInfo = app.instrumentationInfo != null 5888 ? app.instrumentationInfo : app.info; 5889 app.compat = compatibilityInfoForPackageLocked(appInfo); 5890 if (profileFd != null) { 5891 profileFd = profileFd.dup(); 5892 } 5893 ProfilerInfo profilerInfo = profileFile == null ? null 5894 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5895 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5896 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5897 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5898 isRestrictedBackupMode || !normalMode, app.persistent, 5899 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5900 mCoreSettingsObserver.getCoreSettingsLocked()); 5901 updateLruProcessLocked(app, false, null); 5902 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5903 } catch (Exception e) { 5904 // todo: Yikes! What should we do? For now we will try to 5905 // start another process, but that could easily get us in 5906 // an infinite loop of restarting processes... 5907 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5908 5909 app.resetPackageList(mProcessStats); 5910 app.unlinkDeathRecipient(); 5911 startProcessLocked(app, "bind fail", processName); 5912 return false; 5913 } 5914 5915 // Remove this record from the list of starting applications. 5916 mPersistentStartingProcesses.remove(app); 5917 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5918 "Attach application locked removing on hold: " + app); 5919 mProcessesOnHold.remove(app); 5920 5921 boolean badApp = false; 5922 boolean didSomething = false; 5923 5924 // See if the top visible activity is waiting to run in this process... 5925 if (normalMode) { 5926 try { 5927 if (mStackSupervisor.attachApplicationLocked(app)) { 5928 didSomething = true; 5929 } 5930 } catch (Exception e) { 5931 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5932 badApp = true; 5933 } 5934 } 5935 5936 // Find any services that should be running in this process... 5937 if (!badApp) { 5938 try { 5939 didSomething |= mServices.attachApplicationLocked(app, processName); 5940 } catch (Exception e) { 5941 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5942 badApp = true; 5943 } 5944 } 5945 5946 // Check if a next-broadcast receiver is in this process... 5947 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5948 try { 5949 didSomething |= sendPendingBroadcastsLocked(app); 5950 } catch (Exception e) { 5951 // If the app died trying to launch the receiver we declare it 'bad' 5952 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5953 badApp = true; 5954 } 5955 } 5956 5957 // Check whether the next backup agent is in this process... 5958 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5959 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5960 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5961 try { 5962 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5963 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5964 mBackupTarget.backupMode); 5965 } catch (Exception e) { 5966 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5967 badApp = true; 5968 } 5969 } 5970 5971 if (badApp) { 5972 app.kill("error during init", true); 5973 handleAppDiedLocked(app, false, true); 5974 return false; 5975 } 5976 5977 if (!didSomething) { 5978 updateOomAdjLocked(); 5979 } 5980 5981 return true; 5982 } 5983 5984 @Override 5985 public final void attachApplication(IApplicationThread thread) { 5986 synchronized (this) { 5987 int callingPid = Binder.getCallingPid(); 5988 final long origId = Binder.clearCallingIdentity(); 5989 attachApplicationLocked(thread, callingPid); 5990 Binder.restoreCallingIdentity(origId); 5991 } 5992 } 5993 5994 @Override 5995 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5996 final long origId = Binder.clearCallingIdentity(); 5997 synchronized (this) { 5998 ActivityStack stack = ActivityRecord.getStackLocked(token); 5999 if (stack != null) { 6000 ActivityRecord r = 6001 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6002 if (stopProfiling) { 6003 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6004 try { 6005 mProfileFd.close(); 6006 } catch (IOException e) { 6007 } 6008 clearProfilerLocked(); 6009 } 6010 } 6011 } 6012 } 6013 Binder.restoreCallingIdentity(origId); 6014 } 6015 6016 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6017 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6018 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6019 } 6020 6021 void enableScreenAfterBoot() { 6022 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6023 SystemClock.uptimeMillis()); 6024 mWindowManager.enableScreenAfterBoot(); 6025 6026 synchronized (this) { 6027 updateEventDispatchingLocked(); 6028 } 6029 } 6030 6031 @Override 6032 public void showBootMessage(final CharSequence msg, final boolean always) { 6033 enforceNotIsolatedCaller("showBootMessage"); 6034 mWindowManager.showBootMessage(msg, always); 6035 } 6036 6037 @Override 6038 public void keyguardWaitingForActivityDrawn() { 6039 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6040 final long token = Binder.clearCallingIdentity(); 6041 try { 6042 synchronized (this) { 6043 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6044 mWindowManager.keyguardWaitingForActivityDrawn(); 6045 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6046 mLockScreenShown = LOCK_SCREEN_LEAVING; 6047 } 6048 } 6049 } finally { 6050 Binder.restoreCallingIdentity(token); 6051 } 6052 } 6053 6054 final void finishBooting() { 6055 synchronized (this) { 6056 if (!mBootAnimationComplete) { 6057 mCallFinishBooting = true; 6058 return; 6059 } 6060 mCallFinishBooting = false; 6061 } 6062 6063 ArraySet<String> completedIsas = new ArraySet<String>(); 6064 for (String abi : Build.SUPPORTED_ABIS) { 6065 Process.establishZygoteConnectionForAbi(abi); 6066 final String instructionSet = VMRuntime.getInstructionSet(abi); 6067 if (!completedIsas.contains(instructionSet)) { 6068 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6069 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6070 } 6071 completedIsas.add(instructionSet); 6072 } 6073 } 6074 6075 IntentFilter pkgFilter = new IntentFilter(); 6076 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6077 pkgFilter.addDataScheme("package"); 6078 mContext.registerReceiver(new BroadcastReceiver() { 6079 @Override 6080 public void onReceive(Context context, Intent intent) { 6081 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6082 if (pkgs != null) { 6083 for (String pkg : pkgs) { 6084 synchronized (ActivityManagerService.this) { 6085 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6086 0, "finished booting")) { 6087 setResultCode(Activity.RESULT_OK); 6088 return; 6089 } 6090 } 6091 } 6092 } 6093 } 6094 }, pkgFilter); 6095 6096 // Let system services know. 6097 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6098 6099 synchronized (this) { 6100 // Ensure that any processes we had put on hold are now started 6101 // up. 6102 final int NP = mProcessesOnHold.size(); 6103 if (NP > 0) { 6104 ArrayList<ProcessRecord> procs = 6105 new ArrayList<ProcessRecord>(mProcessesOnHold); 6106 for (int ip=0; ip<NP; ip++) { 6107 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6108 + procs.get(ip)); 6109 startProcessLocked(procs.get(ip), "on-hold", null); 6110 } 6111 } 6112 6113 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6114 // Start looking for apps that are abusing wake locks. 6115 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6116 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6117 // Tell anyone interested that we are done booting! 6118 SystemProperties.set("sys.boot_completed", "1"); 6119 6120 // And trigger dev.bootcomplete if we are not showing encryption progress 6121 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6122 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6123 SystemProperties.set("dev.bootcomplete", "1"); 6124 } 6125 for (int i=0; i<mStartedUsers.size(); i++) { 6126 UserStartedState uss = mStartedUsers.valueAt(i); 6127 if (uss.mState == UserStartedState.STATE_BOOTING) { 6128 uss.mState = UserStartedState.STATE_RUNNING; 6129 final int userId = mStartedUsers.keyAt(i); 6130 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6131 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6132 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6133 broadcastIntentLocked(null, null, intent, null, 6134 new IIntentReceiver.Stub() { 6135 @Override 6136 public void performReceive(Intent intent, int resultCode, 6137 String data, Bundle extras, boolean ordered, 6138 boolean sticky, int sendingUser) { 6139 synchronized (ActivityManagerService.this) { 6140 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6141 true, false); 6142 } 6143 } 6144 }, 6145 0, null, null, 6146 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6147 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6148 userId); 6149 } 6150 } 6151 scheduleStartProfilesLocked(); 6152 } 6153 } 6154 } 6155 6156 @Override 6157 public void bootAnimationComplete() { 6158 final boolean callFinishBooting; 6159 synchronized (this) { 6160 callFinishBooting = mCallFinishBooting; 6161 mBootAnimationComplete = true; 6162 } 6163 if (callFinishBooting) { 6164 finishBooting(); 6165 } 6166 } 6167 6168 final void ensureBootCompleted() { 6169 boolean booting; 6170 boolean enableScreen; 6171 synchronized (this) { 6172 booting = mBooting; 6173 mBooting = false; 6174 enableScreen = !mBooted; 6175 mBooted = true; 6176 } 6177 6178 if (booting) { 6179 finishBooting(); 6180 } 6181 6182 if (enableScreen) { 6183 enableScreenAfterBoot(); 6184 } 6185 } 6186 6187 @Override 6188 public final void activityResumed(IBinder token) { 6189 final long origId = Binder.clearCallingIdentity(); 6190 synchronized(this) { 6191 ActivityStack stack = ActivityRecord.getStackLocked(token); 6192 if (stack != null) { 6193 ActivityRecord.activityResumedLocked(token); 6194 } 6195 } 6196 Binder.restoreCallingIdentity(origId); 6197 } 6198 6199 @Override 6200 public final void activityPaused(IBinder token) { 6201 final long origId = Binder.clearCallingIdentity(); 6202 synchronized(this) { 6203 ActivityStack stack = ActivityRecord.getStackLocked(token); 6204 if (stack != null) { 6205 stack.activityPausedLocked(token, false); 6206 } 6207 } 6208 Binder.restoreCallingIdentity(origId); 6209 } 6210 6211 @Override 6212 public final void activityStopped(IBinder token, Bundle icicle, 6213 PersistableBundle persistentState, CharSequence description) { 6214 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6215 6216 // Refuse possible leaked file descriptors 6217 if (icicle != null && icicle.hasFileDescriptors()) { 6218 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6219 } 6220 6221 final long origId = Binder.clearCallingIdentity(); 6222 6223 synchronized (this) { 6224 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6225 if (r != null) { 6226 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6227 } 6228 } 6229 6230 trimApplications(); 6231 6232 Binder.restoreCallingIdentity(origId); 6233 } 6234 6235 @Override 6236 public final void activityDestroyed(IBinder token) { 6237 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6238 synchronized (this) { 6239 ActivityStack stack = ActivityRecord.getStackLocked(token); 6240 if (stack != null) { 6241 stack.activityDestroyedLocked(token); 6242 } 6243 } 6244 } 6245 6246 @Override 6247 public final void backgroundResourcesReleased(IBinder token) { 6248 final long origId = Binder.clearCallingIdentity(); 6249 try { 6250 synchronized (this) { 6251 ActivityStack stack = ActivityRecord.getStackLocked(token); 6252 if (stack != null) { 6253 stack.backgroundResourcesReleased(token); 6254 } 6255 } 6256 } finally { 6257 Binder.restoreCallingIdentity(origId); 6258 } 6259 } 6260 6261 @Override 6262 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6263 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6264 } 6265 6266 @Override 6267 public final void notifyEnterAnimationComplete(IBinder token) { 6268 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6269 } 6270 6271 @Override 6272 public String getCallingPackage(IBinder token) { 6273 synchronized (this) { 6274 ActivityRecord r = getCallingRecordLocked(token); 6275 return r != null ? r.info.packageName : null; 6276 } 6277 } 6278 6279 @Override 6280 public ComponentName getCallingActivity(IBinder token) { 6281 synchronized (this) { 6282 ActivityRecord r = getCallingRecordLocked(token); 6283 return r != null ? r.intent.getComponent() : null; 6284 } 6285 } 6286 6287 private ActivityRecord getCallingRecordLocked(IBinder token) { 6288 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6289 if (r == null) { 6290 return null; 6291 } 6292 return r.resultTo; 6293 } 6294 6295 @Override 6296 public ComponentName getActivityClassForToken(IBinder token) { 6297 synchronized(this) { 6298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6299 if (r == null) { 6300 return null; 6301 } 6302 return r.intent.getComponent(); 6303 } 6304 } 6305 6306 @Override 6307 public String getPackageForToken(IBinder token) { 6308 synchronized(this) { 6309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6310 if (r == null) { 6311 return null; 6312 } 6313 return r.packageName; 6314 } 6315 } 6316 6317 @Override 6318 public IIntentSender getIntentSender(int type, 6319 String packageName, IBinder token, String resultWho, 6320 int requestCode, Intent[] intents, String[] resolvedTypes, 6321 int flags, Bundle options, int userId) { 6322 enforceNotIsolatedCaller("getIntentSender"); 6323 // Refuse possible leaked file descriptors 6324 if (intents != null) { 6325 if (intents.length < 1) { 6326 throw new IllegalArgumentException("Intents array length must be >= 1"); 6327 } 6328 for (int i=0; i<intents.length; i++) { 6329 Intent intent = intents[i]; 6330 if (intent != null) { 6331 if (intent.hasFileDescriptors()) { 6332 throw new IllegalArgumentException("File descriptors passed in Intent"); 6333 } 6334 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6335 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6336 throw new IllegalArgumentException( 6337 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6338 } 6339 intents[i] = new Intent(intent); 6340 } 6341 } 6342 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6343 throw new IllegalArgumentException( 6344 "Intent array length does not match resolvedTypes length"); 6345 } 6346 } 6347 if (options != null) { 6348 if (options.hasFileDescriptors()) { 6349 throw new IllegalArgumentException("File descriptors passed in options"); 6350 } 6351 } 6352 6353 synchronized(this) { 6354 int callingUid = Binder.getCallingUid(); 6355 int origUserId = userId; 6356 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6357 type == ActivityManager.INTENT_SENDER_BROADCAST, 6358 ALLOW_NON_FULL, "getIntentSender", null); 6359 if (origUserId == UserHandle.USER_CURRENT) { 6360 // We don't want to evaluate this until the pending intent is 6361 // actually executed. However, we do want to always do the 6362 // security checking for it above. 6363 userId = UserHandle.USER_CURRENT; 6364 } 6365 try { 6366 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6367 int uid = AppGlobals.getPackageManager() 6368 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6369 if (!UserHandle.isSameApp(callingUid, uid)) { 6370 String msg = "Permission Denial: getIntentSender() from pid=" 6371 + Binder.getCallingPid() 6372 + ", uid=" + Binder.getCallingUid() 6373 + ", (need uid=" + uid + ")" 6374 + " is not allowed to send as package " + packageName; 6375 Slog.w(TAG, msg); 6376 throw new SecurityException(msg); 6377 } 6378 } 6379 6380 return getIntentSenderLocked(type, packageName, callingUid, userId, 6381 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6382 6383 } catch (RemoteException e) { 6384 throw new SecurityException(e); 6385 } 6386 } 6387 } 6388 6389 IIntentSender getIntentSenderLocked(int type, String packageName, 6390 int callingUid, int userId, IBinder token, String resultWho, 6391 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6392 Bundle options) { 6393 if (DEBUG_MU) 6394 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6395 ActivityRecord activity = null; 6396 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6397 activity = ActivityRecord.isInStackLocked(token); 6398 if (activity == null) { 6399 return null; 6400 } 6401 if (activity.finishing) { 6402 return null; 6403 } 6404 } 6405 6406 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6407 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6408 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6409 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6410 |PendingIntent.FLAG_UPDATE_CURRENT); 6411 6412 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6413 type, packageName, activity, resultWho, 6414 requestCode, intents, resolvedTypes, flags, options, userId); 6415 WeakReference<PendingIntentRecord> ref; 6416 ref = mIntentSenderRecords.get(key); 6417 PendingIntentRecord rec = ref != null ? ref.get() : null; 6418 if (rec != null) { 6419 if (!cancelCurrent) { 6420 if (updateCurrent) { 6421 if (rec.key.requestIntent != null) { 6422 rec.key.requestIntent.replaceExtras(intents != null ? 6423 intents[intents.length - 1] : null); 6424 } 6425 if (intents != null) { 6426 intents[intents.length-1] = rec.key.requestIntent; 6427 rec.key.allIntents = intents; 6428 rec.key.allResolvedTypes = resolvedTypes; 6429 } else { 6430 rec.key.allIntents = null; 6431 rec.key.allResolvedTypes = null; 6432 } 6433 } 6434 return rec; 6435 } 6436 rec.canceled = true; 6437 mIntentSenderRecords.remove(key); 6438 } 6439 if (noCreate) { 6440 return rec; 6441 } 6442 rec = new PendingIntentRecord(this, key, callingUid); 6443 mIntentSenderRecords.put(key, rec.ref); 6444 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6445 if (activity.pendingResults == null) { 6446 activity.pendingResults 6447 = new HashSet<WeakReference<PendingIntentRecord>>(); 6448 } 6449 activity.pendingResults.add(rec.ref); 6450 } 6451 return rec; 6452 } 6453 6454 @Override 6455 public void cancelIntentSender(IIntentSender sender) { 6456 if (!(sender instanceof PendingIntentRecord)) { 6457 return; 6458 } 6459 synchronized(this) { 6460 PendingIntentRecord rec = (PendingIntentRecord)sender; 6461 try { 6462 int uid = AppGlobals.getPackageManager() 6463 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6464 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6465 String msg = "Permission Denial: cancelIntentSender() from pid=" 6466 + Binder.getCallingPid() 6467 + ", uid=" + Binder.getCallingUid() 6468 + " is not allowed to cancel packges " 6469 + rec.key.packageName; 6470 Slog.w(TAG, msg); 6471 throw new SecurityException(msg); 6472 } 6473 } catch (RemoteException e) { 6474 throw new SecurityException(e); 6475 } 6476 cancelIntentSenderLocked(rec, true); 6477 } 6478 } 6479 6480 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6481 rec.canceled = true; 6482 mIntentSenderRecords.remove(rec.key); 6483 if (cleanActivity && rec.key.activity != null) { 6484 rec.key.activity.pendingResults.remove(rec.ref); 6485 } 6486 } 6487 6488 @Override 6489 public String getPackageForIntentSender(IIntentSender pendingResult) { 6490 if (!(pendingResult instanceof PendingIntentRecord)) { 6491 return null; 6492 } 6493 try { 6494 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6495 return res.key.packageName; 6496 } catch (ClassCastException e) { 6497 } 6498 return null; 6499 } 6500 6501 @Override 6502 public int getUidForIntentSender(IIntentSender sender) { 6503 if (sender instanceof PendingIntentRecord) { 6504 try { 6505 PendingIntentRecord res = (PendingIntentRecord)sender; 6506 return res.uid; 6507 } catch (ClassCastException e) { 6508 } 6509 } 6510 return -1; 6511 } 6512 6513 @Override 6514 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6515 if (!(pendingResult instanceof PendingIntentRecord)) { 6516 return false; 6517 } 6518 try { 6519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6520 if (res.key.allIntents == null) { 6521 return false; 6522 } 6523 for (int i=0; i<res.key.allIntents.length; i++) { 6524 Intent intent = res.key.allIntents[i]; 6525 if (intent.getPackage() != null && intent.getComponent() != null) { 6526 return false; 6527 } 6528 } 6529 return true; 6530 } catch (ClassCastException e) { 6531 } 6532 return false; 6533 } 6534 6535 @Override 6536 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6537 if (!(pendingResult instanceof PendingIntentRecord)) { 6538 return false; 6539 } 6540 try { 6541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6542 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6543 return true; 6544 } 6545 return false; 6546 } catch (ClassCastException e) { 6547 } 6548 return false; 6549 } 6550 6551 @Override 6552 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6553 if (!(pendingResult instanceof PendingIntentRecord)) { 6554 return null; 6555 } 6556 try { 6557 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6558 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6559 } catch (ClassCastException e) { 6560 } 6561 return null; 6562 } 6563 6564 @Override 6565 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6566 if (!(pendingResult instanceof PendingIntentRecord)) { 6567 return null; 6568 } 6569 try { 6570 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6571 Intent intent = res.key.requestIntent; 6572 if (intent != null) { 6573 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6574 || res.lastTagPrefix.equals(prefix))) { 6575 return res.lastTag; 6576 } 6577 res.lastTagPrefix = prefix; 6578 StringBuilder sb = new StringBuilder(128); 6579 if (prefix != null) { 6580 sb.append(prefix); 6581 } 6582 if (intent.getAction() != null) { 6583 sb.append(intent.getAction()); 6584 } else if (intent.getComponent() != null) { 6585 intent.getComponent().appendShortString(sb); 6586 } else { 6587 sb.append("?"); 6588 } 6589 return res.lastTag = sb.toString(); 6590 } 6591 } catch (ClassCastException e) { 6592 } 6593 return null; 6594 } 6595 6596 @Override 6597 public void setProcessLimit(int max) { 6598 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6599 "setProcessLimit()"); 6600 synchronized (this) { 6601 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6602 mProcessLimitOverride = max; 6603 } 6604 trimApplications(); 6605 } 6606 6607 @Override 6608 public int getProcessLimit() { 6609 synchronized (this) { 6610 return mProcessLimitOverride; 6611 } 6612 } 6613 6614 void foregroundTokenDied(ForegroundToken token) { 6615 synchronized (ActivityManagerService.this) { 6616 synchronized (mPidsSelfLocked) { 6617 ForegroundToken cur 6618 = mForegroundProcesses.get(token.pid); 6619 if (cur != token) { 6620 return; 6621 } 6622 mForegroundProcesses.remove(token.pid); 6623 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6624 if (pr == null) { 6625 return; 6626 } 6627 pr.forcingToForeground = null; 6628 updateProcessForegroundLocked(pr, false, false); 6629 } 6630 updateOomAdjLocked(); 6631 } 6632 } 6633 6634 @Override 6635 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6636 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6637 "setProcessForeground()"); 6638 synchronized(this) { 6639 boolean changed = false; 6640 6641 synchronized (mPidsSelfLocked) { 6642 ProcessRecord pr = mPidsSelfLocked.get(pid); 6643 if (pr == null && isForeground) { 6644 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6645 return; 6646 } 6647 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6648 if (oldToken != null) { 6649 oldToken.token.unlinkToDeath(oldToken, 0); 6650 mForegroundProcesses.remove(pid); 6651 if (pr != null) { 6652 pr.forcingToForeground = null; 6653 } 6654 changed = true; 6655 } 6656 if (isForeground && token != null) { 6657 ForegroundToken newToken = new ForegroundToken() { 6658 @Override 6659 public void binderDied() { 6660 foregroundTokenDied(this); 6661 } 6662 }; 6663 newToken.pid = pid; 6664 newToken.token = token; 6665 try { 6666 token.linkToDeath(newToken, 0); 6667 mForegroundProcesses.put(pid, newToken); 6668 pr.forcingToForeground = token; 6669 changed = true; 6670 } catch (RemoteException e) { 6671 // If the process died while doing this, we will later 6672 // do the cleanup with the process death link. 6673 } 6674 } 6675 } 6676 6677 if (changed) { 6678 updateOomAdjLocked(); 6679 } 6680 } 6681 } 6682 6683 // ========================================================= 6684 // PERMISSIONS 6685 // ========================================================= 6686 6687 static class PermissionController extends IPermissionController.Stub { 6688 ActivityManagerService mActivityManagerService; 6689 PermissionController(ActivityManagerService activityManagerService) { 6690 mActivityManagerService = activityManagerService; 6691 } 6692 6693 @Override 6694 public boolean checkPermission(String permission, int pid, int uid) { 6695 return mActivityManagerService.checkPermission(permission, pid, 6696 uid) == PackageManager.PERMISSION_GRANTED; 6697 } 6698 } 6699 6700 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6701 @Override 6702 public int checkComponentPermission(String permission, int pid, int uid, 6703 int owningUid, boolean exported) { 6704 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6705 owningUid, exported); 6706 } 6707 6708 @Override 6709 public Object getAMSLock() { 6710 return ActivityManagerService.this; 6711 } 6712 } 6713 6714 /** 6715 * This can be called with or without the global lock held. 6716 */ 6717 int checkComponentPermission(String permission, int pid, int uid, 6718 int owningUid, boolean exported) { 6719 // We might be performing an operation on behalf of an indirect binder 6720 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6721 // client identity accordingly before proceeding. 6722 Identity tlsIdentity = sCallerIdentity.get(); 6723 if (tlsIdentity != null) { 6724 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6725 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6726 uid = tlsIdentity.uid; 6727 pid = tlsIdentity.pid; 6728 } 6729 6730 if (pid == MY_PID) { 6731 return PackageManager.PERMISSION_GRANTED; 6732 } 6733 6734 return ActivityManager.checkComponentPermission(permission, uid, 6735 owningUid, exported); 6736 } 6737 6738 /** 6739 * As the only public entry point for permissions checking, this method 6740 * can enforce the semantic that requesting a check on a null global 6741 * permission is automatically denied. (Internally a null permission 6742 * string is used when calling {@link #checkComponentPermission} in cases 6743 * when only uid-based security is needed.) 6744 * 6745 * This can be called with or without the global lock held. 6746 */ 6747 @Override 6748 public int checkPermission(String permission, int pid, int uid) { 6749 if (permission == null) { 6750 return PackageManager.PERMISSION_DENIED; 6751 } 6752 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6753 } 6754 6755 /** 6756 * Binder IPC calls go through the public entry point. 6757 * This can be called with or without the global lock held. 6758 */ 6759 int checkCallingPermission(String permission) { 6760 return checkPermission(permission, 6761 Binder.getCallingPid(), 6762 UserHandle.getAppId(Binder.getCallingUid())); 6763 } 6764 6765 /** 6766 * This can be called with or without the global lock held. 6767 */ 6768 void enforceCallingPermission(String permission, String func) { 6769 if (checkCallingPermission(permission) 6770 == PackageManager.PERMISSION_GRANTED) { 6771 return; 6772 } 6773 6774 String msg = "Permission Denial: " + func + " from pid=" 6775 + Binder.getCallingPid() 6776 + ", uid=" + Binder.getCallingUid() 6777 + " requires " + permission; 6778 Slog.w(TAG, msg); 6779 throw new SecurityException(msg); 6780 } 6781 6782 /** 6783 * Determine if UID is holding permissions required to access {@link Uri} in 6784 * the given {@link ProviderInfo}. Final permission checking is always done 6785 * in {@link ContentProvider}. 6786 */ 6787 private final boolean checkHoldingPermissionsLocked( 6788 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6789 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6790 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6791 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6792 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6793 != PERMISSION_GRANTED) { 6794 return false; 6795 } 6796 } 6797 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6798 } 6799 6800 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6801 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6802 if (pi.applicationInfo.uid == uid) { 6803 return true; 6804 } else if (!pi.exported) { 6805 return false; 6806 } 6807 6808 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6809 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6810 try { 6811 // check if target holds top-level <provider> permissions 6812 if (!readMet && pi.readPermission != null && considerUidPermissions 6813 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6814 readMet = true; 6815 } 6816 if (!writeMet && pi.writePermission != null && considerUidPermissions 6817 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6818 writeMet = true; 6819 } 6820 6821 // track if unprotected read/write is allowed; any denied 6822 // <path-permission> below removes this ability 6823 boolean allowDefaultRead = pi.readPermission == null; 6824 boolean allowDefaultWrite = pi.writePermission == null; 6825 6826 // check if target holds any <path-permission> that match uri 6827 final PathPermission[] pps = pi.pathPermissions; 6828 if (pps != null) { 6829 final String path = grantUri.uri.getPath(); 6830 int i = pps.length; 6831 while (i > 0 && (!readMet || !writeMet)) { 6832 i--; 6833 PathPermission pp = pps[i]; 6834 if (pp.match(path)) { 6835 if (!readMet) { 6836 final String pprperm = pp.getReadPermission(); 6837 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6838 + pprperm + " for " + pp.getPath() 6839 + ": match=" + pp.match(path) 6840 + " check=" + pm.checkUidPermission(pprperm, uid)); 6841 if (pprperm != null) { 6842 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6843 == PERMISSION_GRANTED) { 6844 readMet = true; 6845 } else { 6846 allowDefaultRead = false; 6847 } 6848 } 6849 } 6850 if (!writeMet) { 6851 final String ppwperm = pp.getWritePermission(); 6852 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6853 + ppwperm + " for " + pp.getPath() 6854 + ": match=" + pp.match(path) 6855 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6856 if (ppwperm != null) { 6857 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6858 == PERMISSION_GRANTED) { 6859 writeMet = true; 6860 } else { 6861 allowDefaultWrite = false; 6862 } 6863 } 6864 } 6865 } 6866 } 6867 } 6868 6869 // grant unprotected <provider> read/write, if not blocked by 6870 // <path-permission> above 6871 if (allowDefaultRead) readMet = true; 6872 if (allowDefaultWrite) writeMet = true; 6873 6874 } catch (RemoteException e) { 6875 return false; 6876 } 6877 6878 return readMet && writeMet; 6879 } 6880 6881 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6882 ProviderInfo pi = null; 6883 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6884 if (cpr != null) { 6885 pi = cpr.info; 6886 } else { 6887 try { 6888 pi = AppGlobals.getPackageManager().resolveContentProvider( 6889 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6890 } catch (RemoteException ex) { 6891 } 6892 } 6893 return pi; 6894 } 6895 6896 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6897 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6898 if (targetUris != null) { 6899 return targetUris.get(grantUri); 6900 } 6901 return null; 6902 } 6903 6904 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6905 String targetPkg, int targetUid, GrantUri grantUri) { 6906 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6907 if (targetUris == null) { 6908 targetUris = Maps.newArrayMap(); 6909 mGrantedUriPermissions.put(targetUid, targetUris); 6910 } 6911 6912 UriPermission perm = targetUris.get(grantUri); 6913 if (perm == null) { 6914 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6915 targetUris.put(grantUri, perm); 6916 } 6917 6918 return perm; 6919 } 6920 6921 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6922 final int modeFlags) { 6923 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6924 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6925 : UriPermission.STRENGTH_OWNED; 6926 6927 // Root gets to do everything. 6928 if (uid == 0) { 6929 return true; 6930 } 6931 6932 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6933 if (perms == null) return false; 6934 6935 // First look for exact match 6936 final UriPermission exactPerm = perms.get(grantUri); 6937 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6938 return true; 6939 } 6940 6941 // No exact match, look for prefixes 6942 final int N = perms.size(); 6943 for (int i = 0; i < N; i++) { 6944 final UriPermission perm = perms.valueAt(i); 6945 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6946 && perm.getStrength(modeFlags) >= minStrength) { 6947 return true; 6948 } 6949 } 6950 6951 return false; 6952 } 6953 6954 /** 6955 * @param uri This uri must NOT contain an embedded userId. 6956 * @param userId The userId in which the uri is to be resolved. 6957 */ 6958 @Override 6959 public int checkUriPermission(Uri uri, int pid, int uid, 6960 final int modeFlags, int userId) { 6961 enforceNotIsolatedCaller("checkUriPermission"); 6962 6963 // Another redirected-binder-call permissions check as in 6964 // {@link checkComponentPermission}. 6965 Identity tlsIdentity = sCallerIdentity.get(); 6966 if (tlsIdentity != null) { 6967 uid = tlsIdentity.uid; 6968 pid = tlsIdentity.pid; 6969 } 6970 6971 // Our own process gets to do everything. 6972 if (pid == MY_PID) { 6973 return PackageManager.PERMISSION_GRANTED; 6974 } 6975 synchronized (this) { 6976 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6977 ? PackageManager.PERMISSION_GRANTED 6978 : PackageManager.PERMISSION_DENIED; 6979 } 6980 } 6981 6982 /** 6983 * Check if the targetPkg can be granted permission to access uri by 6984 * the callingUid using the given modeFlags. Throws a security exception 6985 * if callingUid is not allowed to do this. Returns the uid of the target 6986 * if the URI permission grant should be performed; returns -1 if it is not 6987 * needed (for example targetPkg already has permission to access the URI). 6988 * If you already know the uid of the target, you can supply it in 6989 * lastTargetUid else set that to -1. 6990 */ 6991 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6992 final int modeFlags, int lastTargetUid) { 6993 if (!Intent.isAccessUriMode(modeFlags)) { 6994 return -1; 6995 } 6996 6997 if (targetPkg != null) { 6998 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6999 "Checking grant " + targetPkg + " permission to " + grantUri); 7000 } 7001 7002 final IPackageManager pm = AppGlobals.getPackageManager(); 7003 7004 // If this is not a content: uri, we can't do anything with it. 7005 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7006 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7007 "Can't grant URI permission for non-content URI: " + grantUri); 7008 return -1; 7009 } 7010 7011 final String authority = grantUri.uri.getAuthority(); 7012 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7013 if (pi == null) { 7014 Slog.w(TAG, "No content provider found for permission check: " + 7015 grantUri.uri.toSafeString()); 7016 return -1; 7017 } 7018 7019 int targetUid = lastTargetUid; 7020 if (targetUid < 0 && targetPkg != null) { 7021 try { 7022 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7023 if (targetUid < 0) { 7024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7025 "Can't grant URI permission no uid for: " + targetPkg); 7026 return -1; 7027 } 7028 } catch (RemoteException ex) { 7029 return -1; 7030 } 7031 } 7032 7033 if (targetUid >= 0) { 7034 // First... does the target actually need this permission? 7035 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7036 // No need to grant the target this permission. 7037 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7038 "Target " + targetPkg + " already has full permission to " + grantUri); 7039 return -1; 7040 } 7041 } else { 7042 // First... there is no target package, so can anyone access it? 7043 boolean allowed = pi.exported; 7044 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7045 if (pi.readPermission != null) { 7046 allowed = false; 7047 } 7048 } 7049 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7050 if (pi.writePermission != null) { 7051 allowed = false; 7052 } 7053 } 7054 if (allowed) { 7055 return -1; 7056 } 7057 } 7058 7059 /* There is a special cross user grant if: 7060 * - The target is on another user. 7061 * - Apps on the current user can access the uri without any uid permissions. 7062 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7063 * grant uri permissions. 7064 */ 7065 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7066 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7067 modeFlags, false /*without considering the uid permissions*/); 7068 7069 // Second... is the provider allowing granting of URI permissions? 7070 if (!specialCrossUserGrant) { 7071 if (!pi.grantUriPermissions) { 7072 throw new SecurityException("Provider " + pi.packageName 7073 + "/" + pi.name 7074 + " does not allow granting of Uri permissions (uri " 7075 + grantUri + ")"); 7076 } 7077 if (pi.uriPermissionPatterns != null) { 7078 final int N = pi.uriPermissionPatterns.length; 7079 boolean allowed = false; 7080 for (int i=0; i<N; i++) { 7081 if (pi.uriPermissionPatterns[i] != null 7082 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7083 allowed = true; 7084 break; 7085 } 7086 } 7087 if (!allowed) { 7088 throw new SecurityException("Provider " + pi.packageName 7089 + "/" + pi.name 7090 + " does not allow granting of permission to path of Uri " 7091 + grantUri); 7092 } 7093 } 7094 } 7095 7096 // Third... does the caller itself have permission to access 7097 // this uri? 7098 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7099 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7100 // Require they hold a strong enough Uri permission 7101 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7102 throw new SecurityException("Uid " + callingUid 7103 + " does not have permission to uri " + grantUri); 7104 } 7105 } 7106 } 7107 return targetUid; 7108 } 7109 7110 /** 7111 * @param uri This uri must NOT contain an embedded userId. 7112 * @param userId The userId in which the uri is to be resolved. 7113 */ 7114 @Override 7115 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7116 final int modeFlags, int userId) { 7117 enforceNotIsolatedCaller("checkGrantUriPermission"); 7118 synchronized(this) { 7119 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7120 new GrantUri(userId, uri, false), modeFlags, -1); 7121 } 7122 } 7123 7124 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7125 final int modeFlags, UriPermissionOwner owner) { 7126 if (!Intent.isAccessUriMode(modeFlags)) { 7127 return; 7128 } 7129 7130 // So here we are: the caller has the assumed permission 7131 // to the uri, and the target doesn't. Let's now give this to 7132 // the target. 7133 7134 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7135 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7136 7137 final String authority = grantUri.uri.getAuthority(); 7138 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7139 if (pi == null) { 7140 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7141 return; 7142 } 7143 7144 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7145 grantUri.prefix = true; 7146 } 7147 final UriPermission perm = findOrCreateUriPermissionLocked( 7148 pi.packageName, targetPkg, targetUid, grantUri); 7149 perm.grantModes(modeFlags, owner); 7150 } 7151 7152 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7153 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7154 if (targetPkg == null) { 7155 throw new NullPointerException("targetPkg"); 7156 } 7157 int targetUid; 7158 final IPackageManager pm = AppGlobals.getPackageManager(); 7159 try { 7160 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7161 } catch (RemoteException ex) { 7162 return; 7163 } 7164 7165 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7166 targetUid); 7167 if (targetUid < 0) { 7168 return; 7169 } 7170 7171 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7172 owner); 7173 } 7174 7175 static class NeededUriGrants extends ArrayList<GrantUri> { 7176 final String targetPkg; 7177 final int targetUid; 7178 final int flags; 7179 7180 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7181 this.targetPkg = targetPkg; 7182 this.targetUid = targetUid; 7183 this.flags = flags; 7184 } 7185 } 7186 7187 /** 7188 * Like checkGrantUriPermissionLocked, but takes an Intent. 7189 */ 7190 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7191 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7192 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7193 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7194 + " clip=" + (intent != null ? intent.getClipData() : null) 7195 + " from " + intent + "; flags=0x" 7196 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7197 7198 if (targetPkg == null) { 7199 throw new NullPointerException("targetPkg"); 7200 } 7201 7202 if (intent == null) { 7203 return null; 7204 } 7205 Uri data = intent.getData(); 7206 ClipData clip = intent.getClipData(); 7207 if (data == null && clip == null) { 7208 return null; 7209 } 7210 // Default userId for uris in the intent (if they don't specify it themselves) 7211 int contentUserHint = intent.getContentUserHint(); 7212 if (contentUserHint == UserHandle.USER_CURRENT) { 7213 contentUserHint = UserHandle.getUserId(callingUid); 7214 } 7215 final IPackageManager pm = AppGlobals.getPackageManager(); 7216 int targetUid; 7217 if (needed != null) { 7218 targetUid = needed.targetUid; 7219 } else { 7220 try { 7221 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7222 } catch (RemoteException ex) { 7223 return null; 7224 } 7225 if (targetUid < 0) { 7226 if (DEBUG_URI_PERMISSION) { 7227 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7228 + " on user " + targetUserId); 7229 } 7230 return null; 7231 } 7232 } 7233 if (data != null) { 7234 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7235 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7236 targetUid); 7237 if (targetUid > 0) { 7238 if (needed == null) { 7239 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7240 } 7241 needed.add(grantUri); 7242 } 7243 } 7244 if (clip != null) { 7245 for (int i=0; i<clip.getItemCount(); i++) { 7246 Uri uri = clip.getItemAt(i).getUri(); 7247 if (uri != null) { 7248 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7249 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7250 targetUid); 7251 if (targetUid > 0) { 7252 if (needed == null) { 7253 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7254 } 7255 needed.add(grantUri); 7256 } 7257 } else { 7258 Intent clipIntent = clip.getItemAt(i).getIntent(); 7259 if (clipIntent != null) { 7260 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7261 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7262 if (newNeeded != null) { 7263 needed = newNeeded; 7264 } 7265 } 7266 } 7267 } 7268 } 7269 7270 return needed; 7271 } 7272 7273 /** 7274 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7275 */ 7276 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7277 UriPermissionOwner owner) { 7278 if (needed != null) { 7279 for (int i=0; i<needed.size(); i++) { 7280 GrantUri grantUri = needed.get(i); 7281 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7282 grantUri, needed.flags, owner); 7283 } 7284 } 7285 } 7286 7287 void grantUriPermissionFromIntentLocked(int callingUid, 7288 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7289 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7290 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7291 if (needed == null) { 7292 return; 7293 } 7294 7295 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7296 } 7297 7298 /** 7299 * @param uri This uri must NOT contain an embedded userId. 7300 * @param userId The userId in which the uri is to be resolved. 7301 */ 7302 @Override 7303 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7304 final int modeFlags, int userId) { 7305 enforceNotIsolatedCaller("grantUriPermission"); 7306 GrantUri grantUri = new GrantUri(userId, uri, false); 7307 synchronized(this) { 7308 final ProcessRecord r = getRecordForAppLocked(caller); 7309 if (r == null) { 7310 throw new SecurityException("Unable to find app for caller " 7311 + caller 7312 + " when granting permission to uri " + grantUri); 7313 } 7314 if (targetPkg == null) { 7315 throw new IllegalArgumentException("null target"); 7316 } 7317 if (grantUri == null) { 7318 throw new IllegalArgumentException("null uri"); 7319 } 7320 7321 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7322 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7323 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7324 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7325 7326 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7327 UserHandle.getUserId(r.uid)); 7328 } 7329 } 7330 7331 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7332 if (perm.modeFlags == 0) { 7333 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7334 perm.targetUid); 7335 if (perms != null) { 7336 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7337 "Removing " + perm.targetUid + " permission to " + perm.uri); 7338 7339 perms.remove(perm.uri); 7340 if (perms.isEmpty()) { 7341 mGrantedUriPermissions.remove(perm.targetUid); 7342 } 7343 } 7344 } 7345 } 7346 7347 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7348 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7349 7350 final IPackageManager pm = AppGlobals.getPackageManager(); 7351 final String authority = grantUri.uri.getAuthority(); 7352 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7353 if (pi == null) { 7354 Slog.w(TAG, "No content provider found for permission revoke: " 7355 + grantUri.toSafeString()); 7356 return; 7357 } 7358 7359 // Does the caller have this permission on the URI? 7360 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7361 // If they don't have direct access to the URI, then revoke any 7362 // ownerless URI permissions that have been granted to them. 7363 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7364 if (perms != null) { 7365 boolean persistChanged = false; 7366 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7367 final UriPermission perm = it.next(); 7368 if (perm.uri.sourceUserId == grantUri.sourceUserId 7369 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7370 if (DEBUG_URI_PERMISSION) 7371 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7372 " permission to " + perm.uri); 7373 persistChanged |= perm.revokeModes( 7374 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7375 if (perm.modeFlags == 0) { 7376 it.remove(); 7377 } 7378 } 7379 } 7380 if (perms.isEmpty()) { 7381 mGrantedUriPermissions.remove(callingUid); 7382 } 7383 if (persistChanged) { 7384 schedulePersistUriGrants(); 7385 } 7386 } 7387 return; 7388 } 7389 7390 boolean persistChanged = false; 7391 7392 // Go through all of the permissions and remove any that match. 7393 int N = mGrantedUriPermissions.size(); 7394 for (int i = 0; i < N; i++) { 7395 final int targetUid = mGrantedUriPermissions.keyAt(i); 7396 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7397 7398 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7399 final UriPermission perm = it.next(); 7400 if (perm.uri.sourceUserId == grantUri.sourceUserId 7401 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7402 if (DEBUG_URI_PERMISSION) 7403 Slog.v(TAG, 7404 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7405 persistChanged |= perm.revokeModes( 7406 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7407 if (perm.modeFlags == 0) { 7408 it.remove(); 7409 } 7410 } 7411 } 7412 7413 if (perms.isEmpty()) { 7414 mGrantedUriPermissions.remove(targetUid); 7415 N--; 7416 i--; 7417 } 7418 } 7419 7420 if (persistChanged) { 7421 schedulePersistUriGrants(); 7422 } 7423 } 7424 7425 /** 7426 * @param uri This uri must NOT contain an embedded userId. 7427 * @param userId The userId in which the uri is to be resolved. 7428 */ 7429 @Override 7430 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7431 int userId) { 7432 enforceNotIsolatedCaller("revokeUriPermission"); 7433 synchronized(this) { 7434 final ProcessRecord r = getRecordForAppLocked(caller); 7435 if (r == null) { 7436 throw new SecurityException("Unable to find app for caller " 7437 + caller 7438 + " when revoking permission to uri " + uri); 7439 } 7440 if (uri == null) { 7441 Slog.w(TAG, "revokeUriPermission: null uri"); 7442 return; 7443 } 7444 7445 if (!Intent.isAccessUriMode(modeFlags)) { 7446 return; 7447 } 7448 7449 final IPackageManager pm = AppGlobals.getPackageManager(); 7450 final String authority = uri.getAuthority(); 7451 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7452 if (pi == null) { 7453 Slog.w(TAG, "No content provider found for permission revoke: " 7454 + uri.toSafeString()); 7455 return; 7456 } 7457 7458 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7459 } 7460 } 7461 7462 /** 7463 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7464 * given package. 7465 * 7466 * @param packageName Package name to match, or {@code null} to apply to all 7467 * packages. 7468 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7469 * to all users. 7470 * @param persistable If persistable grants should be removed. 7471 */ 7472 private void removeUriPermissionsForPackageLocked( 7473 String packageName, int userHandle, boolean persistable) { 7474 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7475 throw new IllegalArgumentException("Must narrow by either package or user"); 7476 } 7477 7478 boolean persistChanged = false; 7479 7480 int N = mGrantedUriPermissions.size(); 7481 for (int i = 0; i < N; i++) { 7482 final int targetUid = mGrantedUriPermissions.keyAt(i); 7483 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7484 7485 // Only inspect grants matching user 7486 if (userHandle == UserHandle.USER_ALL 7487 || userHandle == UserHandle.getUserId(targetUid)) { 7488 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7489 final UriPermission perm = it.next(); 7490 7491 // Only inspect grants matching package 7492 if (packageName == null || perm.sourcePkg.equals(packageName) 7493 || perm.targetPkg.equals(packageName)) { 7494 persistChanged |= perm.revokeModes(persistable 7495 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7496 7497 // Only remove when no modes remain; any persisted grants 7498 // will keep this alive. 7499 if (perm.modeFlags == 0) { 7500 it.remove(); 7501 } 7502 } 7503 } 7504 7505 if (perms.isEmpty()) { 7506 mGrantedUriPermissions.remove(targetUid); 7507 N--; 7508 i--; 7509 } 7510 } 7511 } 7512 7513 if (persistChanged) { 7514 schedulePersistUriGrants(); 7515 } 7516 } 7517 7518 @Override 7519 public IBinder newUriPermissionOwner(String name) { 7520 enforceNotIsolatedCaller("newUriPermissionOwner"); 7521 synchronized(this) { 7522 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7523 return owner.getExternalTokenLocked(); 7524 } 7525 } 7526 7527 /** 7528 * @param uri This uri must NOT contain an embedded userId. 7529 * @param sourceUserId The userId in which the uri is to be resolved. 7530 * @param targetUserId The userId of the app that receives the grant. 7531 */ 7532 @Override 7533 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7534 final int modeFlags, int sourceUserId, int targetUserId) { 7535 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7536 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7537 synchronized(this) { 7538 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7539 if (owner == null) { 7540 throw new IllegalArgumentException("Unknown owner: " + token); 7541 } 7542 if (fromUid != Binder.getCallingUid()) { 7543 if (Binder.getCallingUid() != Process.myUid()) { 7544 // Only system code can grant URI permissions on behalf 7545 // of other users. 7546 throw new SecurityException("nice try"); 7547 } 7548 } 7549 if (targetPkg == null) { 7550 throw new IllegalArgumentException("null target"); 7551 } 7552 if (uri == null) { 7553 throw new IllegalArgumentException("null uri"); 7554 } 7555 7556 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7557 modeFlags, owner, targetUserId); 7558 } 7559 } 7560 7561 /** 7562 * @param uri This uri must NOT contain an embedded userId. 7563 * @param userId The userId in which the uri is to be resolved. 7564 */ 7565 @Override 7566 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7567 synchronized(this) { 7568 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7569 if (owner == null) { 7570 throw new IllegalArgumentException("Unknown owner: " + token); 7571 } 7572 7573 if (uri == null) { 7574 owner.removeUriPermissionsLocked(mode); 7575 } else { 7576 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7577 } 7578 } 7579 } 7580 7581 private void schedulePersistUriGrants() { 7582 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7583 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7584 10 * DateUtils.SECOND_IN_MILLIS); 7585 } 7586 } 7587 7588 private void writeGrantedUriPermissions() { 7589 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7590 7591 // Snapshot permissions so we can persist without lock 7592 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7593 synchronized (this) { 7594 final int size = mGrantedUriPermissions.size(); 7595 for (int i = 0; i < size; i++) { 7596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7597 for (UriPermission perm : perms.values()) { 7598 if (perm.persistedModeFlags != 0) { 7599 persist.add(perm.snapshot()); 7600 } 7601 } 7602 } 7603 } 7604 7605 FileOutputStream fos = null; 7606 try { 7607 fos = mGrantFile.startWrite(); 7608 7609 XmlSerializer out = new FastXmlSerializer(); 7610 out.setOutput(fos, "utf-8"); 7611 out.startDocument(null, true); 7612 out.startTag(null, TAG_URI_GRANTS); 7613 for (UriPermission.Snapshot perm : persist) { 7614 out.startTag(null, TAG_URI_GRANT); 7615 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7616 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7617 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7618 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7619 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7620 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7621 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7622 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7623 out.endTag(null, TAG_URI_GRANT); 7624 } 7625 out.endTag(null, TAG_URI_GRANTS); 7626 out.endDocument(); 7627 7628 mGrantFile.finishWrite(fos); 7629 } catch (IOException e) { 7630 if (fos != null) { 7631 mGrantFile.failWrite(fos); 7632 } 7633 } 7634 } 7635 7636 private void readGrantedUriPermissionsLocked() { 7637 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7638 7639 final long now = System.currentTimeMillis(); 7640 7641 FileInputStream fis = null; 7642 try { 7643 fis = mGrantFile.openRead(); 7644 final XmlPullParser in = Xml.newPullParser(); 7645 in.setInput(fis, null); 7646 7647 int type; 7648 while ((type = in.next()) != END_DOCUMENT) { 7649 final String tag = in.getName(); 7650 if (type == START_TAG) { 7651 if (TAG_URI_GRANT.equals(tag)) { 7652 final int sourceUserId; 7653 final int targetUserId; 7654 final int userHandle = readIntAttribute(in, 7655 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7656 if (userHandle != UserHandle.USER_NULL) { 7657 // For backwards compatibility. 7658 sourceUserId = userHandle; 7659 targetUserId = userHandle; 7660 } else { 7661 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7662 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7663 } 7664 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7665 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7666 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7667 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7668 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7669 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7670 7671 // Sanity check that provider still belongs to source package 7672 final ProviderInfo pi = getProviderInfoLocked( 7673 uri.getAuthority(), sourceUserId); 7674 if (pi != null && sourcePkg.equals(pi.packageName)) { 7675 int targetUid = -1; 7676 try { 7677 targetUid = AppGlobals.getPackageManager() 7678 .getPackageUid(targetPkg, targetUserId); 7679 } catch (RemoteException e) { 7680 } 7681 if (targetUid != -1) { 7682 final UriPermission perm = findOrCreateUriPermissionLocked( 7683 sourcePkg, targetPkg, targetUid, 7684 new GrantUri(sourceUserId, uri, prefix)); 7685 perm.initPersistedModes(modeFlags, createdTime); 7686 } 7687 } else { 7688 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7689 + " but instead found " + pi); 7690 } 7691 } 7692 } 7693 } 7694 } catch (FileNotFoundException e) { 7695 // Missing grants is okay 7696 } catch (IOException e) { 7697 Slog.wtf(TAG, "Failed reading Uri grants", e); 7698 } catch (XmlPullParserException e) { 7699 Slog.wtf(TAG, "Failed reading Uri grants", e); 7700 } finally { 7701 IoUtils.closeQuietly(fis); 7702 } 7703 } 7704 7705 /** 7706 * @param uri This uri must NOT contain an embedded userId. 7707 * @param userId The userId in which the uri is to be resolved. 7708 */ 7709 @Override 7710 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7711 enforceNotIsolatedCaller("takePersistableUriPermission"); 7712 7713 Preconditions.checkFlagsArgument(modeFlags, 7714 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7715 7716 synchronized (this) { 7717 final int callingUid = Binder.getCallingUid(); 7718 boolean persistChanged = false; 7719 GrantUri grantUri = new GrantUri(userId, uri, false); 7720 7721 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7722 new GrantUri(userId, uri, false)); 7723 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7724 new GrantUri(userId, uri, true)); 7725 7726 final boolean exactValid = (exactPerm != null) 7727 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7728 final boolean prefixValid = (prefixPerm != null) 7729 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7730 7731 if (!(exactValid || prefixValid)) { 7732 throw new SecurityException("No persistable permission grants found for UID " 7733 + callingUid + " and Uri " + grantUri.toSafeString()); 7734 } 7735 7736 if (exactValid) { 7737 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7738 } 7739 if (prefixValid) { 7740 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7741 } 7742 7743 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7744 7745 if (persistChanged) { 7746 schedulePersistUriGrants(); 7747 } 7748 } 7749 } 7750 7751 /** 7752 * @param uri This uri must NOT contain an embedded userId. 7753 * @param userId The userId in which the uri is to be resolved. 7754 */ 7755 @Override 7756 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7757 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7758 7759 Preconditions.checkFlagsArgument(modeFlags, 7760 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7761 7762 synchronized (this) { 7763 final int callingUid = Binder.getCallingUid(); 7764 boolean persistChanged = false; 7765 7766 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7767 new GrantUri(userId, uri, false)); 7768 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7769 new GrantUri(userId, uri, true)); 7770 if (exactPerm == null && prefixPerm == null) { 7771 throw new SecurityException("No permission grants found for UID " + callingUid 7772 + " and Uri " + uri.toSafeString()); 7773 } 7774 7775 if (exactPerm != null) { 7776 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7777 removeUriPermissionIfNeededLocked(exactPerm); 7778 } 7779 if (prefixPerm != null) { 7780 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7781 removeUriPermissionIfNeededLocked(prefixPerm); 7782 } 7783 7784 if (persistChanged) { 7785 schedulePersistUriGrants(); 7786 } 7787 } 7788 } 7789 7790 /** 7791 * Prune any older {@link UriPermission} for the given UID until outstanding 7792 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7793 * 7794 * @return if any mutations occured that require persisting. 7795 */ 7796 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7797 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7798 if (perms == null) return false; 7799 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7800 7801 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7802 for (UriPermission perm : perms.values()) { 7803 if (perm.persistedModeFlags != 0) { 7804 persisted.add(perm); 7805 } 7806 } 7807 7808 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7809 if (trimCount <= 0) return false; 7810 7811 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7812 for (int i = 0; i < trimCount; i++) { 7813 final UriPermission perm = persisted.get(i); 7814 7815 if (DEBUG_URI_PERMISSION) { 7816 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7817 } 7818 7819 perm.releasePersistableModes(~0); 7820 removeUriPermissionIfNeededLocked(perm); 7821 } 7822 7823 return true; 7824 } 7825 7826 @Override 7827 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7828 String packageName, boolean incoming) { 7829 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7830 Preconditions.checkNotNull(packageName, "packageName"); 7831 7832 final int callingUid = Binder.getCallingUid(); 7833 final IPackageManager pm = AppGlobals.getPackageManager(); 7834 try { 7835 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7836 if (packageUid != callingUid) { 7837 throw new SecurityException( 7838 "Package " + packageName + " does not belong to calling UID " + callingUid); 7839 } 7840 } catch (RemoteException e) { 7841 throw new SecurityException("Failed to verify package name ownership"); 7842 } 7843 7844 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7845 synchronized (this) { 7846 if (incoming) { 7847 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7848 callingUid); 7849 if (perms == null) { 7850 Slog.w(TAG, "No permission grants found for " + packageName); 7851 } else { 7852 for (UriPermission perm : perms.values()) { 7853 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7854 result.add(perm.buildPersistedPublicApiObject()); 7855 } 7856 } 7857 } 7858 } else { 7859 final int size = mGrantedUriPermissions.size(); 7860 for (int i = 0; i < size; i++) { 7861 final ArrayMap<GrantUri, UriPermission> perms = 7862 mGrantedUriPermissions.valueAt(i); 7863 for (UriPermission perm : perms.values()) { 7864 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7865 result.add(perm.buildPersistedPublicApiObject()); 7866 } 7867 } 7868 } 7869 } 7870 } 7871 return new ParceledListSlice<android.content.UriPermission>(result); 7872 } 7873 7874 @Override 7875 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7876 synchronized (this) { 7877 ProcessRecord app = 7878 who != null ? getRecordForAppLocked(who) : null; 7879 if (app == null) return; 7880 7881 Message msg = Message.obtain(); 7882 msg.what = WAIT_FOR_DEBUGGER_MSG; 7883 msg.obj = app; 7884 msg.arg1 = waiting ? 1 : 0; 7885 mHandler.sendMessage(msg); 7886 } 7887 } 7888 7889 @Override 7890 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7891 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7892 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7893 outInfo.availMem = Process.getFreeMemory(); 7894 outInfo.totalMem = Process.getTotalMemory(); 7895 outInfo.threshold = homeAppMem; 7896 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7897 outInfo.hiddenAppThreshold = cachedAppMem; 7898 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7899 ProcessList.SERVICE_ADJ); 7900 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7901 ProcessList.VISIBLE_APP_ADJ); 7902 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7903 ProcessList.FOREGROUND_APP_ADJ); 7904 } 7905 7906 // ========================================================= 7907 // TASK MANAGEMENT 7908 // ========================================================= 7909 7910 @Override 7911 public List<IAppTask> getAppTasks(String callingPackage) { 7912 int callingUid = Binder.getCallingUid(); 7913 long ident = Binder.clearCallingIdentity(); 7914 7915 synchronized(this) { 7916 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7917 try { 7918 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7919 7920 final int N = mRecentTasks.size(); 7921 for (int i = 0; i < N; i++) { 7922 TaskRecord tr = mRecentTasks.get(i); 7923 // Skip tasks that do not match the caller. We don't need to verify 7924 // callingPackage, because we are also limiting to callingUid and know 7925 // that will limit to the correct security sandbox. 7926 if (tr.effectiveUid != callingUid) { 7927 continue; 7928 } 7929 Intent intent = tr.getBaseIntent(); 7930 if (intent == null || 7931 !callingPackage.equals(intent.getComponent().getPackageName())) { 7932 continue; 7933 } 7934 ActivityManager.RecentTaskInfo taskInfo = 7935 createRecentTaskInfoFromTaskRecord(tr); 7936 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7937 list.add(taskImpl); 7938 } 7939 } finally { 7940 Binder.restoreCallingIdentity(ident); 7941 } 7942 return list; 7943 } 7944 } 7945 7946 @Override 7947 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7948 final int callingUid = Binder.getCallingUid(); 7949 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7950 7951 synchronized(this) { 7952 if (localLOGV) Slog.v( 7953 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7954 7955 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7956 callingUid); 7957 7958 // TODO: Improve with MRU list from all ActivityStacks. 7959 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7960 } 7961 7962 return list; 7963 } 7964 7965 TaskRecord getMostRecentTask() { 7966 return mRecentTasks.get(0); 7967 } 7968 7969 /** 7970 * Creates a new RecentTaskInfo from a TaskRecord. 7971 */ 7972 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7973 // Update the task description to reflect any changes in the task stack 7974 tr.updateTaskDescription(); 7975 7976 // Compose the recent task info 7977 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7978 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7979 rti.persistentId = tr.taskId; 7980 rti.baseIntent = new Intent(tr.getBaseIntent()); 7981 rti.origActivity = tr.origActivity; 7982 rti.description = tr.lastDescription; 7983 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7984 rti.userId = tr.userId; 7985 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7986 rti.firstActiveTime = tr.firstActiveTime; 7987 rti.lastActiveTime = tr.lastActiveTime; 7988 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7989 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 7990 return rti; 7991 } 7992 7993 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 7994 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 7995 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 7996 if (!allowed) { 7997 if (checkPermission(android.Manifest.permission.GET_TASKS, 7998 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 7999 // Temporary compatibility: some existing apps on the system image may 8000 // still be requesting the old permission and not switched to the new 8001 // one; if so, we'll still allow them full access. This means we need 8002 // to see if they are holding the old permission and are a system app. 8003 try { 8004 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8005 allowed = true; 8006 Slog.w(TAG, caller + ": caller " + callingUid 8007 + " is using old GET_TASKS but privileged; allowing"); 8008 } 8009 } catch (RemoteException e) { 8010 } 8011 } 8012 } 8013 if (!allowed) { 8014 Slog.w(TAG, caller + ": caller " + callingUid 8015 + " does not hold GET_TASKS; limiting output"); 8016 } 8017 return allowed; 8018 } 8019 8020 @Override 8021 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8022 final int callingUid = Binder.getCallingUid(); 8023 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8024 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8025 8026 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8027 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8028 synchronized (this) { 8029 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8030 callingUid); 8031 final boolean detailed = checkCallingPermission( 8032 android.Manifest.permission.GET_DETAILED_TASKS) 8033 == PackageManager.PERMISSION_GRANTED; 8034 8035 final int N = mRecentTasks.size(); 8036 ArrayList<ActivityManager.RecentTaskInfo> res 8037 = new ArrayList<ActivityManager.RecentTaskInfo>( 8038 maxNum < N ? maxNum : N); 8039 8040 final Set<Integer> includedUsers; 8041 if (includeProfiles) { 8042 includedUsers = getProfileIdsLocked(userId); 8043 } else { 8044 includedUsers = new HashSet<Integer>(); 8045 } 8046 includedUsers.add(Integer.valueOf(userId)); 8047 8048 for (int i=0; i<N && maxNum > 0; i++) { 8049 TaskRecord tr = mRecentTasks.get(i); 8050 // Only add calling user or related users recent tasks 8051 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8052 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8053 continue; 8054 } 8055 8056 // Return the entry if desired by the caller. We always return 8057 // the first entry, because callers always expect this to be the 8058 // foreground app. We may filter others if the caller has 8059 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8060 // we should exclude the entry. 8061 8062 if (i == 0 8063 || withExcluded 8064 || (tr.intent == null) 8065 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8066 == 0)) { 8067 if (!allowed) { 8068 // If the caller doesn't have the GET_TASKS permission, then only 8069 // allow them to see a small subset of tasks -- their own and home. 8070 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8071 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8072 continue; 8073 } 8074 } 8075 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8076 if (tr.stack != null && tr.stack.isHomeStack()) { 8077 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8078 continue; 8079 } 8080 } 8081 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8082 // Don't include auto remove tasks that are finished or finishing. 8083 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8084 + tr); 8085 continue; 8086 } 8087 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8088 && !tr.isAvailable) { 8089 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8090 continue; 8091 } 8092 8093 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8094 if (!detailed) { 8095 rti.baseIntent.replaceExtras((Bundle)null); 8096 } 8097 8098 res.add(rti); 8099 maxNum--; 8100 } 8101 } 8102 return res; 8103 } 8104 } 8105 8106 private TaskRecord taskForIdLocked(int id) { 8107 final TaskRecord task = recentTaskForIdLocked(id); 8108 if (task != null) { 8109 return task; 8110 } 8111 8112 // Don't give up. Sometimes it just hasn't made it to recents yet. 8113 return mStackSupervisor.anyTaskForIdLocked(id); 8114 } 8115 8116 private TaskRecord recentTaskForIdLocked(int id) { 8117 final int N = mRecentTasks.size(); 8118 for (int i=0; i<N; i++) { 8119 TaskRecord tr = mRecentTasks.get(i); 8120 if (tr.taskId == id) { 8121 return tr; 8122 } 8123 } 8124 return null; 8125 } 8126 8127 @Override 8128 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8129 synchronized (this) { 8130 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8131 "getTaskThumbnail()"); 8132 TaskRecord tr = recentTaskForIdLocked(id); 8133 if (tr != null) { 8134 return tr.getTaskThumbnailLocked(); 8135 } 8136 } 8137 return null; 8138 } 8139 8140 @Override 8141 public int addAppTask(IBinder activityToken, Intent intent, 8142 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8143 final int callingUid = Binder.getCallingUid(); 8144 final long callingIdent = Binder.clearCallingIdentity(); 8145 8146 try { 8147 synchronized (this) { 8148 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8149 if (r == null) { 8150 throw new IllegalArgumentException("Activity does not exist; token=" 8151 + activityToken); 8152 } 8153 ComponentName comp = intent.getComponent(); 8154 if (comp == null) { 8155 throw new IllegalArgumentException("Intent " + intent 8156 + " must specify explicit component"); 8157 } 8158 if (thumbnail.getWidth() != mThumbnailWidth 8159 || thumbnail.getHeight() != mThumbnailHeight) { 8160 throw new IllegalArgumentException("Bad thumbnail size: got " 8161 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8162 + mThumbnailWidth + "x" + mThumbnailHeight); 8163 } 8164 if (intent.getSelector() != null) { 8165 intent.setSelector(null); 8166 } 8167 if (intent.getSourceBounds() != null) { 8168 intent.setSourceBounds(null); 8169 } 8170 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8171 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8172 // The caller has added this as an auto-remove task... that makes no 8173 // sense, so turn off auto-remove. 8174 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8175 } 8176 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8177 // Must be a new task. 8178 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8179 } 8180 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8181 mLastAddedTaskActivity = null; 8182 } 8183 ActivityInfo ainfo = mLastAddedTaskActivity; 8184 if (ainfo == null) { 8185 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8186 comp, 0, UserHandle.getUserId(callingUid)); 8187 if (ainfo.applicationInfo.uid != callingUid) { 8188 throw new SecurityException( 8189 "Can't add task for another application: target uid=" 8190 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8191 } 8192 } 8193 8194 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8195 intent, description); 8196 8197 int trimIdx = trimRecentsForTask(task, false); 8198 if (trimIdx >= 0) { 8199 // If this would have caused a trim, then we'll abort because that 8200 // means it would be added at the end of the list but then just removed. 8201 return -1; 8202 } 8203 8204 final int N = mRecentTasks.size(); 8205 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8206 final TaskRecord tr = mRecentTasks.remove(N - 1); 8207 tr.removedFromRecents(mTaskPersister); 8208 } 8209 8210 task.inRecents = true; 8211 mRecentTasks.add(task); 8212 r.task.stack.addTask(task, false, false); 8213 8214 task.setLastThumbnail(thumbnail); 8215 task.freeLastThumbnail(); 8216 8217 return task.taskId; 8218 } 8219 } finally { 8220 Binder.restoreCallingIdentity(callingIdent); 8221 } 8222 } 8223 8224 @Override 8225 public Point getAppTaskThumbnailSize() { 8226 synchronized (this) { 8227 return new Point(mThumbnailWidth, mThumbnailHeight); 8228 } 8229 } 8230 8231 @Override 8232 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8233 synchronized (this) { 8234 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8235 if (r != null) { 8236 r.setTaskDescription(td); 8237 r.task.updateTaskDescription(); 8238 } 8239 } 8240 } 8241 8242 @Override 8243 public Bitmap getTaskDescriptionIcon(String filename) { 8244 if (!FileUtils.isValidExtFilename(filename) 8245 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8246 throw new IllegalArgumentException("Bad filename: " + filename); 8247 } 8248 return mTaskPersister.getTaskDescriptionIcon(filename); 8249 } 8250 8251 @Override 8252 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8253 throws RemoteException { 8254 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8255 opts.getCustomInPlaceResId() == 0) { 8256 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8257 "with valid animation"); 8258 } 8259 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8260 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8261 opts.getCustomInPlaceResId()); 8262 mWindowManager.executeAppTransition(); 8263 } 8264 8265 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8266 mRecentTasks.remove(tr); 8267 tr.removedFromRecents(mTaskPersister); 8268 ComponentName component = tr.getBaseIntent().getComponent(); 8269 if (component == null) { 8270 Slog.w(TAG, "No component for base intent of task: " + tr); 8271 return; 8272 } 8273 8274 if (!killProcess) { 8275 return; 8276 } 8277 8278 // Determine if the process(es) for this task should be killed. 8279 final String pkg = component.getPackageName(); 8280 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8281 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8282 for (int i = 0; i < pmap.size(); i++) { 8283 8284 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8285 for (int j = 0; j < uids.size(); j++) { 8286 ProcessRecord proc = uids.valueAt(j); 8287 if (proc.userId != tr.userId) { 8288 // Don't kill process for a different user. 8289 continue; 8290 } 8291 if (proc == mHomeProcess) { 8292 // Don't kill the home process along with tasks from the same package. 8293 continue; 8294 } 8295 if (!proc.pkgList.containsKey(pkg)) { 8296 // Don't kill process that is not associated with this task. 8297 continue; 8298 } 8299 8300 for (int k = 0; k < proc.activities.size(); k++) { 8301 TaskRecord otherTask = proc.activities.get(k).task; 8302 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8303 // Don't kill process(es) that has an activity in a different task that is 8304 // also in recents. 8305 return; 8306 } 8307 } 8308 8309 // Add process to kill list. 8310 procsToKill.add(proc); 8311 } 8312 } 8313 8314 // Find any running services associated with this app and stop if needed. 8315 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8316 8317 // Kill the running processes. 8318 for (int i = 0; i < procsToKill.size(); i++) { 8319 ProcessRecord pr = procsToKill.get(i); 8320 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8321 pr.kill("remove task", true); 8322 } else { 8323 pr.waitingToKill = "remove task"; 8324 } 8325 } 8326 } 8327 8328 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8329 // Remove all tasks with activities in the specified package from the list of recent tasks 8330 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8331 TaskRecord tr = mRecentTasks.get(i); 8332 if (tr.userId != userId) continue; 8333 8334 ComponentName cn = tr.intent.getComponent(); 8335 if (cn != null && cn.getPackageName().equals(packageName)) { 8336 // If the package name matches, remove the task. 8337 removeTaskByIdLocked(tr.taskId, true); 8338 } 8339 } 8340 } 8341 8342 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8343 final IPackageManager pm = AppGlobals.getPackageManager(); 8344 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8345 8346 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8347 TaskRecord tr = mRecentTasks.get(i); 8348 if (tr.userId != userId) continue; 8349 8350 ComponentName cn = tr.intent.getComponent(); 8351 if (cn != null && cn.getPackageName().equals(packageName)) { 8352 // Skip if component still exists in the package. 8353 if (componentsKnownToExist.contains(cn)) continue; 8354 8355 try { 8356 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8357 if (info != null) { 8358 componentsKnownToExist.add(cn); 8359 } else { 8360 removeTaskByIdLocked(tr.taskId, false); 8361 } 8362 } catch (RemoteException e) { 8363 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8364 } 8365 } 8366 } 8367 } 8368 8369 /** 8370 * Removes the task with the specified task id. 8371 * 8372 * @param taskId Identifier of the task to be removed. 8373 * @param killProcess Kill any process associated with the task if possible. 8374 * @return Returns true if the given task was found and removed. 8375 */ 8376 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8377 TaskRecord tr = taskForIdLocked(taskId); 8378 if (tr != null) { 8379 tr.removeTaskActivitiesLocked(); 8380 cleanUpRemovedTaskLocked(tr, killProcess); 8381 if (tr.isPersistable) { 8382 notifyTaskPersisterLocked(null, true); 8383 } 8384 return true; 8385 } 8386 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8387 return false; 8388 } 8389 8390 @Override 8391 public boolean removeTask(int taskId) { 8392 synchronized (this) { 8393 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8394 "removeTask()"); 8395 long ident = Binder.clearCallingIdentity(); 8396 try { 8397 return removeTaskByIdLocked(taskId, true); 8398 } finally { 8399 Binder.restoreCallingIdentity(ident); 8400 } 8401 } 8402 } 8403 8404 /** 8405 * TODO: Add mController hook 8406 */ 8407 @Override 8408 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8409 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8410 "moveTaskToFront()"); 8411 8412 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8413 synchronized(this) { 8414 moveTaskToFrontLocked(taskId, flags, options); 8415 } 8416 } 8417 8418 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8419 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8420 Binder.getCallingUid(), -1, -1, "Task to front")) { 8421 ActivityOptions.abort(options); 8422 return; 8423 } 8424 final long origId = Binder.clearCallingIdentity(); 8425 try { 8426 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8427 if (task == null) { 8428 return; 8429 } 8430 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8431 mStackSupervisor.showLockTaskToast(); 8432 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8433 return; 8434 } 8435 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8436 if (prev != null && prev.isRecentsActivity()) { 8437 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8438 } 8439 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8440 } finally { 8441 Binder.restoreCallingIdentity(origId); 8442 } 8443 ActivityOptions.abort(options); 8444 } 8445 8446 @Override 8447 public void moveTaskToBack(int taskId) { 8448 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8449 "moveTaskToBack()"); 8450 8451 synchronized(this) { 8452 TaskRecord tr = taskForIdLocked(taskId); 8453 if (tr != null) { 8454 if (tr == mStackSupervisor.mLockTaskModeTask) { 8455 mStackSupervisor.showLockTaskToast(); 8456 return; 8457 } 8458 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8459 ActivityStack stack = tr.stack; 8460 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8461 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8462 Binder.getCallingUid(), -1, -1, "Task to back")) { 8463 return; 8464 } 8465 } 8466 final long origId = Binder.clearCallingIdentity(); 8467 try { 8468 stack.moveTaskToBackLocked(taskId, null); 8469 } finally { 8470 Binder.restoreCallingIdentity(origId); 8471 } 8472 } 8473 } 8474 } 8475 8476 /** 8477 * Moves an activity, and all of the other activities within the same task, to the bottom 8478 * of the history stack. The activity's order within the task is unchanged. 8479 * 8480 * @param token A reference to the activity we wish to move 8481 * @param nonRoot If false then this only works if the activity is the root 8482 * of a task; if true it will work for any activity in a task. 8483 * @return Returns true if the move completed, false if not. 8484 */ 8485 @Override 8486 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8487 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8488 synchronized(this) { 8489 final long origId = Binder.clearCallingIdentity(); 8490 try { 8491 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8492 if (taskId >= 0) { 8493 if ((mStackSupervisor.mLockTaskModeTask != null) 8494 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8495 mStackSupervisor.showLockTaskToast(); 8496 return false; 8497 } 8498 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8499 } 8500 } finally { 8501 Binder.restoreCallingIdentity(origId); 8502 } 8503 } 8504 return false; 8505 } 8506 8507 @Override 8508 public void moveTaskBackwards(int task) { 8509 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8510 "moveTaskBackwards()"); 8511 8512 synchronized(this) { 8513 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8514 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8515 return; 8516 } 8517 final long origId = Binder.clearCallingIdentity(); 8518 moveTaskBackwardsLocked(task); 8519 Binder.restoreCallingIdentity(origId); 8520 } 8521 } 8522 8523 private final void moveTaskBackwardsLocked(int task) { 8524 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8525 } 8526 8527 @Override 8528 public IBinder getHomeActivityToken() throws RemoteException { 8529 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8530 "getHomeActivityToken()"); 8531 synchronized (this) { 8532 return mStackSupervisor.getHomeActivityToken(); 8533 } 8534 } 8535 8536 @Override 8537 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8538 IActivityContainerCallback callback) throws RemoteException { 8539 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8540 "createActivityContainer()"); 8541 synchronized (this) { 8542 if (parentActivityToken == null) { 8543 throw new IllegalArgumentException("parent token must not be null"); 8544 } 8545 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8546 if (r == null) { 8547 return null; 8548 } 8549 if (callback == null) { 8550 throw new IllegalArgumentException("callback must not be null"); 8551 } 8552 return mStackSupervisor.createActivityContainer(r, callback); 8553 } 8554 } 8555 8556 @Override 8557 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8558 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8559 "deleteActivityContainer()"); 8560 synchronized (this) { 8561 mStackSupervisor.deleteActivityContainer(container); 8562 } 8563 } 8564 8565 @Override 8566 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8567 throws RemoteException { 8568 synchronized (this) { 8569 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8570 if (stack != null) { 8571 return stack.mActivityContainer; 8572 } 8573 return null; 8574 } 8575 } 8576 8577 @Override 8578 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8579 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8580 "moveTaskToStack()"); 8581 if (stackId == HOME_STACK_ID) { 8582 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8583 new RuntimeException("here").fillInStackTrace()); 8584 } 8585 synchronized (this) { 8586 long ident = Binder.clearCallingIdentity(); 8587 try { 8588 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8589 + stackId + " toTop=" + toTop); 8590 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8591 } finally { 8592 Binder.restoreCallingIdentity(ident); 8593 } 8594 } 8595 } 8596 8597 @Override 8598 public void resizeStack(int stackBoxId, Rect bounds) { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "resizeStackBox()"); 8601 long ident = Binder.clearCallingIdentity(); 8602 try { 8603 mWindowManager.resizeStack(stackBoxId, bounds); 8604 } finally { 8605 Binder.restoreCallingIdentity(ident); 8606 } 8607 } 8608 8609 @Override 8610 public List<StackInfo> getAllStackInfos() { 8611 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8612 "getAllStackInfos()"); 8613 long ident = Binder.clearCallingIdentity(); 8614 try { 8615 synchronized (this) { 8616 return mStackSupervisor.getAllStackInfosLocked(); 8617 } 8618 } finally { 8619 Binder.restoreCallingIdentity(ident); 8620 } 8621 } 8622 8623 @Override 8624 public StackInfo getStackInfo(int stackId) { 8625 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8626 "getStackInfo()"); 8627 long ident = Binder.clearCallingIdentity(); 8628 try { 8629 synchronized (this) { 8630 return mStackSupervisor.getStackInfoLocked(stackId); 8631 } 8632 } finally { 8633 Binder.restoreCallingIdentity(ident); 8634 } 8635 } 8636 8637 @Override 8638 public boolean isInHomeStack(int taskId) { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "getStackInfo()"); 8641 long ident = Binder.clearCallingIdentity(); 8642 try { 8643 synchronized (this) { 8644 TaskRecord tr = taskForIdLocked(taskId); 8645 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8646 } 8647 } finally { 8648 Binder.restoreCallingIdentity(ident); 8649 } 8650 } 8651 8652 @Override 8653 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8654 synchronized(this) { 8655 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8656 } 8657 } 8658 8659 private boolean isLockTaskAuthorized(String pkg) { 8660 final DevicePolicyManager dpm = (DevicePolicyManager) 8661 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8662 try { 8663 int uid = mContext.getPackageManager().getPackageUid(pkg, 8664 Binder.getCallingUserHandle().getIdentifier()); 8665 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8666 } catch (NameNotFoundException e) { 8667 return false; 8668 } 8669 } 8670 8671 void startLockTaskMode(TaskRecord task) { 8672 final String pkg; 8673 synchronized (this) { 8674 pkg = task.intent.getComponent().getPackageName(); 8675 } 8676 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8677 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8678 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8679 StatusBarManagerInternal.class); 8680 if (statusBarManager != null) { 8681 statusBarManager.showScreenPinningRequest(); 8682 } 8683 return; 8684 } 8685 long ident = Binder.clearCallingIdentity(); 8686 try { 8687 synchronized (this) { 8688 // Since we lost lock on task, make sure it is still there. 8689 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8690 if (task != null) { 8691 if (!isSystemInitiated 8692 && ((mStackSupervisor.getFocusedStack() == null) 8693 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8694 throw new IllegalArgumentException("Invalid task, not in foreground"); 8695 } 8696 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8697 } 8698 } 8699 } finally { 8700 Binder.restoreCallingIdentity(ident); 8701 } 8702 } 8703 8704 @Override 8705 public void startLockTaskMode(int taskId) { 8706 final TaskRecord task; 8707 long ident = Binder.clearCallingIdentity(); 8708 try { 8709 synchronized (this) { 8710 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8711 } 8712 } finally { 8713 Binder.restoreCallingIdentity(ident); 8714 } 8715 if (task != null) { 8716 startLockTaskMode(task); 8717 } 8718 } 8719 8720 @Override 8721 public void startLockTaskMode(IBinder token) { 8722 final TaskRecord task; 8723 long ident = Binder.clearCallingIdentity(); 8724 try { 8725 synchronized (this) { 8726 final ActivityRecord r = ActivityRecord.forToken(token); 8727 if (r == null) { 8728 return; 8729 } 8730 task = r.task; 8731 } 8732 } finally { 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 if (task != null) { 8736 startLockTaskMode(task); 8737 } 8738 } 8739 8740 @Override 8741 public void startLockTaskModeOnCurrent() throws RemoteException { 8742 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8743 "startLockTaskModeOnCurrent"); 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 ActivityRecord r = null; 8747 synchronized (this) { 8748 r = mStackSupervisor.topRunningActivityLocked(); 8749 } 8750 startLockTaskMode(r.task); 8751 } finally { 8752 Binder.restoreCallingIdentity(ident); 8753 } 8754 } 8755 8756 @Override 8757 public void stopLockTaskMode() { 8758 // Verify that the user matches the package of the intent for the TaskRecord 8759 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8760 // and stopLockTaskMode. 8761 final int callingUid = Binder.getCallingUid(); 8762 if (callingUid != Process.SYSTEM_UID) { 8763 try { 8764 String pkg = 8765 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8766 int uid = mContext.getPackageManager().getPackageUid(pkg, 8767 Binder.getCallingUserHandle().getIdentifier()); 8768 if (uid != callingUid) { 8769 throw new SecurityException("Invalid uid, expected " + uid); 8770 } 8771 } catch (NameNotFoundException e) { 8772 Log.d(TAG, "stopLockTaskMode " + e); 8773 return; 8774 } 8775 } 8776 long ident = Binder.clearCallingIdentity(); 8777 try { 8778 Log.d(TAG, "stopLockTaskMode"); 8779 // Stop lock task 8780 synchronized (this) { 8781 mStackSupervisor.setLockTaskModeLocked(null, false); 8782 } 8783 } finally { 8784 Binder.restoreCallingIdentity(ident); 8785 } 8786 } 8787 8788 @Override 8789 public void stopLockTaskModeOnCurrent() throws RemoteException { 8790 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8791 "stopLockTaskModeOnCurrent"); 8792 long ident = Binder.clearCallingIdentity(); 8793 try { 8794 stopLockTaskMode(); 8795 } finally { 8796 Binder.restoreCallingIdentity(ident); 8797 } 8798 } 8799 8800 @Override 8801 public boolean isInLockTaskMode() { 8802 synchronized (this) { 8803 return mStackSupervisor.isInLockTaskMode(); 8804 } 8805 } 8806 8807 // ========================================================= 8808 // CONTENT PROVIDERS 8809 // ========================================================= 8810 8811 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8812 List<ProviderInfo> providers = null; 8813 try { 8814 providers = AppGlobals.getPackageManager(). 8815 queryContentProviders(app.processName, app.uid, 8816 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8817 } catch (RemoteException ex) { 8818 } 8819 if (DEBUG_MU) 8820 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8821 int userId = app.userId; 8822 if (providers != null) { 8823 int N = providers.size(); 8824 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8825 for (int i=0; i<N; i++) { 8826 ProviderInfo cpi = 8827 (ProviderInfo)providers.get(i); 8828 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8829 cpi.name, cpi.flags); 8830 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8831 // This is a singleton provider, but a user besides the 8832 // default user is asking to initialize a process it runs 8833 // in... well, no, it doesn't actually run in this process, 8834 // it runs in the process of the default user. Get rid of it. 8835 providers.remove(i); 8836 N--; 8837 i--; 8838 continue; 8839 } 8840 8841 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8842 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8843 if (cpr == null) { 8844 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8845 mProviderMap.putProviderByClass(comp, cpr); 8846 } 8847 if (DEBUG_MU) 8848 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8849 app.pubProviders.put(cpi.name, cpr); 8850 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8851 // Don't add this if it is a platform component that is marked 8852 // to run in multiple processes, because this is actually 8853 // part of the framework so doesn't make sense to track as a 8854 // separate apk in the process. 8855 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8856 mProcessStats); 8857 } 8858 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8859 } 8860 } 8861 return providers; 8862 } 8863 8864 /** 8865 * Check if {@link ProcessRecord} has a possible chance at accessing the 8866 * given {@link ProviderInfo}. Final permission checking is always done 8867 * in {@link ContentProvider}. 8868 */ 8869 private final String checkContentProviderPermissionLocked( 8870 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8871 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8872 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8873 boolean checkedGrants = false; 8874 if (checkUser) { 8875 // Looking for cross-user grants before enforcing the typical cross-users permissions 8876 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8877 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8878 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8879 return null; 8880 } 8881 checkedGrants = true; 8882 } 8883 userId = handleIncomingUser(callingPid, callingUid, userId, 8884 false, ALLOW_NON_FULL, 8885 "checkContentProviderPermissionLocked " + cpi.authority, null); 8886 if (userId != tmpTargetUserId) { 8887 // When we actually went to determine the final targer user ID, this ended 8888 // up different than our initial check for the authority. This is because 8889 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8890 // SELF. So we need to re-check the grants again. 8891 checkedGrants = false; 8892 } 8893 } 8894 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8895 cpi.applicationInfo.uid, cpi.exported) 8896 == PackageManager.PERMISSION_GRANTED) { 8897 return null; 8898 } 8899 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8900 cpi.applicationInfo.uid, cpi.exported) 8901 == PackageManager.PERMISSION_GRANTED) { 8902 return null; 8903 } 8904 8905 PathPermission[] pps = cpi.pathPermissions; 8906 if (pps != null) { 8907 int i = pps.length; 8908 while (i > 0) { 8909 i--; 8910 PathPermission pp = pps[i]; 8911 String pprperm = pp.getReadPermission(); 8912 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8913 cpi.applicationInfo.uid, cpi.exported) 8914 == PackageManager.PERMISSION_GRANTED) { 8915 return null; 8916 } 8917 String ppwperm = pp.getWritePermission(); 8918 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8919 cpi.applicationInfo.uid, cpi.exported) 8920 == PackageManager.PERMISSION_GRANTED) { 8921 return null; 8922 } 8923 } 8924 } 8925 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8926 return null; 8927 } 8928 8929 String msg; 8930 if (!cpi.exported) { 8931 msg = "Permission Denial: opening provider " + cpi.name 8932 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8933 + ", uid=" + callingUid + ") that is not exported from uid " 8934 + cpi.applicationInfo.uid; 8935 } else { 8936 msg = "Permission Denial: opening provider " + cpi.name 8937 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8938 + ", uid=" + callingUid + ") requires " 8939 + cpi.readPermission + " or " + cpi.writePermission; 8940 } 8941 Slog.w(TAG, msg); 8942 return msg; 8943 } 8944 8945 /** 8946 * Returns if the ContentProvider has granted a uri to callingUid 8947 */ 8948 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8949 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8950 if (perms != null) { 8951 for (int i=perms.size()-1; i>=0; i--) { 8952 GrantUri grantUri = perms.keyAt(i); 8953 if (grantUri.sourceUserId == userId || !checkUser) { 8954 if (matchesProvider(grantUri.uri, cpi)) { 8955 return true; 8956 } 8957 } 8958 } 8959 } 8960 return false; 8961 } 8962 8963 /** 8964 * Returns true if the uri authority is one of the authorities specified in the provider. 8965 */ 8966 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8967 String uriAuth = uri.getAuthority(); 8968 String cpiAuth = cpi.authority; 8969 if (cpiAuth.indexOf(';') == -1) { 8970 return cpiAuth.equals(uriAuth); 8971 } 8972 String[] cpiAuths = cpiAuth.split(";"); 8973 int length = cpiAuths.length; 8974 for (int i = 0; i < length; i++) { 8975 if (cpiAuths[i].equals(uriAuth)) return true; 8976 } 8977 return false; 8978 } 8979 8980 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8981 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8982 if (r != null) { 8983 for (int i=0; i<r.conProviders.size(); i++) { 8984 ContentProviderConnection conn = r.conProviders.get(i); 8985 if (conn.provider == cpr) { 8986 if (DEBUG_PROVIDER) Slog.v(TAG, 8987 "Adding provider requested by " 8988 + r.processName + " from process " 8989 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8990 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8991 if (stable) { 8992 conn.stableCount++; 8993 conn.numStableIncs++; 8994 } else { 8995 conn.unstableCount++; 8996 conn.numUnstableIncs++; 8997 } 8998 return conn; 8999 } 9000 } 9001 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9002 if (stable) { 9003 conn.stableCount = 1; 9004 conn.numStableIncs = 1; 9005 } else { 9006 conn.unstableCount = 1; 9007 conn.numUnstableIncs = 1; 9008 } 9009 cpr.connections.add(conn); 9010 r.conProviders.add(conn); 9011 return conn; 9012 } 9013 cpr.addExternalProcessHandleLocked(externalProcessToken); 9014 return null; 9015 } 9016 9017 boolean decProviderCountLocked(ContentProviderConnection conn, 9018 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9019 if (conn != null) { 9020 cpr = conn.provider; 9021 if (DEBUG_PROVIDER) Slog.v(TAG, 9022 "Removing provider requested by " 9023 + conn.client.processName + " from process " 9024 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9025 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9026 if (stable) { 9027 conn.stableCount--; 9028 } else { 9029 conn.unstableCount--; 9030 } 9031 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9032 cpr.connections.remove(conn); 9033 conn.client.conProviders.remove(conn); 9034 return true; 9035 } 9036 return false; 9037 } 9038 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9039 return false; 9040 } 9041 9042 private void checkTime(long startTime, String where) { 9043 long now = SystemClock.elapsedRealtime(); 9044 if ((now-startTime) > 1000) { 9045 // If we are taking more than a second, log about it. 9046 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9047 } 9048 } 9049 9050 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9051 String name, IBinder token, boolean stable, int userId) { 9052 ContentProviderRecord cpr; 9053 ContentProviderConnection conn = null; 9054 ProviderInfo cpi = null; 9055 9056 synchronized(this) { 9057 long startTime = SystemClock.elapsedRealtime(); 9058 9059 ProcessRecord r = null; 9060 if (caller != null) { 9061 r = getRecordForAppLocked(caller); 9062 if (r == null) { 9063 throw new SecurityException( 9064 "Unable to find app for caller " + caller 9065 + " (pid=" + Binder.getCallingPid() 9066 + ") when getting content provider " + name); 9067 } 9068 } 9069 9070 boolean checkCrossUser = true; 9071 9072 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9073 9074 // First check if this content provider has been published... 9075 cpr = mProviderMap.getProviderByName(name, userId); 9076 // If that didn't work, check if it exists for user 0 and then 9077 // verify that it's a singleton provider before using it. 9078 if (cpr == null && userId != UserHandle.USER_OWNER) { 9079 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9080 if (cpr != null) { 9081 cpi = cpr.info; 9082 if (isSingleton(cpi.processName, cpi.applicationInfo, 9083 cpi.name, cpi.flags) 9084 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9085 userId = UserHandle.USER_OWNER; 9086 checkCrossUser = false; 9087 } else { 9088 cpr = null; 9089 cpi = null; 9090 } 9091 } 9092 } 9093 9094 boolean providerRunning = cpr != null; 9095 if (providerRunning) { 9096 cpi = cpr.info; 9097 String msg; 9098 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9099 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9100 != null) { 9101 throw new SecurityException(msg); 9102 } 9103 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9104 9105 if (r != null && cpr.canRunHere(r)) { 9106 // This provider has been published or is in the process 9107 // of being published... but it is also allowed to run 9108 // in the caller's process, so don't make a connection 9109 // and just let the caller instantiate its own instance. 9110 ContentProviderHolder holder = cpr.newHolder(null); 9111 // don't give caller the provider object, it needs 9112 // to make its own. 9113 holder.provider = null; 9114 return holder; 9115 } 9116 9117 final long origId = Binder.clearCallingIdentity(); 9118 9119 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9120 9121 // In this case the provider instance already exists, so we can 9122 // return it right away. 9123 conn = incProviderCountLocked(r, cpr, token, stable); 9124 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9125 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9126 // If this is a perceptible app accessing the provider, 9127 // make sure to count it as being accessed and thus 9128 // back up on the LRU list. This is good because 9129 // content providers are often expensive to start. 9130 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9131 updateLruProcessLocked(cpr.proc, false, null); 9132 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9133 } 9134 } 9135 9136 if (cpr.proc != null) { 9137 if (false) { 9138 if (cpr.name.flattenToShortString().equals( 9139 "com.android.providers.calendar/.CalendarProvider2")) { 9140 Slog.v(TAG, "****************** KILLING " 9141 + cpr.name.flattenToShortString()); 9142 Process.killProcess(cpr.proc.pid); 9143 } 9144 } 9145 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9146 boolean success = updateOomAdjLocked(cpr.proc); 9147 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9148 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9149 // NOTE: there is still a race here where a signal could be 9150 // pending on the process even though we managed to update its 9151 // adj level. Not sure what to do about this, but at least 9152 // the race is now smaller. 9153 if (!success) { 9154 // Uh oh... it looks like the provider's process 9155 // has been killed on us. We need to wait for a new 9156 // process to be started, and make sure its death 9157 // doesn't kill our process. 9158 Slog.i(TAG, 9159 "Existing provider " + cpr.name.flattenToShortString() 9160 + " is crashing; detaching " + r); 9161 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9162 checkTime(startTime, "getContentProviderImpl: before appDied"); 9163 appDiedLocked(cpr.proc); 9164 checkTime(startTime, "getContentProviderImpl: after appDied"); 9165 if (!lastRef) { 9166 // This wasn't the last ref our process had on 9167 // the provider... we have now been killed, bail. 9168 return null; 9169 } 9170 providerRunning = false; 9171 conn = null; 9172 } 9173 } 9174 9175 Binder.restoreCallingIdentity(origId); 9176 } 9177 9178 boolean singleton; 9179 if (!providerRunning) { 9180 try { 9181 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9182 cpi = AppGlobals.getPackageManager(). 9183 resolveContentProvider(name, 9184 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9185 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9186 } catch (RemoteException ex) { 9187 } 9188 if (cpi == null) { 9189 return null; 9190 } 9191 // If the provider is a singleton AND 9192 // (it's a call within the same user || the provider is a 9193 // privileged app) 9194 // Then allow connecting to the singleton provider 9195 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9196 cpi.name, cpi.flags) 9197 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9198 if (singleton) { 9199 userId = UserHandle.USER_OWNER; 9200 } 9201 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9202 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9203 9204 String msg; 9205 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9206 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9207 != null) { 9208 throw new SecurityException(msg); 9209 } 9210 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9211 9212 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9213 && !cpi.processName.equals("system")) { 9214 // If this content provider does not run in the system 9215 // process, and the system is not yet ready to run other 9216 // processes, then fail fast instead of hanging. 9217 throw new IllegalArgumentException( 9218 "Attempt to launch content provider before system ready"); 9219 } 9220 9221 // Make sure that the user who owns this provider is started. If not, 9222 // we don't want to allow it to run. 9223 if (mStartedUsers.get(userId) == null) { 9224 Slog.w(TAG, "Unable to launch app " 9225 + cpi.applicationInfo.packageName + "/" 9226 + cpi.applicationInfo.uid + " for provider " 9227 + name + ": user " + userId + " is stopped"); 9228 return null; 9229 } 9230 9231 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9232 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9233 cpr = mProviderMap.getProviderByClass(comp, userId); 9234 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9235 final boolean firstClass = cpr == null; 9236 if (firstClass) { 9237 final long ident = Binder.clearCallingIdentity(); 9238 try { 9239 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9240 ApplicationInfo ai = 9241 AppGlobals.getPackageManager(). 9242 getApplicationInfo( 9243 cpi.applicationInfo.packageName, 9244 STOCK_PM_FLAGS, userId); 9245 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9246 if (ai == null) { 9247 Slog.w(TAG, "No package info for content provider " 9248 + cpi.name); 9249 return null; 9250 } 9251 ai = getAppInfoForUser(ai, userId); 9252 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9253 } catch (RemoteException ex) { 9254 // pm is in same process, this will never happen. 9255 } finally { 9256 Binder.restoreCallingIdentity(ident); 9257 } 9258 } 9259 9260 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9261 9262 if (r != null && cpr.canRunHere(r)) { 9263 // If this is a multiprocess provider, then just return its 9264 // info and allow the caller to instantiate it. Only do 9265 // this if the provider is the same user as the caller's 9266 // process, or can run as root (so can be in any process). 9267 return cpr.newHolder(null); 9268 } 9269 9270 if (DEBUG_PROVIDER) { 9271 RuntimeException e = new RuntimeException("here"); 9272 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9273 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9274 } 9275 9276 // This is single process, and our app is now connecting to it. 9277 // See if we are already in the process of launching this 9278 // provider. 9279 final int N = mLaunchingProviders.size(); 9280 int i; 9281 for (i=0; i<N; i++) { 9282 if (mLaunchingProviders.get(i) == cpr) { 9283 break; 9284 } 9285 } 9286 9287 // If the provider is not already being launched, then get it 9288 // started. 9289 if (i >= N) { 9290 final long origId = Binder.clearCallingIdentity(); 9291 9292 try { 9293 // Content provider is now in use, its package can't be stopped. 9294 try { 9295 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9296 AppGlobals.getPackageManager().setPackageStoppedState( 9297 cpr.appInfo.packageName, false, userId); 9298 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9299 } catch (RemoteException e) { 9300 } catch (IllegalArgumentException e) { 9301 Slog.w(TAG, "Failed trying to unstop package " 9302 + cpr.appInfo.packageName + ": " + e); 9303 } 9304 9305 // Use existing process if already started 9306 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9307 ProcessRecord proc = getProcessRecordLocked( 9308 cpi.processName, cpr.appInfo.uid, false); 9309 if (proc != null && proc.thread != null) { 9310 if (DEBUG_PROVIDER) { 9311 Slog.d(TAG, "Installing in existing process " + proc); 9312 } 9313 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9314 proc.pubProviders.put(cpi.name, cpr); 9315 try { 9316 proc.thread.scheduleInstallProvider(cpi); 9317 } catch (RemoteException e) { 9318 } 9319 } else { 9320 checkTime(startTime, "getContentProviderImpl: before start process"); 9321 proc = startProcessLocked(cpi.processName, 9322 cpr.appInfo, false, 0, "content provider", 9323 new ComponentName(cpi.applicationInfo.packageName, 9324 cpi.name), false, false, false); 9325 checkTime(startTime, "getContentProviderImpl: after start process"); 9326 if (proc == null) { 9327 Slog.w(TAG, "Unable to launch app " 9328 + cpi.applicationInfo.packageName + "/" 9329 + cpi.applicationInfo.uid + " for provider " 9330 + name + ": process is bad"); 9331 return null; 9332 } 9333 } 9334 cpr.launchingApp = proc; 9335 mLaunchingProviders.add(cpr); 9336 } finally { 9337 Binder.restoreCallingIdentity(origId); 9338 } 9339 } 9340 9341 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9342 9343 // Make sure the provider is published (the same provider class 9344 // may be published under multiple names). 9345 if (firstClass) { 9346 mProviderMap.putProviderByClass(comp, cpr); 9347 } 9348 9349 mProviderMap.putProviderByName(name, cpr); 9350 conn = incProviderCountLocked(r, cpr, token, stable); 9351 if (conn != null) { 9352 conn.waiting = true; 9353 } 9354 } 9355 checkTime(startTime, "getContentProviderImpl: done!"); 9356 } 9357 9358 // Wait for the provider to be published... 9359 synchronized (cpr) { 9360 while (cpr.provider == null) { 9361 if (cpr.launchingApp == null) { 9362 Slog.w(TAG, "Unable to launch app " 9363 + cpi.applicationInfo.packageName + "/" 9364 + cpi.applicationInfo.uid + " for provider " 9365 + name + ": launching app became null"); 9366 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9367 UserHandle.getUserId(cpi.applicationInfo.uid), 9368 cpi.applicationInfo.packageName, 9369 cpi.applicationInfo.uid, name); 9370 return null; 9371 } 9372 try { 9373 if (DEBUG_MU) { 9374 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9375 + cpr.launchingApp); 9376 } 9377 if (conn != null) { 9378 conn.waiting = true; 9379 } 9380 cpr.wait(); 9381 } catch (InterruptedException ex) { 9382 } finally { 9383 if (conn != null) { 9384 conn.waiting = false; 9385 } 9386 } 9387 } 9388 } 9389 return cpr != null ? cpr.newHolder(conn) : null; 9390 } 9391 9392 @Override 9393 public final ContentProviderHolder getContentProvider( 9394 IApplicationThread caller, String name, int userId, boolean stable) { 9395 enforceNotIsolatedCaller("getContentProvider"); 9396 if (caller == null) { 9397 String msg = "null IApplicationThread when getting content provider " 9398 + name; 9399 Slog.w(TAG, msg); 9400 throw new SecurityException(msg); 9401 } 9402 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9403 // with cross-user grant. 9404 return getContentProviderImpl(caller, name, null, stable, userId); 9405 } 9406 9407 public ContentProviderHolder getContentProviderExternal( 9408 String name, int userId, IBinder token) { 9409 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9410 "Do not have permission in call getContentProviderExternal()"); 9411 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9412 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9413 return getContentProviderExternalUnchecked(name, token, userId); 9414 } 9415 9416 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9417 IBinder token, int userId) { 9418 return getContentProviderImpl(null, name, token, true, userId); 9419 } 9420 9421 /** 9422 * Drop a content provider from a ProcessRecord's bookkeeping 9423 */ 9424 public void removeContentProvider(IBinder connection, boolean stable) { 9425 enforceNotIsolatedCaller("removeContentProvider"); 9426 long ident = Binder.clearCallingIdentity(); 9427 try { 9428 synchronized (this) { 9429 ContentProviderConnection conn; 9430 try { 9431 conn = (ContentProviderConnection)connection; 9432 } catch (ClassCastException e) { 9433 String msg ="removeContentProvider: " + connection 9434 + " not a ContentProviderConnection"; 9435 Slog.w(TAG, msg); 9436 throw new IllegalArgumentException(msg); 9437 } 9438 if (conn == null) { 9439 throw new NullPointerException("connection is null"); 9440 } 9441 if (decProviderCountLocked(conn, null, null, stable)) { 9442 updateOomAdjLocked(); 9443 } 9444 } 9445 } finally { 9446 Binder.restoreCallingIdentity(ident); 9447 } 9448 } 9449 9450 public void removeContentProviderExternal(String name, IBinder token) { 9451 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9452 "Do not have permission in call removeContentProviderExternal()"); 9453 int userId = UserHandle.getCallingUserId(); 9454 long ident = Binder.clearCallingIdentity(); 9455 try { 9456 removeContentProviderExternalUnchecked(name, token, userId); 9457 } finally { 9458 Binder.restoreCallingIdentity(ident); 9459 } 9460 } 9461 9462 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9463 synchronized (this) { 9464 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9465 if(cpr == null) { 9466 //remove from mProvidersByClass 9467 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9468 return; 9469 } 9470 9471 //update content provider record entry info 9472 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9473 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9474 if (localCpr.hasExternalProcessHandles()) { 9475 if (localCpr.removeExternalProcessHandleLocked(token)) { 9476 updateOomAdjLocked(); 9477 } else { 9478 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9479 + " with no external reference for token: " 9480 + token + "."); 9481 } 9482 } else { 9483 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9484 + " with no external references."); 9485 } 9486 } 9487 } 9488 9489 public final void publishContentProviders(IApplicationThread caller, 9490 List<ContentProviderHolder> providers) { 9491 if (providers == null) { 9492 return; 9493 } 9494 9495 enforceNotIsolatedCaller("publishContentProviders"); 9496 synchronized (this) { 9497 final ProcessRecord r = getRecordForAppLocked(caller); 9498 if (DEBUG_MU) 9499 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9500 if (r == null) { 9501 throw new SecurityException( 9502 "Unable to find app for caller " + caller 9503 + " (pid=" + Binder.getCallingPid() 9504 + ") when publishing content providers"); 9505 } 9506 9507 final long origId = Binder.clearCallingIdentity(); 9508 9509 final int N = providers.size(); 9510 for (int i=0; i<N; i++) { 9511 ContentProviderHolder src = providers.get(i); 9512 if (src == null || src.info == null || src.provider == null) { 9513 continue; 9514 } 9515 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9516 if (DEBUG_MU) 9517 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9518 if (dst != null) { 9519 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9520 mProviderMap.putProviderByClass(comp, dst); 9521 String names[] = dst.info.authority.split(";"); 9522 for (int j = 0; j < names.length; j++) { 9523 mProviderMap.putProviderByName(names[j], dst); 9524 } 9525 9526 int NL = mLaunchingProviders.size(); 9527 int j; 9528 for (j=0; j<NL; j++) { 9529 if (mLaunchingProviders.get(j) == dst) { 9530 mLaunchingProviders.remove(j); 9531 j--; 9532 NL--; 9533 } 9534 } 9535 synchronized (dst) { 9536 dst.provider = src.provider; 9537 dst.proc = r; 9538 dst.notifyAll(); 9539 } 9540 updateOomAdjLocked(r); 9541 } 9542 } 9543 9544 Binder.restoreCallingIdentity(origId); 9545 } 9546 } 9547 9548 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9549 ContentProviderConnection conn; 9550 try { 9551 conn = (ContentProviderConnection)connection; 9552 } catch (ClassCastException e) { 9553 String msg ="refContentProvider: " + connection 9554 + " not a ContentProviderConnection"; 9555 Slog.w(TAG, msg); 9556 throw new IllegalArgumentException(msg); 9557 } 9558 if (conn == null) { 9559 throw new NullPointerException("connection is null"); 9560 } 9561 9562 synchronized (this) { 9563 if (stable > 0) { 9564 conn.numStableIncs += stable; 9565 } 9566 stable = conn.stableCount + stable; 9567 if (stable < 0) { 9568 throw new IllegalStateException("stableCount < 0: " + stable); 9569 } 9570 9571 if (unstable > 0) { 9572 conn.numUnstableIncs += unstable; 9573 } 9574 unstable = conn.unstableCount + unstable; 9575 if (unstable < 0) { 9576 throw new IllegalStateException("unstableCount < 0: " + unstable); 9577 } 9578 9579 if ((stable+unstable) <= 0) { 9580 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9581 + stable + " unstable=" + unstable); 9582 } 9583 conn.stableCount = stable; 9584 conn.unstableCount = unstable; 9585 return !conn.dead; 9586 } 9587 } 9588 9589 public void unstableProviderDied(IBinder connection) { 9590 ContentProviderConnection conn; 9591 try { 9592 conn = (ContentProviderConnection)connection; 9593 } catch (ClassCastException e) { 9594 String msg ="refContentProvider: " + connection 9595 + " not a ContentProviderConnection"; 9596 Slog.w(TAG, msg); 9597 throw new IllegalArgumentException(msg); 9598 } 9599 if (conn == null) { 9600 throw new NullPointerException("connection is null"); 9601 } 9602 9603 // Safely retrieve the content provider associated with the connection. 9604 IContentProvider provider; 9605 synchronized (this) { 9606 provider = conn.provider.provider; 9607 } 9608 9609 if (provider == null) { 9610 // Um, yeah, we're way ahead of you. 9611 return; 9612 } 9613 9614 // Make sure the caller is being honest with us. 9615 if (provider.asBinder().pingBinder()) { 9616 // Er, no, still looks good to us. 9617 synchronized (this) { 9618 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9619 + " says " + conn + " died, but we don't agree"); 9620 return; 9621 } 9622 } 9623 9624 // Well look at that! It's dead! 9625 synchronized (this) { 9626 if (conn.provider.provider != provider) { 9627 // But something changed... good enough. 9628 return; 9629 } 9630 9631 ProcessRecord proc = conn.provider.proc; 9632 if (proc == null || proc.thread == null) { 9633 // Seems like the process is already cleaned up. 9634 return; 9635 } 9636 9637 // As far as we're concerned, this is just like receiving a 9638 // death notification... just a bit prematurely. 9639 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9640 + ") early provider death"); 9641 final long ident = Binder.clearCallingIdentity(); 9642 try { 9643 appDiedLocked(proc); 9644 } finally { 9645 Binder.restoreCallingIdentity(ident); 9646 } 9647 } 9648 } 9649 9650 @Override 9651 public void appNotRespondingViaProvider(IBinder connection) { 9652 enforceCallingPermission( 9653 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9654 9655 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9656 if (conn == null) { 9657 Slog.w(TAG, "ContentProviderConnection is null"); 9658 return; 9659 } 9660 9661 final ProcessRecord host = conn.provider.proc; 9662 if (host == null) { 9663 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9664 return; 9665 } 9666 9667 final long token = Binder.clearCallingIdentity(); 9668 try { 9669 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9670 } finally { 9671 Binder.restoreCallingIdentity(token); 9672 } 9673 } 9674 9675 public final void installSystemProviders() { 9676 List<ProviderInfo> providers; 9677 synchronized (this) { 9678 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9679 providers = generateApplicationProvidersLocked(app); 9680 if (providers != null) { 9681 for (int i=providers.size()-1; i>=0; i--) { 9682 ProviderInfo pi = (ProviderInfo)providers.get(i); 9683 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9684 Slog.w(TAG, "Not installing system proc provider " + pi.name 9685 + ": not system .apk"); 9686 providers.remove(i); 9687 } 9688 } 9689 } 9690 } 9691 if (providers != null) { 9692 mSystemThread.installSystemProviders(providers); 9693 } 9694 9695 mCoreSettingsObserver = new CoreSettingsObserver(this); 9696 9697 //mUsageStatsService.monitorPackages(); 9698 } 9699 9700 /** 9701 * Allows apps to retrieve the MIME type of a URI. 9702 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9703 * users, then it does not need permission to access the ContentProvider. 9704 * Either, it needs cross-user uri grants. 9705 * 9706 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9707 * 9708 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9709 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9710 */ 9711 public String getProviderMimeType(Uri uri, int userId) { 9712 enforceNotIsolatedCaller("getProviderMimeType"); 9713 final String name = uri.getAuthority(); 9714 int callingUid = Binder.getCallingUid(); 9715 int callingPid = Binder.getCallingPid(); 9716 long ident = 0; 9717 boolean clearedIdentity = false; 9718 userId = unsafeConvertIncomingUser(userId); 9719 if (canClearIdentity(callingPid, callingUid, userId)) { 9720 clearedIdentity = true; 9721 ident = Binder.clearCallingIdentity(); 9722 } 9723 ContentProviderHolder holder = null; 9724 try { 9725 holder = getContentProviderExternalUnchecked(name, null, userId); 9726 if (holder != null) { 9727 return holder.provider.getType(uri); 9728 } 9729 } catch (RemoteException e) { 9730 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9731 return null; 9732 } finally { 9733 // We need to clear the identity to call removeContentProviderExternalUnchecked 9734 if (!clearedIdentity) { 9735 ident = Binder.clearCallingIdentity(); 9736 } 9737 try { 9738 if (holder != null) { 9739 removeContentProviderExternalUnchecked(name, null, userId); 9740 } 9741 } finally { 9742 Binder.restoreCallingIdentity(ident); 9743 } 9744 } 9745 9746 return null; 9747 } 9748 9749 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9750 if (UserHandle.getUserId(callingUid) == userId) { 9751 return true; 9752 } 9753 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9754 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9755 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9756 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9757 return true; 9758 } 9759 return false; 9760 } 9761 9762 // ========================================================= 9763 // GLOBAL MANAGEMENT 9764 // ========================================================= 9765 9766 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9767 boolean isolated, int isolatedUid) { 9768 String proc = customProcess != null ? customProcess : info.processName; 9769 BatteryStatsImpl.Uid.Proc ps = null; 9770 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9771 int uid = info.uid; 9772 if (isolated) { 9773 if (isolatedUid == 0) { 9774 int userId = UserHandle.getUserId(uid); 9775 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9776 while (true) { 9777 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9778 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9779 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9780 } 9781 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9782 mNextIsolatedProcessUid++; 9783 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9784 // No process for this uid, use it. 9785 break; 9786 } 9787 stepsLeft--; 9788 if (stepsLeft <= 0) { 9789 return null; 9790 } 9791 } 9792 } else { 9793 // Special case for startIsolatedProcess (internal only), where 9794 // the uid of the isolated process is specified by the caller. 9795 uid = isolatedUid; 9796 } 9797 } 9798 return new ProcessRecord(stats, info, proc, uid); 9799 } 9800 9801 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9802 String abiOverride) { 9803 ProcessRecord app; 9804 if (!isolated) { 9805 app = getProcessRecordLocked(info.processName, info.uid, true); 9806 } else { 9807 app = null; 9808 } 9809 9810 if (app == null) { 9811 app = newProcessRecordLocked(info, null, isolated, 0); 9812 mProcessNames.put(info.processName, app.uid, app); 9813 if (isolated) { 9814 mIsolatedProcesses.put(app.uid, app); 9815 } 9816 updateLruProcessLocked(app, false, null); 9817 updateOomAdjLocked(); 9818 } 9819 9820 // This package really, really can not be stopped. 9821 try { 9822 AppGlobals.getPackageManager().setPackageStoppedState( 9823 info.packageName, false, UserHandle.getUserId(app.uid)); 9824 } catch (RemoteException e) { 9825 } catch (IllegalArgumentException e) { 9826 Slog.w(TAG, "Failed trying to unstop package " 9827 + info.packageName + ": " + e); 9828 } 9829 9830 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9831 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9832 app.persistent = true; 9833 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9834 } 9835 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9836 mPersistentStartingProcesses.add(app); 9837 startProcessLocked(app, "added application", app.processName, abiOverride, 9838 null /* entryPoint */, null /* entryPointArgs */); 9839 } 9840 9841 return app; 9842 } 9843 9844 public void unhandledBack() { 9845 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9846 "unhandledBack()"); 9847 9848 synchronized(this) { 9849 final long origId = Binder.clearCallingIdentity(); 9850 try { 9851 getFocusedStack().unhandledBackLocked(); 9852 } finally { 9853 Binder.restoreCallingIdentity(origId); 9854 } 9855 } 9856 } 9857 9858 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9859 enforceNotIsolatedCaller("openContentUri"); 9860 final int userId = UserHandle.getCallingUserId(); 9861 String name = uri.getAuthority(); 9862 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9863 ParcelFileDescriptor pfd = null; 9864 if (cph != null) { 9865 // We record the binder invoker's uid in thread-local storage before 9866 // going to the content provider to open the file. Later, in the code 9867 // that handles all permissions checks, we look for this uid and use 9868 // that rather than the Activity Manager's own uid. The effect is that 9869 // we do the check against the caller's permissions even though it looks 9870 // to the content provider like the Activity Manager itself is making 9871 // the request. 9872 sCallerIdentity.set(new Identity( 9873 Binder.getCallingPid(), Binder.getCallingUid())); 9874 try { 9875 pfd = cph.provider.openFile(null, uri, "r", null); 9876 } catch (FileNotFoundException e) { 9877 // do nothing; pfd will be returned null 9878 } finally { 9879 // Ensure that whatever happens, we clean up the identity state 9880 sCallerIdentity.remove(); 9881 } 9882 9883 // We've got the fd now, so we're done with the provider. 9884 removeContentProviderExternalUnchecked(name, null, userId); 9885 } else { 9886 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9887 } 9888 return pfd; 9889 } 9890 9891 // Actually is sleeping or shutting down or whatever else in the future 9892 // is an inactive state. 9893 public boolean isSleepingOrShuttingDown() { 9894 return isSleeping() || mShuttingDown; 9895 } 9896 9897 public boolean isSleeping() { 9898 return mSleeping; 9899 } 9900 9901 void goingToSleep() { 9902 synchronized(this) { 9903 mWentToSleep = true; 9904 goToSleepIfNeededLocked(); 9905 } 9906 } 9907 9908 void finishRunningVoiceLocked() { 9909 if (mRunningVoice) { 9910 mRunningVoice = false; 9911 goToSleepIfNeededLocked(); 9912 } 9913 } 9914 9915 void goToSleepIfNeededLocked() { 9916 if (mWentToSleep && !mRunningVoice) { 9917 if (!mSleeping) { 9918 mSleeping = true; 9919 mStackSupervisor.goingToSleepLocked(); 9920 9921 // Initialize the wake times of all processes. 9922 checkExcessivePowerUsageLocked(false); 9923 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9924 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9925 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9926 } 9927 } 9928 } 9929 9930 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9931 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9932 // Never persist the home stack. 9933 return; 9934 } 9935 mTaskPersister.wakeup(task, flush); 9936 } 9937 9938 @Override 9939 public boolean shutdown(int timeout) { 9940 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9941 != PackageManager.PERMISSION_GRANTED) { 9942 throw new SecurityException("Requires permission " 9943 + android.Manifest.permission.SHUTDOWN); 9944 } 9945 9946 boolean timedout = false; 9947 9948 synchronized(this) { 9949 mShuttingDown = true; 9950 updateEventDispatchingLocked(); 9951 timedout = mStackSupervisor.shutdownLocked(timeout); 9952 } 9953 9954 mAppOpsService.shutdown(); 9955 if (mUsageStatsService != null) { 9956 mUsageStatsService.prepareShutdown(); 9957 } 9958 mBatteryStatsService.shutdown(); 9959 synchronized (this) { 9960 mProcessStats.shutdownLocked(); 9961 } 9962 notifyTaskPersisterLocked(null, true); 9963 9964 return timedout; 9965 } 9966 9967 public final void activitySlept(IBinder token) { 9968 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9969 9970 final long origId = Binder.clearCallingIdentity(); 9971 9972 synchronized (this) { 9973 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9974 if (r != null) { 9975 mStackSupervisor.activitySleptLocked(r); 9976 } 9977 } 9978 9979 Binder.restoreCallingIdentity(origId); 9980 } 9981 9982 private String lockScreenShownToString() { 9983 switch (mLockScreenShown) { 9984 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9985 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9986 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9987 default: return "Unknown=" + mLockScreenShown; 9988 } 9989 } 9990 9991 void logLockScreen(String msg) { 9992 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9993 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 9994 mWentToSleep + " mSleeping=" + mSleeping); 9995 } 9996 9997 void comeOutOfSleepIfNeededLocked() { 9998 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 9999 if (mSleeping) { 10000 mSleeping = false; 10001 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10002 } 10003 } 10004 } 10005 10006 void wakingUp() { 10007 synchronized(this) { 10008 mWentToSleep = false; 10009 comeOutOfSleepIfNeededLocked(); 10010 } 10011 } 10012 10013 void startRunningVoiceLocked() { 10014 if (!mRunningVoice) { 10015 mRunningVoice = true; 10016 comeOutOfSleepIfNeededLocked(); 10017 } 10018 } 10019 10020 private void updateEventDispatchingLocked() { 10021 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10022 } 10023 10024 public void setLockScreenShown(boolean shown) { 10025 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10026 != PackageManager.PERMISSION_GRANTED) { 10027 throw new SecurityException("Requires permission " 10028 + android.Manifest.permission.DEVICE_POWER); 10029 } 10030 10031 synchronized(this) { 10032 long ident = Binder.clearCallingIdentity(); 10033 try { 10034 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10035 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10036 comeOutOfSleepIfNeededLocked(); 10037 } finally { 10038 Binder.restoreCallingIdentity(ident); 10039 } 10040 } 10041 } 10042 10043 @Override 10044 public void stopAppSwitches() { 10045 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10046 != PackageManager.PERMISSION_GRANTED) { 10047 throw new SecurityException("Requires permission " 10048 + android.Manifest.permission.STOP_APP_SWITCHES); 10049 } 10050 10051 synchronized(this) { 10052 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10053 + APP_SWITCH_DELAY_TIME; 10054 mDidAppSwitch = false; 10055 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10056 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10057 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10058 } 10059 } 10060 10061 public void resumeAppSwitches() { 10062 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10063 != PackageManager.PERMISSION_GRANTED) { 10064 throw new SecurityException("Requires permission " 10065 + android.Manifest.permission.STOP_APP_SWITCHES); 10066 } 10067 10068 synchronized(this) { 10069 // Note that we don't execute any pending app switches... we will 10070 // let those wait until either the timeout, or the next start 10071 // activity request. 10072 mAppSwitchesAllowedTime = 0; 10073 } 10074 } 10075 10076 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10077 int callingPid, int callingUid, String name) { 10078 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10079 return true; 10080 } 10081 10082 int perm = checkComponentPermission( 10083 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10084 sourceUid, -1, true); 10085 if (perm == PackageManager.PERMISSION_GRANTED) { 10086 return true; 10087 } 10088 10089 // If the actual IPC caller is different from the logical source, then 10090 // also see if they are allowed to control app switches. 10091 if (callingUid != -1 && callingUid != sourceUid) { 10092 perm = checkComponentPermission( 10093 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10094 callingUid, -1, true); 10095 if (perm == PackageManager.PERMISSION_GRANTED) { 10096 return true; 10097 } 10098 } 10099 10100 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10101 return false; 10102 } 10103 10104 public void setDebugApp(String packageName, boolean waitForDebugger, 10105 boolean persistent) { 10106 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10107 "setDebugApp()"); 10108 10109 long ident = Binder.clearCallingIdentity(); 10110 try { 10111 // Note that this is not really thread safe if there are multiple 10112 // callers into it at the same time, but that's not a situation we 10113 // care about. 10114 if (persistent) { 10115 final ContentResolver resolver = mContext.getContentResolver(); 10116 Settings.Global.putString( 10117 resolver, Settings.Global.DEBUG_APP, 10118 packageName); 10119 Settings.Global.putInt( 10120 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10121 waitForDebugger ? 1 : 0); 10122 } 10123 10124 synchronized (this) { 10125 if (!persistent) { 10126 mOrigDebugApp = mDebugApp; 10127 mOrigWaitForDebugger = mWaitForDebugger; 10128 } 10129 mDebugApp = packageName; 10130 mWaitForDebugger = waitForDebugger; 10131 mDebugTransient = !persistent; 10132 if (packageName != null) { 10133 forceStopPackageLocked(packageName, -1, false, false, true, true, 10134 false, UserHandle.USER_ALL, "set debug app"); 10135 } 10136 } 10137 } finally { 10138 Binder.restoreCallingIdentity(ident); 10139 } 10140 } 10141 10142 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10143 synchronized (this) { 10144 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10145 if (!isDebuggable) { 10146 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10147 throw new SecurityException("Process not debuggable: " + app.packageName); 10148 } 10149 } 10150 10151 mOpenGlTraceApp = processName; 10152 } 10153 } 10154 10155 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10156 synchronized (this) { 10157 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10158 if (!isDebuggable) { 10159 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10160 throw new SecurityException("Process not debuggable: " + app.packageName); 10161 } 10162 } 10163 mProfileApp = processName; 10164 mProfileFile = profilerInfo.profileFile; 10165 if (mProfileFd != null) { 10166 try { 10167 mProfileFd.close(); 10168 } catch (IOException e) { 10169 } 10170 mProfileFd = null; 10171 } 10172 mProfileFd = profilerInfo.profileFd; 10173 mSamplingInterval = profilerInfo.samplingInterval; 10174 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10175 mProfileType = 0; 10176 } 10177 } 10178 10179 @Override 10180 public void setAlwaysFinish(boolean enabled) { 10181 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10182 "setAlwaysFinish()"); 10183 10184 Settings.Global.putInt( 10185 mContext.getContentResolver(), 10186 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10187 10188 synchronized (this) { 10189 mAlwaysFinishActivities = enabled; 10190 } 10191 } 10192 10193 @Override 10194 public void setActivityController(IActivityController controller) { 10195 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10196 "setActivityController()"); 10197 synchronized (this) { 10198 mController = controller; 10199 Watchdog.getInstance().setActivityController(controller); 10200 } 10201 } 10202 10203 @Override 10204 public void setUserIsMonkey(boolean userIsMonkey) { 10205 synchronized (this) { 10206 synchronized (mPidsSelfLocked) { 10207 final int callingPid = Binder.getCallingPid(); 10208 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10209 if (precessRecord == null) { 10210 throw new SecurityException("Unknown process: " + callingPid); 10211 } 10212 if (precessRecord.instrumentationUiAutomationConnection == null) { 10213 throw new SecurityException("Only an instrumentation process " 10214 + "with a UiAutomation can call setUserIsMonkey"); 10215 } 10216 } 10217 mUserIsMonkey = userIsMonkey; 10218 } 10219 } 10220 10221 @Override 10222 public boolean isUserAMonkey() { 10223 synchronized (this) { 10224 // If there is a controller also implies the user is a monkey. 10225 return (mUserIsMonkey || mController != null); 10226 } 10227 } 10228 10229 public void requestBugReport() { 10230 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10231 SystemProperties.set("ctl.start", "bugreport"); 10232 } 10233 10234 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10235 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10236 } 10237 10238 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10239 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10240 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10241 } 10242 return KEY_DISPATCHING_TIMEOUT; 10243 } 10244 10245 @Override 10246 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10247 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10248 != PackageManager.PERMISSION_GRANTED) { 10249 throw new SecurityException("Requires permission " 10250 + android.Manifest.permission.FILTER_EVENTS); 10251 } 10252 ProcessRecord proc; 10253 long timeout; 10254 synchronized (this) { 10255 synchronized (mPidsSelfLocked) { 10256 proc = mPidsSelfLocked.get(pid); 10257 } 10258 timeout = getInputDispatchingTimeoutLocked(proc); 10259 } 10260 10261 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10262 return -1; 10263 } 10264 10265 return timeout; 10266 } 10267 10268 /** 10269 * Handle input dispatching timeouts. 10270 * Returns whether input dispatching should be aborted or not. 10271 */ 10272 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10273 final ActivityRecord activity, final ActivityRecord parent, 10274 final boolean aboveSystem, String reason) { 10275 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10276 != PackageManager.PERMISSION_GRANTED) { 10277 throw new SecurityException("Requires permission " 10278 + android.Manifest.permission.FILTER_EVENTS); 10279 } 10280 10281 final String annotation; 10282 if (reason == null) { 10283 annotation = "Input dispatching timed out"; 10284 } else { 10285 annotation = "Input dispatching timed out (" + reason + ")"; 10286 } 10287 10288 if (proc != null) { 10289 synchronized (this) { 10290 if (proc.debugging) { 10291 return false; 10292 } 10293 10294 if (mDidDexOpt) { 10295 // Give more time since we were dexopting. 10296 mDidDexOpt = false; 10297 return false; 10298 } 10299 10300 if (proc.instrumentationClass != null) { 10301 Bundle info = new Bundle(); 10302 info.putString("shortMsg", "keyDispatchingTimedOut"); 10303 info.putString("longMsg", annotation); 10304 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10305 return true; 10306 } 10307 } 10308 mHandler.post(new Runnable() { 10309 @Override 10310 public void run() { 10311 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10312 } 10313 }); 10314 } 10315 10316 return true; 10317 } 10318 10319 public Bundle getAssistContextExtras(int requestType) { 10320 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10321 UserHandle.getCallingUserId()); 10322 if (pae == null) { 10323 return null; 10324 } 10325 synchronized (pae) { 10326 while (!pae.haveResult) { 10327 try { 10328 pae.wait(); 10329 } catch (InterruptedException e) { 10330 } 10331 } 10332 if (pae.result != null) { 10333 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10334 } 10335 } 10336 synchronized (this) { 10337 mPendingAssistExtras.remove(pae); 10338 mHandler.removeCallbacks(pae); 10339 } 10340 return pae.extras; 10341 } 10342 10343 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10344 int userHandle) { 10345 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10346 "getAssistContextExtras()"); 10347 PendingAssistExtras pae; 10348 Bundle extras = new Bundle(); 10349 synchronized (this) { 10350 ActivityRecord activity = getFocusedStack().mResumedActivity; 10351 if (activity == null) { 10352 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10353 return null; 10354 } 10355 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10356 if (activity.app == null || activity.app.thread == null) { 10357 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10358 return null; 10359 } 10360 if (activity.app.pid == Binder.getCallingPid()) { 10361 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10362 return null; 10363 } 10364 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10365 try { 10366 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10367 requestType); 10368 mPendingAssistExtras.add(pae); 10369 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10370 } catch (RemoteException e) { 10371 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10372 return null; 10373 } 10374 return pae; 10375 } 10376 } 10377 10378 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10379 PendingAssistExtras pae = (PendingAssistExtras)token; 10380 synchronized (pae) { 10381 pae.result = extras; 10382 pae.haveResult = true; 10383 pae.notifyAll(); 10384 if (pae.intent == null) { 10385 // Caller is just waiting for the result. 10386 return; 10387 } 10388 } 10389 10390 // We are now ready to launch the assist activity. 10391 synchronized (this) { 10392 boolean exists = mPendingAssistExtras.remove(pae); 10393 mHandler.removeCallbacks(pae); 10394 if (!exists) { 10395 // Timed out. 10396 return; 10397 } 10398 } 10399 pae.intent.replaceExtras(extras); 10400 if (pae.hint != null) { 10401 pae.intent.putExtra(pae.hint, true); 10402 } 10403 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10404 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10405 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10406 closeSystemDialogs("assist"); 10407 try { 10408 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10409 } catch (ActivityNotFoundException e) { 10410 Slog.w(TAG, "No activity to handle assist action.", e); 10411 } 10412 } 10413 10414 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10415 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10416 } 10417 10418 public void registerProcessObserver(IProcessObserver observer) { 10419 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10420 "registerProcessObserver()"); 10421 synchronized (this) { 10422 mProcessObservers.register(observer); 10423 } 10424 } 10425 10426 @Override 10427 public void unregisterProcessObserver(IProcessObserver observer) { 10428 synchronized (this) { 10429 mProcessObservers.unregister(observer); 10430 } 10431 } 10432 10433 @Override 10434 public boolean convertFromTranslucent(IBinder token) { 10435 final long origId = Binder.clearCallingIdentity(); 10436 try { 10437 synchronized (this) { 10438 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10439 if (r == null) { 10440 return false; 10441 } 10442 final boolean translucentChanged = r.changeWindowTranslucency(true); 10443 if (translucentChanged) { 10444 r.task.stack.releaseBackgroundResources(); 10445 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10446 } 10447 mWindowManager.setAppFullscreen(token, true); 10448 return translucentChanged; 10449 } 10450 } finally { 10451 Binder.restoreCallingIdentity(origId); 10452 } 10453 } 10454 10455 @Override 10456 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10457 final long origId = Binder.clearCallingIdentity(); 10458 try { 10459 synchronized (this) { 10460 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10461 if (r == null) { 10462 return false; 10463 } 10464 int index = r.task.mActivities.lastIndexOf(r); 10465 if (index > 0) { 10466 ActivityRecord under = r.task.mActivities.get(index - 1); 10467 under.returningOptions = options; 10468 } 10469 final boolean translucentChanged = r.changeWindowTranslucency(false); 10470 if (translucentChanged) { 10471 r.task.stack.convertToTranslucent(r); 10472 } 10473 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10474 mWindowManager.setAppFullscreen(token, false); 10475 return translucentChanged; 10476 } 10477 } finally { 10478 Binder.restoreCallingIdentity(origId); 10479 } 10480 } 10481 10482 @Override 10483 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10484 final long origId = Binder.clearCallingIdentity(); 10485 try { 10486 synchronized (this) { 10487 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10488 if (r != null) { 10489 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10490 } 10491 } 10492 return false; 10493 } finally { 10494 Binder.restoreCallingIdentity(origId); 10495 } 10496 } 10497 10498 @Override 10499 public boolean isBackgroundVisibleBehind(IBinder token) { 10500 final long origId = Binder.clearCallingIdentity(); 10501 try { 10502 synchronized (this) { 10503 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10504 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10505 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10506 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10507 return visible; 10508 } 10509 } finally { 10510 Binder.restoreCallingIdentity(origId); 10511 } 10512 } 10513 10514 @Override 10515 public ActivityOptions getActivityOptions(IBinder token) { 10516 final long origId = Binder.clearCallingIdentity(); 10517 try { 10518 synchronized (this) { 10519 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10520 if (r != null) { 10521 final ActivityOptions activityOptions = r.pendingOptions; 10522 r.pendingOptions = null; 10523 return activityOptions; 10524 } 10525 return null; 10526 } 10527 } finally { 10528 Binder.restoreCallingIdentity(origId); 10529 } 10530 } 10531 10532 @Override 10533 public void setImmersive(IBinder token, boolean immersive) { 10534 synchronized(this) { 10535 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10536 if (r == null) { 10537 throw new IllegalArgumentException(); 10538 } 10539 r.immersive = immersive; 10540 10541 // update associated state if we're frontmost 10542 if (r == mFocusedActivity) { 10543 if (DEBUG_IMMERSIVE) { 10544 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10545 } 10546 applyUpdateLockStateLocked(r); 10547 } 10548 } 10549 } 10550 10551 @Override 10552 public boolean isImmersive(IBinder token) { 10553 synchronized (this) { 10554 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10555 if (r == null) { 10556 throw new IllegalArgumentException(); 10557 } 10558 return r.immersive; 10559 } 10560 } 10561 10562 public boolean isTopActivityImmersive() { 10563 enforceNotIsolatedCaller("startActivity"); 10564 synchronized (this) { 10565 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10566 return (r != null) ? r.immersive : false; 10567 } 10568 } 10569 10570 @Override 10571 public boolean isTopOfTask(IBinder token) { 10572 synchronized (this) { 10573 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10574 if (r == null) { 10575 throw new IllegalArgumentException(); 10576 } 10577 return r.task.getTopActivity() == r; 10578 } 10579 } 10580 10581 public final void enterSafeMode() { 10582 synchronized(this) { 10583 // It only makes sense to do this before the system is ready 10584 // and started launching other packages. 10585 if (!mSystemReady) { 10586 try { 10587 AppGlobals.getPackageManager().enterSafeMode(); 10588 } catch (RemoteException e) { 10589 } 10590 } 10591 10592 mSafeMode = true; 10593 } 10594 } 10595 10596 public final void showSafeModeOverlay() { 10597 View v = LayoutInflater.from(mContext).inflate( 10598 com.android.internal.R.layout.safe_mode, null); 10599 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10600 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10601 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10602 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10603 lp.gravity = Gravity.BOTTOM | Gravity.START; 10604 lp.format = v.getBackground().getOpacity(); 10605 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10606 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10607 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10608 ((WindowManager)mContext.getSystemService( 10609 Context.WINDOW_SERVICE)).addView(v, lp); 10610 } 10611 10612 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10613 if (!(sender instanceof PendingIntentRecord)) { 10614 return; 10615 } 10616 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10617 synchronized (stats) { 10618 if (mBatteryStatsService.isOnBattery()) { 10619 mBatteryStatsService.enforceCallingPermission(); 10620 PendingIntentRecord rec = (PendingIntentRecord)sender; 10621 int MY_UID = Binder.getCallingUid(); 10622 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10623 BatteryStatsImpl.Uid.Pkg pkg = 10624 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10625 sourcePkg != null ? sourcePkg : rec.key.packageName); 10626 pkg.incWakeupsLocked(); 10627 } 10628 } 10629 } 10630 10631 public boolean killPids(int[] pids, String pReason, boolean secure) { 10632 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10633 throw new SecurityException("killPids only available to the system"); 10634 } 10635 String reason = (pReason == null) ? "Unknown" : pReason; 10636 // XXX Note: don't acquire main activity lock here, because the window 10637 // manager calls in with its locks held. 10638 10639 boolean killed = false; 10640 synchronized (mPidsSelfLocked) { 10641 int[] types = new int[pids.length]; 10642 int worstType = 0; 10643 for (int i=0; i<pids.length; i++) { 10644 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10645 if (proc != null) { 10646 int type = proc.setAdj; 10647 types[i] = type; 10648 if (type > worstType) { 10649 worstType = type; 10650 } 10651 } 10652 } 10653 10654 // If the worst oom_adj is somewhere in the cached proc LRU range, 10655 // then constrain it so we will kill all cached procs. 10656 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10657 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10658 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10659 } 10660 10661 // If this is not a secure call, don't let it kill processes that 10662 // are important. 10663 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10664 worstType = ProcessList.SERVICE_ADJ; 10665 } 10666 10667 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10668 for (int i=0; i<pids.length; i++) { 10669 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10670 if (proc == null) { 10671 continue; 10672 } 10673 int adj = proc.setAdj; 10674 if (adj >= worstType && !proc.killedByAm) { 10675 proc.kill(reason, true); 10676 killed = true; 10677 } 10678 } 10679 } 10680 return killed; 10681 } 10682 10683 @Override 10684 public void killUid(int uid, String reason) { 10685 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10686 throw new SecurityException("killUid only available to the system"); 10687 } 10688 synchronized (this) { 10689 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10690 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10691 reason != null ? reason : "kill uid"); 10692 } 10693 } 10694 10695 @Override 10696 public boolean killProcessesBelowForeground(String reason) { 10697 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10698 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10699 } 10700 10701 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10702 } 10703 10704 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10705 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10706 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10707 } 10708 10709 boolean killed = false; 10710 synchronized (mPidsSelfLocked) { 10711 final int size = mPidsSelfLocked.size(); 10712 for (int i = 0; i < size; i++) { 10713 final int pid = mPidsSelfLocked.keyAt(i); 10714 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10715 if (proc == null) continue; 10716 10717 final int adj = proc.setAdj; 10718 if (adj > belowAdj && !proc.killedByAm) { 10719 proc.kill(reason, true); 10720 killed = true; 10721 } 10722 } 10723 } 10724 return killed; 10725 } 10726 10727 @Override 10728 public void hang(final IBinder who, boolean allowRestart) { 10729 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10730 != PackageManager.PERMISSION_GRANTED) { 10731 throw new SecurityException("Requires permission " 10732 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10733 } 10734 10735 final IBinder.DeathRecipient death = new DeathRecipient() { 10736 @Override 10737 public void binderDied() { 10738 synchronized (this) { 10739 notifyAll(); 10740 } 10741 } 10742 }; 10743 10744 try { 10745 who.linkToDeath(death, 0); 10746 } catch (RemoteException e) { 10747 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10748 return; 10749 } 10750 10751 synchronized (this) { 10752 Watchdog.getInstance().setAllowRestart(allowRestart); 10753 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10754 synchronized (death) { 10755 while (who.isBinderAlive()) { 10756 try { 10757 death.wait(); 10758 } catch (InterruptedException e) { 10759 } 10760 } 10761 } 10762 Watchdog.getInstance().setAllowRestart(true); 10763 } 10764 } 10765 10766 @Override 10767 public void restart() { 10768 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10769 != PackageManager.PERMISSION_GRANTED) { 10770 throw new SecurityException("Requires permission " 10771 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10772 } 10773 10774 Log.i(TAG, "Sending shutdown broadcast..."); 10775 10776 BroadcastReceiver br = new BroadcastReceiver() { 10777 @Override public void onReceive(Context context, Intent intent) { 10778 // Now the broadcast is done, finish up the low-level shutdown. 10779 Log.i(TAG, "Shutting down activity manager..."); 10780 shutdown(10000); 10781 Log.i(TAG, "Shutdown complete, restarting!"); 10782 Process.killProcess(Process.myPid()); 10783 System.exit(10); 10784 } 10785 }; 10786 10787 // First send the high-level shut down broadcast. 10788 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10789 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10790 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10791 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10792 mContext.sendOrderedBroadcastAsUser(intent, 10793 UserHandle.ALL, null, br, mHandler, 0, null, null); 10794 */ 10795 br.onReceive(mContext, intent); 10796 } 10797 10798 private long getLowRamTimeSinceIdle(long now) { 10799 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10800 } 10801 10802 @Override 10803 public void performIdleMaintenance() { 10804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10805 != PackageManager.PERMISSION_GRANTED) { 10806 throw new SecurityException("Requires permission " 10807 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10808 } 10809 10810 synchronized (this) { 10811 final long now = SystemClock.uptimeMillis(); 10812 final long timeSinceLastIdle = now - mLastIdleTime; 10813 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10814 mLastIdleTime = now; 10815 mLowRamTimeSinceLastIdle = 0; 10816 if (mLowRamStartTime != 0) { 10817 mLowRamStartTime = now; 10818 } 10819 10820 StringBuilder sb = new StringBuilder(128); 10821 sb.append("Idle maintenance over "); 10822 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10823 sb.append(" low RAM for "); 10824 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10825 Slog.i(TAG, sb.toString()); 10826 10827 // If at least 1/3 of our time since the last idle period has been spent 10828 // with RAM low, then we want to kill processes. 10829 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10830 10831 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10832 ProcessRecord proc = mLruProcesses.get(i); 10833 if (proc.notCachedSinceIdle) { 10834 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10835 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10836 if (doKilling && proc.initialIdlePss != 0 10837 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10838 proc.kill("idle maint (pss " + proc.lastPss 10839 + " from " + proc.initialIdlePss + ")", true); 10840 } 10841 } 10842 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10843 proc.notCachedSinceIdle = true; 10844 proc.initialIdlePss = 0; 10845 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10846 isSleeping(), now); 10847 } 10848 } 10849 10850 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10851 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10852 } 10853 } 10854 10855 private void retrieveSettings() { 10856 final ContentResolver resolver = mContext.getContentResolver(); 10857 String debugApp = Settings.Global.getString( 10858 resolver, Settings.Global.DEBUG_APP); 10859 boolean waitForDebugger = Settings.Global.getInt( 10860 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10861 boolean alwaysFinishActivities = Settings.Global.getInt( 10862 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10863 boolean forceRtl = Settings.Global.getInt( 10864 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10865 // Transfer any global setting for forcing RTL layout, into a System Property 10866 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10867 10868 Configuration configuration = new Configuration(); 10869 Settings.System.getConfiguration(resolver, configuration); 10870 if (forceRtl) { 10871 // This will take care of setting the correct layout direction flags 10872 configuration.setLayoutDirection(configuration.locale); 10873 } 10874 10875 synchronized (this) { 10876 mDebugApp = mOrigDebugApp = debugApp; 10877 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10878 mAlwaysFinishActivities = alwaysFinishActivities; 10879 // This happens before any activities are started, so we can 10880 // change mConfiguration in-place. 10881 updateConfigurationLocked(configuration, null, false, true); 10882 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10883 } 10884 } 10885 10886 /** Loads resources after the current configuration has been set. */ 10887 private void loadResourcesOnSystemReady() { 10888 final Resources res = mContext.getResources(); 10889 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10890 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10891 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10892 } 10893 10894 public boolean testIsSystemReady() { 10895 // no need to synchronize(this) just to read & return the value 10896 return mSystemReady; 10897 } 10898 10899 private static File getCalledPreBootReceiversFile() { 10900 File dataDir = Environment.getDataDirectory(); 10901 File systemDir = new File(dataDir, "system"); 10902 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10903 return fname; 10904 } 10905 10906 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10907 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10908 File file = getCalledPreBootReceiversFile(); 10909 FileInputStream fis = null; 10910 try { 10911 fis = new FileInputStream(file); 10912 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10913 int fvers = dis.readInt(); 10914 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10915 String vers = dis.readUTF(); 10916 String codename = dis.readUTF(); 10917 String build = dis.readUTF(); 10918 if (android.os.Build.VERSION.RELEASE.equals(vers) 10919 && android.os.Build.VERSION.CODENAME.equals(codename) 10920 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10921 int num = dis.readInt(); 10922 while (num > 0) { 10923 num--; 10924 String pkg = dis.readUTF(); 10925 String cls = dis.readUTF(); 10926 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10927 } 10928 } 10929 } 10930 } catch (FileNotFoundException e) { 10931 } catch (IOException e) { 10932 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10933 } finally { 10934 if (fis != null) { 10935 try { 10936 fis.close(); 10937 } catch (IOException e) { 10938 } 10939 } 10940 } 10941 return lastDoneReceivers; 10942 } 10943 10944 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10945 File file = getCalledPreBootReceiversFile(); 10946 FileOutputStream fos = null; 10947 DataOutputStream dos = null; 10948 try { 10949 fos = new FileOutputStream(file); 10950 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10951 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10952 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10953 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10954 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10955 dos.writeInt(list.size()); 10956 for (int i=0; i<list.size(); i++) { 10957 dos.writeUTF(list.get(i).getPackageName()); 10958 dos.writeUTF(list.get(i).getClassName()); 10959 } 10960 } catch (IOException e) { 10961 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10962 file.delete(); 10963 } finally { 10964 FileUtils.sync(fos); 10965 if (dos != null) { 10966 try { 10967 dos.close(); 10968 } catch (IOException e) { 10969 // TODO Auto-generated catch block 10970 e.printStackTrace(); 10971 } 10972 } 10973 } 10974 } 10975 10976 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10977 ArrayList<ComponentName> doneReceivers, int userId) { 10978 boolean waitingUpdate = false; 10979 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10980 List<ResolveInfo> ris = null; 10981 try { 10982 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10983 intent, null, 0, userId); 10984 } catch (RemoteException e) { 10985 } 10986 if (ris != null) { 10987 for (int i=ris.size()-1; i>=0; i--) { 10988 if ((ris.get(i).activityInfo.applicationInfo.flags 10989 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10990 ris.remove(i); 10991 } 10992 } 10993 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10994 10995 // For User 0, load the version number. When delivering to a new user, deliver 10996 // to all receivers. 10997 if (userId == UserHandle.USER_OWNER) { 10998 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10999 for (int i=0; i<ris.size(); i++) { 11000 ActivityInfo ai = ris.get(i).activityInfo; 11001 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11002 if (lastDoneReceivers.contains(comp)) { 11003 // We already did the pre boot receiver for this app with the current 11004 // platform version, so don't do it again... 11005 ris.remove(i); 11006 i--; 11007 // ...however, do keep it as one that has been done, so we don't 11008 // forget about it when rewriting the file of last done receivers. 11009 doneReceivers.add(comp); 11010 } 11011 } 11012 } 11013 11014 // If primary user, send broadcast to all available users, else just to userId 11015 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11016 : new int[] { userId }; 11017 for (int i = 0; i < ris.size(); i++) { 11018 ActivityInfo ai = ris.get(i).activityInfo; 11019 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11020 doneReceivers.add(comp); 11021 intent.setComponent(comp); 11022 for (int j=0; j<users.length; j++) { 11023 IIntentReceiver finisher = null; 11024 // On last receiver and user, set up a completion callback 11025 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11026 finisher = new IIntentReceiver.Stub() { 11027 public void performReceive(Intent intent, int resultCode, 11028 String data, Bundle extras, boolean ordered, 11029 boolean sticky, int sendingUser) { 11030 // The raw IIntentReceiver interface is called 11031 // with the AM lock held, so redispatch to 11032 // execute our code without the lock. 11033 mHandler.post(onFinishCallback); 11034 } 11035 }; 11036 } 11037 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11038 + " for user " + users[j]); 11039 broadcastIntentLocked(null, null, intent, null, finisher, 11040 0, null, null, null, AppOpsManager.OP_NONE, 11041 true, false, MY_PID, Process.SYSTEM_UID, 11042 users[j]); 11043 if (finisher != null) { 11044 waitingUpdate = true; 11045 } 11046 } 11047 } 11048 } 11049 11050 return waitingUpdate; 11051 } 11052 11053 public void systemReady(final Runnable goingCallback) { 11054 synchronized(this) { 11055 if (mSystemReady) { 11056 // If we're done calling all the receivers, run the next "boot phase" passed in 11057 // by the SystemServer 11058 if (goingCallback != null) { 11059 goingCallback.run(); 11060 } 11061 return; 11062 } 11063 11064 // Make sure we have the current profile info, since it is needed for 11065 // security checks. 11066 updateCurrentProfileIdsLocked(); 11067 11068 if (mRecentTasks == null) { 11069 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11070 if (!mRecentTasks.isEmpty()) { 11071 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11072 } 11073 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11074 mTaskPersister.startPersisting(); 11075 } 11076 11077 // Check to see if there are any update receivers to run. 11078 if (!mDidUpdate) { 11079 if (mWaitingUpdate) { 11080 return; 11081 } 11082 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11083 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11084 public void run() { 11085 synchronized (ActivityManagerService.this) { 11086 mDidUpdate = true; 11087 } 11088 writeLastDonePreBootReceivers(doneReceivers); 11089 showBootMessage(mContext.getText( 11090 R.string.android_upgrading_complete), 11091 false); 11092 systemReady(goingCallback); 11093 } 11094 }, doneReceivers, UserHandle.USER_OWNER); 11095 11096 if (mWaitingUpdate) { 11097 return; 11098 } 11099 mDidUpdate = true; 11100 } 11101 11102 mAppOpsService.systemReady(); 11103 mSystemReady = true; 11104 } 11105 11106 ArrayList<ProcessRecord> procsToKill = null; 11107 synchronized(mPidsSelfLocked) { 11108 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11109 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11110 if (!isAllowedWhileBooting(proc.info)){ 11111 if (procsToKill == null) { 11112 procsToKill = new ArrayList<ProcessRecord>(); 11113 } 11114 procsToKill.add(proc); 11115 } 11116 } 11117 } 11118 11119 synchronized(this) { 11120 if (procsToKill != null) { 11121 for (int i=procsToKill.size()-1; i>=0; i--) { 11122 ProcessRecord proc = procsToKill.get(i); 11123 Slog.i(TAG, "Removing system update proc: " + proc); 11124 removeProcessLocked(proc, true, false, "system update done"); 11125 } 11126 } 11127 11128 // Now that we have cleaned up any update processes, we 11129 // are ready to start launching real processes and know that 11130 // we won't trample on them any more. 11131 mProcessesReady = true; 11132 } 11133 11134 Slog.i(TAG, "System now ready"); 11135 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11136 SystemClock.uptimeMillis()); 11137 11138 synchronized(this) { 11139 // Make sure we have no pre-ready processes sitting around. 11140 11141 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11142 ResolveInfo ri = mContext.getPackageManager() 11143 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11144 STOCK_PM_FLAGS); 11145 CharSequence errorMsg = null; 11146 if (ri != null) { 11147 ActivityInfo ai = ri.activityInfo; 11148 ApplicationInfo app = ai.applicationInfo; 11149 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11150 mTopAction = Intent.ACTION_FACTORY_TEST; 11151 mTopData = null; 11152 mTopComponent = new ComponentName(app.packageName, 11153 ai.name); 11154 } else { 11155 errorMsg = mContext.getResources().getText( 11156 com.android.internal.R.string.factorytest_not_system); 11157 } 11158 } else { 11159 errorMsg = mContext.getResources().getText( 11160 com.android.internal.R.string.factorytest_no_action); 11161 } 11162 if (errorMsg != null) { 11163 mTopAction = null; 11164 mTopData = null; 11165 mTopComponent = null; 11166 Message msg = Message.obtain(); 11167 msg.what = SHOW_FACTORY_ERROR_MSG; 11168 msg.getData().putCharSequence("msg", errorMsg); 11169 mHandler.sendMessage(msg); 11170 } 11171 } 11172 } 11173 11174 retrieveSettings(); 11175 loadResourcesOnSystemReady(); 11176 11177 synchronized (this) { 11178 readGrantedUriPermissionsLocked(); 11179 } 11180 11181 if (goingCallback != null) goingCallback.run(); 11182 11183 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11184 Integer.toString(mCurrentUserId), mCurrentUserId); 11185 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11186 Integer.toString(mCurrentUserId), mCurrentUserId); 11187 mSystemServiceManager.startUser(mCurrentUserId); 11188 11189 synchronized (this) { 11190 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11191 try { 11192 List apps = AppGlobals.getPackageManager(). 11193 getPersistentApplications(STOCK_PM_FLAGS); 11194 if (apps != null) { 11195 int N = apps.size(); 11196 int i; 11197 for (i=0; i<N; i++) { 11198 ApplicationInfo info 11199 = (ApplicationInfo)apps.get(i); 11200 if (info != null && 11201 !info.packageName.equals("android")) { 11202 addAppLocked(info, false, null /* ABI override */); 11203 } 11204 } 11205 } 11206 } catch (RemoteException ex) { 11207 // pm is in same process, this will never happen. 11208 } 11209 } 11210 11211 // Start up initial activity. 11212 mBooting = true; 11213 startHomeActivityLocked(mCurrentUserId); 11214 11215 try { 11216 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11217 Message msg = Message.obtain(); 11218 msg.what = SHOW_UID_ERROR_MSG; 11219 mHandler.sendMessage(msg); 11220 } 11221 } catch (RemoteException e) { 11222 } 11223 11224 long ident = Binder.clearCallingIdentity(); 11225 try { 11226 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11227 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11228 | Intent.FLAG_RECEIVER_FOREGROUND); 11229 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11230 broadcastIntentLocked(null, null, intent, 11231 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11232 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11233 intent = new Intent(Intent.ACTION_USER_STARTING); 11234 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11235 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11236 broadcastIntentLocked(null, null, intent, 11237 null, new IIntentReceiver.Stub() { 11238 @Override 11239 public void performReceive(Intent intent, int resultCode, String data, 11240 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11241 throws RemoteException { 11242 } 11243 }, 0, null, null, 11244 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11245 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11246 } catch (Throwable t) { 11247 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11248 } finally { 11249 Binder.restoreCallingIdentity(ident); 11250 } 11251 mStackSupervisor.resumeTopActivitiesLocked(); 11252 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11253 } 11254 } 11255 11256 private boolean makeAppCrashingLocked(ProcessRecord app, 11257 String shortMsg, String longMsg, String stackTrace) { 11258 app.crashing = true; 11259 app.crashingReport = generateProcessError(app, 11260 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11261 startAppProblemLocked(app); 11262 app.stopFreezingAllLocked(); 11263 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11264 } 11265 11266 private void makeAppNotRespondingLocked(ProcessRecord app, 11267 String activity, String shortMsg, String longMsg) { 11268 app.notResponding = true; 11269 app.notRespondingReport = generateProcessError(app, 11270 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11271 activity, shortMsg, longMsg, null); 11272 startAppProblemLocked(app); 11273 app.stopFreezingAllLocked(); 11274 } 11275 11276 /** 11277 * Generate a process error record, suitable for attachment to a ProcessRecord. 11278 * 11279 * @param app The ProcessRecord in which the error occurred. 11280 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11281 * ActivityManager.AppErrorStateInfo 11282 * @param activity The activity associated with the crash, if known. 11283 * @param shortMsg Short message describing the crash. 11284 * @param longMsg Long message describing the crash. 11285 * @param stackTrace Full crash stack trace, may be null. 11286 * 11287 * @return Returns a fully-formed AppErrorStateInfo record. 11288 */ 11289 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11290 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11291 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11292 11293 report.condition = condition; 11294 report.processName = app.processName; 11295 report.pid = app.pid; 11296 report.uid = app.info.uid; 11297 report.tag = activity; 11298 report.shortMsg = shortMsg; 11299 report.longMsg = longMsg; 11300 report.stackTrace = stackTrace; 11301 11302 return report; 11303 } 11304 11305 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11306 synchronized (this) { 11307 app.crashing = false; 11308 app.crashingReport = null; 11309 app.notResponding = false; 11310 app.notRespondingReport = null; 11311 if (app.anrDialog == fromDialog) { 11312 app.anrDialog = null; 11313 } 11314 if (app.waitDialog == fromDialog) { 11315 app.waitDialog = null; 11316 } 11317 if (app.pid > 0 && app.pid != MY_PID) { 11318 handleAppCrashLocked(app, null, null, null); 11319 app.kill("user request after error", true); 11320 } 11321 } 11322 } 11323 11324 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11325 String stackTrace) { 11326 long now = SystemClock.uptimeMillis(); 11327 11328 Long crashTime; 11329 if (!app.isolated) { 11330 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11331 } else { 11332 crashTime = null; 11333 } 11334 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11335 // This process loses! 11336 Slog.w(TAG, "Process " + app.info.processName 11337 + " has crashed too many times: killing!"); 11338 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11339 app.userId, app.info.processName, app.uid); 11340 mStackSupervisor.handleAppCrashLocked(app); 11341 if (!app.persistent) { 11342 // We don't want to start this process again until the user 11343 // explicitly does so... but for persistent process, we really 11344 // need to keep it running. If a persistent process is actually 11345 // repeatedly crashing, then badness for everyone. 11346 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11347 app.info.processName); 11348 if (!app.isolated) { 11349 // XXX We don't have a way to mark isolated processes 11350 // as bad, since they don't have a peristent identity. 11351 mBadProcesses.put(app.info.processName, app.uid, 11352 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11353 mProcessCrashTimes.remove(app.info.processName, app.uid); 11354 } 11355 app.bad = true; 11356 app.removed = true; 11357 // Don't let services in this process be restarted and potentially 11358 // annoy the user repeatedly. Unless it is persistent, since those 11359 // processes run critical code. 11360 removeProcessLocked(app, false, false, "crash"); 11361 mStackSupervisor.resumeTopActivitiesLocked(); 11362 return false; 11363 } 11364 mStackSupervisor.resumeTopActivitiesLocked(); 11365 } else { 11366 mStackSupervisor.finishTopRunningActivityLocked(app); 11367 } 11368 11369 // Bump up the crash count of any services currently running in the proc. 11370 for (int i=app.services.size()-1; i>=0; i--) { 11371 // Any services running in the application need to be placed 11372 // back in the pending list. 11373 ServiceRecord sr = app.services.valueAt(i); 11374 sr.crashCount++; 11375 } 11376 11377 // If the crashing process is what we consider to be the "home process" and it has been 11378 // replaced by a third-party app, clear the package preferred activities from packages 11379 // with a home activity running in the process to prevent a repeatedly crashing app 11380 // from blocking the user to manually clear the list. 11381 final ArrayList<ActivityRecord> activities = app.activities; 11382 if (app == mHomeProcess && activities.size() > 0 11383 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11384 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11385 final ActivityRecord r = activities.get(activityNdx); 11386 if (r.isHomeActivity()) { 11387 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11388 try { 11389 ActivityThread.getPackageManager() 11390 .clearPackagePreferredActivities(r.packageName); 11391 } catch (RemoteException c) { 11392 // pm is in same process, this will never happen. 11393 } 11394 } 11395 } 11396 } 11397 11398 if (!app.isolated) { 11399 // XXX Can't keep track of crash times for isolated processes, 11400 // because they don't have a perisistent identity. 11401 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11402 } 11403 11404 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11405 return true; 11406 } 11407 11408 void startAppProblemLocked(ProcessRecord app) { 11409 // If this app is not running under the current user, then we 11410 // can't give it a report button because that would require 11411 // launching the report UI under a different user. 11412 app.errorReportReceiver = null; 11413 11414 for (int userId : mCurrentProfileIds) { 11415 if (app.userId == userId) { 11416 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11417 mContext, app.info.packageName, app.info.flags); 11418 } 11419 } 11420 skipCurrentReceiverLocked(app); 11421 } 11422 11423 void skipCurrentReceiverLocked(ProcessRecord app) { 11424 for (BroadcastQueue queue : mBroadcastQueues) { 11425 queue.skipCurrentReceiverLocked(app); 11426 } 11427 } 11428 11429 /** 11430 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11431 * The application process will exit immediately after this call returns. 11432 * @param app object of the crashing app, null for the system server 11433 * @param crashInfo describing the exception 11434 */ 11435 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11436 ProcessRecord r = findAppProcess(app, "Crash"); 11437 final String processName = app == null ? "system_server" 11438 : (r == null ? "unknown" : r.processName); 11439 11440 handleApplicationCrashInner("crash", r, processName, crashInfo); 11441 } 11442 11443 /* Native crash reporting uses this inner version because it needs to be somewhat 11444 * decoupled from the AM-managed cleanup lifecycle 11445 */ 11446 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11447 ApplicationErrorReport.CrashInfo crashInfo) { 11448 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11449 UserHandle.getUserId(Binder.getCallingUid()), processName, 11450 r == null ? -1 : r.info.flags, 11451 crashInfo.exceptionClassName, 11452 crashInfo.exceptionMessage, 11453 crashInfo.throwFileName, 11454 crashInfo.throwLineNumber); 11455 11456 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11457 11458 crashApplication(r, crashInfo); 11459 } 11460 11461 public void handleApplicationStrictModeViolation( 11462 IBinder app, 11463 int violationMask, 11464 StrictMode.ViolationInfo info) { 11465 ProcessRecord r = findAppProcess(app, "StrictMode"); 11466 if (r == null) { 11467 return; 11468 } 11469 11470 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11471 Integer stackFingerprint = info.hashCode(); 11472 boolean logIt = true; 11473 synchronized (mAlreadyLoggedViolatedStacks) { 11474 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11475 logIt = false; 11476 // TODO: sub-sample into EventLog for these, with 11477 // the info.durationMillis? Then we'd get 11478 // the relative pain numbers, without logging all 11479 // the stack traces repeatedly. We'd want to do 11480 // likewise in the client code, which also does 11481 // dup suppression, before the Binder call. 11482 } else { 11483 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11484 mAlreadyLoggedViolatedStacks.clear(); 11485 } 11486 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11487 } 11488 } 11489 if (logIt) { 11490 logStrictModeViolationToDropBox(r, info); 11491 } 11492 } 11493 11494 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11495 AppErrorResult result = new AppErrorResult(); 11496 synchronized (this) { 11497 final long origId = Binder.clearCallingIdentity(); 11498 11499 Message msg = Message.obtain(); 11500 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11501 HashMap<String, Object> data = new HashMap<String, Object>(); 11502 data.put("result", result); 11503 data.put("app", r); 11504 data.put("violationMask", violationMask); 11505 data.put("info", info); 11506 msg.obj = data; 11507 mHandler.sendMessage(msg); 11508 11509 Binder.restoreCallingIdentity(origId); 11510 } 11511 int res = result.get(); 11512 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11513 } 11514 } 11515 11516 // Depending on the policy in effect, there could be a bunch of 11517 // these in quick succession so we try to batch these together to 11518 // minimize disk writes, number of dropbox entries, and maximize 11519 // compression, by having more fewer, larger records. 11520 private void logStrictModeViolationToDropBox( 11521 ProcessRecord process, 11522 StrictMode.ViolationInfo info) { 11523 if (info == null) { 11524 return; 11525 } 11526 final boolean isSystemApp = process == null || 11527 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11528 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11529 final String processName = process == null ? "unknown" : process.processName; 11530 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11531 final DropBoxManager dbox = (DropBoxManager) 11532 mContext.getSystemService(Context.DROPBOX_SERVICE); 11533 11534 // Exit early if the dropbox isn't configured to accept this report type. 11535 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11536 11537 boolean bufferWasEmpty; 11538 boolean needsFlush; 11539 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11540 synchronized (sb) { 11541 bufferWasEmpty = sb.length() == 0; 11542 appendDropBoxProcessHeaders(process, processName, sb); 11543 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11544 sb.append("System-App: ").append(isSystemApp).append("\n"); 11545 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11546 if (info.violationNumThisLoop != 0) { 11547 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11548 } 11549 if (info.numAnimationsRunning != 0) { 11550 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11551 } 11552 if (info.broadcastIntentAction != null) { 11553 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11554 } 11555 if (info.durationMillis != -1) { 11556 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11557 } 11558 if (info.numInstances != -1) { 11559 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11560 } 11561 if (info.tags != null) { 11562 for (String tag : info.tags) { 11563 sb.append("Span-Tag: ").append(tag).append("\n"); 11564 } 11565 } 11566 sb.append("\n"); 11567 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11568 sb.append(info.crashInfo.stackTrace); 11569 } 11570 sb.append("\n"); 11571 11572 // Only buffer up to ~64k. Various logging bits truncate 11573 // things at 128k. 11574 needsFlush = (sb.length() > 64 * 1024); 11575 } 11576 11577 // Flush immediately if the buffer's grown too large, or this 11578 // is a non-system app. Non-system apps are isolated with a 11579 // different tag & policy and not batched. 11580 // 11581 // Batching is useful during internal testing with 11582 // StrictMode settings turned up high. Without batching, 11583 // thousands of separate files could be created on boot. 11584 if (!isSystemApp || needsFlush) { 11585 new Thread("Error dump: " + dropboxTag) { 11586 @Override 11587 public void run() { 11588 String report; 11589 synchronized (sb) { 11590 report = sb.toString(); 11591 sb.delete(0, sb.length()); 11592 sb.trimToSize(); 11593 } 11594 if (report.length() != 0) { 11595 dbox.addText(dropboxTag, report); 11596 } 11597 } 11598 }.start(); 11599 return; 11600 } 11601 11602 // System app batching: 11603 if (!bufferWasEmpty) { 11604 // An existing dropbox-writing thread is outstanding, so 11605 // we don't need to start it up. The existing thread will 11606 // catch the buffer appends we just did. 11607 return; 11608 } 11609 11610 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11611 // (After this point, we shouldn't access AMS internal data structures.) 11612 new Thread("Error dump: " + dropboxTag) { 11613 @Override 11614 public void run() { 11615 // 5 second sleep to let stacks arrive and be batched together 11616 try { 11617 Thread.sleep(5000); // 5 seconds 11618 } catch (InterruptedException e) {} 11619 11620 String errorReport; 11621 synchronized (mStrictModeBuffer) { 11622 errorReport = mStrictModeBuffer.toString(); 11623 if (errorReport.length() == 0) { 11624 return; 11625 } 11626 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11627 mStrictModeBuffer.trimToSize(); 11628 } 11629 dbox.addText(dropboxTag, errorReport); 11630 } 11631 }.start(); 11632 } 11633 11634 /** 11635 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11636 * @param app object of the crashing app, null for the system server 11637 * @param tag reported by the caller 11638 * @param system whether this wtf is coming from the system 11639 * @param crashInfo describing the context of the error 11640 * @return true if the process should exit immediately (WTF is fatal) 11641 */ 11642 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11643 final ApplicationErrorReport.CrashInfo crashInfo) { 11644 final int callingUid = Binder.getCallingUid(); 11645 final int callingPid = Binder.getCallingPid(); 11646 11647 if (system) { 11648 // If this is coming from the system, we could very well have low-level 11649 // system locks held, so we want to do this all asynchronously. And we 11650 // never want this to become fatal, so there is that too. 11651 mHandler.post(new Runnable() { 11652 @Override public void run() { 11653 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11654 } 11655 }); 11656 return false; 11657 } 11658 11659 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11660 crashInfo); 11661 11662 if (r != null && r.pid != Process.myPid() && 11663 Settings.Global.getInt(mContext.getContentResolver(), 11664 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11665 crashApplication(r, crashInfo); 11666 return true; 11667 } else { 11668 return false; 11669 } 11670 } 11671 11672 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11673 final ApplicationErrorReport.CrashInfo crashInfo) { 11674 final ProcessRecord r = findAppProcess(app, "WTF"); 11675 final String processName = app == null ? "system_server" 11676 : (r == null ? "unknown" : r.processName); 11677 11678 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11679 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11680 11681 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11682 11683 return r; 11684 } 11685 11686 /** 11687 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11688 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11689 */ 11690 private ProcessRecord findAppProcess(IBinder app, String reason) { 11691 if (app == null) { 11692 return null; 11693 } 11694 11695 synchronized (this) { 11696 final int NP = mProcessNames.getMap().size(); 11697 for (int ip=0; ip<NP; ip++) { 11698 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11699 final int NA = apps.size(); 11700 for (int ia=0; ia<NA; ia++) { 11701 ProcessRecord p = apps.valueAt(ia); 11702 if (p.thread != null && p.thread.asBinder() == app) { 11703 return p; 11704 } 11705 } 11706 } 11707 11708 Slog.w(TAG, "Can't find mystery application for " + reason 11709 + " from pid=" + Binder.getCallingPid() 11710 + " uid=" + Binder.getCallingUid() + ": " + app); 11711 return null; 11712 } 11713 } 11714 11715 /** 11716 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11717 * to append various headers to the dropbox log text. 11718 */ 11719 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11720 StringBuilder sb) { 11721 // Watchdog thread ends up invoking this function (with 11722 // a null ProcessRecord) to add the stack file to dropbox. 11723 // Do not acquire a lock on this (am) in such cases, as it 11724 // could cause a potential deadlock, if and when watchdog 11725 // is invoked due to unavailability of lock on am and it 11726 // would prevent watchdog from killing system_server. 11727 if (process == null) { 11728 sb.append("Process: ").append(processName).append("\n"); 11729 return; 11730 } 11731 // Note: ProcessRecord 'process' is guarded by the service 11732 // instance. (notably process.pkgList, which could otherwise change 11733 // concurrently during execution of this method) 11734 synchronized (this) { 11735 sb.append("Process: ").append(processName).append("\n"); 11736 int flags = process.info.flags; 11737 IPackageManager pm = AppGlobals.getPackageManager(); 11738 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11739 for (int ip=0; ip<process.pkgList.size(); ip++) { 11740 String pkg = process.pkgList.keyAt(ip); 11741 sb.append("Package: ").append(pkg); 11742 try { 11743 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11744 if (pi != null) { 11745 sb.append(" v").append(pi.versionCode); 11746 if (pi.versionName != null) { 11747 sb.append(" (").append(pi.versionName).append(")"); 11748 } 11749 } 11750 } catch (RemoteException e) { 11751 Slog.e(TAG, "Error getting package info: " + pkg, e); 11752 } 11753 sb.append("\n"); 11754 } 11755 } 11756 } 11757 11758 private static String processClass(ProcessRecord process) { 11759 if (process == null || process.pid == MY_PID) { 11760 return "system_server"; 11761 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11762 return "system_app"; 11763 } else { 11764 return "data_app"; 11765 } 11766 } 11767 11768 /** 11769 * Write a description of an error (crash, WTF, ANR) to the drop box. 11770 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11771 * @param process which caused the error, null means the system server 11772 * @param activity which triggered the error, null if unknown 11773 * @param parent activity related to the error, null if unknown 11774 * @param subject line related to the error, null if absent 11775 * @param report in long form describing the error, null if absent 11776 * @param logFile to include in the report, null if none 11777 * @param crashInfo giving an application stack trace, null if absent 11778 */ 11779 public void addErrorToDropBox(String eventType, 11780 ProcessRecord process, String processName, ActivityRecord activity, 11781 ActivityRecord parent, String subject, 11782 final String report, final File logFile, 11783 final ApplicationErrorReport.CrashInfo crashInfo) { 11784 // NOTE -- this must never acquire the ActivityManagerService lock, 11785 // otherwise the watchdog may be prevented from resetting the system. 11786 11787 final String dropboxTag = processClass(process) + "_" + eventType; 11788 final DropBoxManager dbox = (DropBoxManager) 11789 mContext.getSystemService(Context.DROPBOX_SERVICE); 11790 11791 // Exit early if the dropbox isn't configured to accept this report type. 11792 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11793 11794 final StringBuilder sb = new StringBuilder(1024); 11795 appendDropBoxProcessHeaders(process, processName, sb); 11796 if (activity != null) { 11797 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11798 } 11799 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11800 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11801 } 11802 if (parent != null && parent != activity) { 11803 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11804 } 11805 if (subject != null) { 11806 sb.append("Subject: ").append(subject).append("\n"); 11807 } 11808 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11809 if (Debug.isDebuggerConnected()) { 11810 sb.append("Debugger: Connected\n"); 11811 } 11812 sb.append("\n"); 11813 11814 // Do the rest in a worker thread to avoid blocking the caller on I/O 11815 // (After this point, we shouldn't access AMS internal data structures.) 11816 Thread worker = new Thread("Error dump: " + dropboxTag) { 11817 @Override 11818 public void run() { 11819 if (report != null) { 11820 sb.append(report); 11821 } 11822 if (logFile != null) { 11823 try { 11824 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11825 "\n\n[[TRUNCATED]]")); 11826 } catch (IOException e) { 11827 Slog.e(TAG, "Error reading " + logFile, e); 11828 } 11829 } 11830 if (crashInfo != null && crashInfo.stackTrace != null) { 11831 sb.append(crashInfo.stackTrace); 11832 } 11833 11834 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11835 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11836 if (lines > 0) { 11837 sb.append("\n"); 11838 11839 // Merge several logcat streams, and take the last N lines 11840 InputStreamReader input = null; 11841 try { 11842 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11843 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11844 "-b", "crash", 11845 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11846 11847 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11848 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11849 input = new InputStreamReader(logcat.getInputStream()); 11850 11851 int num; 11852 char[] buf = new char[8192]; 11853 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11854 } catch (IOException e) { 11855 Slog.e(TAG, "Error running logcat", e); 11856 } finally { 11857 if (input != null) try { input.close(); } catch (IOException e) {} 11858 } 11859 } 11860 11861 dbox.addText(dropboxTag, sb.toString()); 11862 } 11863 }; 11864 11865 if (process == null) { 11866 // If process is null, we are being called from some internal code 11867 // and may be about to die -- run this synchronously. 11868 worker.run(); 11869 } else { 11870 worker.start(); 11871 } 11872 } 11873 11874 /** 11875 * Bring up the "unexpected error" dialog box for a crashing app. 11876 * Deal with edge cases (intercepts from instrumented applications, 11877 * ActivityController, error intent receivers, that sort of thing). 11878 * @param r the application crashing 11879 * @param crashInfo describing the failure 11880 */ 11881 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11882 long timeMillis = System.currentTimeMillis(); 11883 String shortMsg = crashInfo.exceptionClassName; 11884 String longMsg = crashInfo.exceptionMessage; 11885 String stackTrace = crashInfo.stackTrace; 11886 if (shortMsg != null && longMsg != null) { 11887 longMsg = shortMsg + ": " + longMsg; 11888 } else if (shortMsg != null) { 11889 longMsg = shortMsg; 11890 } 11891 11892 AppErrorResult result = new AppErrorResult(); 11893 synchronized (this) { 11894 if (mController != null) { 11895 try { 11896 String name = r != null ? r.processName : null; 11897 int pid = r != null ? r.pid : Binder.getCallingPid(); 11898 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11899 if (!mController.appCrashed(name, pid, 11900 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11901 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11902 && "Native crash".equals(crashInfo.exceptionClassName)) { 11903 Slog.w(TAG, "Skip killing native crashed app " + name 11904 + "(" + pid + ") during testing"); 11905 } else { 11906 Slog.w(TAG, "Force-killing crashed app " + name 11907 + " at watcher's request"); 11908 if (r != null) { 11909 r.kill("crash", true); 11910 } else { 11911 // Huh. 11912 Process.killProcess(pid); 11913 Process.killProcessGroup(uid, pid); 11914 } 11915 } 11916 return; 11917 } 11918 } catch (RemoteException e) { 11919 mController = null; 11920 Watchdog.getInstance().setActivityController(null); 11921 } 11922 } 11923 11924 final long origId = Binder.clearCallingIdentity(); 11925 11926 // If this process is running instrumentation, finish it. 11927 if (r != null && r.instrumentationClass != null) { 11928 Slog.w(TAG, "Error in app " + r.processName 11929 + " running instrumentation " + r.instrumentationClass + ":"); 11930 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11931 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11932 Bundle info = new Bundle(); 11933 info.putString("shortMsg", shortMsg); 11934 info.putString("longMsg", longMsg); 11935 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11936 Binder.restoreCallingIdentity(origId); 11937 return; 11938 } 11939 11940 // If we can't identify the process or it's already exceeded its crash quota, 11941 // quit right away without showing a crash dialog. 11942 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11943 Binder.restoreCallingIdentity(origId); 11944 return; 11945 } 11946 11947 Message msg = Message.obtain(); 11948 msg.what = SHOW_ERROR_MSG; 11949 HashMap data = new HashMap(); 11950 data.put("result", result); 11951 data.put("app", r); 11952 msg.obj = data; 11953 mHandler.sendMessage(msg); 11954 11955 Binder.restoreCallingIdentity(origId); 11956 } 11957 11958 int res = result.get(); 11959 11960 Intent appErrorIntent = null; 11961 synchronized (this) { 11962 if (r != null && !r.isolated) { 11963 // XXX Can't keep track of crash time for isolated processes, 11964 // since they don't have a persistent identity. 11965 mProcessCrashTimes.put(r.info.processName, r.uid, 11966 SystemClock.uptimeMillis()); 11967 } 11968 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11969 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11970 } 11971 } 11972 11973 if (appErrorIntent != null) { 11974 try { 11975 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11976 } catch (ActivityNotFoundException e) { 11977 Slog.w(TAG, "bug report receiver dissappeared", e); 11978 } 11979 } 11980 } 11981 11982 Intent createAppErrorIntentLocked(ProcessRecord r, 11983 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11984 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11985 if (report == null) { 11986 return null; 11987 } 11988 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11989 result.setComponent(r.errorReportReceiver); 11990 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11991 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11992 return result; 11993 } 11994 11995 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11996 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11997 if (r.errorReportReceiver == null) { 11998 return null; 11999 } 12000 12001 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12002 return null; 12003 } 12004 12005 ApplicationErrorReport report = new ApplicationErrorReport(); 12006 report.packageName = r.info.packageName; 12007 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12008 report.processName = r.processName; 12009 report.time = timeMillis; 12010 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12011 12012 if (r.crashing || r.forceCrashReport) { 12013 report.type = ApplicationErrorReport.TYPE_CRASH; 12014 report.crashInfo = crashInfo; 12015 } else if (r.notResponding) { 12016 report.type = ApplicationErrorReport.TYPE_ANR; 12017 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12018 12019 report.anrInfo.activity = r.notRespondingReport.tag; 12020 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12021 report.anrInfo.info = r.notRespondingReport.longMsg; 12022 } 12023 12024 return report; 12025 } 12026 12027 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12028 enforceNotIsolatedCaller("getProcessesInErrorState"); 12029 // assume our apps are happy - lazy create the list 12030 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12031 12032 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12033 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12034 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12035 12036 synchronized (this) { 12037 12038 // iterate across all processes 12039 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12040 ProcessRecord app = mLruProcesses.get(i); 12041 if (!allUsers && app.userId != userId) { 12042 continue; 12043 } 12044 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12045 // This one's in trouble, so we'll generate a report for it 12046 // crashes are higher priority (in case there's a crash *and* an anr) 12047 ActivityManager.ProcessErrorStateInfo report = null; 12048 if (app.crashing) { 12049 report = app.crashingReport; 12050 } else if (app.notResponding) { 12051 report = app.notRespondingReport; 12052 } 12053 12054 if (report != null) { 12055 if (errList == null) { 12056 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12057 } 12058 errList.add(report); 12059 } else { 12060 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12061 " crashing = " + app.crashing + 12062 " notResponding = " + app.notResponding); 12063 } 12064 } 12065 } 12066 } 12067 12068 return errList; 12069 } 12070 12071 static int procStateToImportance(int procState, int memAdj, 12072 ActivityManager.RunningAppProcessInfo currApp) { 12073 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12074 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12075 currApp.lru = memAdj; 12076 } else { 12077 currApp.lru = 0; 12078 } 12079 return imp; 12080 } 12081 12082 private void fillInProcMemInfo(ProcessRecord app, 12083 ActivityManager.RunningAppProcessInfo outInfo) { 12084 outInfo.pid = app.pid; 12085 outInfo.uid = app.info.uid; 12086 if (mHeavyWeightProcess == app) { 12087 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12088 } 12089 if (app.persistent) { 12090 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12091 } 12092 if (app.activities.size() > 0) { 12093 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12094 } 12095 outInfo.lastTrimLevel = app.trimMemoryLevel; 12096 int adj = app.curAdj; 12097 int procState = app.curProcState; 12098 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12099 outInfo.importanceReasonCode = app.adjTypeCode; 12100 outInfo.processState = app.curProcState; 12101 } 12102 12103 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12104 enforceNotIsolatedCaller("getRunningAppProcesses"); 12105 // Lazy instantiation of list 12106 List<ActivityManager.RunningAppProcessInfo> runList = null; 12107 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12108 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12109 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12110 synchronized (this) { 12111 // Iterate across all processes 12112 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12113 ProcessRecord app = mLruProcesses.get(i); 12114 if (!allUsers && app.userId != userId) { 12115 continue; 12116 } 12117 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12118 // Generate process state info for running application 12119 ActivityManager.RunningAppProcessInfo currApp = 12120 new ActivityManager.RunningAppProcessInfo(app.processName, 12121 app.pid, app.getPackageList()); 12122 fillInProcMemInfo(app, currApp); 12123 if (app.adjSource instanceof ProcessRecord) { 12124 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12125 currApp.importanceReasonImportance = 12126 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12127 app.adjSourceProcState); 12128 } else if (app.adjSource instanceof ActivityRecord) { 12129 ActivityRecord r = (ActivityRecord)app.adjSource; 12130 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12131 } 12132 if (app.adjTarget instanceof ComponentName) { 12133 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12134 } 12135 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12136 // + " lru=" + currApp.lru); 12137 if (runList == null) { 12138 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12139 } 12140 runList.add(currApp); 12141 } 12142 } 12143 } 12144 return runList; 12145 } 12146 12147 public List<ApplicationInfo> getRunningExternalApplications() { 12148 enforceNotIsolatedCaller("getRunningExternalApplications"); 12149 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12150 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12151 if (runningApps != null && runningApps.size() > 0) { 12152 Set<String> extList = new HashSet<String>(); 12153 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12154 if (app.pkgList != null) { 12155 for (String pkg : app.pkgList) { 12156 extList.add(pkg); 12157 } 12158 } 12159 } 12160 IPackageManager pm = AppGlobals.getPackageManager(); 12161 for (String pkg : extList) { 12162 try { 12163 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12164 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12165 retList.add(info); 12166 } 12167 } catch (RemoteException e) { 12168 } 12169 } 12170 } 12171 return retList; 12172 } 12173 12174 @Override 12175 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12176 enforceNotIsolatedCaller("getMyMemoryState"); 12177 synchronized (this) { 12178 ProcessRecord proc; 12179 synchronized (mPidsSelfLocked) { 12180 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12181 } 12182 fillInProcMemInfo(proc, outInfo); 12183 } 12184 } 12185 12186 @Override 12187 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12188 if (checkCallingPermission(android.Manifest.permission.DUMP) 12189 != PackageManager.PERMISSION_GRANTED) { 12190 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12191 + Binder.getCallingPid() 12192 + ", uid=" + Binder.getCallingUid() 12193 + " without permission " 12194 + android.Manifest.permission.DUMP); 12195 return; 12196 } 12197 12198 boolean dumpAll = false; 12199 boolean dumpClient = false; 12200 String dumpPackage = null; 12201 12202 int opti = 0; 12203 while (opti < args.length) { 12204 String opt = args[opti]; 12205 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12206 break; 12207 } 12208 opti++; 12209 if ("-a".equals(opt)) { 12210 dumpAll = true; 12211 } else if ("-c".equals(opt)) { 12212 dumpClient = true; 12213 } else if ("-h".equals(opt)) { 12214 pw.println("Activity manager dump options:"); 12215 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12216 pw.println(" cmd may be one of:"); 12217 pw.println(" a[ctivities]: activity stack state"); 12218 pw.println(" r[recents]: recent activities state"); 12219 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12220 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12221 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12222 pw.println(" o[om]: out of memory management"); 12223 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12224 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12225 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12226 pw.println(" service [COMP_SPEC]: service client-side state"); 12227 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12228 pw.println(" all: dump all activities"); 12229 pw.println(" top: dump the top activity"); 12230 pw.println(" write: write all pending state to storage"); 12231 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12232 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12233 pw.println(" a partial substring in a component name, a"); 12234 pw.println(" hex object identifier."); 12235 pw.println(" -a: include all available server state."); 12236 pw.println(" -c: include client state."); 12237 return; 12238 } else { 12239 pw.println("Unknown argument: " + opt + "; use -h for help"); 12240 } 12241 } 12242 12243 long origId = Binder.clearCallingIdentity(); 12244 boolean more = false; 12245 // Is the caller requesting to dump a particular piece of data? 12246 if (opti < args.length) { 12247 String cmd = args[opti]; 12248 opti++; 12249 if ("activities".equals(cmd) || "a".equals(cmd)) { 12250 synchronized (this) { 12251 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12252 } 12253 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12254 synchronized (this) { 12255 dumpRecentsLocked(fd, pw, args, opti, true, null); 12256 } 12257 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12258 String[] newArgs; 12259 String name; 12260 if (opti >= args.length) { 12261 name = null; 12262 newArgs = EMPTY_STRING_ARRAY; 12263 } else { 12264 name = args[opti]; 12265 opti++; 12266 newArgs = new String[args.length - opti]; 12267 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12268 args.length - opti); 12269 } 12270 synchronized (this) { 12271 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12272 } 12273 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12274 String[] newArgs; 12275 String name; 12276 if (opti >= args.length) { 12277 name = null; 12278 newArgs = EMPTY_STRING_ARRAY; 12279 } else { 12280 name = args[opti]; 12281 opti++; 12282 newArgs = new String[args.length - opti]; 12283 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12284 args.length - opti); 12285 } 12286 synchronized (this) { 12287 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12288 } 12289 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12290 String[] newArgs; 12291 String name; 12292 if (opti >= args.length) { 12293 name = null; 12294 newArgs = EMPTY_STRING_ARRAY; 12295 } else { 12296 name = args[opti]; 12297 opti++; 12298 newArgs = new String[args.length - opti]; 12299 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12300 args.length - opti); 12301 } 12302 synchronized (this) { 12303 dumpProcessesLocked(fd, pw, args, opti, true, name); 12304 } 12305 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12306 synchronized (this) { 12307 dumpOomLocked(fd, pw, args, opti, true); 12308 } 12309 } else if ("provider".equals(cmd)) { 12310 String[] newArgs; 12311 String name; 12312 if (opti >= args.length) { 12313 name = null; 12314 newArgs = EMPTY_STRING_ARRAY; 12315 } else { 12316 name = args[opti]; 12317 opti++; 12318 newArgs = new String[args.length - opti]; 12319 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12320 } 12321 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12322 pw.println("No providers match: " + name); 12323 pw.println("Use -h for help."); 12324 } 12325 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12326 synchronized (this) { 12327 dumpProvidersLocked(fd, pw, args, opti, true, null); 12328 } 12329 } else if ("service".equals(cmd)) { 12330 String[] newArgs; 12331 String name; 12332 if (opti >= args.length) { 12333 name = null; 12334 newArgs = EMPTY_STRING_ARRAY; 12335 } else { 12336 name = args[opti]; 12337 opti++; 12338 newArgs = new String[args.length - opti]; 12339 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12340 args.length - opti); 12341 } 12342 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12343 pw.println("No services match: " + name); 12344 pw.println("Use -h for help."); 12345 } 12346 } else if ("package".equals(cmd)) { 12347 String[] newArgs; 12348 if (opti >= args.length) { 12349 pw.println("package: no package name specified"); 12350 pw.println("Use -h for help."); 12351 } else { 12352 dumpPackage = args[opti]; 12353 opti++; 12354 newArgs = new String[args.length - opti]; 12355 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12356 args.length - opti); 12357 args = newArgs; 12358 opti = 0; 12359 more = true; 12360 } 12361 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12362 synchronized (this) { 12363 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12364 } 12365 } else if ("write".equals(cmd)) { 12366 mTaskPersister.flush(); 12367 pw.println("All tasks persisted."); 12368 return; 12369 } else { 12370 // Dumping a single activity? 12371 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12372 pw.println("Bad activity command, or no activities match: " + cmd); 12373 pw.println("Use -h for help."); 12374 } 12375 } 12376 if (!more) { 12377 Binder.restoreCallingIdentity(origId); 12378 return; 12379 } 12380 } 12381 12382 // No piece of data specified, dump everything. 12383 synchronized (this) { 12384 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12385 pw.println(); 12386 if (dumpAll) { 12387 pw.println("-------------------------------------------------------------------------------"); 12388 } 12389 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12390 pw.println(); 12391 if (dumpAll) { 12392 pw.println("-------------------------------------------------------------------------------"); 12393 } 12394 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12395 pw.println(); 12396 if (dumpAll) { 12397 pw.println("-------------------------------------------------------------------------------"); 12398 } 12399 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12400 pw.println(); 12401 if (dumpAll) { 12402 pw.println("-------------------------------------------------------------------------------"); 12403 } 12404 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12405 pw.println(); 12406 if (dumpAll) { 12407 pw.println("-------------------------------------------------------------------------------"); 12408 } 12409 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12410 pw.println(); 12411 if (dumpAll) { 12412 pw.println("-------------------------------------------------------------------------------"); 12413 } 12414 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12415 } 12416 Binder.restoreCallingIdentity(origId); 12417 } 12418 12419 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12420 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12421 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12422 12423 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12424 dumpPackage); 12425 boolean needSep = printedAnything; 12426 12427 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12428 dumpPackage, needSep, " mFocusedActivity: "); 12429 if (printed) { 12430 printedAnything = true; 12431 needSep = false; 12432 } 12433 12434 if (dumpPackage == null) { 12435 if (needSep) { 12436 pw.println(); 12437 } 12438 needSep = true; 12439 printedAnything = true; 12440 mStackSupervisor.dump(pw, " "); 12441 } 12442 12443 if (!printedAnything) { 12444 pw.println(" (nothing)"); 12445 } 12446 } 12447 12448 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12449 int opti, boolean dumpAll, String dumpPackage) { 12450 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12451 12452 boolean printedAnything = false; 12453 12454 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12455 boolean printedHeader = false; 12456 12457 final int N = mRecentTasks.size(); 12458 for (int i=0; i<N; i++) { 12459 TaskRecord tr = mRecentTasks.get(i); 12460 if (dumpPackage != null) { 12461 if (tr.realActivity == null || 12462 !dumpPackage.equals(tr.realActivity)) { 12463 continue; 12464 } 12465 } 12466 if (!printedHeader) { 12467 pw.println(" Recent tasks:"); 12468 printedHeader = true; 12469 printedAnything = true; 12470 } 12471 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12472 pw.println(tr); 12473 if (dumpAll) { 12474 mRecentTasks.get(i).dump(pw, " "); 12475 } 12476 } 12477 } 12478 12479 if (!printedAnything) { 12480 pw.println(" (nothing)"); 12481 } 12482 } 12483 12484 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12485 int opti, boolean dumpAll, String dumpPackage) { 12486 boolean needSep = false; 12487 boolean printedAnything = false; 12488 int numPers = 0; 12489 12490 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12491 12492 if (dumpAll) { 12493 final int NP = mProcessNames.getMap().size(); 12494 for (int ip=0; ip<NP; ip++) { 12495 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12496 final int NA = procs.size(); 12497 for (int ia=0; ia<NA; ia++) { 12498 ProcessRecord r = procs.valueAt(ia); 12499 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12500 continue; 12501 } 12502 if (!needSep) { 12503 pw.println(" All known processes:"); 12504 needSep = true; 12505 printedAnything = true; 12506 } 12507 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12508 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12509 pw.print(" "); pw.println(r); 12510 r.dump(pw, " "); 12511 if (r.persistent) { 12512 numPers++; 12513 } 12514 } 12515 } 12516 } 12517 12518 if (mIsolatedProcesses.size() > 0) { 12519 boolean printed = false; 12520 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12521 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12522 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12523 continue; 12524 } 12525 if (!printed) { 12526 if (needSep) { 12527 pw.println(); 12528 } 12529 pw.println(" Isolated process list (sorted by uid):"); 12530 printedAnything = true; 12531 printed = true; 12532 needSep = true; 12533 } 12534 pw.println(String.format("%sIsolated #%2d: %s", 12535 " ", i, r.toString())); 12536 } 12537 } 12538 12539 if (mLruProcesses.size() > 0) { 12540 if (needSep) { 12541 pw.println(); 12542 } 12543 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12544 pw.print(" total, non-act at "); 12545 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12546 pw.print(", non-svc at "); 12547 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12548 pw.println("):"); 12549 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12550 needSep = true; 12551 printedAnything = true; 12552 } 12553 12554 if (dumpAll || dumpPackage != null) { 12555 synchronized (mPidsSelfLocked) { 12556 boolean printed = false; 12557 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12558 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12559 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12560 continue; 12561 } 12562 if (!printed) { 12563 if (needSep) pw.println(); 12564 needSep = true; 12565 pw.println(" PID mappings:"); 12566 printed = true; 12567 printedAnything = true; 12568 } 12569 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12570 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12571 } 12572 } 12573 } 12574 12575 if (mForegroundProcesses.size() > 0) { 12576 synchronized (mPidsSelfLocked) { 12577 boolean printed = false; 12578 for (int i=0; i<mForegroundProcesses.size(); i++) { 12579 ProcessRecord r = mPidsSelfLocked.get( 12580 mForegroundProcesses.valueAt(i).pid); 12581 if (dumpPackage != null && (r == null 12582 || !r.pkgList.containsKey(dumpPackage))) { 12583 continue; 12584 } 12585 if (!printed) { 12586 if (needSep) pw.println(); 12587 needSep = true; 12588 pw.println(" Foreground Processes:"); 12589 printed = true; 12590 printedAnything = true; 12591 } 12592 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12593 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12594 } 12595 } 12596 } 12597 12598 if (mPersistentStartingProcesses.size() > 0) { 12599 if (needSep) pw.println(); 12600 needSep = true; 12601 printedAnything = true; 12602 pw.println(" Persisent processes that are starting:"); 12603 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12604 "Starting Norm", "Restarting PERS", dumpPackage); 12605 } 12606 12607 if (mRemovedProcesses.size() > 0) { 12608 if (needSep) pw.println(); 12609 needSep = true; 12610 printedAnything = true; 12611 pw.println(" Processes that are being removed:"); 12612 dumpProcessList(pw, this, mRemovedProcesses, " ", 12613 "Removed Norm", "Removed PERS", dumpPackage); 12614 } 12615 12616 if (mProcessesOnHold.size() > 0) { 12617 if (needSep) pw.println(); 12618 needSep = true; 12619 printedAnything = true; 12620 pw.println(" Processes that are on old until the system is ready:"); 12621 dumpProcessList(pw, this, mProcessesOnHold, " ", 12622 "OnHold Norm", "OnHold PERS", dumpPackage); 12623 } 12624 12625 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12626 12627 if (mProcessCrashTimes.getMap().size() > 0) { 12628 boolean printed = false; 12629 long now = SystemClock.uptimeMillis(); 12630 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12631 final int NP = pmap.size(); 12632 for (int ip=0; ip<NP; ip++) { 12633 String pname = pmap.keyAt(ip); 12634 SparseArray<Long> uids = pmap.valueAt(ip); 12635 final int N = uids.size(); 12636 for (int i=0; i<N; i++) { 12637 int puid = uids.keyAt(i); 12638 ProcessRecord r = mProcessNames.get(pname, puid); 12639 if (dumpPackage != null && (r == null 12640 || !r.pkgList.containsKey(dumpPackage))) { 12641 continue; 12642 } 12643 if (!printed) { 12644 if (needSep) pw.println(); 12645 needSep = true; 12646 pw.println(" Time since processes crashed:"); 12647 printed = true; 12648 printedAnything = true; 12649 } 12650 pw.print(" Process "); pw.print(pname); 12651 pw.print(" uid "); pw.print(puid); 12652 pw.print(": last crashed "); 12653 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12654 pw.println(" ago"); 12655 } 12656 } 12657 } 12658 12659 if (mBadProcesses.getMap().size() > 0) { 12660 boolean printed = false; 12661 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12662 final int NP = pmap.size(); 12663 for (int ip=0; ip<NP; ip++) { 12664 String pname = pmap.keyAt(ip); 12665 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12666 final int N = uids.size(); 12667 for (int i=0; i<N; i++) { 12668 int puid = uids.keyAt(i); 12669 ProcessRecord r = mProcessNames.get(pname, puid); 12670 if (dumpPackage != null && (r == null 12671 || !r.pkgList.containsKey(dumpPackage))) { 12672 continue; 12673 } 12674 if (!printed) { 12675 if (needSep) pw.println(); 12676 needSep = true; 12677 pw.println(" Bad processes:"); 12678 printedAnything = true; 12679 } 12680 BadProcessInfo info = uids.valueAt(i); 12681 pw.print(" Bad process "); pw.print(pname); 12682 pw.print(" uid "); pw.print(puid); 12683 pw.print(": crashed at time "); pw.println(info.time); 12684 if (info.shortMsg != null) { 12685 pw.print(" Short msg: "); pw.println(info.shortMsg); 12686 } 12687 if (info.longMsg != null) { 12688 pw.print(" Long msg: "); pw.println(info.longMsg); 12689 } 12690 if (info.stack != null) { 12691 pw.println(" Stack:"); 12692 int lastPos = 0; 12693 for (int pos=0; pos<info.stack.length(); pos++) { 12694 if (info.stack.charAt(pos) == '\n') { 12695 pw.print(" "); 12696 pw.write(info.stack, lastPos, pos-lastPos); 12697 pw.println(); 12698 lastPos = pos+1; 12699 } 12700 } 12701 if (lastPos < info.stack.length()) { 12702 pw.print(" "); 12703 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12704 pw.println(); 12705 } 12706 } 12707 } 12708 } 12709 } 12710 12711 if (dumpPackage == null) { 12712 pw.println(); 12713 needSep = false; 12714 pw.println(" mStartedUsers:"); 12715 for (int i=0; i<mStartedUsers.size(); i++) { 12716 UserStartedState uss = mStartedUsers.valueAt(i); 12717 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12718 pw.print(": "); uss.dump("", pw); 12719 } 12720 pw.print(" mStartedUserArray: ["); 12721 for (int i=0; i<mStartedUserArray.length; i++) { 12722 if (i > 0) pw.print(", "); 12723 pw.print(mStartedUserArray[i]); 12724 } 12725 pw.println("]"); 12726 pw.print(" mUserLru: ["); 12727 for (int i=0; i<mUserLru.size(); i++) { 12728 if (i > 0) pw.print(", "); 12729 pw.print(mUserLru.get(i)); 12730 } 12731 pw.println("]"); 12732 if (dumpAll) { 12733 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12734 } 12735 synchronized (mUserProfileGroupIdsSelfLocked) { 12736 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12737 pw.println(" mUserProfileGroupIds:"); 12738 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12739 pw.print(" User #"); 12740 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12741 pw.print(" -> profile #"); 12742 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12743 } 12744 } 12745 } 12746 } 12747 if (mHomeProcess != null && (dumpPackage == null 12748 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12749 if (needSep) { 12750 pw.println(); 12751 needSep = false; 12752 } 12753 pw.println(" mHomeProcess: " + mHomeProcess); 12754 } 12755 if (mPreviousProcess != null && (dumpPackage == null 12756 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12757 if (needSep) { 12758 pw.println(); 12759 needSep = false; 12760 } 12761 pw.println(" mPreviousProcess: " + mPreviousProcess); 12762 } 12763 if (dumpAll) { 12764 StringBuilder sb = new StringBuilder(128); 12765 sb.append(" mPreviousProcessVisibleTime: "); 12766 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12767 pw.println(sb); 12768 } 12769 if (mHeavyWeightProcess != null && (dumpPackage == null 12770 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12771 if (needSep) { 12772 pw.println(); 12773 needSep = false; 12774 } 12775 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12776 } 12777 if (dumpPackage == null) { 12778 pw.println(" mConfiguration: " + mConfiguration); 12779 } 12780 if (dumpAll) { 12781 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12782 if (mCompatModePackages.getPackages().size() > 0) { 12783 boolean printed = false; 12784 for (Map.Entry<String, Integer> entry 12785 : mCompatModePackages.getPackages().entrySet()) { 12786 String pkg = entry.getKey(); 12787 int mode = entry.getValue(); 12788 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12789 continue; 12790 } 12791 if (!printed) { 12792 pw.println(" mScreenCompatPackages:"); 12793 printed = true; 12794 } 12795 pw.print(" "); pw.print(pkg); pw.print(": "); 12796 pw.print(mode); pw.println(); 12797 } 12798 } 12799 } 12800 if (dumpPackage == null) { 12801 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12802 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12803 + " mLockScreenShown " + lockScreenShownToString()); 12804 } 12805 if (mShuttingDown || mRunningVoice) { 12806 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12807 } 12808 } 12809 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12810 || mOrigWaitForDebugger) { 12811 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12812 || dumpPackage.equals(mOrigDebugApp)) { 12813 if (needSep) { 12814 pw.println(); 12815 needSep = false; 12816 } 12817 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12818 + " mDebugTransient=" + mDebugTransient 12819 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12820 } 12821 } 12822 if (mOpenGlTraceApp != null) { 12823 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12824 if (needSep) { 12825 pw.println(); 12826 needSep = false; 12827 } 12828 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12829 } 12830 } 12831 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12832 || mProfileFd != null) { 12833 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12834 if (needSep) { 12835 pw.println(); 12836 needSep = false; 12837 } 12838 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12839 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12840 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12841 + mAutoStopProfiler); 12842 pw.println(" mProfileType=" + mProfileType); 12843 } 12844 } 12845 if (dumpPackage == null) { 12846 if (mAlwaysFinishActivities || mController != null) { 12847 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12848 + " mController=" + mController); 12849 } 12850 if (dumpAll) { 12851 pw.println(" Total persistent processes: " + numPers); 12852 pw.println(" mProcessesReady=" + mProcessesReady 12853 + " mSystemReady=" + mSystemReady 12854 + " mBooted=" + mBooted 12855 + " mFactoryTest=" + mFactoryTest); 12856 pw.println(" mBooting=" + mBooting 12857 + " mCallFinishBooting=" + mCallFinishBooting 12858 + " mBootAnimationComplete=" + mBootAnimationComplete); 12859 pw.print(" mLastPowerCheckRealtime="); 12860 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12861 pw.println(""); 12862 pw.print(" mLastPowerCheckUptime="); 12863 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12864 pw.println(""); 12865 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12866 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12867 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12868 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12869 + " (" + mLruProcesses.size() + " total)" 12870 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12871 + " mNumServiceProcs=" + mNumServiceProcs 12872 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12873 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12874 + " mLastMemoryLevel" + mLastMemoryLevel 12875 + " mLastNumProcesses" + mLastNumProcesses); 12876 long now = SystemClock.uptimeMillis(); 12877 pw.print(" mLastIdleTime="); 12878 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12879 pw.print(" mLowRamSinceLastIdle="); 12880 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12881 pw.println(); 12882 } 12883 } 12884 12885 if (!printedAnything) { 12886 pw.println(" (nothing)"); 12887 } 12888 } 12889 12890 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12891 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12892 if (mProcessesToGc.size() > 0) { 12893 boolean printed = false; 12894 long now = SystemClock.uptimeMillis(); 12895 for (int i=0; i<mProcessesToGc.size(); i++) { 12896 ProcessRecord proc = mProcessesToGc.get(i); 12897 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12898 continue; 12899 } 12900 if (!printed) { 12901 if (needSep) pw.println(); 12902 needSep = true; 12903 pw.println(" Processes that are waiting to GC:"); 12904 printed = true; 12905 } 12906 pw.print(" Process "); pw.println(proc); 12907 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12908 pw.print(", last gced="); 12909 pw.print(now-proc.lastRequestedGc); 12910 pw.print(" ms ago, last lowMem="); 12911 pw.print(now-proc.lastLowMemory); 12912 pw.println(" ms ago"); 12913 12914 } 12915 } 12916 return needSep; 12917 } 12918 12919 void printOomLevel(PrintWriter pw, String name, int adj) { 12920 pw.print(" "); 12921 if (adj >= 0) { 12922 pw.print(' '); 12923 if (adj < 10) pw.print(' '); 12924 } else { 12925 if (adj > -10) pw.print(' '); 12926 } 12927 pw.print(adj); 12928 pw.print(": "); 12929 pw.print(name); 12930 pw.print(" ("); 12931 pw.print(mProcessList.getMemLevel(adj)/1024); 12932 pw.println(" kB)"); 12933 } 12934 12935 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12936 int opti, boolean dumpAll) { 12937 boolean needSep = false; 12938 12939 if (mLruProcesses.size() > 0) { 12940 if (needSep) pw.println(); 12941 needSep = true; 12942 pw.println(" OOM levels:"); 12943 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12944 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12945 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12946 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12947 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12948 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12949 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12950 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12951 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12952 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12953 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12954 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12955 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12956 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12957 12958 if (needSep) pw.println(); 12959 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12960 pw.print(" total, non-act at "); 12961 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12962 pw.print(", non-svc at "); 12963 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12964 pw.println("):"); 12965 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12966 needSep = true; 12967 } 12968 12969 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12970 12971 pw.println(); 12972 pw.println(" mHomeProcess: " + mHomeProcess); 12973 pw.println(" mPreviousProcess: " + mPreviousProcess); 12974 if (mHeavyWeightProcess != null) { 12975 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12976 } 12977 12978 return true; 12979 } 12980 12981 /** 12982 * There are three ways to call this: 12983 * - no provider specified: dump all the providers 12984 * - a flattened component name that matched an existing provider was specified as the 12985 * first arg: dump that one provider 12986 * - the first arg isn't the flattened component name of an existing provider: 12987 * dump all providers whose component contains the first arg as a substring 12988 */ 12989 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12990 int opti, boolean dumpAll) { 12991 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12992 } 12993 12994 static class ItemMatcher { 12995 ArrayList<ComponentName> components; 12996 ArrayList<String> strings; 12997 ArrayList<Integer> objects; 12998 boolean all; 12999 13000 ItemMatcher() { 13001 all = true; 13002 } 13003 13004 void build(String name) { 13005 ComponentName componentName = ComponentName.unflattenFromString(name); 13006 if (componentName != null) { 13007 if (components == null) { 13008 components = new ArrayList<ComponentName>(); 13009 } 13010 components.add(componentName); 13011 all = false; 13012 } else { 13013 int objectId = 0; 13014 // Not a '/' separated full component name; maybe an object ID? 13015 try { 13016 objectId = Integer.parseInt(name, 16); 13017 if (objects == null) { 13018 objects = new ArrayList<Integer>(); 13019 } 13020 objects.add(objectId); 13021 all = false; 13022 } catch (RuntimeException e) { 13023 // Not an integer; just do string match. 13024 if (strings == null) { 13025 strings = new ArrayList<String>(); 13026 } 13027 strings.add(name); 13028 all = false; 13029 } 13030 } 13031 } 13032 13033 int build(String[] args, int opti) { 13034 for (; opti<args.length; opti++) { 13035 String name = args[opti]; 13036 if ("--".equals(name)) { 13037 return opti+1; 13038 } 13039 build(name); 13040 } 13041 return opti; 13042 } 13043 13044 boolean match(Object object, ComponentName comp) { 13045 if (all) { 13046 return true; 13047 } 13048 if (components != null) { 13049 for (int i=0; i<components.size(); i++) { 13050 if (components.get(i).equals(comp)) { 13051 return true; 13052 } 13053 } 13054 } 13055 if (objects != null) { 13056 for (int i=0; i<objects.size(); i++) { 13057 if (System.identityHashCode(object) == objects.get(i)) { 13058 return true; 13059 } 13060 } 13061 } 13062 if (strings != null) { 13063 String flat = comp.flattenToString(); 13064 for (int i=0; i<strings.size(); i++) { 13065 if (flat.contains(strings.get(i))) { 13066 return true; 13067 } 13068 } 13069 } 13070 return false; 13071 } 13072 } 13073 13074 /** 13075 * There are three things that cmd can be: 13076 * - a flattened component name that matches an existing activity 13077 * - the cmd arg isn't the flattened component name of an existing activity: 13078 * dump all activity whose component contains the cmd as a substring 13079 * - A hex number of the ActivityRecord object instance. 13080 */ 13081 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13082 int opti, boolean dumpAll) { 13083 ArrayList<ActivityRecord> activities; 13084 13085 synchronized (this) { 13086 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13087 } 13088 13089 if (activities.size() <= 0) { 13090 return false; 13091 } 13092 13093 String[] newArgs = new String[args.length - opti]; 13094 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13095 13096 TaskRecord lastTask = null; 13097 boolean needSep = false; 13098 for (int i=activities.size()-1; i>=0; i--) { 13099 ActivityRecord r = activities.get(i); 13100 if (needSep) { 13101 pw.println(); 13102 } 13103 needSep = true; 13104 synchronized (this) { 13105 if (lastTask != r.task) { 13106 lastTask = r.task; 13107 pw.print("TASK "); pw.print(lastTask.affinity); 13108 pw.print(" id="); pw.println(lastTask.taskId); 13109 if (dumpAll) { 13110 lastTask.dump(pw, " "); 13111 } 13112 } 13113 } 13114 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13115 } 13116 return true; 13117 } 13118 13119 /** 13120 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13121 * there is a thread associated with the activity. 13122 */ 13123 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13124 final ActivityRecord r, String[] args, boolean dumpAll) { 13125 String innerPrefix = prefix + " "; 13126 synchronized (this) { 13127 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13128 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13129 pw.print(" pid="); 13130 if (r.app != null) pw.println(r.app.pid); 13131 else pw.println("(not running)"); 13132 if (dumpAll) { 13133 r.dump(pw, innerPrefix); 13134 } 13135 } 13136 if (r.app != null && r.app.thread != null) { 13137 // flush anything that is already in the PrintWriter since the thread is going 13138 // to write to the file descriptor directly 13139 pw.flush(); 13140 try { 13141 TransferPipe tp = new TransferPipe(); 13142 try { 13143 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13144 r.appToken, innerPrefix, args); 13145 tp.go(fd); 13146 } finally { 13147 tp.kill(); 13148 } 13149 } catch (IOException e) { 13150 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13151 } catch (RemoteException e) { 13152 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13153 } 13154 } 13155 } 13156 13157 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13158 int opti, boolean dumpAll, String dumpPackage) { 13159 boolean needSep = false; 13160 boolean onlyHistory = false; 13161 boolean printedAnything = false; 13162 13163 if ("history".equals(dumpPackage)) { 13164 if (opti < args.length && "-s".equals(args[opti])) { 13165 dumpAll = false; 13166 } 13167 onlyHistory = true; 13168 dumpPackage = null; 13169 } 13170 13171 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13172 if (!onlyHistory && dumpAll) { 13173 if (mRegisteredReceivers.size() > 0) { 13174 boolean printed = false; 13175 Iterator it = mRegisteredReceivers.values().iterator(); 13176 while (it.hasNext()) { 13177 ReceiverList r = (ReceiverList)it.next(); 13178 if (dumpPackage != null && (r.app == null || 13179 !dumpPackage.equals(r.app.info.packageName))) { 13180 continue; 13181 } 13182 if (!printed) { 13183 pw.println(" Registered Receivers:"); 13184 needSep = true; 13185 printed = true; 13186 printedAnything = true; 13187 } 13188 pw.print(" * "); pw.println(r); 13189 r.dump(pw, " "); 13190 } 13191 } 13192 13193 if (mReceiverResolver.dump(pw, needSep ? 13194 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13195 " ", dumpPackage, false)) { 13196 needSep = true; 13197 printedAnything = true; 13198 } 13199 } 13200 13201 for (BroadcastQueue q : mBroadcastQueues) { 13202 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13203 printedAnything |= needSep; 13204 } 13205 13206 needSep = true; 13207 13208 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13209 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13210 if (needSep) { 13211 pw.println(); 13212 } 13213 needSep = true; 13214 printedAnything = true; 13215 pw.print(" Sticky broadcasts for user "); 13216 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13217 StringBuilder sb = new StringBuilder(128); 13218 for (Map.Entry<String, ArrayList<Intent>> ent 13219 : mStickyBroadcasts.valueAt(user).entrySet()) { 13220 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13221 if (dumpAll) { 13222 pw.println(":"); 13223 ArrayList<Intent> intents = ent.getValue(); 13224 final int N = intents.size(); 13225 for (int i=0; i<N; i++) { 13226 sb.setLength(0); 13227 sb.append(" Intent: "); 13228 intents.get(i).toShortString(sb, false, true, false, false); 13229 pw.println(sb.toString()); 13230 Bundle bundle = intents.get(i).getExtras(); 13231 if (bundle != null) { 13232 pw.print(" "); 13233 pw.println(bundle.toString()); 13234 } 13235 } 13236 } else { 13237 pw.println(""); 13238 } 13239 } 13240 } 13241 } 13242 13243 if (!onlyHistory && dumpAll) { 13244 pw.println(); 13245 for (BroadcastQueue queue : mBroadcastQueues) { 13246 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13247 + queue.mBroadcastsScheduled); 13248 } 13249 pw.println(" mHandler:"); 13250 mHandler.dump(new PrintWriterPrinter(pw), " "); 13251 needSep = true; 13252 printedAnything = true; 13253 } 13254 13255 if (!printedAnything) { 13256 pw.println(" (nothing)"); 13257 } 13258 } 13259 13260 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13261 int opti, boolean dumpAll, String dumpPackage) { 13262 boolean needSep; 13263 boolean printedAnything = false; 13264 13265 ItemMatcher matcher = new ItemMatcher(); 13266 matcher.build(args, opti); 13267 13268 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13269 13270 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13271 printedAnything |= needSep; 13272 13273 if (mLaunchingProviders.size() > 0) { 13274 boolean printed = false; 13275 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13276 ContentProviderRecord r = mLaunchingProviders.get(i); 13277 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13278 continue; 13279 } 13280 if (!printed) { 13281 if (needSep) pw.println(); 13282 needSep = true; 13283 pw.println(" Launching content providers:"); 13284 printed = true; 13285 printedAnything = true; 13286 } 13287 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13288 pw.println(r); 13289 } 13290 } 13291 13292 if (mGrantedUriPermissions.size() > 0) { 13293 boolean printed = false; 13294 int dumpUid = -2; 13295 if (dumpPackage != null) { 13296 try { 13297 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13298 } catch (NameNotFoundException e) { 13299 dumpUid = -1; 13300 } 13301 } 13302 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13303 int uid = mGrantedUriPermissions.keyAt(i); 13304 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13305 continue; 13306 } 13307 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13308 if (!printed) { 13309 if (needSep) pw.println(); 13310 needSep = true; 13311 pw.println(" Granted Uri Permissions:"); 13312 printed = true; 13313 printedAnything = true; 13314 } 13315 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13316 for (UriPermission perm : perms.values()) { 13317 pw.print(" "); pw.println(perm); 13318 if (dumpAll) { 13319 perm.dump(pw, " "); 13320 } 13321 } 13322 } 13323 } 13324 13325 if (!printedAnything) { 13326 pw.println(" (nothing)"); 13327 } 13328 } 13329 13330 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13331 int opti, boolean dumpAll, String dumpPackage) { 13332 boolean printed = false; 13333 13334 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13335 13336 if (mIntentSenderRecords.size() > 0) { 13337 Iterator<WeakReference<PendingIntentRecord>> it 13338 = mIntentSenderRecords.values().iterator(); 13339 while (it.hasNext()) { 13340 WeakReference<PendingIntentRecord> ref = it.next(); 13341 PendingIntentRecord rec = ref != null ? ref.get(): null; 13342 if (dumpPackage != null && (rec == null 13343 || !dumpPackage.equals(rec.key.packageName))) { 13344 continue; 13345 } 13346 printed = true; 13347 if (rec != null) { 13348 pw.print(" * "); pw.println(rec); 13349 if (dumpAll) { 13350 rec.dump(pw, " "); 13351 } 13352 } else { 13353 pw.print(" * "); pw.println(ref); 13354 } 13355 } 13356 } 13357 13358 if (!printed) { 13359 pw.println(" (nothing)"); 13360 } 13361 } 13362 13363 private static final int dumpProcessList(PrintWriter pw, 13364 ActivityManagerService service, List list, 13365 String prefix, String normalLabel, String persistentLabel, 13366 String dumpPackage) { 13367 int numPers = 0; 13368 final int N = list.size()-1; 13369 for (int i=N; i>=0; i--) { 13370 ProcessRecord r = (ProcessRecord)list.get(i); 13371 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13372 continue; 13373 } 13374 pw.println(String.format("%s%s #%2d: %s", 13375 prefix, (r.persistent ? persistentLabel : normalLabel), 13376 i, r.toString())); 13377 if (r.persistent) { 13378 numPers++; 13379 } 13380 } 13381 return numPers; 13382 } 13383 13384 private static final boolean dumpProcessOomList(PrintWriter pw, 13385 ActivityManagerService service, List<ProcessRecord> origList, 13386 String prefix, String normalLabel, String persistentLabel, 13387 boolean inclDetails, String dumpPackage) { 13388 13389 ArrayList<Pair<ProcessRecord, Integer>> list 13390 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13391 for (int i=0; i<origList.size(); i++) { 13392 ProcessRecord r = origList.get(i); 13393 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13394 continue; 13395 } 13396 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13397 } 13398 13399 if (list.size() <= 0) { 13400 return false; 13401 } 13402 13403 Comparator<Pair<ProcessRecord, Integer>> comparator 13404 = new Comparator<Pair<ProcessRecord, Integer>>() { 13405 @Override 13406 public int compare(Pair<ProcessRecord, Integer> object1, 13407 Pair<ProcessRecord, Integer> object2) { 13408 if (object1.first.setAdj != object2.first.setAdj) { 13409 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13410 } 13411 if (object1.second.intValue() != object2.second.intValue()) { 13412 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13413 } 13414 return 0; 13415 } 13416 }; 13417 13418 Collections.sort(list, comparator); 13419 13420 final long curRealtime = SystemClock.elapsedRealtime(); 13421 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13422 final long curUptime = SystemClock.uptimeMillis(); 13423 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13424 13425 for (int i=list.size()-1; i>=0; i--) { 13426 ProcessRecord r = list.get(i).first; 13427 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13428 char schedGroup; 13429 switch (r.setSchedGroup) { 13430 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13431 schedGroup = 'B'; 13432 break; 13433 case Process.THREAD_GROUP_DEFAULT: 13434 schedGroup = 'F'; 13435 break; 13436 default: 13437 schedGroup = '?'; 13438 break; 13439 } 13440 char foreground; 13441 if (r.foregroundActivities) { 13442 foreground = 'A'; 13443 } else if (r.foregroundServices) { 13444 foreground = 'S'; 13445 } else { 13446 foreground = ' '; 13447 } 13448 String procState = ProcessList.makeProcStateString(r.curProcState); 13449 pw.print(prefix); 13450 pw.print(r.persistent ? persistentLabel : normalLabel); 13451 pw.print(" #"); 13452 int num = (origList.size()-1)-list.get(i).second; 13453 if (num < 10) pw.print(' '); 13454 pw.print(num); 13455 pw.print(": "); 13456 pw.print(oomAdj); 13457 pw.print(' '); 13458 pw.print(schedGroup); 13459 pw.print('/'); 13460 pw.print(foreground); 13461 pw.print('/'); 13462 pw.print(procState); 13463 pw.print(" trm:"); 13464 if (r.trimMemoryLevel < 10) pw.print(' '); 13465 pw.print(r.trimMemoryLevel); 13466 pw.print(' '); 13467 pw.print(r.toShortString()); 13468 pw.print(" ("); 13469 pw.print(r.adjType); 13470 pw.println(')'); 13471 if (r.adjSource != null || r.adjTarget != null) { 13472 pw.print(prefix); 13473 pw.print(" "); 13474 if (r.adjTarget instanceof ComponentName) { 13475 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13476 } else if (r.adjTarget != null) { 13477 pw.print(r.adjTarget.toString()); 13478 } else { 13479 pw.print("{null}"); 13480 } 13481 pw.print("<="); 13482 if (r.adjSource instanceof ProcessRecord) { 13483 pw.print("Proc{"); 13484 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13485 pw.println("}"); 13486 } else if (r.adjSource != null) { 13487 pw.println(r.adjSource.toString()); 13488 } else { 13489 pw.println("{null}"); 13490 } 13491 } 13492 if (inclDetails) { 13493 pw.print(prefix); 13494 pw.print(" "); 13495 pw.print("oom: max="); pw.print(r.maxAdj); 13496 pw.print(" curRaw="); pw.print(r.curRawAdj); 13497 pw.print(" setRaw="); pw.print(r.setRawAdj); 13498 pw.print(" cur="); pw.print(r.curAdj); 13499 pw.print(" set="); pw.println(r.setAdj); 13500 pw.print(prefix); 13501 pw.print(" "); 13502 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13503 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13504 pw.print(" lastPss="); pw.print(r.lastPss); 13505 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13506 pw.print(prefix); 13507 pw.print(" "); 13508 pw.print("cached="); pw.print(r.cached); 13509 pw.print(" empty="); pw.print(r.empty); 13510 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13511 13512 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13513 if (r.lastWakeTime != 0) { 13514 long wtime; 13515 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13516 synchronized (stats) { 13517 wtime = stats.getProcessWakeTime(r.info.uid, 13518 r.pid, curRealtime); 13519 } 13520 long timeUsed = wtime - r.lastWakeTime; 13521 pw.print(prefix); 13522 pw.print(" "); 13523 pw.print("keep awake over "); 13524 TimeUtils.formatDuration(realtimeSince, pw); 13525 pw.print(" used "); 13526 TimeUtils.formatDuration(timeUsed, pw); 13527 pw.print(" ("); 13528 pw.print((timeUsed*100)/realtimeSince); 13529 pw.println("%)"); 13530 } 13531 if (r.lastCpuTime != 0) { 13532 long timeUsed = r.curCpuTime - r.lastCpuTime; 13533 pw.print(prefix); 13534 pw.print(" "); 13535 pw.print("run cpu over "); 13536 TimeUtils.formatDuration(uptimeSince, pw); 13537 pw.print(" used "); 13538 TimeUtils.formatDuration(timeUsed, pw); 13539 pw.print(" ("); 13540 pw.print((timeUsed*100)/uptimeSince); 13541 pw.println("%)"); 13542 } 13543 } 13544 } 13545 } 13546 return true; 13547 } 13548 13549 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13550 String[] args) { 13551 ArrayList<ProcessRecord> procs; 13552 synchronized (this) { 13553 if (args != null && args.length > start 13554 && args[start].charAt(0) != '-') { 13555 procs = new ArrayList<ProcessRecord>(); 13556 int pid = -1; 13557 try { 13558 pid = Integer.parseInt(args[start]); 13559 } catch (NumberFormatException e) { 13560 } 13561 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13562 ProcessRecord proc = mLruProcesses.get(i); 13563 if (proc.pid == pid) { 13564 procs.add(proc); 13565 } else if (allPkgs && proc.pkgList != null 13566 && proc.pkgList.containsKey(args[start])) { 13567 procs.add(proc); 13568 } else if (proc.processName.equals(args[start])) { 13569 procs.add(proc); 13570 } 13571 } 13572 if (procs.size() <= 0) { 13573 return null; 13574 } 13575 } else { 13576 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13577 } 13578 } 13579 return procs; 13580 } 13581 13582 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13583 PrintWriter pw, String[] args) { 13584 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13585 if (procs == null) { 13586 pw.println("No process found for: " + args[0]); 13587 return; 13588 } 13589 13590 long uptime = SystemClock.uptimeMillis(); 13591 long realtime = SystemClock.elapsedRealtime(); 13592 pw.println("Applications Graphics Acceleration Info:"); 13593 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13594 13595 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13596 ProcessRecord r = procs.get(i); 13597 if (r.thread != null) { 13598 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13599 pw.flush(); 13600 try { 13601 TransferPipe tp = new TransferPipe(); 13602 try { 13603 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13604 tp.go(fd); 13605 } finally { 13606 tp.kill(); 13607 } 13608 } catch (IOException e) { 13609 pw.println("Failure while dumping the app: " + r); 13610 pw.flush(); 13611 } catch (RemoteException e) { 13612 pw.println("Got a RemoteException while dumping the app " + r); 13613 pw.flush(); 13614 } 13615 } 13616 } 13617 } 13618 13619 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13620 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13621 if (procs == null) { 13622 pw.println("No process found for: " + args[0]); 13623 return; 13624 } 13625 13626 pw.println("Applications Database Info:"); 13627 13628 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13629 ProcessRecord r = procs.get(i); 13630 if (r.thread != null) { 13631 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13632 pw.flush(); 13633 try { 13634 TransferPipe tp = new TransferPipe(); 13635 try { 13636 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13637 tp.go(fd); 13638 } finally { 13639 tp.kill(); 13640 } 13641 } catch (IOException e) { 13642 pw.println("Failure while dumping the app: " + r); 13643 pw.flush(); 13644 } catch (RemoteException e) { 13645 pw.println("Got a RemoteException while dumping the app " + r); 13646 pw.flush(); 13647 } 13648 } 13649 } 13650 } 13651 13652 final static class MemItem { 13653 final boolean isProc; 13654 final String label; 13655 final String shortLabel; 13656 final long pss; 13657 final int id; 13658 final boolean hasActivities; 13659 ArrayList<MemItem> subitems; 13660 13661 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13662 boolean _hasActivities) { 13663 isProc = true; 13664 label = _label; 13665 shortLabel = _shortLabel; 13666 pss = _pss; 13667 id = _id; 13668 hasActivities = _hasActivities; 13669 } 13670 13671 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13672 isProc = false; 13673 label = _label; 13674 shortLabel = _shortLabel; 13675 pss = _pss; 13676 id = _id; 13677 hasActivities = false; 13678 } 13679 } 13680 13681 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13682 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13683 if (sort && !isCompact) { 13684 Collections.sort(items, new Comparator<MemItem>() { 13685 @Override 13686 public int compare(MemItem lhs, MemItem rhs) { 13687 if (lhs.pss < rhs.pss) { 13688 return 1; 13689 } else if (lhs.pss > rhs.pss) { 13690 return -1; 13691 } 13692 return 0; 13693 } 13694 }); 13695 } 13696 13697 for (int i=0; i<items.size(); i++) { 13698 MemItem mi = items.get(i); 13699 if (!isCompact) { 13700 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13701 } else if (mi.isProc) { 13702 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13703 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13704 pw.println(mi.hasActivities ? ",a" : ",e"); 13705 } else { 13706 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13707 pw.println(mi.pss); 13708 } 13709 if (mi.subitems != null) { 13710 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13711 true, isCompact); 13712 } 13713 } 13714 } 13715 13716 // These are in KB. 13717 static final long[] DUMP_MEM_BUCKETS = new long[] { 13718 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13719 120*1024, 160*1024, 200*1024, 13720 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13721 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13722 }; 13723 13724 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13725 boolean stackLike) { 13726 int start = label.lastIndexOf('.'); 13727 if (start >= 0) start++; 13728 else start = 0; 13729 int end = label.length(); 13730 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13731 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13732 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13733 out.append(bucket); 13734 out.append(stackLike ? "MB." : "MB "); 13735 out.append(label, start, end); 13736 return; 13737 } 13738 } 13739 out.append(memKB/1024); 13740 out.append(stackLike ? "MB." : "MB "); 13741 out.append(label, start, end); 13742 } 13743 13744 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13745 ProcessList.NATIVE_ADJ, 13746 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13747 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13748 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13749 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13750 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13751 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13752 }; 13753 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13754 "Native", 13755 "System", "Persistent", "Persistent Service", "Foreground", 13756 "Visible", "Perceptible", 13757 "Heavy Weight", "Backup", 13758 "A Services", "Home", 13759 "Previous", "B Services", "Cached" 13760 }; 13761 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13762 "native", 13763 "sys", "pers", "persvc", "fore", 13764 "vis", "percept", 13765 "heavy", "backup", 13766 "servicea", "home", 13767 "prev", "serviceb", "cached" 13768 }; 13769 13770 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13771 long realtime, boolean isCheckinRequest, boolean isCompact) { 13772 if (isCheckinRequest || isCompact) { 13773 // short checkin version 13774 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13775 } else { 13776 pw.println("Applications Memory Usage (kB):"); 13777 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13778 } 13779 } 13780 13781 private static final int KSM_SHARED = 0; 13782 private static final int KSM_SHARING = 1; 13783 private static final int KSM_UNSHARED = 2; 13784 private static final int KSM_VOLATILE = 3; 13785 13786 private final long[] getKsmInfo() { 13787 long[] longOut = new long[4]; 13788 final int[] SINGLE_LONG_FORMAT = new int[] { 13789 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13790 }; 13791 long[] longTmp = new long[1]; 13792 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13793 SINGLE_LONG_FORMAT, null, longTmp, null); 13794 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13795 longTmp[0] = 0; 13796 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13797 SINGLE_LONG_FORMAT, null, longTmp, null); 13798 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13799 longTmp[0] = 0; 13800 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13801 SINGLE_LONG_FORMAT, null, longTmp, null); 13802 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13803 longTmp[0] = 0; 13804 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13805 SINGLE_LONG_FORMAT, null, longTmp, null); 13806 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13807 return longOut; 13808 } 13809 13810 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13811 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13812 boolean dumpDetails = false; 13813 boolean dumpFullDetails = false; 13814 boolean dumpDalvik = false; 13815 boolean oomOnly = false; 13816 boolean isCompact = false; 13817 boolean localOnly = false; 13818 boolean packages = false; 13819 13820 int opti = 0; 13821 while (opti < args.length) { 13822 String opt = args[opti]; 13823 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13824 break; 13825 } 13826 opti++; 13827 if ("-a".equals(opt)) { 13828 dumpDetails = true; 13829 dumpFullDetails = true; 13830 dumpDalvik = true; 13831 } else if ("-d".equals(opt)) { 13832 dumpDalvik = true; 13833 } else if ("-c".equals(opt)) { 13834 isCompact = true; 13835 } else if ("--oom".equals(opt)) { 13836 oomOnly = true; 13837 } else if ("--local".equals(opt)) { 13838 localOnly = true; 13839 } else if ("--package".equals(opt)) { 13840 packages = true; 13841 } else if ("-h".equals(opt)) { 13842 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13843 pw.println(" -a: include all available information for each process."); 13844 pw.println(" -d: include dalvik details when dumping process details."); 13845 pw.println(" -c: dump in a compact machine-parseable representation."); 13846 pw.println(" --oom: only show processes organized by oom adj."); 13847 pw.println(" --local: only collect details locally, don't call process."); 13848 pw.println(" --package: interpret process arg as package, dumping all"); 13849 pw.println(" processes that have loaded that package."); 13850 pw.println("If [process] is specified it can be the name or "); 13851 pw.println("pid of a specific process to dump."); 13852 return; 13853 } else { 13854 pw.println("Unknown argument: " + opt + "; use -h for help"); 13855 } 13856 } 13857 13858 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13859 long uptime = SystemClock.uptimeMillis(); 13860 long realtime = SystemClock.elapsedRealtime(); 13861 final long[] tmpLong = new long[1]; 13862 13863 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13864 if (procs == null) { 13865 // No Java processes. Maybe they want to print a native process. 13866 if (args != null && args.length > opti 13867 && args[opti].charAt(0) != '-') { 13868 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13869 = new ArrayList<ProcessCpuTracker.Stats>(); 13870 updateCpuStatsNow(); 13871 int findPid = -1; 13872 try { 13873 findPid = Integer.parseInt(args[opti]); 13874 } catch (NumberFormatException e) { 13875 } 13876 synchronized (mProcessCpuTracker) { 13877 final int N = mProcessCpuTracker.countStats(); 13878 for (int i=0; i<N; i++) { 13879 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13880 if (st.pid == findPid || (st.baseName != null 13881 && st.baseName.equals(args[opti]))) { 13882 nativeProcs.add(st); 13883 } 13884 } 13885 } 13886 if (nativeProcs.size() > 0) { 13887 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13888 isCompact); 13889 Debug.MemoryInfo mi = null; 13890 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13891 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13892 final int pid = r.pid; 13893 if (!isCheckinRequest && dumpDetails) { 13894 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13895 } 13896 if (mi == null) { 13897 mi = new Debug.MemoryInfo(); 13898 } 13899 if (dumpDetails || (!brief && !oomOnly)) { 13900 Debug.getMemoryInfo(pid, mi); 13901 } else { 13902 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13903 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13904 } 13905 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13906 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13907 if (isCheckinRequest) { 13908 pw.println(); 13909 } 13910 } 13911 return; 13912 } 13913 } 13914 pw.println("No process found for: " + args[opti]); 13915 return; 13916 } 13917 13918 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13919 dumpDetails = true; 13920 } 13921 13922 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13923 13924 String[] innerArgs = new String[args.length-opti]; 13925 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13926 13927 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13928 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13929 long nativePss=0, dalvikPss=0, otherPss=0; 13930 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13931 13932 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13933 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13934 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13935 13936 long totalPss = 0; 13937 long cachedPss = 0; 13938 13939 Debug.MemoryInfo mi = null; 13940 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13941 final ProcessRecord r = procs.get(i); 13942 final IApplicationThread thread; 13943 final int pid; 13944 final int oomAdj; 13945 final boolean hasActivities; 13946 synchronized (this) { 13947 thread = r.thread; 13948 pid = r.pid; 13949 oomAdj = r.getSetAdjWithServices(); 13950 hasActivities = r.activities.size() > 0; 13951 } 13952 if (thread != null) { 13953 if (!isCheckinRequest && dumpDetails) { 13954 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13955 } 13956 if (mi == null) { 13957 mi = new Debug.MemoryInfo(); 13958 } 13959 if (dumpDetails || (!brief && !oomOnly)) { 13960 Debug.getMemoryInfo(pid, mi); 13961 } else { 13962 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13963 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13964 } 13965 if (dumpDetails) { 13966 if (localOnly) { 13967 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13968 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13969 if (isCheckinRequest) { 13970 pw.println(); 13971 } 13972 } else { 13973 try { 13974 pw.flush(); 13975 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13976 dumpDalvik, innerArgs); 13977 } catch (RemoteException e) { 13978 if (!isCheckinRequest) { 13979 pw.println("Got RemoteException!"); 13980 pw.flush(); 13981 } 13982 } 13983 } 13984 } 13985 13986 final long myTotalPss = mi.getTotalPss(); 13987 final long myTotalUss = mi.getTotalUss(); 13988 13989 synchronized (this) { 13990 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13991 // Record this for posterity if the process has been stable. 13992 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13993 } 13994 } 13995 13996 if (!isCheckinRequest && mi != null) { 13997 totalPss += myTotalPss; 13998 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13999 (hasActivities ? " / activities)" : ")"), 14000 r.processName, myTotalPss, pid, hasActivities); 14001 procMems.add(pssItem); 14002 procMemsMap.put(pid, pssItem); 14003 14004 nativePss += mi.nativePss; 14005 dalvikPss += mi.dalvikPss; 14006 otherPss += mi.otherPss; 14007 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14008 long mem = mi.getOtherPss(j); 14009 miscPss[j] += mem; 14010 otherPss -= mem; 14011 } 14012 14013 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14014 cachedPss += myTotalPss; 14015 } 14016 14017 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14018 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14019 || oomIndex == (oomPss.length-1)) { 14020 oomPss[oomIndex] += myTotalPss; 14021 if (oomProcs[oomIndex] == null) { 14022 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14023 } 14024 oomProcs[oomIndex].add(pssItem); 14025 break; 14026 } 14027 } 14028 } 14029 } 14030 } 14031 14032 long nativeProcTotalPss = 0; 14033 14034 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14035 // If we are showing aggregations, also look for native processes to 14036 // include so that our aggregations are more accurate. 14037 updateCpuStatsNow(); 14038 synchronized (mProcessCpuTracker) { 14039 final int N = mProcessCpuTracker.countStats(); 14040 for (int i=0; i<N; i++) { 14041 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14042 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14043 if (mi == null) { 14044 mi = new Debug.MemoryInfo(); 14045 } 14046 if (!brief && !oomOnly) { 14047 Debug.getMemoryInfo(st.pid, mi); 14048 } else { 14049 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14050 mi.nativePrivateDirty = (int)tmpLong[0]; 14051 } 14052 14053 final long myTotalPss = mi.getTotalPss(); 14054 totalPss += myTotalPss; 14055 nativeProcTotalPss += myTotalPss; 14056 14057 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14058 st.name, myTotalPss, st.pid, false); 14059 procMems.add(pssItem); 14060 14061 nativePss += mi.nativePss; 14062 dalvikPss += mi.dalvikPss; 14063 otherPss += mi.otherPss; 14064 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14065 long mem = mi.getOtherPss(j); 14066 miscPss[j] += mem; 14067 otherPss -= mem; 14068 } 14069 oomPss[0] += myTotalPss; 14070 if (oomProcs[0] == null) { 14071 oomProcs[0] = new ArrayList<MemItem>(); 14072 } 14073 oomProcs[0].add(pssItem); 14074 } 14075 } 14076 } 14077 14078 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14079 14080 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14081 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14082 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14083 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14084 String label = Debug.MemoryInfo.getOtherLabel(j); 14085 catMems.add(new MemItem(label, label, miscPss[j], j)); 14086 } 14087 14088 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14089 for (int j=0; j<oomPss.length; j++) { 14090 if (oomPss[j] != 0) { 14091 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14092 : DUMP_MEM_OOM_LABEL[j]; 14093 MemItem item = new MemItem(label, label, oomPss[j], 14094 DUMP_MEM_OOM_ADJ[j]); 14095 item.subitems = oomProcs[j]; 14096 oomMems.add(item); 14097 } 14098 } 14099 14100 if (!brief && !oomOnly && !isCompact) { 14101 pw.println(); 14102 pw.println("Total PSS by process:"); 14103 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14104 pw.println(); 14105 } 14106 if (!isCompact) { 14107 pw.println("Total PSS by OOM adjustment:"); 14108 } 14109 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14110 if (!brief && !oomOnly) { 14111 PrintWriter out = categoryPw != null ? categoryPw : pw; 14112 if (!isCompact) { 14113 out.println(); 14114 out.println("Total PSS by category:"); 14115 } 14116 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14117 } 14118 if (!isCompact) { 14119 pw.println(); 14120 } 14121 MemInfoReader memInfo = new MemInfoReader(); 14122 memInfo.readMemInfo(); 14123 if (nativeProcTotalPss > 0) { 14124 synchronized (this) { 14125 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14126 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14127 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14128 } 14129 } 14130 if (!brief) { 14131 if (!isCompact) { 14132 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14133 pw.print(" kB (status "); 14134 switch (mLastMemoryLevel) { 14135 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14136 pw.println("normal)"); 14137 break; 14138 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14139 pw.println("moderate)"); 14140 break; 14141 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14142 pw.println("low)"); 14143 break; 14144 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14145 pw.println("critical)"); 14146 break; 14147 default: 14148 pw.print(mLastMemoryLevel); 14149 pw.println(")"); 14150 break; 14151 } 14152 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14153 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14154 pw.print(cachedPss); pw.print(" cached pss + "); 14155 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14156 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14157 } else { 14158 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14159 pw.print(cachedPss + memInfo.getCachedSizeKb() 14160 + memInfo.getFreeSizeKb()); pw.print(","); 14161 pw.println(totalPss - cachedPss); 14162 } 14163 } 14164 if (!isCompact) { 14165 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14166 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14167 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14168 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14169 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14170 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14171 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14172 } 14173 if (!brief) { 14174 if (memInfo.getZramTotalSizeKb() != 0) { 14175 if (!isCompact) { 14176 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14177 pw.print(" kB physical used for "); 14178 pw.print(memInfo.getSwapTotalSizeKb() 14179 - memInfo.getSwapFreeSizeKb()); 14180 pw.print(" kB in swap ("); 14181 pw.print(memInfo.getSwapTotalSizeKb()); 14182 pw.println(" kB total swap)"); 14183 } else { 14184 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14185 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14186 pw.println(memInfo.getSwapFreeSizeKb()); 14187 } 14188 } 14189 final long[] ksm = getKsmInfo(); 14190 if (!isCompact) { 14191 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14192 || ksm[KSM_VOLATILE] != 0) { 14193 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14194 pw.print(" kB saved from shared "); 14195 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14196 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14197 pw.print(" kB unshared; "); 14198 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14199 } 14200 pw.print(" Tuning: "); 14201 pw.print(ActivityManager.staticGetMemoryClass()); 14202 pw.print(" (large "); 14203 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14204 pw.print("), oom "); 14205 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14206 pw.print(" kB"); 14207 pw.print(", restore limit "); 14208 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14209 pw.print(" kB"); 14210 if (ActivityManager.isLowRamDeviceStatic()) { 14211 pw.print(" (low-ram)"); 14212 } 14213 if (ActivityManager.isHighEndGfx()) { 14214 pw.print(" (high-end-gfx)"); 14215 } 14216 pw.println(); 14217 } else { 14218 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14219 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14220 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14221 pw.print("tuning,"); 14222 pw.print(ActivityManager.staticGetMemoryClass()); 14223 pw.print(','); 14224 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14225 pw.print(','); 14226 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14227 if (ActivityManager.isLowRamDeviceStatic()) { 14228 pw.print(",low-ram"); 14229 } 14230 if (ActivityManager.isHighEndGfx()) { 14231 pw.print(",high-end-gfx"); 14232 } 14233 pw.println(); 14234 } 14235 } 14236 } 14237 } 14238 14239 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14240 String name) { 14241 sb.append(" "); 14242 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14243 sb.append(' '); 14244 sb.append(ProcessList.makeProcStateString(procState)); 14245 sb.append(' '); 14246 ProcessList.appendRamKb(sb, pss); 14247 sb.append(" kB: "); 14248 sb.append(name); 14249 } 14250 14251 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14252 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14253 sb.append(" ("); 14254 sb.append(mi.pid); 14255 sb.append(") "); 14256 sb.append(mi.adjType); 14257 sb.append('\n'); 14258 if (mi.adjReason != null) { 14259 sb.append(" "); 14260 sb.append(mi.adjReason); 14261 sb.append('\n'); 14262 } 14263 } 14264 14265 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14266 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14267 for (int i=0, N=memInfos.size(); i<N; i++) { 14268 ProcessMemInfo mi = memInfos.get(i); 14269 infoMap.put(mi.pid, mi); 14270 } 14271 updateCpuStatsNow(); 14272 synchronized (mProcessCpuTracker) { 14273 final int N = mProcessCpuTracker.countStats(); 14274 for (int i=0; i<N; i++) { 14275 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14276 if (st.vsize > 0) { 14277 long pss = Debug.getPss(st.pid, null); 14278 if (pss > 0) { 14279 if (infoMap.indexOfKey(st.pid) < 0) { 14280 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14281 ProcessList.NATIVE_ADJ, -1, "native", null); 14282 mi.pss = pss; 14283 memInfos.add(mi); 14284 } 14285 } 14286 } 14287 } 14288 } 14289 14290 long totalPss = 0; 14291 for (int i=0, N=memInfos.size(); i<N; i++) { 14292 ProcessMemInfo mi = memInfos.get(i); 14293 if (mi.pss == 0) { 14294 mi.pss = Debug.getPss(mi.pid, null); 14295 } 14296 totalPss += mi.pss; 14297 } 14298 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14299 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14300 if (lhs.oomAdj != rhs.oomAdj) { 14301 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14302 } 14303 if (lhs.pss != rhs.pss) { 14304 return lhs.pss < rhs.pss ? 1 : -1; 14305 } 14306 return 0; 14307 } 14308 }); 14309 14310 StringBuilder tag = new StringBuilder(128); 14311 StringBuilder stack = new StringBuilder(128); 14312 tag.append("Low on memory -- "); 14313 appendMemBucket(tag, totalPss, "total", false); 14314 appendMemBucket(stack, totalPss, "total", true); 14315 14316 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14317 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14318 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14319 14320 boolean firstLine = true; 14321 int lastOomAdj = Integer.MIN_VALUE; 14322 long extraNativeRam = 0; 14323 long cachedPss = 0; 14324 for (int i=0, N=memInfos.size(); i<N; i++) { 14325 ProcessMemInfo mi = memInfos.get(i); 14326 14327 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14328 cachedPss += mi.pss; 14329 } 14330 14331 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14332 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14333 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14334 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14335 if (lastOomAdj != mi.oomAdj) { 14336 lastOomAdj = mi.oomAdj; 14337 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14338 tag.append(" / "); 14339 } 14340 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14341 if (firstLine) { 14342 stack.append(":"); 14343 firstLine = false; 14344 } 14345 stack.append("\n\t at "); 14346 } else { 14347 stack.append("$"); 14348 } 14349 } else { 14350 tag.append(" "); 14351 stack.append("$"); 14352 } 14353 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14354 appendMemBucket(tag, mi.pss, mi.name, false); 14355 } 14356 appendMemBucket(stack, mi.pss, mi.name, true); 14357 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14358 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14359 stack.append("("); 14360 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14361 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14362 stack.append(DUMP_MEM_OOM_LABEL[k]); 14363 stack.append(":"); 14364 stack.append(DUMP_MEM_OOM_ADJ[k]); 14365 } 14366 } 14367 stack.append(")"); 14368 } 14369 } 14370 14371 appendMemInfo(fullNativeBuilder, mi); 14372 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14373 // The short form only has native processes that are >= 1MB. 14374 if (mi.pss >= 1000) { 14375 appendMemInfo(shortNativeBuilder, mi); 14376 } else { 14377 extraNativeRam += mi.pss; 14378 } 14379 } else { 14380 // Short form has all other details, but if we have collected RAM 14381 // from smaller native processes let's dump a summary of that. 14382 if (extraNativeRam > 0) { 14383 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14384 -1, extraNativeRam, "(Other native)"); 14385 shortNativeBuilder.append('\n'); 14386 extraNativeRam = 0; 14387 } 14388 appendMemInfo(fullJavaBuilder, mi); 14389 } 14390 } 14391 14392 fullJavaBuilder.append(" "); 14393 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14394 fullJavaBuilder.append(" kB: TOTAL\n"); 14395 14396 MemInfoReader memInfo = new MemInfoReader(); 14397 memInfo.readMemInfo(); 14398 final long[] infos = memInfo.getRawInfo(); 14399 14400 StringBuilder memInfoBuilder = new StringBuilder(1024); 14401 Debug.getMemInfo(infos); 14402 memInfoBuilder.append(" MemInfo: "); 14403 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14404 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14405 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14406 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14407 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14408 memInfoBuilder.append(" "); 14409 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14410 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14411 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14412 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14413 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14414 memInfoBuilder.append(" ZRAM: "); 14415 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14416 memInfoBuilder.append(" kB RAM, "); 14417 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14418 memInfoBuilder.append(" kB swap total, "); 14419 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14420 memInfoBuilder.append(" kB swap free\n"); 14421 } 14422 final long[] ksm = getKsmInfo(); 14423 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14424 || ksm[KSM_VOLATILE] != 0) { 14425 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14426 memInfoBuilder.append(" kB saved from shared "); 14427 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14428 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14429 memInfoBuilder.append(" kB unshared; "); 14430 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14431 } 14432 memInfoBuilder.append(" Free RAM: "); 14433 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14434 + memInfo.getFreeSizeKb()); 14435 memInfoBuilder.append(" kB\n"); 14436 memInfoBuilder.append(" Used RAM: "); 14437 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14438 memInfoBuilder.append(" kB\n"); 14439 memInfoBuilder.append(" Lost RAM: "); 14440 memInfoBuilder.append(memInfo.getTotalSizeKb() 14441 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14442 - memInfo.getKernelUsedSizeKb()); 14443 memInfoBuilder.append(" kB\n"); 14444 Slog.i(TAG, "Low on memory:"); 14445 Slog.i(TAG, shortNativeBuilder.toString()); 14446 Slog.i(TAG, fullJavaBuilder.toString()); 14447 Slog.i(TAG, memInfoBuilder.toString()); 14448 14449 StringBuilder dropBuilder = new StringBuilder(1024); 14450 /* 14451 StringWriter oomSw = new StringWriter(); 14452 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14453 StringWriter catSw = new StringWriter(); 14454 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14455 String[] emptyArgs = new String[] { }; 14456 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14457 oomPw.flush(); 14458 String oomString = oomSw.toString(); 14459 */ 14460 dropBuilder.append("Low on memory:"); 14461 dropBuilder.append(stack); 14462 dropBuilder.append('\n'); 14463 dropBuilder.append(fullNativeBuilder); 14464 dropBuilder.append(fullJavaBuilder); 14465 dropBuilder.append('\n'); 14466 dropBuilder.append(memInfoBuilder); 14467 dropBuilder.append('\n'); 14468 /* 14469 dropBuilder.append(oomString); 14470 dropBuilder.append('\n'); 14471 */ 14472 StringWriter catSw = new StringWriter(); 14473 synchronized (ActivityManagerService.this) { 14474 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14475 String[] emptyArgs = new String[] { }; 14476 catPw.println(); 14477 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14478 catPw.println(); 14479 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14480 false, false, null); 14481 catPw.println(); 14482 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14483 catPw.flush(); 14484 } 14485 dropBuilder.append(catSw.toString()); 14486 addErrorToDropBox("lowmem", null, "system_server", null, 14487 null, tag.toString(), dropBuilder.toString(), null, null); 14488 //Slog.i(TAG, "Sent to dropbox:"); 14489 //Slog.i(TAG, dropBuilder.toString()); 14490 synchronized (ActivityManagerService.this) { 14491 long now = SystemClock.uptimeMillis(); 14492 if (mLastMemUsageReportTime < now) { 14493 mLastMemUsageReportTime = now; 14494 } 14495 } 14496 } 14497 14498 /** 14499 * Searches array of arguments for the specified string 14500 * @param args array of argument strings 14501 * @param value value to search for 14502 * @return true if the value is contained in the array 14503 */ 14504 private static boolean scanArgs(String[] args, String value) { 14505 if (args != null) { 14506 for (String arg : args) { 14507 if (value.equals(arg)) { 14508 return true; 14509 } 14510 } 14511 } 14512 return false; 14513 } 14514 14515 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14516 ContentProviderRecord cpr, boolean always) { 14517 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14518 14519 if (!inLaunching || always) { 14520 synchronized (cpr) { 14521 cpr.launchingApp = null; 14522 cpr.notifyAll(); 14523 } 14524 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14525 String names[] = cpr.info.authority.split(";"); 14526 for (int j = 0; j < names.length; j++) { 14527 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14528 } 14529 } 14530 14531 for (int i=0; i<cpr.connections.size(); i++) { 14532 ContentProviderConnection conn = cpr.connections.get(i); 14533 if (conn.waiting) { 14534 // If this connection is waiting for the provider, then we don't 14535 // need to mess with its process unless we are always removing 14536 // or for some reason the provider is not currently launching. 14537 if (inLaunching && !always) { 14538 continue; 14539 } 14540 } 14541 ProcessRecord capp = conn.client; 14542 conn.dead = true; 14543 if (conn.stableCount > 0) { 14544 if (!capp.persistent && capp.thread != null 14545 && capp.pid != 0 14546 && capp.pid != MY_PID) { 14547 capp.kill("depends on provider " 14548 + cpr.name.flattenToShortString() 14549 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14550 } 14551 } else if (capp.thread != null && conn.provider.provider != null) { 14552 try { 14553 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14554 } catch (RemoteException e) { 14555 } 14556 // In the protocol here, we don't expect the client to correctly 14557 // clean up this connection, we'll just remove it. 14558 cpr.connections.remove(i); 14559 conn.client.conProviders.remove(conn); 14560 } 14561 } 14562 14563 if (inLaunching && always) { 14564 mLaunchingProviders.remove(cpr); 14565 } 14566 return inLaunching; 14567 } 14568 14569 /** 14570 * Main code for cleaning up a process when it has gone away. This is 14571 * called both as a result of the process dying, or directly when stopping 14572 * a process when running in single process mode. 14573 * 14574 * @return Returns true if the given process has been restarted, so the 14575 * app that was passed in must remain on the process lists. 14576 */ 14577 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14578 boolean restarting, boolean allowRestart, int index) { 14579 if (index >= 0) { 14580 removeLruProcessLocked(app); 14581 ProcessList.remove(app.pid); 14582 } 14583 14584 mProcessesToGc.remove(app); 14585 mPendingPssProcesses.remove(app); 14586 14587 // Dismiss any open dialogs. 14588 if (app.crashDialog != null && !app.forceCrashReport) { 14589 app.crashDialog.dismiss(); 14590 app.crashDialog = null; 14591 } 14592 if (app.anrDialog != null) { 14593 app.anrDialog.dismiss(); 14594 app.anrDialog = null; 14595 } 14596 if (app.waitDialog != null) { 14597 app.waitDialog.dismiss(); 14598 app.waitDialog = null; 14599 } 14600 14601 app.crashing = false; 14602 app.notResponding = false; 14603 14604 app.resetPackageList(mProcessStats); 14605 app.unlinkDeathRecipient(); 14606 app.makeInactive(mProcessStats); 14607 app.waitingToKill = null; 14608 app.forcingToForeground = null; 14609 updateProcessForegroundLocked(app, false, false); 14610 app.foregroundActivities = false; 14611 app.hasShownUi = false; 14612 app.treatLikeActivity = false; 14613 app.hasAboveClient = false; 14614 app.hasClientActivities = false; 14615 14616 mServices.killServicesLocked(app, allowRestart); 14617 14618 boolean restart = false; 14619 14620 // Remove published content providers. 14621 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14622 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14623 final boolean always = app.bad || !allowRestart; 14624 if (removeDyingProviderLocked(app, cpr, always) || always) { 14625 // We left the provider in the launching list, need to 14626 // restart it. 14627 restart = true; 14628 } 14629 14630 cpr.provider = null; 14631 cpr.proc = null; 14632 } 14633 app.pubProviders.clear(); 14634 14635 // Take care of any launching providers waiting for this process. 14636 if (checkAppInLaunchingProvidersLocked(app, false)) { 14637 restart = true; 14638 } 14639 14640 // Unregister from connected content providers. 14641 if (!app.conProviders.isEmpty()) { 14642 for (int i=0; i<app.conProviders.size(); i++) { 14643 ContentProviderConnection conn = app.conProviders.get(i); 14644 conn.provider.connections.remove(conn); 14645 } 14646 app.conProviders.clear(); 14647 } 14648 14649 // At this point there may be remaining entries in mLaunchingProviders 14650 // where we were the only one waiting, so they are no longer of use. 14651 // Look for these and clean up if found. 14652 // XXX Commented out for now. Trying to figure out a way to reproduce 14653 // the actual situation to identify what is actually going on. 14654 if (false) { 14655 for (int i=0; i<mLaunchingProviders.size(); i++) { 14656 ContentProviderRecord cpr = (ContentProviderRecord) 14657 mLaunchingProviders.get(i); 14658 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14659 synchronized (cpr) { 14660 cpr.launchingApp = null; 14661 cpr.notifyAll(); 14662 } 14663 } 14664 } 14665 } 14666 14667 skipCurrentReceiverLocked(app); 14668 14669 // Unregister any receivers. 14670 for (int i=app.receivers.size()-1; i>=0; i--) { 14671 removeReceiverLocked(app.receivers.valueAt(i)); 14672 } 14673 app.receivers.clear(); 14674 14675 // If the app is undergoing backup, tell the backup manager about it 14676 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14677 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14678 + mBackupTarget.appInfo + " died during backup"); 14679 try { 14680 IBackupManager bm = IBackupManager.Stub.asInterface( 14681 ServiceManager.getService(Context.BACKUP_SERVICE)); 14682 bm.agentDisconnected(app.info.packageName); 14683 } catch (RemoteException e) { 14684 // can't happen; backup manager is local 14685 } 14686 } 14687 14688 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14689 ProcessChangeItem item = mPendingProcessChanges.get(i); 14690 if (item.pid == app.pid) { 14691 mPendingProcessChanges.remove(i); 14692 mAvailProcessChanges.add(item); 14693 } 14694 } 14695 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14696 14697 // If the caller is restarting this app, then leave it in its 14698 // current lists and let the caller take care of it. 14699 if (restarting) { 14700 return false; 14701 } 14702 14703 if (!app.persistent || app.isolated) { 14704 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14705 "Removing non-persistent process during cleanup: " + app); 14706 mProcessNames.remove(app.processName, app.uid); 14707 mIsolatedProcesses.remove(app.uid); 14708 if (mHeavyWeightProcess == app) { 14709 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14710 mHeavyWeightProcess.userId, 0)); 14711 mHeavyWeightProcess = null; 14712 } 14713 } else if (!app.removed) { 14714 // This app is persistent, so we need to keep its record around. 14715 // If it is not already on the pending app list, add it there 14716 // and start a new process for it. 14717 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14718 mPersistentStartingProcesses.add(app); 14719 restart = true; 14720 } 14721 } 14722 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14723 "Clean-up removing on hold: " + app); 14724 mProcessesOnHold.remove(app); 14725 14726 if (app == mHomeProcess) { 14727 mHomeProcess = null; 14728 } 14729 if (app == mPreviousProcess) { 14730 mPreviousProcess = null; 14731 } 14732 14733 if (restart && !app.isolated) { 14734 // We have components that still need to be running in the 14735 // process, so re-launch it. 14736 if (index < 0) { 14737 ProcessList.remove(app.pid); 14738 } 14739 mProcessNames.put(app.processName, app.uid, app); 14740 startProcessLocked(app, "restart", app.processName); 14741 return true; 14742 } else if (app.pid > 0 && app.pid != MY_PID) { 14743 // Goodbye! 14744 boolean removed; 14745 synchronized (mPidsSelfLocked) { 14746 mPidsSelfLocked.remove(app.pid); 14747 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14748 } 14749 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14750 if (app.isolated) { 14751 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14752 } 14753 app.setPid(0); 14754 } 14755 return false; 14756 } 14757 14758 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14759 // Look through the content providers we are waiting to have launched, 14760 // and if any run in this process then either schedule a restart of 14761 // the process or kill the client waiting for it if this process has 14762 // gone bad. 14763 int NL = mLaunchingProviders.size(); 14764 boolean restart = false; 14765 for (int i=0; i<NL; i++) { 14766 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14767 if (cpr.launchingApp == app) { 14768 if (!alwaysBad && !app.bad) { 14769 restart = true; 14770 } else { 14771 removeDyingProviderLocked(app, cpr, true); 14772 // cpr should have been removed from mLaunchingProviders 14773 NL = mLaunchingProviders.size(); 14774 i--; 14775 } 14776 } 14777 } 14778 return restart; 14779 } 14780 14781 // ========================================================= 14782 // SERVICES 14783 // ========================================================= 14784 14785 @Override 14786 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14787 int flags) { 14788 enforceNotIsolatedCaller("getServices"); 14789 synchronized (this) { 14790 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14791 } 14792 } 14793 14794 @Override 14795 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14796 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14797 synchronized (this) { 14798 return mServices.getRunningServiceControlPanelLocked(name); 14799 } 14800 } 14801 14802 @Override 14803 public ComponentName startService(IApplicationThread caller, Intent service, 14804 String resolvedType, int userId) { 14805 enforceNotIsolatedCaller("startService"); 14806 // Refuse possible leaked file descriptors 14807 if (service != null && service.hasFileDescriptors() == true) { 14808 throw new IllegalArgumentException("File descriptors passed in Intent"); 14809 } 14810 14811 if (DEBUG_SERVICE) 14812 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14813 synchronized(this) { 14814 final int callingPid = Binder.getCallingPid(); 14815 final int callingUid = Binder.getCallingUid(); 14816 final long origId = Binder.clearCallingIdentity(); 14817 ComponentName res = mServices.startServiceLocked(caller, service, 14818 resolvedType, callingPid, callingUid, userId); 14819 Binder.restoreCallingIdentity(origId); 14820 return res; 14821 } 14822 } 14823 14824 ComponentName startServiceInPackage(int uid, 14825 Intent service, String resolvedType, int userId) { 14826 synchronized(this) { 14827 if (DEBUG_SERVICE) 14828 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14829 final long origId = Binder.clearCallingIdentity(); 14830 ComponentName res = mServices.startServiceLocked(null, service, 14831 resolvedType, -1, uid, userId); 14832 Binder.restoreCallingIdentity(origId); 14833 return res; 14834 } 14835 } 14836 14837 @Override 14838 public int stopService(IApplicationThread caller, Intent service, 14839 String resolvedType, int userId) { 14840 enforceNotIsolatedCaller("stopService"); 14841 // Refuse possible leaked file descriptors 14842 if (service != null && service.hasFileDescriptors() == true) { 14843 throw new IllegalArgumentException("File descriptors passed in Intent"); 14844 } 14845 14846 synchronized(this) { 14847 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14848 } 14849 } 14850 14851 @Override 14852 public IBinder peekService(Intent service, String resolvedType) { 14853 enforceNotIsolatedCaller("peekService"); 14854 // Refuse possible leaked file descriptors 14855 if (service != null && service.hasFileDescriptors() == true) { 14856 throw new IllegalArgumentException("File descriptors passed in Intent"); 14857 } 14858 synchronized(this) { 14859 return mServices.peekServiceLocked(service, resolvedType); 14860 } 14861 } 14862 14863 @Override 14864 public boolean stopServiceToken(ComponentName className, IBinder token, 14865 int startId) { 14866 synchronized(this) { 14867 return mServices.stopServiceTokenLocked(className, token, startId); 14868 } 14869 } 14870 14871 @Override 14872 public void setServiceForeground(ComponentName className, IBinder token, 14873 int id, Notification notification, boolean removeNotification) { 14874 synchronized(this) { 14875 mServices.setServiceForegroundLocked(className, token, id, notification, 14876 removeNotification); 14877 } 14878 } 14879 14880 @Override 14881 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14882 boolean requireFull, String name, String callerPackage) { 14883 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14884 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14885 } 14886 14887 int unsafeConvertIncomingUser(int userId) { 14888 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14889 ? mCurrentUserId : userId; 14890 } 14891 14892 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14893 int allowMode, String name, String callerPackage) { 14894 final int callingUserId = UserHandle.getUserId(callingUid); 14895 if (callingUserId == userId) { 14896 return userId; 14897 } 14898 14899 // Note that we may be accessing mCurrentUserId outside of a lock... 14900 // shouldn't be a big deal, if this is being called outside 14901 // of a locked context there is intrinsically a race with 14902 // the value the caller will receive and someone else changing it. 14903 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14904 // we will switch to the calling user if access to the current user fails. 14905 int targetUserId = unsafeConvertIncomingUser(userId); 14906 14907 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14908 final boolean allow; 14909 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14910 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14911 // If the caller has this permission, they always pass go. And collect $200. 14912 allow = true; 14913 } else if (allowMode == ALLOW_FULL_ONLY) { 14914 // We require full access, sucks to be you. 14915 allow = false; 14916 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14917 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14918 // If the caller does not have either permission, they are always doomed. 14919 allow = false; 14920 } else if (allowMode == ALLOW_NON_FULL) { 14921 // We are blanket allowing non-full access, you lucky caller! 14922 allow = true; 14923 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14924 // We may or may not allow this depending on whether the two users are 14925 // in the same profile. 14926 synchronized (mUserProfileGroupIdsSelfLocked) { 14927 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14928 UserInfo.NO_PROFILE_GROUP_ID); 14929 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14930 UserInfo.NO_PROFILE_GROUP_ID); 14931 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14932 && callingProfile == targetProfile; 14933 } 14934 } else { 14935 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14936 } 14937 if (!allow) { 14938 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14939 // In this case, they would like to just execute as their 14940 // owner user instead of failing. 14941 targetUserId = callingUserId; 14942 } else { 14943 StringBuilder builder = new StringBuilder(128); 14944 builder.append("Permission Denial: "); 14945 builder.append(name); 14946 if (callerPackage != null) { 14947 builder.append(" from "); 14948 builder.append(callerPackage); 14949 } 14950 builder.append(" asks to run as user "); 14951 builder.append(userId); 14952 builder.append(" but is calling from user "); 14953 builder.append(UserHandle.getUserId(callingUid)); 14954 builder.append("; this requires "); 14955 builder.append(INTERACT_ACROSS_USERS_FULL); 14956 if (allowMode != ALLOW_FULL_ONLY) { 14957 builder.append(" or "); 14958 builder.append(INTERACT_ACROSS_USERS); 14959 } 14960 String msg = builder.toString(); 14961 Slog.w(TAG, msg); 14962 throw new SecurityException(msg); 14963 } 14964 } 14965 } 14966 if (!allowAll && targetUserId < 0) { 14967 throw new IllegalArgumentException( 14968 "Call does not support special user #" + targetUserId); 14969 } 14970 // Check shell permission 14971 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14972 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14973 targetUserId)) { 14974 throw new SecurityException("Shell does not have permission to access user " 14975 + targetUserId + "\n " + Debug.getCallers(3)); 14976 } 14977 } 14978 return targetUserId; 14979 } 14980 14981 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14982 String className, int flags) { 14983 boolean result = false; 14984 // For apps that don't have pre-defined UIDs, check for permission 14985 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14986 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14987 if (ActivityManager.checkUidPermission( 14988 INTERACT_ACROSS_USERS, 14989 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14990 ComponentName comp = new ComponentName(aInfo.packageName, className); 14991 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14992 + " requests FLAG_SINGLE_USER, but app does not hold " 14993 + INTERACT_ACROSS_USERS; 14994 Slog.w(TAG, msg); 14995 throw new SecurityException(msg); 14996 } 14997 // Permission passed 14998 result = true; 14999 } 15000 } else if ("system".equals(componentProcessName)) { 15001 result = true; 15002 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15003 // Phone app and persistent apps are allowed to export singleuser providers. 15004 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15005 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15006 } 15007 if (DEBUG_MU) { 15008 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15009 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15010 } 15011 return result; 15012 } 15013 15014 /** 15015 * Checks to see if the caller is in the same app as the singleton 15016 * component, or the component is in a special app. It allows special apps 15017 * to export singleton components but prevents exporting singleton 15018 * components for regular apps. 15019 */ 15020 boolean isValidSingletonCall(int callingUid, int componentUid) { 15021 int componentAppId = UserHandle.getAppId(componentUid); 15022 return UserHandle.isSameApp(callingUid, componentUid) 15023 || componentAppId == Process.SYSTEM_UID 15024 || componentAppId == Process.PHONE_UID 15025 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15026 == PackageManager.PERMISSION_GRANTED; 15027 } 15028 15029 public int bindService(IApplicationThread caller, IBinder token, 15030 Intent service, String resolvedType, 15031 IServiceConnection connection, int flags, int userId) { 15032 enforceNotIsolatedCaller("bindService"); 15033 15034 // Refuse possible leaked file descriptors 15035 if (service != null && service.hasFileDescriptors() == true) { 15036 throw new IllegalArgumentException("File descriptors passed in Intent"); 15037 } 15038 15039 synchronized(this) { 15040 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15041 connection, flags, userId); 15042 } 15043 } 15044 15045 public boolean unbindService(IServiceConnection connection) { 15046 synchronized (this) { 15047 return mServices.unbindServiceLocked(connection); 15048 } 15049 } 15050 15051 public void publishService(IBinder token, Intent intent, IBinder service) { 15052 // Refuse possible leaked file descriptors 15053 if (intent != null && intent.hasFileDescriptors() == true) { 15054 throw new IllegalArgumentException("File descriptors passed in Intent"); 15055 } 15056 15057 synchronized(this) { 15058 if (!(token instanceof ServiceRecord)) { 15059 throw new IllegalArgumentException("Invalid service token"); 15060 } 15061 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15062 } 15063 } 15064 15065 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15066 // Refuse possible leaked file descriptors 15067 if (intent != null && intent.hasFileDescriptors() == true) { 15068 throw new IllegalArgumentException("File descriptors passed in Intent"); 15069 } 15070 15071 synchronized(this) { 15072 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15073 } 15074 } 15075 15076 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15077 synchronized(this) { 15078 if (!(token instanceof ServiceRecord)) { 15079 throw new IllegalArgumentException("Invalid service token"); 15080 } 15081 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15082 } 15083 } 15084 15085 // ========================================================= 15086 // BACKUP AND RESTORE 15087 // ========================================================= 15088 15089 // Cause the target app to be launched if necessary and its backup agent 15090 // instantiated. The backup agent will invoke backupAgentCreated() on the 15091 // activity manager to announce its creation. 15092 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15093 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15094 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15095 15096 synchronized(this) { 15097 // !!! TODO: currently no check here that we're already bound 15098 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15099 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15100 synchronized (stats) { 15101 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15102 } 15103 15104 // Backup agent is now in use, its package can't be stopped. 15105 try { 15106 AppGlobals.getPackageManager().setPackageStoppedState( 15107 app.packageName, false, UserHandle.getUserId(app.uid)); 15108 } catch (RemoteException e) { 15109 } catch (IllegalArgumentException e) { 15110 Slog.w(TAG, "Failed trying to unstop package " 15111 + app.packageName + ": " + e); 15112 } 15113 15114 BackupRecord r = new BackupRecord(ss, app, backupMode); 15115 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15116 ? new ComponentName(app.packageName, app.backupAgentName) 15117 : new ComponentName("android", "FullBackupAgent"); 15118 // startProcessLocked() returns existing proc's record if it's already running 15119 ProcessRecord proc = startProcessLocked(app.processName, app, 15120 false, 0, "backup", hostingName, false, false, false); 15121 if (proc == null) { 15122 Slog.e(TAG, "Unable to start backup agent process " + r); 15123 return false; 15124 } 15125 15126 r.app = proc; 15127 mBackupTarget = r; 15128 mBackupAppName = app.packageName; 15129 15130 // Try not to kill the process during backup 15131 updateOomAdjLocked(proc); 15132 15133 // If the process is already attached, schedule the creation of the backup agent now. 15134 // If it is not yet live, this will be done when it attaches to the framework. 15135 if (proc.thread != null) { 15136 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15137 try { 15138 proc.thread.scheduleCreateBackupAgent(app, 15139 compatibilityInfoForPackageLocked(app), backupMode); 15140 } catch (RemoteException e) { 15141 // Will time out on the backup manager side 15142 } 15143 } else { 15144 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15145 } 15146 // Invariants: at this point, the target app process exists and the application 15147 // is either already running or in the process of coming up. mBackupTarget and 15148 // mBackupAppName describe the app, so that when it binds back to the AM we 15149 // know that it's scheduled for a backup-agent operation. 15150 } 15151 15152 return true; 15153 } 15154 15155 @Override 15156 public void clearPendingBackup() { 15157 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15158 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15159 15160 synchronized (this) { 15161 mBackupTarget = null; 15162 mBackupAppName = null; 15163 } 15164 } 15165 15166 // A backup agent has just come up 15167 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15168 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15169 + " = " + agent); 15170 15171 synchronized(this) { 15172 if (!agentPackageName.equals(mBackupAppName)) { 15173 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15174 return; 15175 } 15176 } 15177 15178 long oldIdent = Binder.clearCallingIdentity(); 15179 try { 15180 IBackupManager bm = IBackupManager.Stub.asInterface( 15181 ServiceManager.getService(Context.BACKUP_SERVICE)); 15182 bm.agentConnected(agentPackageName, agent); 15183 } catch (RemoteException e) { 15184 // can't happen; the backup manager service is local 15185 } catch (Exception e) { 15186 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15187 e.printStackTrace(); 15188 } finally { 15189 Binder.restoreCallingIdentity(oldIdent); 15190 } 15191 } 15192 15193 // done with this agent 15194 public void unbindBackupAgent(ApplicationInfo appInfo) { 15195 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15196 if (appInfo == null) { 15197 Slog.w(TAG, "unbind backup agent for null app"); 15198 return; 15199 } 15200 15201 synchronized(this) { 15202 try { 15203 if (mBackupAppName == null) { 15204 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15205 return; 15206 } 15207 15208 if (!mBackupAppName.equals(appInfo.packageName)) { 15209 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15210 return; 15211 } 15212 15213 // Not backing this app up any more; reset its OOM adjustment 15214 final ProcessRecord proc = mBackupTarget.app; 15215 updateOomAdjLocked(proc); 15216 15217 // If the app crashed during backup, 'thread' will be null here 15218 if (proc.thread != null) { 15219 try { 15220 proc.thread.scheduleDestroyBackupAgent(appInfo, 15221 compatibilityInfoForPackageLocked(appInfo)); 15222 } catch (Exception e) { 15223 Slog.e(TAG, "Exception when unbinding backup agent:"); 15224 e.printStackTrace(); 15225 } 15226 } 15227 } finally { 15228 mBackupTarget = null; 15229 mBackupAppName = null; 15230 } 15231 } 15232 } 15233 // ========================================================= 15234 // BROADCASTS 15235 // ========================================================= 15236 15237 private final List getStickiesLocked(String action, IntentFilter filter, 15238 List cur, int userId) { 15239 final ContentResolver resolver = mContext.getContentResolver(); 15240 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15241 if (stickies == null) { 15242 return cur; 15243 } 15244 final ArrayList<Intent> list = stickies.get(action); 15245 if (list == null) { 15246 return cur; 15247 } 15248 int N = list.size(); 15249 for (int i=0; i<N; i++) { 15250 Intent intent = list.get(i); 15251 if (filter.match(resolver, intent, true, TAG) >= 0) { 15252 if (cur == null) { 15253 cur = new ArrayList<Intent>(); 15254 } 15255 cur.add(intent); 15256 } 15257 } 15258 return cur; 15259 } 15260 15261 boolean isPendingBroadcastProcessLocked(int pid) { 15262 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15263 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15264 } 15265 15266 void skipPendingBroadcastLocked(int pid) { 15267 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15268 for (BroadcastQueue queue : mBroadcastQueues) { 15269 queue.skipPendingBroadcastLocked(pid); 15270 } 15271 } 15272 15273 // The app just attached; send any pending broadcasts that it should receive 15274 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15275 boolean didSomething = false; 15276 for (BroadcastQueue queue : mBroadcastQueues) { 15277 didSomething |= queue.sendPendingBroadcastsLocked(app); 15278 } 15279 return didSomething; 15280 } 15281 15282 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15283 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15284 enforceNotIsolatedCaller("registerReceiver"); 15285 int callingUid; 15286 int callingPid; 15287 synchronized(this) { 15288 ProcessRecord callerApp = null; 15289 if (caller != null) { 15290 callerApp = getRecordForAppLocked(caller); 15291 if (callerApp == null) { 15292 throw new SecurityException( 15293 "Unable to find app for caller " + caller 15294 + " (pid=" + Binder.getCallingPid() 15295 + ") when registering receiver " + receiver); 15296 } 15297 if (callerApp.info.uid != Process.SYSTEM_UID && 15298 !callerApp.pkgList.containsKey(callerPackage) && 15299 !"android".equals(callerPackage)) { 15300 throw new SecurityException("Given caller package " + callerPackage 15301 + " is not running in process " + callerApp); 15302 } 15303 callingUid = callerApp.info.uid; 15304 callingPid = callerApp.pid; 15305 } else { 15306 callerPackage = null; 15307 callingUid = Binder.getCallingUid(); 15308 callingPid = Binder.getCallingPid(); 15309 } 15310 15311 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15312 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15313 15314 List allSticky = null; 15315 15316 // Look for any matching sticky broadcasts... 15317 Iterator actions = filter.actionsIterator(); 15318 if (actions != null) { 15319 while (actions.hasNext()) { 15320 String action = (String)actions.next(); 15321 allSticky = getStickiesLocked(action, filter, allSticky, 15322 UserHandle.USER_ALL); 15323 allSticky = getStickiesLocked(action, filter, allSticky, 15324 UserHandle.getUserId(callingUid)); 15325 } 15326 } else { 15327 allSticky = getStickiesLocked(null, filter, allSticky, 15328 UserHandle.USER_ALL); 15329 allSticky = getStickiesLocked(null, filter, allSticky, 15330 UserHandle.getUserId(callingUid)); 15331 } 15332 15333 // The first sticky in the list is returned directly back to 15334 // the client. 15335 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15336 15337 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15338 + ": " + sticky); 15339 15340 if (receiver == null) { 15341 return sticky; 15342 } 15343 15344 ReceiverList rl 15345 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15346 if (rl == null) { 15347 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15348 userId, receiver); 15349 if (rl.app != null) { 15350 rl.app.receivers.add(rl); 15351 } else { 15352 try { 15353 receiver.asBinder().linkToDeath(rl, 0); 15354 } catch (RemoteException e) { 15355 return sticky; 15356 } 15357 rl.linkedToDeath = true; 15358 } 15359 mRegisteredReceivers.put(receiver.asBinder(), rl); 15360 } else if (rl.uid != callingUid) { 15361 throw new IllegalArgumentException( 15362 "Receiver requested to register for uid " + callingUid 15363 + " was previously registered for uid " + rl.uid); 15364 } else if (rl.pid != callingPid) { 15365 throw new IllegalArgumentException( 15366 "Receiver requested to register for pid " + callingPid 15367 + " was previously registered for pid " + rl.pid); 15368 } else if (rl.userId != userId) { 15369 throw new IllegalArgumentException( 15370 "Receiver requested to register for user " + userId 15371 + " was previously registered for user " + rl.userId); 15372 } 15373 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15374 permission, callingUid, userId); 15375 rl.add(bf); 15376 if (!bf.debugCheck()) { 15377 Slog.w(TAG, "==> For Dynamic broadast"); 15378 } 15379 mReceiverResolver.addFilter(bf); 15380 15381 // Enqueue broadcasts for all existing stickies that match 15382 // this filter. 15383 if (allSticky != null) { 15384 ArrayList receivers = new ArrayList(); 15385 receivers.add(bf); 15386 15387 int N = allSticky.size(); 15388 for (int i=0; i<N; i++) { 15389 Intent intent = (Intent)allSticky.get(i); 15390 BroadcastQueue queue = broadcastQueueForIntent(intent); 15391 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15392 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15393 null, null, false, true, true, -1); 15394 queue.enqueueParallelBroadcastLocked(r); 15395 queue.scheduleBroadcastsLocked(); 15396 } 15397 } 15398 15399 return sticky; 15400 } 15401 } 15402 15403 public void unregisterReceiver(IIntentReceiver receiver) { 15404 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15405 15406 final long origId = Binder.clearCallingIdentity(); 15407 try { 15408 boolean doTrim = false; 15409 15410 synchronized(this) { 15411 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15412 if (rl != null) { 15413 if (rl.curBroadcast != null) { 15414 BroadcastRecord r = rl.curBroadcast; 15415 final boolean doNext = finishReceiverLocked( 15416 receiver.asBinder(), r.resultCode, r.resultData, 15417 r.resultExtras, r.resultAbort); 15418 if (doNext) { 15419 doTrim = true; 15420 r.queue.processNextBroadcast(false); 15421 } 15422 } 15423 15424 if (rl.app != null) { 15425 rl.app.receivers.remove(rl); 15426 } 15427 removeReceiverLocked(rl); 15428 if (rl.linkedToDeath) { 15429 rl.linkedToDeath = false; 15430 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15431 } 15432 } 15433 } 15434 15435 // If we actually concluded any broadcasts, we might now be able 15436 // to trim the recipients' apps from our working set 15437 if (doTrim) { 15438 trimApplications(); 15439 return; 15440 } 15441 15442 } finally { 15443 Binder.restoreCallingIdentity(origId); 15444 } 15445 } 15446 15447 void removeReceiverLocked(ReceiverList rl) { 15448 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15449 int N = rl.size(); 15450 for (int i=0; i<N; i++) { 15451 mReceiverResolver.removeFilter(rl.get(i)); 15452 } 15453 } 15454 15455 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15456 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15457 ProcessRecord r = mLruProcesses.get(i); 15458 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15459 try { 15460 r.thread.dispatchPackageBroadcast(cmd, packages); 15461 } catch (RemoteException ex) { 15462 } 15463 } 15464 } 15465 } 15466 15467 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15468 int callingUid, int[] users) { 15469 List<ResolveInfo> receivers = null; 15470 try { 15471 HashSet<ComponentName> singleUserReceivers = null; 15472 boolean scannedFirstReceivers = false; 15473 for (int user : users) { 15474 // Skip users that have Shell restrictions 15475 if (callingUid == Process.SHELL_UID 15476 && getUserManagerLocked().hasUserRestriction( 15477 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15478 continue; 15479 } 15480 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15481 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15482 if (user != 0 && newReceivers != null) { 15483 // If this is not the primary user, we need to check for 15484 // any receivers that should be filtered out. 15485 for (int i=0; i<newReceivers.size(); i++) { 15486 ResolveInfo ri = newReceivers.get(i); 15487 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15488 newReceivers.remove(i); 15489 i--; 15490 } 15491 } 15492 } 15493 if (newReceivers != null && newReceivers.size() == 0) { 15494 newReceivers = null; 15495 } 15496 if (receivers == null) { 15497 receivers = newReceivers; 15498 } else if (newReceivers != null) { 15499 // We need to concatenate the additional receivers 15500 // found with what we have do far. This would be easy, 15501 // but we also need to de-dup any receivers that are 15502 // singleUser. 15503 if (!scannedFirstReceivers) { 15504 // Collect any single user receivers we had already retrieved. 15505 scannedFirstReceivers = true; 15506 for (int i=0; i<receivers.size(); i++) { 15507 ResolveInfo ri = receivers.get(i); 15508 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15509 ComponentName cn = new ComponentName( 15510 ri.activityInfo.packageName, ri.activityInfo.name); 15511 if (singleUserReceivers == null) { 15512 singleUserReceivers = new HashSet<ComponentName>(); 15513 } 15514 singleUserReceivers.add(cn); 15515 } 15516 } 15517 } 15518 // Add the new results to the existing results, tracking 15519 // and de-dupping single user receivers. 15520 for (int i=0; i<newReceivers.size(); i++) { 15521 ResolveInfo ri = newReceivers.get(i); 15522 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15523 ComponentName cn = new ComponentName( 15524 ri.activityInfo.packageName, ri.activityInfo.name); 15525 if (singleUserReceivers == null) { 15526 singleUserReceivers = new HashSet<ComponentName>(); 15527 } 15528 if (!singleUserReceivers.contains(cn)) { 15529 singleUserReceivers.add(cn); 15530 receivers.add(ri); 15531 } 15532 } else { 15533 receivers.add(ri); 15534 } 15535 } 15536 } 15537 } 15538 } catch (RemoteException ex) { 15539 // pm is in same process, this will never happen. 15540 } 15541 return receivers; 15542 } 15543 15544 private final int broadcastIntentLocked(ProcessRecord callerApp, 15545 String callerPackage, Intent intent, String resolvedType, 15546 IIntentReceiver resultTo, int resultCode, String resultData, 15547 Bundle map, String requiredPermission, int appOp, 15548 boolean ordered, boolean sticky, int callingPid, int callingUid, 15549 int userId) { 15550 intent = new Intent(intent); 15551 15552 // By default broadcasts do not go to stopped apps. 15553 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15554 15555 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15556 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15557 + " ordered=" + ordered + " userid=" + userId); 15558 if ((resultTo != null) && !ordered) { 15559 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15560 } 15561 15562 userId = handleIncomingUser(callingPid, callingUid, userId, 15563 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15564 15565 // Make sure that the user who is receiving this broadcast is started. 15566 // If not, we will just skip it. 15567 15568 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15569 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15570 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15571 Slog.w(TAG, "Skipping broadcast of " + intent 15572 + ": user " + userId + " is stopped"); 15573 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15574 } 15575 } 15576 15577 /* 15578 * Prevent non-system code (defined here to be non-persistent 15579 * processes) from sending protected broadcasts. 15580 */ 15581 int callingAppId = UserHandle.getAppId(callingUid); 15582 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15583 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15584 || callingAppId == Process.NFC_UID || callingUid == 0) { 15585 // Always okay. 15586 } else if (callerApp == null || !callerApp.persistent) { 15587 try { 15588 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15589 intent.getAction())) { 15590 String msg = "Permission Denial: not allowed to send broadcast " 15591 + intent.getAction() + " from pid=" 15592 + callingPid + ", uid=" + callingUid; 15593 Slog.w(TAG, msg); 15594 throw new SecurityException(msg); 15595 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15596 // Special case for compatibility: we don't want apps to send this, 15597 // but historically it has not been protected and apps may be using it 15598 // to poke their own app widget. So, instead of making it protected, 15599 // just limit it to the caller. 15600 if (callerApp == null) { 15601 String msg = "Permission Denial: not allowed to send broadcast " 15602 + intent.getAction() + " from unknown caller."; 15603 Slog.w(TAG, msg); 15604 throw new SecurityException(msg); 15605 } else if (intent.getComponent() != null) { 15606 // They are good enough to send to an explicit component... verify 15607 // it is being sent to the calling app. 15608 if (!intent.getComponent().getPackageName().equals( 15609 callerApp.info.packageName)) { 15610 String msg = "Permission Denial: not allowed to send broadcast " 15611 + intent.getAction() + " to " 15612 + intent.getComponent().getPackageName() + " from " 15613 + callerApp.info.packageName; 15614 Slog.w(TAG, msg); 15615 throw new SecurityException(msg); 15616 } 15617 } else { 15618 // Limit broadcast to their own package. 15619 intent.setPackage(callerApp.info.packageName); 15620 } 15621 } 15622 } catch (RemoteException e) { 15623 Slog.w(TAG, "Remote exception", e); 15624 return ActivityManager.BROADCAST_SUCCESS; 15625 } 15626 } 15627 15628 final String action = intent.getAction(); 15629 if (action != null) { 15630 switch (action) { 15631 case Intent.ACTION_UID_REMOVED: 15632 case Intent.ACTION_PACKAGE_REMOVED: 15633 case Intent.ACTION_PACKAGE_CHANGED: 15634 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15635 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15636 // Handle special intents: if this broadcast is from the package 15637 // manager about a package being removed, we need to remove all of 15638 // its activities from the history stack. 15639 if (checkComponentPermission( 15640 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15641 callingPid, callingUid, -1, true) 15642 != PackageManager.PERMISSION_GRANTED) { 15643 String msg = "Permission Denial: " + intent.getAction() 15644 + " broadcast from " + callerPackage + " (pid=" + callingPid 15645 + ", uid=" + callingUid + ")" 15646 + " requires " 15647 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15648 Slog.w(TAG, msg); 15649 throw new SecurityException(msg); 15650 } 15651 switch (action) { 15652 case Intent.ACTION_UID_REMOVED: 15653 final Bundle intentExtras = intent.getExtras(); 15654 final int uid = intentExtras != null 15655 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15656 if (uid >= 0) { 15657 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15658 synchronized (bs) { 15659 bs.removeUidStatsLocked(uid); 15660 } 15661 mAppOpsService.uidRemoved(uid); 15662 } 15663 break; 15664 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15665 // If resources are unavailable just force stop all those packages 15666 // and flush the attribute cache as well. 15667 String list[] = 15668 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15669 if (list != null && list.length > 0) { 15670 for (int i = 0; i < list.length; i++) { 15671 forceStopPackageLocked(list[i], -1, false, true, true, 15672 false, false, userId, "storage unmount"); 15673 } 15674 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15675 sendPackageBroadcastLocked( 15676 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15677 userId); 15678 } 15679 break; 15680 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15681 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15682 break; 15683 case Intent.ACTION_PACKAGE_REMOVED: 15684 case Intent.ACTION_PACKAGE_CHANGED: 15685 Uri data = intent.getData(); 15686 String ssp; 15687 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15688 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15689 boolean fullUninstall = removed && 15690 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15691 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15692 forceStopPackageLocked(ssp, UserHandle.getAppId( 15693 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15694 false, true, true, false, fullUninstall, userId, 15695 removed ? "pkg removed" : "pkg changed"); 15696 } 15697 if (removed) { 15698 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15699 new String[] {ssp}, userId); 15700 if (fullUninstall) { 15701 mAppOpsService.packageRemoved( 15702 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15703 15704 // Remove all permissions granted from/to this package 15705 removeUriPermissionsForPackageLocked(ssp, userId, true); 15706 15707 removeTasksByPackageNameLocked(ssp, userId); 15708 } 15709 } else { 15710 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15711 } 15712 } 15713 break; 15714 } 15715 break; 15716 case Intent.ACTION_PACKAGE_ADDED: 15717 // Special case for adding a package: by default turn on compatibility mode. 15718 Uri data = intent.getData(); 15719 String ssp; 15720 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15721 final boolean replacing = 15722 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15723 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15724 15725 if (replacing) { 15726 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15727 } 15728 } 15729 break; 15730 case Intent.ACTION_TIMEZONE_CHANGED: 15731 // If this is the time zone changed action, queue up a message that will reset 15732 // the timezone of all currently running processes. This message will get 15733 // queued up before the broadcast happens. 15734 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15735 break; 15736 case Intent.ACTION_TIME_CHANGED: 15737 // If the user set the time, let all running processes know. 15738 final int is24Hour = 15739 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15740 : 0; 15741 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15742 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15743 synchronized (stats) { 15744 stats.noteCurrentTimeChangedLocked(); 15745 } 15746 break; 15747 case Intent.ACTION_CLEAR_DNS_CACHE: 15748 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15749 break; 15750 case Proxy.PROXY_CHANGE_ACTION: 15751 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15752 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15753 break; 15754 } 15755 } 15756 15757 // Add to the sticky list if requested. 15758 if (sticky) { 15759 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15760 callingPid, callingUid) 15761 != PackageManager.PERMISSION_GRANTED) { 15762 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15763 + callingPid + ", uid=" + callingUid 15764 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15765 Slog.w(TAG, msg); 15766 throw new SecurityException(msg); 15767 } 15768 if (requiredPermission != null) { 15769 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15770 + " and enforce permission " + requiredPermission); 15771 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15772 } 15773 if (intent.getComponent() != null) { 15774 throw new SecurityException( 15775 "Sticky broadcasts can't target a specific component"); 15776 } 15777 // We use userId directly here, since the "all" target is maintained 15778 // as a separate set of sticky broadcasts. 15779 if (userId != UserHandle.USER_ALL) { 15780 // But first, if this is not a broadcast to all users, then 15781 // make sure it doesn't conflict with an existing broadcast to 15782 // all users. 15783 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15784 UserHandle.USER_ALL); 15785 if (stickies != null) { 15786 ArrayList<Intent> list = stickies.get(intent.getAction()); 15787 if (list != null) { 15788 int N = list.size(); 15789 int i; 15790 for (i=0; i<N; i++) { 15791 if (intent.filterEquals(list.get(i))) { 15792 throw new IllegalArgumentException( 15793 "Sticky broadcast " + intent + " for user " 15794 + userId + " conflicts with existing global broadcast"); 15795 } 15796 } 15797 } 15798 } 15799 } 15800 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15801 if (stickies == null) { 15802 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15803 mStickyBroadcasts.put(userId, stickies); 15804 } 15805 ArrayList<Intent> list = stickies.get(intent.getAction()); 15806 if (list == null) { 15807 list = new ArrayList<Intent>(); 15808 stickies.put(intent.getAction(), list); 15809 } 15810 int N = list.size(); 15811 int i; 15812 for (i=0; i<N; i++) { 15813 if (intent.filterEquals(list.get(i))) { 15814 // This sticky already exists, replace it. 15815 list.set(i, new Intent(intent)); 15816 break; 15817 } 15818 } 15819 if (i >= N) { 15820 list.add(new Intent(intent)); 15821 } 15822 } 15823 15824 int[] users; 15825 if (userId == UserHandle.USER_ALL) { 15826 // Caller wants broadcast to go to all started users. 15827 users = mStartedUserArray; 15828 } else { 15829 // Caller wants broadcast to go to one specific user. 15830 users = new int[] {userId}; 15831 } 15832 15833 // Figure out who all will receive this broadcast. 15834 List receivers = null; 15835 List<BroadcastFilter> registeredReceivers = null; 15836 // Need to resolve the intent to interested receivers... 15837 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15838 == 0) { 15839 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15840 } 15841 if (intent.getComponent() == null) { 15842 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15843 // Query one target user at a time, excluding shell-restricted users 15844 UserManagerService ums = getUserManagerLocked(); 15845 for (int i = 0; i < users.length; i++) { 15846 if (ums.hasUserRestriction( 15847 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15848 continue; 15849 } 15850 List<BroadcastFilter> registeredReceiversForUser = 15851 mReceiverResolver.queryIntent(intent, 15852 resolvedType, false, users[i]); 15853 if (registeredReceivers == null) { 15854 registeredReceivers = registeredReceiversForUser; 15855 } else if (registeredReceiversForUser != null) { 15856 registeredReceivers.addAll(registeredReceiversForUser); 15857 } 15858 } 15859 } else { 15860 registeredReceivers = mReceiverResolver.queryIntent(intent, 15861 resolvedType, false, userId); 15862 } 15863 } 15864 15865 final boolean replacePending = 15866 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15867 15868 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15869 + " replacePending=" + replacePending); 15870 15871 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15872 if (!ordered && NR > 0) { 15873 // If we are not serializing this broadcast, then send the 15874 // registered receivers separately so they don't wait for the 15875 // components to be launched. 15876 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15877 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15878 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15879 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15880 ordered, sticky, false, userId); 15881 if (DEBUG_BROADCAST) Slog.v( 15882 TAG, "Enqueueing parallel broadcast " + r); 15883 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15884 if (!replaced) { 15885 queue.enqueueParallelBroadcastLocked(r); 15886 queue.scheduleBroadcastsLocked(); 15887 } 15888 registeredReceivers = null; 15889 NR = 0; 15890 } 15891 15892 // Merge into one list. 15893 int ir = 0; 15894 if (receivers != null) { 15895 // A special case for PACKAGE_ADDED: do not allow the package 15896 // being added to see this broadcast. This prevents them from 15897 // using this as a back door to get run as soon as they are 15898 // installed. Maybe in the future we want to have a special install 15899 // broadcast or such for apps, but we'd like to deliberately make 15900 // this decision. 15901 String skipPackages[] = null; 15902 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15903 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15904 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15905 Uri data = intent.getData(); 15906 if (data != null) { 15907 String pkgName = data.getSchemeSpecificPart(); 15908 if (pkgName != null) { 15909 skipPackages = new String[] { pkgName }; 15910 } 15911 } 15912 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15913 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15914 } 15915 if (skipPackages != null && (skipPackages.length > 0)) { 15916 for (String skipPackage : skipPackages) { 15917 if (skipPackage != null) { 15918 int NT = receivers.size(); 15919 for (int it=0; it<NT; it++) { 15920 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15921 if (curt.activityInfo.packageName.equals(skipPackage)) { 15922 receivers.remove(it); 15923 it--; 15924 NT--; 15925 } 15926 } 15927 } 15928 } 15929 } 15930 15931 int NT = receivers != null ? receivers.size() : 0; 15932 int it = 0; 15933 ResolveInfo curt = null; 15934 BroadcastFilter curr = null; 15935 while (it < NT && ir < NR) { 15936 if (curt == null) { 15937 curt = (ResolveInfo)receivers.get(it); 15938 } 15939 if (curr == null) { 15940 curr = registeredReceivers.get(ir); 15941 } 15942 if (curr.getPriority() >= curt.priority) { 15943 // Insert this broadcast record into the final list. 15944 receivers.add(it, curr); 15945 ir++; 15946 curr = null; 15947 it++; 15948 NT++; 15949 } else { 15950 // Skip to the next ResolveInfo in the final list. 15951 it++; 15952 curt = null; 15953 } 15954 } 15955 } 15956 while (ir < NR) { 15957 if (receivers == null) { 15958 receivers = new ArrayList(); 15959 } 15960 receivers.add(registeredReceivers.get(ir)); 15961 ir++; 15962 } 15963 15964 if ((receivers != null && receivers.size() > 0) 15965 || resultTo != null) { 15966 BroadcastQueue queue = broadcastQueueForIntent(intent); 15967 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15968 callerPackage, callingPid, callingUid, resolvedType, 15969 requiredPermission, appOp, receivers, resultTo, resultCode, 15970 resultData, map, ordered, sticky, false, userId); 15971 if (DEBUG_BROADCAST) Slog.v( 15972 TAG, "Enqueueing ordered broadcast " + r 15973 + ": prev had " + queue.mOrderedBroadcasts.size()); 15974 if (DEBUG_BROADCAST) { 15975 int seq = r.intent.getIntExtra("seq", -1); 15976 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15977 } 15978 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15979 if (!replaced) { 15980 queue.enqueueOrderedBroadcastLocked(r); 15981 queue.scheduleBroadcastsLocked(); 15982 } 15983 } 15984 15985 return ActivityManager.BROADCAST_SUCCESS; 15986 } 15987 15988 final Intent verifyBroadcastLocked(Intent intent) { 15989 // Refuse possible leaked file descriptors 15990 if (intent != null && intent.hasFileDescriptors() == true) { 15991 throw new IllegalArgumentException("File descriptors passed in Intent"); 15992 } 15993 15994 int flags = intent.getFlags(); 15995 15996 if (!mProcessesReady) { 15997 // if the caller really truly claims to know what they're doing, go 15998 // ahead and allow the broadcast without launching any receivers 15999 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16000 intent = new Intent(intent); 16001 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16002 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16003 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16004 + " before boot completion"); 16005 throw new IllegalStateException("Cannot broadcast before boot completed"); 16006 } 16007 } 16008 16009 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16010 throw new IllegalArgumentException( 16011 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16012 } 16013 16014 return intent; 16015 } 16016 16017 public final int broadcastIntent(IApplicationThread caller, 16018 Intent intent, String resolvedType, IIntentReceiver resultTo, 16019 int resultCode, String resultData, Bundle map, 16020 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16021 enforceNotIsolatedCaller("broadcastIntent"); 16022 synchronized(this) { 16023 intent = verifyBroadcastLocked(intent); 16024 16025 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16026 final int callingPid = Binder.getCallingPid(); 16027 final int callingUid = Binder.getCallingUid(); 16028 final long origId = Binder.clearCallingIdentity(); 16029 int res = broadcastIntentLocked(callerApp, 16030 callerApp != null ? callerApp.info.packageName : null, 16031 intent, resolvedType, resultTo, 16032 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16033 callingPid, callingUid, userId); 16034 Binder.restoreCallingIdentity(origId); 16035 return res; 16036 } 16037 } 16038 16039 int broadcastIntentInPackage(String packageName, int uid, 16040 Intent intent, String resolvedType, IIntentReceiver resultTo, 16041 int resultCode, String resultData, Bundle map, 16042 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16043 synchronized(this) { 16044 intent = verifyBroadcastLocked(intent); 16045 16046 final long origId = Binder.clearCallingIdentity(); 16047 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16048 resultTo, resultCode, resultData, map, requiredPermission, 16049 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16050 Binder.restoreCallingIdentity(origId); 16051 return res; 16052 } 16053 } 16054 16055 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16056 // Refuse possible leaked file descriptors 16057 if (intent != null && intent.hasFileDescriptors() == true) { 16058 throw new IllegalArgumentException("File descriptors passed in Intent"); 16059 } 16060 16061 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16062 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16063 16064 synchronized(this) { 16065 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16066 != PackageManager.PERMISSION_GRANTED) { 16067 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16068 + Binder.getCallingPid() 16069 + ", uid=" + Binder.getCallingUid() 16070 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16071 Slog.w(TAG, msg); 16072 throw new SecurityException(msg); 16073 } 16074 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16075 if (stickies != null) { 16076 ArrayList<Intent> list = stickies.get(intent.getAction()); 16077 if (list != null) { 16078 int N = list.size(); 16079 int i; 16080 for (i=0; i<N; i++) { 16081 if (intent.filterEquals(list.get(i))) { 16082 list.remove(i); 16083 break; 16084 } 16085 } 16086 if (list.size() <= 0) { 16087 stickies.remove(intent.getAction()); 16088 } 16089 } 16090 if (stickies.size() <= 0) { 16091 mStickyBroadcasts.remove(userId); 16092 } 16093 } 16094 } 16095 } 16096 16097 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16098 String resultData, Bundle resultExtras, boolean resultAbort) { 16099 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16100 if (r == null) { 16101 Slog.w(TAG, "finishReceiver called but not found on queue"); 16102 return false; 16103 } 16104 16105 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16106 } 16107 16108 void backgroundServicesFinishedLocked(int userId) { 16109 for (BroadcastQueue queue : mBroadcastQueues) { 16110 queue.backgroundServicesFinishedLocked(userId); 16111 } 16112 } 16113 16114 public void finishReceiver(IBinder who, int resultCode, String resultData, 16115 Bundle resultExtras, boolean resultAbort) { 16116 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16117 16118 // Refuse possible leaked file descriptors 16119 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16120 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16121 } 16122 16123 final long origId = Binder.clearCallingIdentity(); 16124 try { 16125 boolean doNext = false; 16126 BroadcastRecord r; 16127 16128 synchronized(this) { 16129 r = broadcastRecordForReceiverLocked(who); 16130 if (r != null) { 16131 doNext = r.queue.finishReceiverLocked(r, resultCode, 16132 resultData, resultExtras, resultAbort, true); 16133 } 16134 } 16135 16136 if (doNext) { 16137 r.queue.processNextBroadcast(false); 16138 } 16139 trimApplications(); 16140 } finally { 16141 Binder.restoreCallingIdentity(origId); 16142 } 16143 } 16144 16145 // ========================================================= 16146 // INSTRUMENTATION 16147 // ========================================================= 16148 16149 public boolean startInstrumentation(ComponentName className, 16150 String profileFile, int flags, Bundle arguments, 16151 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16152 int userId, String abiOverride) { 16153 enforceNotIsolatedCaller("startInstrumentation"); 16154 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16155 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16156 // Refuse possible leaked file descriptors 16157 if (arguments != null && arguments.hasFileDescriptors()) { 16158 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16159 } 16160 16161 synchronized(this) { 16162 InstrumentationInfo ii = null; 16163 ApplicationInfo ai = null; 16164 try { 16165 ii = mContext.getPackageManager().getInstrumentationInfo( 16166 className, STOCK_PM_FLAGS); 16167 ai = AppGlobals.getPackageManager().getApplicationInfo( 16168 ii.targetPackage, STOCK_PM_FLAGS, userId); 16169 } catch (PackageManager.NameNotFoundException e) { 16170 } catch (RemoteException e) { 16171 } 16172 if (ii == null) { 16173 reportStartInstrumentationFailure(watcher, className, 16174 "Unable to find instrumentation info for: " + className); 16175 return false; 16176 } 16177 if (ai == null) { 16178 reportStartInstrumentationFailure(watcher, className, 16179 "Unable to find instrumentation target package: " + ii.targetPackage); 16180 return false; 16181 } 16182 16183 int match = mContext.getPackageManager().checkSignatures( 16184 ii.targetPackage, ii.packageName); 16185 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16186 String msg = "Permission Denial: starting instrumentation " 16187 + className + " from pid=" 16188 + Binder.getCallingPid() 16189 + ", uid=" + Binder.getCallingPid() 16190 + " not allowed because package " + ii.packageName 16191 + " does not have a signature matching the target " 16192 + ii.targetPackage; 16193 reportStartInstrumentationFailure(watcher, className, msg); 16194 throw new SecurityException(msg); 16195 } 16196 16197 final long origId = Binder.clearCallingIdentity(); 16198 // Instrumentation can kill and relaunch even persistent processes 16199 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16200 "start instr"); 16201 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16202 app.instrumentationClass = className; 16203 app.instrumentationInfo = ai; 16204 app.instrumentationProfileFile = profileFile; 16205 app.instrumentationArguments = arguments; 16206 app.instrumentationWatcher = watcher; 16207 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16208 app.instrumentationResultClass = className; 16209 Binder.restoreCallingIdentity(origId); 16210 } 16211 16212 return true; 16213 } 16214 16215 /** 16216 * Report errors that occur while attempting to start Instrumentation. Always writes the 16217 * error to the logs, but if somebody is watching, send the report there too. This enables 16218 * the "am" command to report errors with more information. 16219 * 16220 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16221 * @param cn The component name of the instrumentation. 16222 * @param report The error report. 16223 */ 16224 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16225 ComponentName cn, String report) { 16226 Slog.w(TAG, report); 16227 try { 16228 if (watcher != null) { 16229 Bundle results = new Bundle(); 16230 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16231 results.putString("Error", report); 16232 watcher.instrumentationStatus(cn, -1, results); 16233 } 16234 } catch (RemoteException e) { 16235 Slog.w(TAG, e); 16236 } 16237 } 16238 16239 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16240 if (app.instrumentationWatcher != null) { 16241 try { 16242 // NOTE: IInstrumentationWatcher *must* be oneway here 16243 app.instrumentationWatcher.instrumentationFinished( 16244 app.instrumentationClass, 16245 resultCode, 16246 results); 16247 } catch (RemoteException e) { 16248 } 16249 } 16250 if (app.instrumentationUiAutomationConnection != null) { 16251 try { 16252 app.instrumentationUiAutomationConnection.shutdown(); 16253 } catch (RemoteException re) { 16254 /* ignore */ 16255 } 16256 // Only a UiAutomation can set this flag and now that 16257 // it is finished we make sure it is reset to its default. 16258 mUserIsMonkey = false; 16259 } 16260 app.instrumentationWatcher = null; 16261 app.instrumentationUiAutomationConnection = null; 16262 app.instrumentationClass = null; 16263 app.instrumentationInfo = null; 16264 app.instrumentationProfileFile = null; 16265 app.instrumentationArguments = null; 16266 16267 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16268 "finished inst"); 16269 } 16270 16271 public void finishInstrumentation(IApplicationThread target, 16272 int resultCode, Bundle results) { 16273 int userId = UserHandle.getCallingUserId(); 16274 // Refuse possible leaked file descriptors 16275 if (results != null && results.hasFileDescriptors()) { 16276 throw new IllegalArgumentException("File descriptors passed in Intent"); 16277 } 16278 16279 synchronized(this) { 16280 ProcessRecord app = getRecordForAppLocked(target); 16281 if (app == null) { 16282 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16283 return; 16284 } 16285 final long origId = Binder.clearCallingIdentity(); 16286 finishInstrumentationLocked(app, resultCode, results); 16287 Binder.restoreCallingIdentity(origId); 16288 } 16289 } 16290 16291 // ========================================================= 16292 // CONFIGURATION 16293 // ========================================================= 16294 16295 public ConfigurationInfo getDeviceConfigurationInfo() { 16296 ConfigurationInfo config = new ConfigurationInfo(); 16297 synchronized (this) { 16298 config.reqTouchScreen = mConfiguration.touchscreen; 16299 config.reqKeyboardType = mConfiguration.keyboard; 16300 config.reqNavigation = mConfiguration.navigation; 16301 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16302 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16303 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16304 } 16305 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16306 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16307 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16308 } 16309 config.reqGlEsVersion = GL_ES_VERSION; 16310 } 16311 return config; 16312 } 16313 16314 ActivityStack getFocusedStack() { 16315 return mStackSupervisor.getFocusedStack(); 16316 } 16317 16318 public Configuration getConfiguration() { 16319 Configuration ci; 16320 synchronized(this) { 16321 ci = new Configuration(mConfiguration); 16322 } 16323 return ci; 16324 } 16325 16326 public void updatePersistentConfiguration(Configuration values) { 16327 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16328 "updateConfiguration()"); 16329 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16330 "updateConfiguration()"); 16331 if (values == null) { 16332 throw new NullPointerException("Configuration must not be null"); 16333 } 16334 16335 synchronized(this) { 16336 final long origId = Binder.clearCallingIdentity(); 16337 updateConfigurationLocked(values, null, true, false); 16338 Binder.restoreCallingIdentity(origId); 16339 } 16340 } 16341 16342 public void updateConfiguration(Configuration values) { 16343 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16344 "updateConfiguration()"); 16345 16346 synchronized(this) { 16347 if (values == null && mWindowManager != null) { 16348 // sentinel: fetch the current configuration from the window manager 16349 values = mWindowManager.computeNewConfiguration(); 16350 } 16351 16352 if (mWindowManager != null) { 16353 mProcessList.applyDisplaySize(mWindowManager); 16354 } 16355 16356 final long origId = Binder.clearCallingIdentity(); 16357 if (values != null) { 16358 Settings.System.clearConfiguration(values); 16359 } 16360 updateConfigurationLocked(values, null, false, false); 16361 Binder.restoreCallingIdentity(origId); 16362 } 16363 } 16364 16365 /** 16366 * Do either or both things: (1) change the current configuration, and (2) 16367 * make sure the given activity is running with the (now) current 16368 * configuration. Returns true if the activity has been left running, or 16369 * false if <var>starting</var> is being destroyed to match the new 16370 * configuration. 16371 * @param persistent TODO 16372 */ 16373 boolean updateConfigurationLocked(Configuration values, 16374 ActivityRecord starting, boolean persistent, boolean initLocale) { 16375 int changes = 0; 16376 16377 if (values != null) { 16378 Configuration newConfig = new Configuration(mConfiguration); 16379 changes = newConfig.updateFrom(values); 16380 if (changes != 0) { 16381 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16382 Slog.i(TAG, "Updating configuration to: " + values); 16383 } 16384 16385 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16386 16387 if (values.locale != null && !initLocale) { 16388 saveLocaleLocked(values.locale, 16389 !values.locale.equals(mConfiguration.locale), 16390 values.userSetLocale); 16391 } 16392 16393 mConfigurationSeq++; 16394 if (mConfigurationSeq <= 0) { 16395 mConfigurationSeq = 1; 16396 } 16397 newConfig.seq = mConfigurationSeq; 16398 mConfiguration = newConfig; 16399 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16400 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16401 //mUsageStatsService.noteStartConfig(newConfig); 16402 16403 final Configuration configCopy = new Configuration(mConfiguration); 16404 16405 // TODO: If our config changes, should we auto dismiss any currently 16406 // showing dialogs? 16407 mShowDialogs = shouldShowDialogs(newConfig); 16408 16409 AttributeCache ac = AttributeCache.instance(); 16410 if (ac != null) { 16411 ac.updateConfiguration(configCopy); 16412 } 16413 16414 // Make sure all resources in our process are updated 16415 // right now, so that anyone who is going to retrieve 16416 // resource values after we return will be sure to get 16417 // the new ones. This is especially important during 16418 // boot, where the first config change needs to guarantee 16419 // all resources have that config before following boot 16420 // code is executed. 16421 mSystemThread.applyConfigurationToResources(configCopy); 16422 16423 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16424 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16425 msg.obj = new Configuration(configCopy); 16426 mHandler.sendMessage(msg); 16427 } 16428 16429 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16430 ProcessRecord app = mLruProcesses.get(i); 16431 try { 16432 if (app.thread != null) { 16433 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16434 + app.processName + " new config " + mConfiguration); 16435 app.thread.scheduleConfigurationChanged(configCopy); 16436 } 16437 } catch (Exception e) { 16438 } 16439 } 16440 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16441 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16442 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16443 | Intent.FLAG_RECEIVER_FOREGROUND); 16444 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16445 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16446 Process.SYSTEM_UID, UserHandle.USER_ALL); 16447 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16448 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16449 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16450 broadcastIntentLocked(null, null, intent, 16451 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16452 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16453 } 16454 } 16455 } 16456 16457 boolean kept = true; 16458 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16459 // mainStack is null during startup. 16460 if (mainStack != null) { 16461 if (changes != 0 && starting == null) { 16462 // If the configuration changed, and the caller is not already 16463 // in the process of starting an activity, then find the top 16464 // activity to check if its configuration needs to change. 16465 starting = mainStack.topRunningActivityLocked(null); 16466 } 16467 16468 if (starting != null) { 16469 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16470 // And we need to make sure at this point that all other activities 16471 // are made visible with the correct configuration. 16472 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16473 } 16474 } 16475 16476 if (values != null && mWindowManager != null) { 16477 mWindowManager.setNewConfiguration(mConfiguration); 16478 } 16479 16480 return kept; 16481 } 16482 16483 /** 16484 * Decide based on the configuration whether we should shouw the ANR, 16485 * crash, etc dialogs. The idea is that if there is no affordnace to 16486 * press the on-screen buttons, we shouldn't show the dialog. 16487 * 16488 * A thought: SystemUI might also want to get told about this, the Power 16489 * dialog / global actions also might want different behaviors. 16490 */ 16491 private static final boolean shouldShowDialogs(Configuration config) { 16492 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16493 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16494 } 16495 16496 /** 16497 * Save the locale. You must be inside a synchronized (this) block. 16498 */ 16499 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16500 if(isDiff) { 16501 SystemProperties.set("user.language", l.getLanguage()); 16502 SystemProperties.set("user.region", l.getCountry()); 16503 } 16504 16505 if(isPersist) { 16506 SystemProperties.set("persist.sys.language", l.getLanguage()); 16507 SystemProperties.set("persist.sys.country", l.getCountry()); 16508 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16509 16510 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16511 } 16512 } 16513 16514 @Override 16515 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16516 synchronized (this) { 16517 ActivityRecord srec = ActivityRecord.forToken(token); 16518 if (srec.task != null && srec.task.stack != null) { 16519 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16520 } 16521 } 16522 return false; 16523 } 16524 16525 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16526 Intent resultData) { 16527 16528 synchronized (this) { 16529 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16530 if (stack != null) { 16531 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16532 } 16533 return false; 16534 } 16535 } 16536 16537 public int getLaunchedFromUid(IBinder activityToken) { 16538 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16539 if (srec == null) { 16540 return -1; 16541 } 16542 return srec.launchedFromUid; 16543 } 16544 16545 public String getLaunchedFromPackage(IBinder activityToken) { 16546 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16547 if (srec == null) { 16548 return null; 16549 } 16550 return srec.launchedFromPackage; 16551 } 16552 16553 // ========================================================= 16554 // LIFETIME MANAGEMENT 16555 // ========================================================= 16556 16557 // Returns which broadcast queue the app is the current [or imminent] receiver 16558 // on, or 'null' if the app is not an active broadcast recipient. 16559 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16560 BroadcastRecord r = app.curReceiver; 16561 if (r != null) { 16562 return r.queue; 16563 } 16564 16565 // It's not the current receiver, but it might be starting up to become one 16566 synchronized (this) { 16567 for (BroadcastQueue queue : mBroadcastQueues) { 16568 r = queue.mPendingBroadcast; 16569 if (r != null && r.curApp == app) { 16570 // found it; report which queue it's in 16571 return queue; 16572 } 16573 } 16574 } 16575 16576 return null; 16577 } 16578 16579 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16580 boolean doingAll, long now) { 16581 if (mAdjSeq == app.adjSeq) { 16582 // This adjustment has already been computed. 16583 return app.curRawAdj; 16584 } 16585 16586 if (app.thread == null) { 16587 app.adjSeq = mAdjSeq; 16588 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16589 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16590 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16591 } 16592 16593 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16594 app.adjSource = null; 16595 app.adjTarget = null; 16596 app.empty = false; 16597 app.cached = false; 16598 16599 final int activitiesSize = app.activities.size(); 16600 16601 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16602 // The max adjustment doesn't allow this app to be anything 16603 // below foreground, so it is not worth doing work for it. 16604 app.adjType = "fixed"; 16605 app.adjSeq = mAdjSeq; 16606 app.curRawAdj = app.maxAdj; 16607 app.foregroundActivities = false; 16608 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16609 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16610 // System processes can do UI, and when they do we want to have 16611 // them trim their memory after the user leaves the UI. To 16612 // facilitate this, here we need to determine whether or not it 16613 // is currently showing UI. 16614 app.systemNoUi = true; 16615 if (app == TOP_APP) { 16616 app.systemNoUi = false; 16617 } else if (activitiesSize > 0) { 16618 for (int j = 0; j < activitiesSize; j++) { 16619 final ActivityRecord r = app.activities.get(j); 16620 if (r.visible) { 16621 app.systemNoUi = false; 16622 } 16623 } 16624 } 16625 if (!app.systemNoUi) { 16626 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16627 } 16628 return (app.curAdj=app.maxAdj); 16629 } 16630 16631 app.systemNoUi = false; 16632 16633 // Determine the importance of the process, starting with most 16634 // important to least, and assign an appropriate OOM adjustment. 16635 int adj; 16636 int schedGroup; 16637 int procState; 16638 boolean foregroundActivities = false; 16639 BroadcastQueue queue; 16640 if (app == TOP_APP) { 16641 // The last app on the list is the foreground app. 16642 adj = ProcessList.FOREGROUND_APP_ADJ; 16643 schedGroup = Process.THREAD_GROUP_DEFAULT; 16644 app.adjType = "top-activity"; 16645 foregroundActivities = true; 16646 procState = ActivityManager.PROCESS_STATE_TOP; 16647 } else if (app.instrumentationClass != null) { 16648 // Don't want to kill running instrumentation. 16649 adj = ProcessList.FOREGROUND_APP_ADJ; 16650 schedGroup = Process.THREAD_GROUP_DEFAULT; 16651 app.adjType = "instrumentation"; 16652 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16653 } else if ((queue = isReceivingBroadcast(app)) != null) { 16654 // An app that is currently receiving a broadcast also 16655 // counts as being in the foreground for OOM killer purposes. 16656 // It's placed in a sched group based on the nature of the 16657 // broadcast as reflected by which queue it's active in. 16658 adj = ProcessList.FOREGROUND_APP_ADJ; 16659 schedGroup = (queue == mFgBroadcastQueue) 16660 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16661 app.adjType = "broadcast"; 16662 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16663 } else if (app.executingServices.size() > 0) { 16664 // An app that is currently executing a service callback also 16665 // counts as being in the foreground. 16666 adj = ProcessList.FOREGROUND_APP_ADJ; 16667 schedGroup = app.execServicesFg ? 16668 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16669 app.adjType = "exec-service"; 16670 procState = ActivityManager.PROCESS_STATE_SERVICE; 16671 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16672 } else { 16673 // As far as we know the process is empty. We may change our mind later. 16674 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16675 // At this point we don't actually know the adjustment. Use the cached adj 16676 // value that the caller wants us to. 16677 adj = cachedAdj; 16678 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16679 app.cached = true; 16680 app.empty = true; 16681 app.adjType = "cch-empty"; 16682 } 16683 16684 // Examine all activities if not already foreground. 16685 if (!foregroundActivities && activitiesSize > 0) { 16686 for (int j = 0; j < activitiesSize; j++) { 16687 final ActivityRecord r = app.activities.get(j); 16688 if (r.app != app) { 16689 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16690 + app + "?!?"); 16691 continue; 16692 } 16693 if (r.visible) { 16694 // App has a visible activity; only upgrade adjustment. 16695 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16696 adj = ProcessList.VISIBLE_APP_ADJ; 16697 app.adjType = "visible"; 16698 } 16699 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16700 procState = ActivityManager.PROCESS_STATE_TOP; 16701 } 16702 schedGroup = Process.THREAD_GROUP_DEFAULT; 16703 app.cached = false; 16704 app.empty = false; 16705 foregroundActivities = true; 16706 break; 16707 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16708 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16709 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16710 app.adjType = "pausing"; 16711 } 16712 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16713 procState = ActivityManager.PROCESS_STATE_TOP; 16714 } 16715 schedGroup = Process.THREAD_GROUP_DEFAULT; 16716 app.cached = false; 16717 app.empty = false; 16718 foregroundActivities = true; 16719 } else if (r.state == ActivityState.STOPPING) { 16720 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16721 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16722 app.adjType = "stopping"; 16723 } 16724 // For the process state, we will at this point consider the 16725 // process to be cached. It will be cached either as an activity 16726 // or empty depending on whether the activity is finishing. We do 16727 // this so that we can treat the process as cached for purposes of 16728 // memory trimming (determing current memory level, trim command to 16729 // send to process) since there can be an arbitrary number of stopping 16730 // processes and they should soon all go into the cached state. 16731 if (!r.finishing) { 16732 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16733 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16734 } 16735 } 16736 app.cached = false; 16737 app.empty = false; 16738 foregroundActivities = true; 16739 } else { 16740 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16741 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16742 app.adjType = "cch-act"; 16743 } 16744 } 16745 } 16746 } 16747 16748 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16749 if (app.foregroundServices) { 16750 // The user is aware of this app, so make it visible. 16751 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16752 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16753 app.cached = false; 16754 app.adjType = "fg-service"; 16755 schedGroup = Process.THREAD_GROUP_DEFAULT; 16756 } else if (app.forcingToForeground != null) { 16757 // The user is aware of this app, so make it visible. 16758 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16759 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16760 app.cached = false; 16761 app.adjType = "force-fg"; 16762 app.adjSource = app.forcingToForeground; 16763 schedGroup = Process.THREAD_GROUP_DEFAULT; 16764 } 16765 } 16766 16767 if (app == mHeavyWeightProcess) { 16768 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16769 // We don't want to kill the current heavy-weight process. 16770 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16771 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16772 app.cached = false; 16773 app.adjType = "heavy"; 16774 } 16775 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16776 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16777 } 16778 } 16779 16780 if (app == mHomeProcess) { 16781 if (adj > ProcessList.HOME_APP_ADJ) { 16782 // This process is hosting what we currently consider to be the 16783 // home app, so we don't want to let it go into the background. 16784 adj = ProcessList.HOME_APP_ADJ; 16785 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16786 app.cached = false; 16787 app.adjType = "home"; 16788 } 16789 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16790 procState = ActivityManager.PROCESS_STATE_HOME; 16791 } 16792 } 16793 16794 if (app == mPreviousProcess && app.activities.size() > 0) { 16795 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16796 // This was the previous process that showed UI to the user. 16797 // We want to try to keep it around more aggressively, to give 16798 // a good experience around switching between two apps. 16799 adj = ProcessList.PREVIOUS_APP_ADJ; 16800 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16801 app.cached = false; 16802 app.adjType = "previous"; 16803 } 16804 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16805 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16806 } 16807 } 16808 16809 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16810 + " reason=" + app.adjType); 16811 16812 // By default, we use the computed adjustment. It may be changed if 16813 // there are applications dependent on our services or providers, but 16814 // this gives us a baseline and makes sure we don't get into an 16815 // infinite recursion. 16816 app.adjSeq = mAdjSeq; 16817 app.curRawAdj = adj; 16818 app.hasStartedServices = false; 16819 16820 if (mBackupTarget != null && app == mBackupTarget.app) { 16821 // If possible we want to avoid killing apps while they're being backed up 16822 if (adj > ProcessList.BACKUP_APP_ADJ) { 16823 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16824 adj = ProcessList.BACKUP_APP_ADJ; 16825 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16826 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16827 } 16828 app.adjType = "backup"; 16829 app.cached = false; 16830 } 16831 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16832 procState = ActivityManager.PROCESS_STATE_BACKUP; 16833 } 16834 } 16835 16836 boolean mayBeTop = false; 16837 16838 for (int is = app.services.size()-1; 16839 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16840 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16841 || procState > ActivityManager.PROCESS_STATE_TOP); 16842 is--) { 16843 ServiceRecord s = app.services.valueAt(is); 16844 if (s.startRequested) { 16845 app.hasStartedServices = true; 16846 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16847 procState = ActivityManager.PROCESS_STATE_SERVICE; 16848 } 16849 if (app.hasShownUi && app != mHomeProcess) { 16850 // If this process has shown some UI, let it immediately 16851 // go to the LRU list because it may be pretty heavy with 16852 // UI stuff. We'll tag it with a label just to help 16853 // debug and understand what is going on. 16854 if (adj > ProcessList.SERVICE_ADJ) { 16855 app.adjType = "cch-started-ui-services"; 16856 } 16857 } else { 16858 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16859 // This service has seen some activity within 16860 // recent memory, so we will keep its process ahead 16861 // of the background processes. 16862 if (adj > ProcessList.SERVICE_ADJ) { 16863 adj = ProcessList.SERVICE_ADJ; 16864 app.adjType = "started-services"; 16865 app.cached = false; 16866 } 16867 } 16868 // If we have let the service slide into the background 16869 // state, still have some text describing what it is doing 16870 // even though the service no longer has an impact. 16871 if (adj > ProcessList.SERVICE_ADJ) { 16872 app.adjType = "cch-started-services"; 16873 } 16874 } 16875 } 16876 for (int conni = s.connections.size()-1; 16877 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16878 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16879 || procState > ActivityManager.PROCESS_STATE_TOP); 16880 conni--) { 16881 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16882 for (int i = 0; 16883 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16884 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16885 || procState > ActivityManager.PROCESS_STATE_TOP); 16886 i++) { 16887 // XXX should compute this based on the max of 16888 // all connected clients. 16889 ConnectionRecord cr = clist.get(i); 16890 if (cr.binding.client == app) { 16891 // Binding to ourself is not interesting. 16892 continue; 16893 } 16894 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16895 ProcessRecord client = cr.binding.client; 16896 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16897 TOP_APP, doingAll, now); 16898 int clientProcState = client.curProcState; 16899 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16900 // If the other app is cached for any reason, for purposes here 16901 // we are going to consider it empty. The specific cached state 16902 // doesn't propagate except under certain conditions. 16903 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16904 } 16905 String adjType = null; 16906 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16907 // Not doing bind OOM management, so treat 16908 // this guy more like a started service. 16909 if (app.hasShownUi && app != mHomeProcess) { 16910 // If this process has shown some UI, let it immediately 16911 // go to the LRU list because it may be pretty heavy with 16912 // UI stuff. We'll tag it with a label just to help 16913 // debug and understand what is going on. 16914 if (adj > clientAdj) { 16915 adjType = "cch-bound-ui-services"; 16916 } 16917 app.cached = false; 16918 clientAdj = adj; 16919 clientProcState = procState; 16920 } else { 16921 if (now >= (s.lastActivity 16922 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16923 // This service has not seen activity within 16924 // recent memory, so allow it to drop to the 16925 // LRU list if there is no other reason to keep 16926 // it around. We'll also tag it with a label just 16927 // to help debug and undertand what is going on. 16928 if (adj > clientAdj) { 16929 adjType = "cch-bound-services"; 16930 } 16931 clientAdj = adj; 16932 } 16933 } 16934 } 16935 if (adj > clientAdj) { 16936 // If this process has recently shown UI, and 16937 // the process that is binding to it is less 16938 // important than being visible, then we don't 16939 // care about the binding as much as we care 16940 // about letting this process get into the LRU 16941 // list to be killed and restarted if needed for 16942 // memory. 16943 if (app.hasShownUi && app != mHomeProcess 16944 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16945 adjType = "cch-bound-ui-services"; 16946 } else { 16947 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16948 |Context.BIND_IMPORTANT)) != 0) { 16949 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16950 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16951 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16952 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16953 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16954 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16955 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16956 adj = clientAdj; 16957 } else { 16958 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16959 adj = ProcessList.VISIBLE_APP_ADJ; 16960 } 16961 } 16962 if (!client.cached) { 16963 app.cached = false; 16964 } 16965 adjType = "service"; 16966 } 16967 } 16968 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16969 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16970 schedGroup = Process.THREAD_GROUP_DEFAULT; 16971 } 16972 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16973 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16974 // Special handling of clients who are in the top state. 16975 // We *may* want to consider this process to be in the 16976 // top state as well, but only if there is not another 16977 // reason for it to be running. Being on the top is a 16978 // special state, meaning you are specifically running 16979 // for the current top app. If the process is already 16980 // running in the background for some other reason, it 16981 // is more important to continue considering it to be 16982 // in the background state. 16983 mayBeTop = true; 16984 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16985 } else { 16986 // Special handling for above-top states (persistent 16987 // processes). These should not bring the current process 16988 // into the top state, since they are not on top. Instead 16989 // give them the best state after that. 16990 clientProcState = 16991 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16992 } 16993 } 16994 } else { 16995 if (clientProcState < 16996 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16997 clientProcState = 16998 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16999 } 17000 } 17001 if (procState > clientProcState) { 17002 procState = clientProcState; 17003 } 17004 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17005 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17006 app.pendingUiClean = true; 17007 } 17008 if (adjType != null) { 17009 app.adjType = adjType; 17010 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17011 .REASON_SERVICE_IN_USE; 17012 app.adjSource = cr.binding.client; 17013 app.adjSourceProcState = clientProcState; 17014 app.adjTarget = s.name; 17015 } 17016 } 17017 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17018 app.treatLikeActivity = true; 17019 } 17020 final ActivityRecord a = cr.activity; 17021 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17022 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17023 (a.visible || a.state == ActivityState.RESUMED 17024 || a.state == ActivityState.PAUSING)) { 17025 adj = ProcessList.FOREGROUND_APP_ADJ; 17026 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17027 schedGroup = Process.THREAD_GROUP_DEFAULT; 17028 } 17029 app.cached = false; 17030 app.adjType = "service"; 17031 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17032 .REASON_SERVICE_IN_USE; 17033 app.adjSource = a; 17034 app.adjSourceProcState = procState; 17035 app.adjTarget = s.name; 17036 } 17037 } 17038 } 17039 } 17040 } 17041 17042 for (int provi = app.pubProviders.size()-1; 17043 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17044 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17045 || procState > ActivityManager.PROCESS_STATE_TOP); 17046 provi--) { 17047 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17048 for (int i = cpr.connections.size()-1; 17049 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17050 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17051 || procState > ActivityManager.PROCESS_STATE_TOP); 17052 i--) { 17053 ContentProviderConnection conn = cpr.connections.get(i); 17054 ProcessRecord client = conn.client; 17055 if (client == app) { 17056 // Being our own client is not interesting. 17057 continue; 17058 } 17059 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17060 int clientProcState = client.curProcState; 17061 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17062 // If the other app is cached for any reason, for purposes here 17063 // we are going to consider it empty. 17064 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17065 } 17066 if (adj > clientAdj) { 17067 if (app.hasShownUi && app != mHomeProcess 17068 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17069 app.adjType = "cch-ui-provider"; 17070 } else { 17071 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17072 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17073 app.adjType = "provider"; 17074 } 17075 app.cached &= client.cached; 17076 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17077 .REASON_PROVIDER_IN_USE; 17078 app.adjSource = client; 17079 app.adjSourceProcState = clientProcState; 17080 app.adjTarget = cpr.name; 17081 } 17082 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17083 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17084 // Special handling of clients who are in the top state. 17085 // We *may* want to consider this process to be in the 17086 // top state as well, but only if there is not another 17087 // reason for it to be running. Being on the top is a 17088 // special state, meaning you are specifically running 17089 // for the current top app. If the process is already 17090 // running in the background for some other reason, it 17091 // is more important to continue considering it to be 17092 // in the background state. 17093 mayBeTop = true; 17094 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17095 } else { 17096 // Special handling for above-top states (persistent 17097 // processes). These should not bring the current process 17098 // into the top state, since they are not on top. Instead 17099 // give them the best state after that. 17100 clientProcState = 17101 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17102 } 17103 } 17104 if (procState > clientProcState) { 17105 procState = clientProcState; 17106 } 17107 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17108 schedGroup = Process.THREAD_GROUP_DEFAULT; 17109 } 17110 } 17111 // If the provider has external (non-framework) process 17112 // dependencies, ensure that its adjustment is at least 17113 // FOREGROUND_APP_ADJ. 17114 if (cpr.hasExternalProcessHandles()) { 17115 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17116 adj = ProcessList.FOREGROUND_APP_ADJ; 17117 schedGroup = Process.THREAD_GROUP_DEFAULT; 17118 app.cached = false; 17119 app.adjType = "provider"; 17120 app.adjTarget = cpr.name; 17121 } 17122 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17123 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17124 } 17125 } 17126 } 17127 17128 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17129 // A client of one of our services or providers is in the top state. We 17130 // *may* want to be in the top state, but not if we are already running in 17131 // the background for some other reason. For the decision here, we are going 17132 // to pick out a few specific states that we want to remain in when a client 17133 // is top (states that tend to be longer-term) and otherwise allow it to go 17134 // to the top state. 17135 switch (procState) { 17136 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17137 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17138 case ActivityManager.PROCESS_STATE_SERVICE: 17139 // These all are longer-term states, so pull them up to the top 17140 // of the background states, but not all the way to the top state. 17141 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17142 break; 17143 default: 17144 // Otherwise, top is a better choice, so take it. 17145 procState = ActivityManager.PROCESS_STATE_TOP; 17146 break; 17147 } 17148 } 17149 17150 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17151 if (app.hasClientActivities) { 17152 // This is a cached process, but with client activities. Mark it so. 17153 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17154 app.adjType = "cch-client-act"; 17155 } else if (app.treatLikeActivity) { 17156 // This is a cached process, but somebody wants us to treat it like it has 17157 // an activity, okay! 17158 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17159 app.adjType = "cch-as-act"; 17160 } 17161 } 17162 17163 if (adj == ProcessList.SERVICE_ADJ) { 17164 if (doingAll) { 17165 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17166 mNewNumServiceProcs++; 17167 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17168 if (!app.serviceb) { 17169 // This service isn't far enough down on the LRU list to 17170 // normally be a B service, but if we are low on RAM and it 17171 // is large we want to force it down since we would prefer to 17172 // keep launcher over it. 17173 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17174 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17175 app.serviceHighRam = true; 17176 app.serviceb = true; 17177 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17178 } else { 17179 mNewNumAServiceProcs++; 17180 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17181 } 17182 } else { 17183 app.serviceHighRam = false; 17184 } 17185 } 17186 if (app.serviceb) { 17187 adj = ProcessList.SERVICE_B_ADJ; 17188 } 17189 } 17190 17191 app.curRawAdj = adj; 17192 17193 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17194 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17195 if (adj > app.maxAdj) { 17196 adj = app.maxAdj; 17197 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17198 schedGroup = Process.THREAD_GROUP_DEFAULT; 17199 } 17200 } 17201 17202 // Do final modification to adj. Everything we do between here and applying 17203 // the final setAdj must be done in this function, because we will also use 17204 // it when computing the final cached adj later. Note that we don't need to 17205 // worry about this for max adj above, since max adj will always be used to 17206 // keep it out of the cached vaues. 17207 app.curAdj = app.modifyRawOomAdj(adj); 17208 app.curSchedGroup = schedGroup; 17209 app.curProcState = procState; 17210 app.foregroundActivities = foregroundActivities; 17211 17212 return app.curRawAdj; 17213 } 17214 17215 /** 17216 * Schedule PSS collection of a process. 17217 */ 17218 void requestPssLocked(ProcessRecord proc, int procState) { 17219 if (mPendingPssProcesses.contains(proc)) { 17220 return; 17221 } 17222 if (mPendingPssProcesses.size() == 0) { 17223 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17224 } 17225 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17226 proc.pssProcState = procState; 17227 mPendingPssProcesses.add(proc); 17228 } 17229 17230 /** 17231 * Schedule PSS collection of all processes. 17232 */ 17233 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17234 if (!always) { 17235 if (now < (mLastFullPssTime + 17236 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17237 return; 17238 } 17239 } 17240 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17241 mLastFullPssTime = now; 17242 mFullPssPending = true; 17243 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17244 mPendingPssProcesses.clear(); 17245 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17246 ProcessRecord app = mLruProcesses.get(i); 17247 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17248 app.pssProcState = app.setProcState; 17249 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17250 isSleeping(), now); 17251 mPendingPssProcesses.add(app); 17252 } 17253 } 17254 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17255 } 17256 17257 /** 17258 * Ask a given process to GC right now. 17259 */ 17260 final void performAppGcLocked(ProcessRecord app) { 17261 try { 17262 app.lastRequestedGc = SystemClock.uptimeMillis(); 17263 if (app.thread != null) { 17264 if (app.reportLowMemory) { 17265 app.reportLowMemory = false; 17266 app.thread.scheduleLowMemory(); 17267 } else { 17268 app.thread.processInBackground(); 17269 } 17270 } 17271 } catch (Exception e) { 17272 // whatever. 17273 } 17274 } 17275 17276 /** 17277 * Returns true if things are idle enough to perform GCs. 17278 */ 17279 private final boolean canGcNowLocked() { 17280 boolean processingBroadcasts = false; 17281 for (BroadcastQueue q : mBroadcastQueues) { 17282 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17283 processingBroadcasts = true; 17284 } 17285 } 17286 return !processingBroadcasts 17287 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17288 } 17289 17290 /** 17291 * Perform GCs on all processes that are waiting for it, but only 17292 * if things are idle. 17293 */ 17294 final void performAppGcsLocked() { 17295 final int N = mProcessesToGc.size(); 17296 if (N <= 0) { 17297 return; 17298 } 17299 if (canGcNowLocked()) { 17300 while (mProcessesToGc.size() > 0) { 17301 ProcessRecord proc = mProcessesToGc.remove(0); 17302 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17303 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17304 <= SystemClock.uptimeMillis()) { 17305 // To avoid spamming the system, we will GC processes one 17306 // at a time, waiting a few seconds between each. 17307 performAppGcLocked(proc); 17308 scheduleAppGcsLocked(); 17309 return; 17310 } else { 17311 // It hasn't been long enough since we last GCed this 17312 // process... put it in the list to wait for its time. 17313 addProcessToGcListLocked(proc); 17314 break; 17315 } 17316 } 17317 } 17318 17319 scheduleAppGcsLocked(); 17320 } 17321 } 17322 17323 /** 17324 * If all looks good, perform GCs on all processes waiting for them. 17325 */ 17326 final void performAppGcsIfAppropriateLocked() { 17327 if (canGcNowLocked()) { 17328 performAppGcsLocked(); 17329 return; 17330 } 17331 // Still not idle, wait some more. 17332 scheduleAppGcsLocked(); 17333 } 17334 17335 /** 17336 * Schedule the execution of all pending app GCs. 17337 */ 17338 final void scheduleAppGcsLocked() { 17339 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17340 17341 if (mProcessesToGc.size() > 0) { 17342 // Schedule a GC for the time to the next process. 17343 ProcessRecord proc = mProcessesToGc.get(0); 17344 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17345 17346 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17347 long now = SystemClock.uptimeMillis(); 17348 if (when < (now+GC_TIMEOUT)) { 17349 when = now + GC_TIMEOUT; 17350 } 17351 mHandler.sendMessageAtTime(msg, when); 17352 } 17353 } 17354 17355 /** 17356 * Add a process to the array of processes waiting to be GCed. Keeps the 17357 * list in sorted order by the last GC time. The process can't already be 17358 * on the list. 17359 */ 17360 final void addProcessToGcListLocked(ProcessRecord proc) { 17361 boolean added = false; 17362 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17363 if (mProcessesToGc.get(i).lastRequestedGc < 17364 proc.lastRequestedGc) { 17365 added = true; 17366 mProcessesToGc.add(i+1, proc); 17367 break; 17368 } 17369 } 17370 if (!added) { 17371 mProcessesToGc.add(0, proc); 17372 } 17373 } 17374 17375 /** 17376 * Set up to ask a process to GC itself. This will either do it 17377 * immediately, or put it on the list of processes to gc the next 17378 * time things are idle. 17379 */ 17380 final void scheduleAppGcLocked(ProcessRecord app) { 17381 long now = SystemClock.uptimeMillis(); 17382 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17383 return; 17384 } 17385 if (!mProcessesToGc.contains(app)) { 17386 addProcessToGcListLocked(app); 17387 scheduleAppGcsLocked(); 17388 } 17389 } 17390 17391 final void checkExcessivePowerUsageLocked(boolean doKills) { 17392 updateCpuStatsNow(); 17393 17394 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17395 boolean doWakeKills = doKills; 17396 boolean doCpuKills = doKills; 17397 if (mLastPowerCheckRealtime == 0) { 17398 doWakeKills = false; 17399 } 17400 if (mLastPowerCheckUptime == 0) { 17401 doCpuKills = false; 17402 } 17403 if (stats.isScreenOn()) { 17404 doWakeKills = false; 17405 } 17406 final long curRealtime = SystemClock.elapsedRealtime(); 17407 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17408 final long curUptime = SystemClock.uptimeMillis(); 17409 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17410 mLastPowerCheckRealtime = curRealtime; 17411 mLastPowerCheckUptime = curUptime; 17412 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17413 doWakeKills = false; 17414 } 17415 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17416 doCpuKills = false; 17417 } 17418 int i = mLruProcesses.size(); 17419 while (i > 0) { 17420 i--; 17421 ProcessRecord app = mLruProcesses.get(i); 17422 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17423 long wtime; 17424 synchronized (stats) { 17425 wtime = stats.getProcessWakeTime(app.info.uid, 17426 app.pid, curRealtime); 17427 } 17428 long wtimeUsed = wtime - app.lastWakeTime; 17429 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17430 if (DEBUG_POWER) { 17431 StringBuilder sb = new StringBuilder(128); 17432 sb.append("Wake for "); 17433 app.toShortString(sb); 17434 sb.append(": over "); 17435 TimeUtils.formatDuration(realtimeSince, sb); 17436 sb.append(" used "); 17437 TimeUtils.formatDuration(wtimeUsed, sb); 17438 sb.append(" ("); 17439 sb.append((wtimeUsed*100)/realtimeSince); 17440 sb.append("%)"); 17441 Slog.i(TAG, sb.toString()); 17442 sb.setLength(0); 17443 sb.append("CPU for "); 17444 app.toShortString(sb); 17445 sb.append(": over "); 17446 TimeUtils.formatDuration(uptimeSince, sb); 17447 sb.append(" used "); 17448 TimeUtils.formatDuration(cputimeUsed, sb); 17449 sb.append(" ("); 17450 sb.append((cputimeUsed*100)/uptimeSince); 17451 sb.append("%)"); 17452 Slog.i(TAG, sb.toString()); 17453 } 17454 // If a process has held a wake lock for more 17455 // than 50% of the time during this period, 17456 // that sounds bad. Kill! 17457 if (doWakeKills && realtimeSince > 0 17458 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17459 synchronized (stats) { 17460 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17461 realtimeSince, wtimeUsed); 17462 } 17463 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17464 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17465 } else if (doCpuKills && uptimeSince > 0 17466 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17467 synchronized (stats) { 17468 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17469 uptimeSince, cputimeUsed); 17470 } 17471 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17472 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17473 } else { 17474 app.lastWakeTime = wtime; 17475 app.lastCpuTime = app.curCpuTime; 17476 } 17477 } 17478 } 17479 } 17480 17481 private final boolean applyOomAdjLocked(ProcessRecord app, 17482 ProcessRecord TOP_APP, boolean doingAll, long now) { 17483 boolean success = true; 17484 17485 if (app.curRawAdj != app.setRawAdj) { 17486 app.setRawAdj = app.curRawAdj; 17487 } 17488 17489 int changes = 0; 17490 17491 if (app.curAdj != app.setAdj) { 17492 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17493 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17494 TAG, "Set " + app.pid + " " + app.processName + 17495 " adj " + app.curAdj + ": " + app.adjType); 17496 app.setAdj = app.curAdj; 17497 } 17498 17499 if (app.setSchedGroup != app.curSchedGroup) { 17500 app.setSchedGroup = app.curSchedGroup; 17501 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17502 "Setting process group of " + app.processName 17503 + " to " + app.curSchedGroup); 17504 if (app.waitingToKill != null && 17505 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17506 app.kill(app.waitingToKill, true); 17507 success = false; 17508 } else { 17509 if (true) { 17510 long oldId = Binder.clearCallingIdentity(); 17511 try { 17512 Process.setProcessGroup(app.pid, app.curSchedGroup); 17513 } catch (Exception e) { 17514 Slog.w(TAG, "Failed setting process group of " + app.pid 17515 + " to " + app.curSchedGroup); 17516 e.printStackTrace(); 17517 } finally { 17518 Binder.restoreCallingIdentity(oldId); 17519 } 17520 } else { 17521 if (app.thread != null) { 17522 try { 17523 app.thread.setSchedulingGroup(app.curSchedGroup); 17524 } catch (RemoteException e) { 17525 } 17526 } 17527 } 17528 Process.setSwappiness(app.pid, 17529 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17530 } 17531 } 17532 if (app.repForegroundActivities != app.foregroundActivities) { 17533 app.repForegroundActivities = app.foregroundActivities; 17534 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17535 } 17536 if (app.repProcState != app.curProcState) { 17537 app.repProcState = app.curProcState; 17538 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17539 if (app.thread != null) { 17540 try { 17541 if (false) { 17542 //RuntimeException h = new RuntimeException("here"); 17543 Slog.i(TAG, "Sending new process state " + app.repProcState 17544 + " to " + app /*, h*/); 17545 } 17546 app.thread.setProcessState(app.repProcState); 17547 } catch (RemoteException e) { 17548 } 17549 } 17550 } 17551 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17552 app.setProcState)) { 17553 app.lastStateTime = now; 17554 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17555 isSleeping(), now); 17556 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17557 + ProcessList.makeProcStateString(app.setProcState) + " to " 17558 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17559 + (app.nextPssTime-now) + ": " + app); 17560 } else { 17561 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17562 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17563 requestPssLocked(app, app.setProcState); 17564 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17565 isSleeping(), now); 17566 } else if (false && DEBUG_PSS) { 17567 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17568 } 17569 } 17570 if (app.setProcState != app.curProcState) { 17571 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17572 "Proc state change of " + app.processName 17573 + " to " + app.curProcState); 17574 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17575 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17576 if (setImportant && !curImportant) { 17577 // This app is no longer something we consider important enough to allow to 17578 // use arbitrary amounts of battery power. Note 17579 // its current wake lock time to later know to kill it if 17580 // it is not behaving well. 17581 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17582 synchronized (stats) { 17583 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17584 app.pid, SystemClock.elapsedRealtime()); 17585 } 17586 app.lastCpuTime = app.curCpuTime; 17587 17588 } 17589 app.setProcState = app.curProcState; 17590 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17591 app.notCachedSinceIdle = false; 17592 } 17593 if (!doingAll) { 17594 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17595 } else { 17596 app.procStateChanged = true; 17597 } 17598 } 17599 17600 if (changes != 0) { 17601 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17602 int i = mPendingProcessChanges.size()-1; 17603 ProcessChangeItem item = null; 17604 while (i >= 0) { 17605 item = mPendingProcessChanges.get(i); 17606 if (item.pid == app.pid) { 17607 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17608 break; 17609 } 17610 i--; 17611 } 17612 if (i < 0) { 17613 // No existing item in pending changes; need a new one. 17614 final int NA = mAvailProcessChanges.size(); 17615 if (NA > 0) { 17616 item = mAvailProcessChanges.remove(NA-1); 17617 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17618 } else { 17619 item = new ProcessChangeItem(); 17620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17621 } 17622 item.changes = 0; 17623 item.pid = app.pid; 17624 item.uid = app.info.uid; 17625 if (mPendingProcessChanges.size() == 0) { 17626 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17627 "*** Enqueueing dispatch processes changed!"); 17628 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17629 } 17630 mPendingProcessChanges.add(item); 17631 } 17632 item.changes |= changes; 17633 item.processState = app.repProcState; 17634 item.foregroundActivities = app.repForegroundActivities; 17635 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17636 + Integer.toHexString(System.identityHashCode(item)) 17637 + " " + app.toShortString() + ": changes=" + item.changes 17638 + " procState=" + item.processState 17639 + " foreground=" + item.foregroundActivities 17640 + " type=" + app.adjType + " source=" + app.adjSource 17641 + " target=" + app.adjTarget); 17642 } 17643 17644 return success; 17645 } 17646 17647 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17648 if (proc.thread != null) { 17649 if (proc.baseProcessTracker != null) { 17650 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17651 } 17652 if (proc.repProcState >= 0) { 17653 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17654 proc.repProcState); 17655 } 17656 } 17657 } 17658 17659 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17660 ProcessRecord TOP_APP, boolean doingAll, long now) { 17661 if (app.thread == null) { 17662 return false; 17663 } 17664 17665 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17666 17667 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17668 } 17669 17670 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17671 boolean oomAdj) { 17672 if (isForeground != proc.foregroundServices) { 17673 proc.foregroundServices = isForeground; 17674 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17675 proc.info.uid); 17676 if (isForeground) { 17677 if (curProcs == null) { 17678 curProcs = new ArrayList<ProcessRecord>(); 17679 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17680 } 17681 if (!curProcs.contains(proc)) { 17682 curProcs.add(proc); 17683 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17684 proc.info.packageName, proc.info.uid); 17685 } 17686 } else { 17687 if (curProcs != null) { 17688 if (curProcs.remove(proc)) { 17689 mBatteryStatsService.noteEvent( 17690 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17691 proc.info.packageName, proc.info.uid); 17692 if (curProcs.size() <= 0) { 17693 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17694 } 17695 } 17696 } 17697 } 17698 if (oomAdj) { 17699 updateOomAdjLocked(); 17700 } 17701 } 17702 } 17703 17704 private final ActivityRecord resumedAppLocked() { 17705 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17706 String pkg; 17707 int uid; 17708 if (act != null) { 17709 pkg = act.packageName; 17710 uid = act.info.applicationInfo.uid; 17711 } else { 17712 pkg = null; 17713 uid = -1; 17714 } 17715 // Has the UID or resumed package name changed? 17716 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17717 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17718 if (mCurResumedPackage != null) { 17719 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17720 mCurResumedPackage, mCurResumedUid); 17721 } 17722 mCurResumedPackage = pkg; 17723 mCurResumedUid = uid; 17724 if (mCurResumedPackage != null) { 17725 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17726 mCurResumedPackage, mCurResumedUid); 17727 } 17728 } 17729 return act; 17730 } 17731 17732 final boolean updateOomAdjLocked(ProcessRecord app) { 17733 final ActivityRecord TOP_ACT = resumedAppLocked(); 17734 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17735 final boolean wasCached = app.cached; 17736 17737 mAdjSeq++; 17738 17739 // This is the desired cached adjusment we want to tell it to use. 17740 // If our app is currently cached, we know it, and that is it. Otherwise, 17741 // we don't know it yet, and it needs to now be cached we will then 17742 // need to do a complete oom adj. 17743 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17744 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17745 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17746 SystemClock.uptimeMillis()); 17747 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17748 // Changed to/from cached state, so apps after it in the LRU 17749 // list may also be changed. 17750 updateOomAdjLocked(); 17751 } 17752 return success; 17753 } 17754 17755 final void updateOomAdjLocked() { 17756 final ActivityRecord TOP_ACT = resumedAppLocked(); 17757 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17758 final long now = SystemClock.uptimeMillis(); 17759 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17760 final int N = mLruProcesses.size(); 17761 17762 if (false) { 17763 RuntimeException e = new RuntimeException(); 17764 e.fillInStackTrace(); 17765 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17766 } 17767 17768 mAdjSeq++; 17769 mNewNumServiceProcs = 0; 17770 mNewNumAServiceProcs = 0; 17771 17772 final int emptyProcessLimit; 17773 final int cachedProcessLimit; 17774 if (mProcessLimit <= 0) { 17775 emptyProcessLimit = cachedProcessLimit = 0; 17776 } else if (mProcessLimit == 1) { 17777 emptyProcessLimit = 1; 17778 cachedProcessLimit = 0; 17779 } else { 17780 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17781 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17782 } 17783 17784 // Let's determine how many processes we have running vs. 17785 // how many slots we have for background processes; we may want 17786 // to put multiple processes in a slot of there are enough of 17787 // them. 17788 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17789 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17790 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17791 if (numEmptyProcs > cachedProcessLimit) { 17792 // If there are more empty processes than our limit on cached 17793 // processes, then use the cached process limit for the factor. 17794 // This ensures that the really old empty processes get pushed 17795 // down to the bottom, so if we are running low on memory we will 17796 // have a better chance at keeping around more cached processes 17797 // instead of a gazillion empty processes. 17798 numEmptyProcs = cachedProcessLimit; 17799 } 17800 int emptyFactor = numEmptyProcs/numSlots; 17801 if (emptyFactor < 1) emptyFactor = 1; 17802 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17803 if (cachedFactor < 1) cachedFactor = 1; 17804 int stepCached = 0; 17805 int stepEmpty = 0; 17806 int numCached = 0; 17807 int numEmpty = 0; 17808 int numTrimming = 0; 17809 17810 mNumNonCachedProcs = 0; 17811 mNumCachedHiddenProcs = 0; 17812 17813 // First update the OOM adjustment for each of the 17814 // application processes based on their current state. 17815 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17816 int nextCachedAdj = curCachedAdj+1; 17817 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17818 int nextEmptyAdj = curEmptyAdj+2; 17819 for (int i=N-1; i>=0; i--) { 17820 ProcessRecord app = mLruProcesses.get(i); 17821 if (!app.killedByAm && app.thread != null) { 17822 app.procStateChanged = false; 17823 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17824 17825 // If we haven't yet assigned the final cached adj 17826 // to the process, do that now. 17827 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17828 switch (app.curProcState) { 17829 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17830 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17831 // This process is a cached process holding activities... 17832 // assign it the next cached value for that type, and then 17833 // step that cached level. 17834 app.curRawAdj = curCachedAdj; 17835 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17836 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17837 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17838 + ")"); 17839 if (curCachedAdj != nextCachedAdj) { 17840 stepCached++; 17841 if (stepCached >= cachedFactor) { 17842 stepCached = 0; 17843 curCachedAdj = nextCachedAdj; 17844 nextCachedAdj += 2; 17845 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17846 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17847 } 17848 } 17849 } 17850 break; 17851 default: 17852 // For everything else, assign next empty cached process 17853 // level and bump that up. Note that this means that 17854 // long-running services that have dropped down to the 17855 // cached level will be treated as empty (since their process 17856 // state is still as a service), which is what we want. 17857 app.curRawAdj = curEmptyAdj; 17858 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17859 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17860 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17861 + ")"); 17862 if (curEmptyAdj != nextEmptyAdj) { 17863 stepEmpty++; 17864 if (stepEmpty >= emptyFactor) { 17865 stepEmpty = 0; 17866 curEmptyAdj = nextEmptyAdj; 17867 nextEmptyAdj += 2; 17868 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17869 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17870 } 17871 } 17872 } 17873 break; 17874 } 17875 } 17876 17877 applyOomAdjLocked(app, TOP_APP, true, now); 17878 17879 // Count the number of process types. 17880 switch (app.curProcState) { 17881 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17882 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17883 mNumCachedHiddenProcs++; 17884 numCached++; 17885 if (numCached > cachedProcessLimit) { 17886 app.kill("cached #" + numCached, true); 17887 } 17888 break; 17889 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17890 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17891 && app.lastActivityTime < oldTime) { 17892 app.kill("empty for " 17893 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17894 / 1000) + "s", true); 17895 } else { 17896 numEmpty++; 17897 if (numEmpty > emptyProcessLimit) { 17898 app.kill("empty #" + numEmpty, true); 17899 } 17900 } 17901 break; 17902 default: 17903 mNumNonCachedProcs++; 17904 break; 17905 } 17906 17907 if (app.isolated && app.services.size() <= 0) { 17908 // If this is an isolated process, and there are no 17909 // services running in it, then the process is no longer 17910 // needed. We agressively kill these because we can by 17911 // definition not re-use the same process again, and it is 17912 // good to avoid having whatever code was running in them 17913 // left sitting around after no longer needed. 17914 app.kill("isolated not needed", true); 17915 } 17916 17917 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17918 && !app.killedByAm) { 17919 numTrimming++; 17920 } 17921 } 17922 } 17923 17924 mNumServiceProcs = mNewNumServiceProcs; 17925 17926 // Now determine the memory trimming level of background processes. 17927 // Unfortunately we need to start at the back of the list to do this 17928 // properly. We only do this if the number of background apps we 17929 // are managing to keep around is less than half the maximum we desire; 17930 // if we are keeping a good number around, we'll let them use whatever 17931 // memory they want. 17932 final int numCachedAndEmpty = numCached + numEmpty; 17933 int memFactor; 17934 if (numCached <= ProcessList.TRIM_CACHED_APPS 17935 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17936 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17937 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17938 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17939 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17940 } else { 17941 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17942 } 17943 } else { 17944 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17945 } 17946 // We always allow the memory level to go up (better). We only allow it to go 17947 // down if we are in a state where that is allowed, *and* the total number of processes 17948 // has gone down since last time. 17949 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17950 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17951 + " last=" + mLastNumProcesses); 17952 if (memFactor > mLastMemoryLevel) { 17953 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17954 memFactor = mLastMemoryLevel; 17955 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17956 } 17957 } 17958 mLastMemoryLevel = memFactor; 17959 mLastNumProcesses = mLruProcesses.size(); 17960 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17961 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17962 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17963 if (mLowRamStartTime == 0) { 17964 mLowRamStartTime = now; 17965 } 17966 int step = 0; 17967 int fgTrimLevel; 17968 switch (memFactor) { 17969 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17970 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17971 break; 17972 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17973 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17974 break; 17975 default: 17976 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17977 break; 17978 } 17979 int factor = numTrimming/3; 17980 int minFactor = 2; 17981 if (mHomeProcess != null) minFactor++; 17982 if (mPreviousProcess != null) minFactor++; 17983 if (factor < minFactor) factor = minFactor; 17984 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17985 for (int i=N-1; i>=0; i--) { 17986 ProcessRecord app = mLruProcesses.get(i); 17987 if (allChanged || app.procStateChanged) { 17988 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17989 app.procStateChanged = false; 17990 } 17991 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17992 && !app.killedByAm) { 17993 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17994 try { 17995 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17996 "Trimming memory of " + app.processName 17997 + " to " + curLevel); 17998 app.thread.scheduleTrimMemory(curLevel); 17999 } catch (RemoteException e) { 18000 } 18001 if (false) { 18002 // For now we won't do this; our memory trimming seems 18003 // to be good enough at this point that destroying 18004 // activities causes more harm than good. 18005 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18006 && app != mHomeProcess && app != mPreviousProcess) { 18007 // Need to do this on its own message because the stack may not 18008 // be in a consistent state at this point. 18009 // For these apps we will also finish their activities 18010 // to help them free memory. 18011 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18012 } 18013 } 18014 } 18015 app.trimMemoryLevel = curLevel; 18016 step++; 18017 if (step >= factor) { 18018 step = 0; 18019 switch (curLevel) { 18020 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18021 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18022 break; 18023 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18024 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18025 break; 18026 } 18027 } 18028 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18029 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18030 && app.thread != null) { 18031 try { 18032 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18033 "Trimming memory of heavy-weight " + app.processName 18034 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18035 app.thread.scheduleTrimMemory( 18036 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18037 } catch (RemoteException e) { 18038 } 18039 } 18040 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18041 } else { 18042 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18043 || app.systemNoUi) && app.pendingUiClean) { 18044 // If this application is now in the background and it 18045 // had done UI, then give it the special trim level to 18046 // have it free UI resources. 18047 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18048 if (app.trimMemoryLevel < level && app.thread != null) { 18049 try { 18050 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18051 "Trimming memory of bg-ui " + app.processName 18052 + " to " + level); 18053 app.thread.scheduleTrimMemory(level); 18054 } catch (RemoteException e) { 18055 } 18056 } 18057 app.pendingUiClean = false; 18058 } 18059 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18060 try { 18061 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18062 "Trimming memory of fg " + app.processName 18063 + " to " + fgTrimLevel); 18064 app.thread.scheduleTrimMemory(fgTrimLevel); 18065 } catch (RemoteException e) { 18066 } 18067 } 18068 app.trimMemoryLevel = fgTrimLevel; 18069 } 18070 } 18071 } else { 18072 if (mLowRamStartTime != 0) { 18073 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18074 mLowRamStartTime = 0; 18075 } 18076 for (int i=N-1; i>=0; i--) { 18077 ProcessRecord app = mLruProcesses.get(i); 18078 if (allChanged || app.procStateChanged) { 18079 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18080 app.procStateChanged = false; 18081 } 18082 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18083 || app.systemNoUi) && app.pendingUiClean) { 18084 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18085 && app.thread != null) { 18086 try { 18087 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18088 "Trimming memory of ui hidden " + app.processName 18089 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18090 app.thread.scheduleTrimMemory( 18091 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18092 } catch (RemoteException e) { 18093 } 18094 } 18095 app.pendingUiClean = false; 18096 } 18097 app.trimMemoryLevel = 0; 18098 } 18099 } 18100 18101 if (mAlwaysFinishActivities) { 18102 // Need to do this on its own message because the stack may not 18103 // be in a consistent state at this point. 18104 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18105 } 18106 18107 if (allChanged) { 18108 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18109 } 18110 18111 if (mProcessStats.shouldWriteNowLocked(now)) { 18112 mHandler.post(new Runnable() { 18113 @Override public void run() { 18114 synchronized (ActivityManagerService.this) { 18115 mProcessStats.writeStateAsyncLocked(); 18116 } 18117 } 18118 }); 18119 } 18120 18121 if (DEBUG_OOM_ADJ) { 18122 if (false) { 18123 RuntimeException here = new RuntimeException("here"); 18124 here.fillInStackTrace(); 18125 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18126 } else { 18127 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18128 } 18129 } 18130 } 18131 18132 final void trimApplications() { 18133 synchronized (this) { 18134 int i; 18135 18136 // First remove any unused application processes whose package 18137 // has been removed. 18138 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18139 final ProcessRecord app = mRemovedProcesses.get(i); 18140 if (app.activities.size() == 0 18141 && app.curReceiver == null && app.services.size() == 0) { 18142 Slog.i( 18143 TAG, "Exiting empty application process " 18144 + app.processName + " (" 18145 + (app.thread != null ? app.thread.asBinder() : null) 18146 + ")\n"); 18147 if (app.pid > 0 && app.pid != MY_PID) { 18148 app.kill("empty", false); 18149 } else { 18150 try { 18151 app.thread.scheduleExit(); 18152 } catch (Exception e) { 18153 // Ignore exceptions. 18154 } 18155 } 18156 cleanUpApplicationRecordLocked(app, false, true, -1); 18157 mRemovedProcesses.remove(i); 18158 18159 if (app.persistent) { 18160 addAppLocked(app.info, false, null /* ABI override */); 18161 } 18162 } 18163 } 18164 18165 // Now update the oom adj for all processes. 18166 updateOomAdjLocked(); 18167 } 18168 } 18169 18170 /** This method sends the specified signal to each of the persistent apps */ 18171 public void signalPersistentProcesses(int sig) throws RemoteException { 18172 if (sig != Process.SIGNAL_USR1) { 18173 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18174 } 18175 18176 synchronized (this) { 18177 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18178 != PackageManager.PERMISSION_GRANTED) { 18179 throw new SecurityException("Requires permission " 18180 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18181 } 18182 18183 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18184 ProcessRecord r = mLruProcesses.get(i); 18185 if (r.thread != null && r.persistent) { 18186 Process.sendSignal(r.pid, sig); 18187 } 18188 } 18189 } 18190 } 18191 18192 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18193 if (proc == null || proc == mProfileProc) { 18194 proc = mProfileProc; 18195 profileType = mProfileType; 18196 clearProfilerLocked(); 18197 } 18198 if (proc == null) { 18199 return; 18200 } 18201 try { 18202 proc.thread.profilerControl(false, null, profileType); 18203 } catch (RemoteException e) { 18204 throw new IllegalStateException("Process disappeared"); 18205 } 18206 } 18207 18208 private void clearProfilerLocked() { 18209 if (mProfileFd != null) { 18210 try { 18211 mProfileFd.close(); 18212 } catch (IOException e) { 18213 } 18214 } 18215 mProfileApp = null; 18216 mProfileProc = null; 18217 mProfileFile = null; 18218 mProfileType = 0; 18219 mAutoStopProfiler = false; 18220 mSamplingInterval = 0; 18221 } 18222 18223 public boolean profileControl(String process, int userId, boolean start, 18224 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18225 18226 try { 18227 synchronized (this) { 18228 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18229 // its own permission. 18230 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18231 != PackageManager.PERMISSION_GRANTED) { 18232 throw new SecurityException("Requires permission " 18233 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18234 } 18235 18236 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18237 throw new IllegalArgumentException("null profile info or fd"); 18238 } 18239 18240 ProcessRecord proc = null; 18241 if (process != null) { 18242 proc = findProcessLocked(process, userId, "profileControl"); 18243 } 18244 18245 if (start && (proc == null || proc.thread == null)) { 18246 throw new IllegalArgumentException("Unknown process: " + process); 18247 } 18248 18249 if (start) { 18250 stopProfilerLocked(null, 0); 18251 setProfileApp(proc.info, proc.processName, profilerInfo); 18252 mProfileProc = proc; 18253 mProfileType = profileType; 18254 ParcelFileDescriptor fd = profilerInfo.profileFd; 18255 try { 18256 fd = fd.dup(); 18257 } catch (IOException e) { 18258 fd = null; 18259 } 18260 profilerInfo.profileFd = fd; 18261 proc.thread.profilerControl(start, profilerInfo, profileType); 18262 fd = null; 18263 mProfileFd = null; 18264 } else { 18265 stopProfilerLocked(proc, profileType); 18266 if (profilerInfo != null && profilerInfo.profileFd != null) { 18267 try { 18268 profilerInfo.profileFd.close(); 18269 } catch (IOException e) { 18270 } 18271 } 18272 } 18273 18274 return true; 18275 } 18276 } catch (RemoteException e) { 18277 throw new IllegalStateException("Process disappeared"); 18278 } finally { 18279 if (profilerInfo != null && profilerInfo.profileFd != null) { 18280 try { 18281 profilerInfo.profileFd.close(); 18282 } catch (IOException e) { 18283 } 18284 } 18285 } 18286 } 18287 18288 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18289 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18290 userId, true, ALLOW_FULL_ONLY, callName, null); 18291 ProcessRecord proc = null; 18292 try { 18293 int pid = Integer.parseInt(process); 18294 synchronized (mPidsSelfLocked) { 18295 proc = mPidsSelfLocked.get(pid); 18296 } 18297 } catch (NumberFormatException e) { 18298 } 18299 18300 if (proc == null) { 18301 ArrayMap<String, SparseArray<ProcessRecord>> all 18302 = mProcessNames.getMap(); 18303 SparseArray<ProcessRecord> procs = all.get(process); 18304 if (procs != null && procs.size() > 0) { 18305 proc = procs.valueAt(0); 18306 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18307 for (int i=1; i<procs.size(); i++) { 18308 ProcessRecord thisProc = procs.valueAt(i); 18309 if (thisProc.userId == userId) { 18310 proc = thisProc; 18311 break; 18312 } 18313 } 18314 } 18315 } 18316 } 18317 18318 return proc; 18319 } 18320 18321 public boolean dumpHeap(String process, int userId, boolean managed, 18322 String path, ParcelFileDescriptor fd) throws RemoteException { 18323 18324 try { 18325 synchronized (this) { 18326 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18327 // its own permission (same as profileControl). 18328 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18329 != PackageManager.PERMISSION_GRANTED) { 18330 throw new SecurityException("Requires permission " 18331 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18332 } 18333 18334 if (fd == null) { 18335 throw new IllegalArgumentException("null fd"); 18336 } 18337 18338 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18339 if (proc == null || proc.thread == null) { 18340 throw new IllegalArgumentException("Unknown process: " + process); 18341 } 18342 18343 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18344 if (!isDebuggable) { 18345 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18346 throw new SecurityException("Process not debuggable: " + proc); 18347 } 18348 } 18349 18350 proc.thread.dumpHeap(managed, path, fd); 18351 fd = null; 18352 return true; 18353 } 18354 } catch (RemoteException e) { 18355 throw new IllegalStateException("Process disappeared"); 18356 } finally { 18357 if (fd != null) { 18358 try { 18359 fd.close(); 18360 } catch (IOException e) { 18361 } 18362 } 18363 } 18364 } 18365 18366 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18367 public void monitor() { 18368 synchronized (this) { } 18369 } 18370 18371 void onCoreSettingsChange(Bundle settings) { 18372 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18373 ProcessRecord processRecord = mLruProcesses.get(i); 18374 try { 18375 if (processRecord.thread != null) { 18376 processRecord.thread.setCoreSettings(settings); 18377 } 18378 } catch (RemoteException re) { 18379 /* ignore */ 18380 } 18381 } 18382 } 18383 18384 // Multi-user methods 18385 18386 /** 18387 * Start user, if its not already running, but don't bring it to foreground. 18388 */ 18389 @Override 18390 public boolean startUserInBackground(final int userId) { 18391 return startUser(userId, /* foreground */ false); 18392 } 18393 18394 /** 18395 * Start user, if its not already running, and bring it to foreground. 18396 */ 18397 boolean startUserInForeground(final int userId, Dialog dlg) { 18398 boolean result = startUser(userId, /* foreground */ true); 18399 dlg.dismiss(); 18400 return result; 18401 } 18402 18403 /** 18404 * Refreshes the list of users related to the current user when either a 18405 * user switch happens or when a new related user is started in the 18406 * background. 18407 */ 18408 private void updateCurrentProfileIdsLocked() { 18409 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18410 mCurrentUserId, false /* enabledOnly */); 18411 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18412 for (int i = 0; i < currentProfileIds.length; i++) { 18413 currentProfileIds[i] = profiles.get(i).id; 18414 } 18415 mCurrentProfileIds = currentProfileIds; 18416 18417 synchronized (mUserProfileGroupIdsSelfLocked) { 18418 mUserProfileGroupIdsSelfLocked.clear(); 18419 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18420 for (int i = 0; i < users.size(); i++) { 18421 UserInfo user = users.get(i); 18422 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18423 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18424 } 18425 } 18426 } 18427 } 18428 18429 private Set getProfileIdsLocked(int userId) { 18430 Set userIds = new HashSet<Integer>(); 18431 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18432 userId, false /* enabledOnly */); 18433 for (UserInfo user : profiles) { 18434 userIds.add(Integer.valueOf(user.id)); 18435 } 18436 return userIds; 18437 } 18438 18439 @Override 18440 public boolean switchUser(final int userId) { 18441 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18442 String userName; 18443 synchronized (this) { 18444 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18445 if (userInfo == null) { 18446 Slog.w(TAG, "No user info for user #" + userId); 18447 return false; 18448 } 18449 if (userInfo.isManagedProfile()) { 18450 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18451 return false; 18452 } 18453 userName = userInfo.name; 18454 mTargetUserId = userId; 18455 } 18456 mHandler.removeMessages(START_USER_SWITCH_MSG); 18457 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18458 return true; 18459 } 18460 18461 private void showUserSwitchDialog(int userId, String userName) { 18462 // The dialog will show and then initiate the user switch by calling startUserInForeground 18463 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18464 true /* above system */); 18465 d.show(); 18466 } 18467 18468 private boolean startUser(final int userId, final boolean foreground) { 18469 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18470 != PackageManager.PERMISSION_GRANTED) { 18471 String msg = "Permission Denial: switchUser() from pid=" 18472 + Binder.getCallingPid() 18473 + ", uid=" + Binder.getCallingUid() 18474 + " requires " + INTERACT_ACROSS_USERS_FULL; 18475 Slog.w(TAG, msg); 18476 throw new SecurityException(msg); 18477 } 18478 18479 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18480 18481 final long ident = Binder.clearCallingIdentity(); 18482 try { 18483 synchronized (this) { 18484 final int oldUserId = mCurrentUserId; 18485 if (oldUserId == userId) { 18486 return true; 18487 } 18488 18489 mStackSupervisor.setLockTaskModeLocked(null, false); 18490 18491 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18492 if (userInfo == null) { 18493 Slog.w(TAG, "No user info for user #" + userId); 18494 return false; 18495 } 18496 if (foreground && userInfo.isManagedProfile()) { 18497 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18498 return false; 18499 } 18500 18501 if (foreground) { 18502 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18503 R.anim.screen_user_enter); 18504 } 18505 18506 boolean needStart = false; 18507 18508 // If the user we are switching to is not currently started, then 18509 // we need to start it now. 18510 if (mStartedUsers.get(userId) == null) { 18511 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18512 updateStartedUserArrayLocked(); 18513 needStart = true; 18514 } 18515 18516 final Integer userIdInt = Integer.valueOf(userId); 18517 mUserLru.remove(userIdInt); 18518 mUserLru.add(userIdInt); 18519 18520 if (foreground) { 18521 mCurrentUserId = userId; 18522 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18523 updateCurrentProfileIdsLocked(); 18524 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18525 // Once the internal notion of the active user has switched, we lock the device 18526 // with the option to show the user switcher on the keyguard. 18527 mWindowManager.lockNow(null); 18528 } else { 18529 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18530 updateCurrentProfileIdsLocked(); 18531 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18532 mUserLru.remove(currentUserIdInt); 18533 mUserLru.add(currentUserIdInt); 18534 } 18535 18536 final UserStartedState uss = mStartedUsers.get(userId); 18537 18538 // Make sure user is in the started state. If it is currently 18539 // stopping, we need to knock that off. 18540 if (uss.mState == UserStartedState.STATE_STOPPING) { 18541 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18542 // so we can just fairly silently bring the user back from 18543 // the almost-dead. 18544 uss.mState = UserStartedState.STATE_RUNNING; 18545 updateStartedUserArrayLocked(); 18546 needStart = true; 18547 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18548 // This means ACTION_SHUTDOWN has been sent, so we will 18549 // need to treat this as a new boot of the user. 18550 uss.mState = UserStartedState.STATE_BOOTING; 18551 updateStartedUserArrayLocked(); 18552 needStart = true; 18553 } 18554 18555 if (uss.mState == UserStartedState.STATE_BOOTING) { 18556 // Booting up a new user, need to tell system services about it. 18557 // Note that this is on the same handler as scheduling of broadcasts, 18558 // which is important because it needs to go first. 18559 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18560 } 18561 18562 if (foreground) { 18563 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18564 oldUserId)); 18565 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18566 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18567 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18568 oldUserId, userId, uss)); 18569 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18570 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18571 } 18572 18573 if (needStart) { 18574 // Send USER_STARTED broadcast 18575 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18576 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18577 | Intent.FLAG_RECEIVER_FOREGROUND); 18578 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18579 broadcastIntentLocked(null, null, intent, 18580 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18581 false, false, MY_PID, Process.SYSTEM_UID, userId); 18582 } 18583 18584 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18585 if (userId != UserHandle.USER_OWNER) { 18586 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18587 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18588 broadcastIntentLocked(null, null, intent, null, 18589 new IIntentReceiver.Stub() { 18590 public void performReceive(Intent intent, int resultCode, 18591 String data, Bundle extras, boolean ordered, 18592 boolean sticky, int sendingUser) { 18593 onUserInitialized(uss, foreground, oldUserId, userId); 18594 } 18595 }, 0, null, null, null, AppOpsManager.OP_NONE, 18596 true, false, MY_PID, Process.SYSTEM_UID, 18597 userId); 18598 uss.initializing = true; 18599 } else { 18600 getUserManagerLocked().makeInitialized(userInfo.id); 18601 } 18602 } 18603 18604 if (foreground) { 18605 if (!uss.initializing) { 18606 moveUserToForeground(uss, oldUserId, userId); 18607 } 18608 } else { 18609 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18610 } 18611 18612 if (needStart) { 18613 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18614 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18615 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18616 broadcastIntentLocked(null, null, intent, 18617 null, new IIntentReceiver.Stub() { 18618 @Override 18619 public void performReceive(Intent intent, int resultCode, String data, 18620 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18621 throws RemoteException { 18622 } 18623 }, 0, null, null, 18624 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18625 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18626 } 18627 } 18628 } finally { 18629 Binder.restoreCallingIdentity(ident); 18630 } 18631 18632 return true; 18633 } 18634 18635 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18636 long ident = Binder.clearCallingIdentity(); 18637 try { 18638 Intent intent; 18639 if (oldUserId >= 0) { 18640 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18641 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18642 int count = profiles.size(); 18643 for (int i = 0; i < count; i++) { 18644 int profileUserId = profiles.get(i).id; 18645 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18646 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18647 | Intent.FLAG_RECEIVER_FOREGROUND); 18648 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18649 broadcastIntentLocked(null, null, intent, 18650 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18651 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18652 } 18653 } 18654 if (newUserId >= 0) { 18655 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18656 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18657 int count = profiles.size(); 18658 for (int i = 0; i < count; i++) { 18659 int profileUserId = profiles.get(i).id; 18660 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18661 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18662 | Intent.FLAG_RECEIVER_FOREGROUND); 18663 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18664 broadcastIntentLocked(null, null, intent, 18665 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18666 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18667 } 18668 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18670 | Intent.FLAG_RECEIVER_FOREGROUND); 18671 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18672 broadcastIntentLocked(null, null, intent, 18673 null, null, 0, null, null, 18674 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18675 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18676 } 18677 } finally { 18678 Binder.restoreCallingIdentity(ident); 18679 } 18680 } 18681 18682 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18683 final int newUserId) { 18684 final int N = mUserSwitchObservers.beginBroadcast(); 18685 if (N > 0) { 18686 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18687 int mCount = 0; 18688 @Override 18689 public void sendResult(Bundle data) throws RemoteException { 18690 synchronized (ActivityManagerService.this) { 18691 if (mCurUserSwitchCallback == this) { 18692 mCount++; 18693 if (mCount == N) { 18694 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18695 } 18696 } 18697 } 18698 } 18699 }; 18700 synchronized (this) { 18701 uss.switching = true; 18702 mCurUserSwitchCallback = callback; 18703 } 18704 for (int i=0; i<N; i++) { 18705 try { 18706 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18707 newUserId, callback); 18708 } catch (RemoteException e) { 18709 } 18710 } 18711 } else { 18712 synchronized (this) { 18713 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18714 } 18715 } 18716 mUserSwitchObservers.finishBroadcast(); 18717 } 18718 18719 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18720 synchronized (this) { 18721 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18722 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18723 } 18724 } 18725 18726 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18727 mCurUserSwitchCallback = null; 18728 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18729 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18730 oldUserId, newUserId, uss)); 18731 } 18732 18733 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18734 synchronized (this) { 18735 if (foreground) { 18736 moveUserToForeground(uss, oldUserId, newUserId); 18737 } 18738 } 18739 18740 completeSwitchAndInitalize(uss, newUserId, true, false); 18741 } 18742 18743 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18744 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18745 if (homeInFront) { 18746 startHomeActivityLocked(newUserId); 18747 } else { 18748 mStackSupervisor.resumeTopActivitiesLocked(); 18749 } 18750 EventLogTags.writeAmSwitchUser(newUserId); 18751 getUserManagerLocked().userForeground(newUserId); 18752 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18753 } 18754 18755 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18756 completeSwitchAndInitalize(uss, newUserId, false, true); 18757 } 18758 18759 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18760 boolean clearInitializing, boolean clearSwitching) { 18761 boolean unfrozen = false; 18762 synchronized (this) { 18763 if (clearInitializing) { 18764 uss.initializing = false; 18765 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18766 } 18767 if (clearSwitching) { 18768 uss.switching = false; 18769 } 18770 if (!uss.switching && !uss.initializing) { 18771 mWindowManager.stopFreezingScreen(); 18772 unfrozen = true; 18773 } 18774 } 18775 if (unfrozen) { 18776 final int N = mUserSwitchObservers.beginBroadcast(); 18777 for (int i=0; i<N; i++) { 18778 try { 18779 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18780 } catch (RemoteException e) { 18781 } 18782 } 18783 mUserSwitchObservers.finishBroadcast(); 18784 } 18785 } 18786 18787 void scheduleStartProfilesLocked() { 18788 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18789 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18790 DateUtils.SECOND_IN_MILLIS); 18791 } 18792 } 18793 18794 void startProfilesLocked() { 18795 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18796 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18797 mCurrentUserId, false /* enabledOnly */); 18798 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18799 for (UserInfo user : profiles) { 18800 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18801 && user.id != mCurrentUserId) { 18802 toStart.add(user); 18803 } 18804 } 18805 final int n = toStart.size(); 18806 int i = 0; 18807 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18808 startUserInBackground(toStart.get(i).id); 18809 } 18810 if (i < n) { 18811 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18812 } 18813 } 18814 18815 void finishUserBoot(UserStartedState uss) { 18816 synchronized (this) { 18817 if (uss.mState == UserStartedState.STATE_BOOTING 18818 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18819 uss.mState = UserStartedState.STATE_RUNNING; 18820 final int userId = uss.mHandle.getIdentifier(); 18821 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18822 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18823 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18824 broadcastIntentLocked(null, null, intent, 18825 null, null, 0, null, null, 18826 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18827 true, false, MY_PID, Process.SYSTEM_UID, userId); 18828 } 18829 } 18830 } 18831 18832 void finishUserSwitch(UserStartedState uss) { 18833 synchronized (this) { 18834 finishUserBoot(uss); 18835 18836 startProfilesLocked(); 18837 18838 int num = mUserLru.size(); 18839 int i = 0; 18840 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18841 Integer oldUserId = mUserLru.get(i); 18842 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18843 if (oldUss == null) { 18844 // Shouldn't happen, but be sane if it does. 18845 mUserLru.remove(i); 18846 num--; 18847 continue; 18848 } 18849 if (oldUss.mState == UserStartedState.STATE_STOPPING 18850 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18851 // This user is already stopping, doesn't count. 18852 num--; 18853 i++; 18854 continue; 18855 } 18856 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18857 // Owner and current can't be stopped, but count as running. 18858 i++; 18859 continue; 18860 } 18861 // This is a user to be stopped. 18862 stopUserLocked(oldUserId, null); 18863 num--; 18864 i++; 18865 } 18866 } 18867 } 18868 18869 @Override 18870 public int stopUser(final int userId, final IStopUserCallback callback) { 18871 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18872 != PackageManager.PERMISSION_GRANTED) { 18873 String msg = "Permission Denial: switchUser() from pid=" 18874 + Binder.getCallingPid() 18875 + ", uid=" + Binder.getCallingUid() 18876 + " requires " + INTERACT_ACROSS_USERS_FULL; 18877 Slog.w(TAG, msg); 18878 throw new SecurityException(msg); 18879 } 18880 if (userId <= 0) { 18881 throw new IllegalArgumentException("Can't stop primary user " + userId); 18882 } 18883 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18884 synchronized (this) { 18885 return stopUserLocked(userId, callback); 18886 } 18887 } 18888 18889 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18890 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18891 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18892 return ActivityManager.USER_OP_IS_CURRENT; 18893 } 18894 18895 final UserStartedState uss = mStartedUsers.get(userId); 18896 if (uss == null) { 18897 // User is not started, nothing to do... but we do need to 18898 // callback if requested. 18899 if (callback != null) { 18900 mHandler.post(new Runnable() { 18901 @Override 18902 public void run() { 18903 try { 18904 callback.userStopped(userId); 18905 } catch (RemoteException e) { 18906 } 18907 } 18908 }); 18909 } 18910 return ActivityManager.USER_OP_SUCCESS; 18911 } 18912 18913 if (callback != null) { 18914 uss.mStopCallbacks.add(callback); 18915 } 18916 18917 if (uss.mState != UserStartedState.STATE_STOPPING 18918 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18919 uss.mState = UserStartedState.STATE_STOPPING; 18920 updateStartedUserArrayLocked(); 18921 18922 long ident = Binder.clearCallingIdentity(); 18923 try { 18924 // We are going to broadcast ACTION_USER_STOPPING and then 18925 // once that is done send a final ACTION_SHUTDOWN and then 18926 // stop the user. 18927 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18928 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18929 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18930 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18931 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18932 // This is the result receiver for the final shutdown broadcast. 18933 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18934 @Override 18935 public void performReceive(Intent intent, int resultCode, String data, 18936 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18937 finishUserStop(uss); 18938 } 18939 }; 18940 // This is the result receiver for the initial stopping broadcast. 18941 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18942 @Override 18943 public void performReceive(Intent intent, int resultCode, String data, 18944 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18945 // On to the next. 18946 synchronized (ActivityManagerService.this) { 18947 if (uss.mState != UserStartedState.STATE_STOPPING) { 18948 // Whoops, we are being started back up. Abort, abort! 18949 return; 18950 } 18951 uss.mState = UserStartedState.STATE_SHUTDOWN; 18952 } 18953 mBatteryStatsService.noteEvent( 18954 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18955 Integer.toString(userId), userId); 18956 mSystemServiceManager.stopUser(userId); 18957 broadcastIntentLocked(null, null, shutdownIntent, 18958 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18959 true, false, MY_PID, Process.SYSTEM_UID, userId); 18960 } 18961 }; 18962 // Kick things off. 18963 broadcastIntentLocked(null, null, stoppingIntent, 18964 null, stoppingReceiver, 0, null, null, 18965 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18966 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18967 } finally { 18968 Binder.restoreCallingIdentity(ident); 18969 } 18970 } 18971 18972 return ActivityManager.USER_OP_SUCCESS; 18973 } 18974 18975 void finishUserStop(UserStartedState uss) { 18976 final int userId = uss.mHandle.getIdentifier(); 18977 boolean stopped; 18978 ArrayList<IStopUserCallback> callbacks; 18979 synchronized (this) { 18980 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18981 if (mStartedUsers.get(userId) != uss) { 18982 stopped = false; 18983 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18984 stopped = false; 18985 } else { 18986 stopped = true; 18987 // User can no longer run. 18988 mStartedUsers.remove(userId); 18989 mUserLru.remove(Integer.valueOf(userId)); 18990 updateStartedUserArrayLocked(); 18991 18992 // Clean up all state and processes associated with the user. 18993 // Kill all the processes for the user. 18994 forceStopUserLocked(userId, "finish user"); 18995 } 18996 18997 // Explicitly remove the old information in mRecentTasks. 18998 removeRecentTasksForUserLocked(userId); 18999 } 19000 19001 for (int i=0; i<callbacks.size(); i++) { 19002 try { 19003 if (stopped) callbacks.get(i).userStopped(userId); 19004 else callbacks.get(i).userStopAborted(userId); 19005 } catch (RemoteException e) { 19006 } 19007 } 19008 19009 if (stopped) { 19010 mSystemServiceManager.cleanupUser(userId); 19011 synchronized (this) { 19012 mStackSupervisor.removeUserLocked(userId); 19013 } 19014 } 19015 } 19016 19017 @Override 19018 public UserInfo getCurrentUser() { 19019 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19020 != PackageManager.PERMISSION_GRANTED) && ( 19021 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19022 != PackageManager.PERMISSION_GRANTED)) { 19023 String msg = "Permission Denial: getCurrentUser() from pid=" 19024 + Binder.getCallingPid() 19025 + ", uid=" + Binder.getCallingUid() 19026 + " requires " + INTERACT_ACROSS_USERS; 19027 Slog.w(TAG, msg); 19028 throw new SecurityException(msg); 19029 } 19030 synchronized (this) { 19031 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19032 return getUserManagerLocked().getUserInfo(userId); 19033 } 19034 } 19035 19036 int getCurrentUserIdLocked() { 19037 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19038 } 19039 19040 @Override 19041 public boolean isUserRunning(int userId, boolean orStopped) { 19042 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19043 != PackageManager.PERMISSION_GRANTED) { 19044 String msg = "Permission Denial: isUserRunning() from pid=" 19045 + Binder.getCallingPid() 19046 + ", uid=" + Binder.getCallingUid() 19047 + " requires " + INTERACT_ACROSS_USERS; 19048 Slog.w(TAG, msg); 19049 throw new SecurityException(msg); 19050 } 19051 synchronized (this) { 19052 return isUserRunningLocked(userId, orStopped); 19053 } 19054 } 19055 19056 boolean isUserRunningLocked(int userId, boolean orStopped) { 19057 UserStartedState state = mStartedUsers.get(userId); 19058 if (state == null) { 19059 return false; 19060 } 19061 if (orStopped) { 19062 return true; 19063 } 19064 return state.mState != UserStartedState.STATE_STOPPING 19065 && state.mState != UserStartedState.STATE_SHUTDOWN; 19066 } 19067 19068 @Override 19069 public int[] getRunningUserIds() { 19070 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19071 != PackageManager.PERMISSION_GRANTED) { 19072 String msg = "Permission Denial: isUserRunning() from pid=" 19073 + Binder.getCallingPid() 19074 + ", uid=" + Binder.getCallingUid() 19075 + " requires " + INTERACT_ACROSS_USERS; 19076 Slog.w(TAG, msg); 19077 throw new SecurityException(msg); 19078 } 19079 synchronized (this) { 19080 return mStartedUserArray; 19081 } 19082 } 19083 19084 private void updateStartedUserArrayLocked() { 19085 int num = 0; 19086 for (int i=0; i<mStartedUsers.size(); i++) { 19087 UserStartedState uss = mStartedUsers.valueAt(i); 19088 // This list does not include stopping users. 19089 if (uss.mState != UserStartedState.STATE_STOPPING 19090 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19091 num++; 19092 } 19093 } 19094 mStartedUserArray = new int[num]; 19095 num = 0; 19096 for (int i=0; i<mStartedUsers.size(); i++) { 19097 UserStartedState uss = mStartedUsers.valueAt(i); 19098 if (uss.mState != UserStartedState.STATE_STOPPING 19099 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19100 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19101 num++; 19102 } 19103 } 19104 } 19105 19106 @Override 19107 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19108 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19109 != PackageManager.PERMISSION_GRANTED) { 19110 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19111 + Binder.getCallingPid() 19112 + ", uid=" + Binder.getCallingUid() 19113 + " requires " + INTERACT_ACROSS_USERS_FULL; 19114 Slog.w(TAG, msg); 19115 throw new SecurityException(msg); 19116 } 19117 19118 mUserSwitchObservers.register(observer); 19119 } 19120 19121 @Override 19122 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19123 mUserSwitchObservers.unregister(observer); 19124 } 19125 19126 private boolean userExists(int userId) { 19127 if (userId == 0) { 19128 return true; 19129 } 19130 UserManagerService ums = getUserManagerLocked(); 19131 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19132 } 19133 19134 int[] getUsersLocked() { 19135 UserManagerService ums = getUserManagerLocked(); 19136 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19137 } 19138 19139 UserManagerService getUserManagerLocked() { 19140 if (mUserManager == null) { 19141 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19142 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19143 } 19144 return mUserManager; 19145 } 19146 19147 private int applyUserId(int uid, int userId) { 19148 return UserHandle.getUid(userId, uid); 19149 } 19150 19151 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19152 if (info == null) return null; 19153 ApplicationInfo newInfo = new ApplicationInfo(info); 19154 newInfo.uid = applyUserId(info.uid, userId); 19155 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19156 + info.packageName; 19157 return newInfo; 19158 } 19159 19160 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19161 if (aInfo == null 19162 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19163 return aInfo; 19164 } 19165 19166 ActivityInfo info = new ActivityInfo(aInfo); 19167 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19168 return info; 19169 } 19170 19171 private final class LocalService extends ActivityManagerInternal { 19172 @Override 19173 public void goingToSleep() { 19174 ActivityManagerService.this.goingToSleep(); 19175 } 19176 19177 @Override 19178 public void wakingUp() { 19179 ActivityManagerService.this.wakingUp(); 19180 } 19181 19182 @Override 19183 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19184 String processName, String abiOverride, int uid, Runnable crashHandler) { 19185 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19186 processName, abiOverride, uid, crashHandler); 19187 } 19188 } 19189 19190 /** 19191 * An implementation of IAppTask, that allows an app to manage its own tasks via 19192 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19193 * only the process that calls getAppTasks() can call the AppTask methods. 19194 */ 19195 class AppTaskImpl extends IAppTask.Stub { 19196 private int mTaskId; 19197 private int mCallingUid; 19198 19199 public AppTaskImpl(int taskId, int callingUid) { 19200 mTaskId = taskId; 19201 mCallingUid = callingUid; 19202 } 19203 19204 private void checkCaller() { 19205 if (mCallingUid != Binder.getCallingUid()) { 19206 throw new SecurityException("Caller " + mCallingUid 19207 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19208 } 19209 } 19210 19211 @Override 19212 public void finishAndRemoveTask() { 19213 checkCaller(); 19214 19215 synchronized (ActivityManagerService.this) { 19216 long origId = Binder.clearCallingIdentity(); 19217 try { 19218 if (!removeTaskByIdLocked(mTaskId, false)) { 19219 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19220 } 19221 } finally { 19222 Binder.restoreCallingIdentity(origId); 19223 } 19224 } 19225 } 19226 19227 @Override 19228 public ActivityManager.RecentTaskInfo getTaskInfo() { 19229 checkCaller(); 19230 19231 synchronized (ActivityManagerService.this) { 19232 long origId = Binder.clearCallingIdentity(); 19233 try { 19234 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19235 if (tr == null) { 19236 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19237 } 19238 return createRecentTaskInfoFromTaskRecord(tr); 19239 } finally { 19240 Binder.restoreCallingIdentity(origId); 19241 } 19242 } 19243 } 19244 19245 @Override 19246 public void moveToFront() { 19247 checkCaller(); 19248 19249 final TaskRecord tr; 19250 synchronized (ActivityManagerService.this) { 19251 tr = recentTaskForIdLocked(mTaskId); 19252 if (tr == null) { 19253 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19254 } 19255 if (tr.getRootActivity() != null) { 19256 moveTaskToFrontLocked(tr.taskId, 0, null); 19257 return; 19258 } 19259 } 19260 19261 startActivityFromRecentsInner(tr.taskId, null); 19262 } 19263 19264 @Override 19265 public int startActivity(IBinder whoThread, String callingPackage, 19266 Intent intent, String resolvedType, Bundle options) { 19267 checkCaller(); 19268 19269 int callingUser = UserHandle.getCallingUserId(); 19270 TaskRecord tr; 19271 IApplicationThread appThread; 19272 synchronized (ActivityManagerService.this) { 19273 tr = recentTaskForIdLocked(mTaskId); 19274 if (tr == null) { 19275 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19276 } 19277 appThread = ApplicationThreadNative.asInterface(whoThread); 19278 if (appThread == null) { 19279 throw new IllegalArgumentException("Bad app thread " + appThread); 19280 } 19281 } 19282 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19283 resolvedType, null, null, null, null, 0, 0, null, null, 19284 null, options, callingUser, null, tr); 19285 } 19286 19287 @Override 19288 public void setExcludeFromRecents(boolean exclude) { 19289 checkCaller(); 19290 19291 synchronized (ActivityManagerService.this) { 19292 long origId = Binder.clearCallingIdentity(); 19293 try { 19294 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19295 if (tr == null) { 19296 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19297 } 19298 Intent intent = tr.getBaseIntent(); 19299 if (exclude) { 19300 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19301 } else { 19302 intent.setFlags(intent.getFlags() 19303 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19304 } 19305 } finally { 19306 Binder.restoreCallingIdentity(origId); 19307 } 19308 } 19309 } 19310 } 19311} 19312