ActivityManagerService.java revision 42d04db459e5a510c8c815c38e17e419c3e3b404
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.UserManagerService; 85import com.android.server.wm.AppTransition; 86import com.android.server.wm.WindowManagerService; 87import com.google.android.collect.Lists; 88import com.google.android.collect.Maps; 89 90import libcore.io.IoUtils; 91 92import org.xmlpull.v1.XmlPullParser; 93import org.xmlpull.v1.XmlPullParserException; 94import org.xmlpull.v1.XmlSerializer; 95 96import android.app.Activity; 97import android.app.ActivityManager; 98import android.app.ActivityManager.RunningTaskInfo; 99import android.app.ActivityManager.StackInfo; 100import android.app.ActivityManagerInternal; 101import android.app.ActivityManagerNative; 102import android.app.ActivityOptions; 103import android.app.ActivityThread; 104import android.app.AlertDialog; 105import android.app.AppGlobals; 106import android.app.ApplicationErrorReport; 107import android.app.Dialog; 108import android.app.IActivityController; 109import android.app.IApplicationThread; 110import android.app.IInstrumentationWatcher; 111import android.app.INotificationManager; 112import android.app.IProcessObserver; 113import android.app.IServiceConnection; 114import android.app.IStopUserCallback; 115import android.app.IUiAutomationConnection; 116import android.app.IUserSwitchObserver; 117import android.app.Instrumentation; 118import android.app.Notification; 119import android.app.NotificationManager; 120import android.app.PendingIntent; 121import android.app.backup.IBackupManager; 122import android.content.ActivityNotFoundException; 123import android.content.BroadcastReceiver; 124import android.content.ClipData; 125import android.content.ComponentCallbacks2; 126import android.content.ComponentName; 127import android.content.ContentProvider; 128import android.content.ContentResolver; 129import android.content.Context; 130import android.content.DialogInterface; 131import android.content.IContentProvider; 132import android.content.IIntentReceiver; 133import android.content.IIntentSender; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.IntentSender; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.ConfigurationInfo; 140import android.content.pm.IPackageDataObserver; 141import android.content.pm.IPackageManager; 142import android.content.pm.InstrumentationInfo; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageManager; 145import android.content.pm.ParceledListSlice; 146import android.content.pm.UserInfo; 147import android.content.pm.PackageManager.NameNotFoundException; 148import android.content.pm.PathPermission; 149import android.content.pm.ProviderInfo; 150import android.content.pm.ResolveInfo; 151import android.content.pm.ServiceInfo; 152import android.content.res.CompatibilityInfo; 153import android.content.res.Configuration; 154import android.net.Proxy; 155import android.net.ProxyInfo; 156import android.net.Uri; 157import android.os.Binder; 158import android.os.Build; 159import android.os.Bundle; 160import android.os.Debug; 161import android.os.DropBoxManager; 162import android.os.Environment; 163import android.os.FactoryTest; 164import android.os.FileObserver; 165import android.os.FileUtils; 166import android.os.Handler; 167import android.os.IBinder; 168import android.os.IPermissionController; 169import android.os.IRemoteCallback; 170import android.os.IUserManager; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Process; 176import android.os.RemoteCallbackList; 177import android.os.RemoteException; 178import android.os.SELinux; 179import android.os.ServiceManager; 180import android.os.StrictMode; 181import android.os.SystemClock; 182import android.os.SystemProperties; 183import android.os.UpdateLock; 184import android.os.UserHandle; 185import android.os.UserManager; 186import android.provider.Settings; 187import android.text.format.DateUtils; 188import android.text.format.Time; 189import android.util.AtomicFile; 190import android.util.EventLog; 191import android.util.Log; 192import android.util.Pair; 193import android.util.PrintWriterPrinter; 194import android.util.Slog; 195import android.util.SparseArray; 196import android.util.TimeUtils; 197import android.util.Xml; 198import android.view.Gravity; 199import android.view.LayoutInflater; 200import android.view.View; 201import android.view.WindowManager; 202import dalvik.system.VMRuntime; 203 204import java.io.BufferedInputStream; 205import java.io.BufferedOutputStream; 206import java.io.DataInputStream; 207import java.io.DataOutputStream; 208import java.io.File; 209import java.io.FileDescriptor; 210import java.io.FileInputStream; 211import java.io.FileNotFoundException; 212import java.io.FileOutputStream; 213import java.io.IOException; 214import java.io.InputStreamReader; 215import java.io.PrintWriter; 216import java.io.StringWriter; 217import java.lang.ref.WeakReference; 218import java.util.ArrayList; 219import java.util.Arrays; 220import java.util.Collections; 221import java.util.Comparator; 222import java.util.HashMap; 223import java.util.HashSet; 224import java.util.Iterator; 225import java.util.List; 226import java.util.Locale; 227import java.util.Map; 228import java.util.Set; 229import java.util.concurrent.atomic.AtomicBoolean; 230import java.util.concurrent.atomic.AtomicLong; 231 232public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 static final int LOCK_SCREEN_HIDDEN = 0; 956 static final int LOCK_SCREEN_LEAVING = 1; 957 static final int LOCK_SCREEN_SHOWN = 2; 958 /** 959 * State of external call telling us if the lock screen is shown. 960 */ 961 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 962 963 /** 964 * Set if we are shutting down the system, similar to sleeping. 965 */ 966 boolean mShuttingDown = false; 967 968 /** 969 * Current sequence id for oom_adj computation traversal. 970 */ 971 int mAdjSeq = 0; 972 973 /** 974 * Current sequence id for process LRU updating. 975 */ 976 int mLruSeq = 0; 977 978 /** 979 * Keep track of the non-cached/empty process we last found, to help 980 * determine how to distribute cached/empty processes next time. 981 */ 982 int mNumNonCachedProcs = 0; 983 984 /** 985 * Keep track of the number of cached hidden procs, to balance oom adj 986 * distribution between those and empty procs. 987 */ 988 int mNumCachedHiddenProcs = 0; 989 990 /** 991 * Keep track of the number of service processes we last found, to 992 * determine on the next iteration which should be B services. 993 */ 994 int mNumServiceProcs = 0; 995 int mNewNumAServiceProcs = 0; 996 int mNewNumServiceProcs = 0; 997 998 /** 999 * Allow the current computed overall memory level of the system to go down? 1000 * This is set to false when we are killing processes for reasons other than 1001 * memory management, so that the now smaller process list will not be taken as 1002 * an indication that memory is tighter. 1003 */ 1004 boolean mAllowLowerMemLevel = false; 1005 1006 /** 1007 * The last computed memory level, for holding when we are in a state that 1008 * processes are going away for other reasons. 1009 */ 1010 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1011 1012 /** 1013 * The last total number of process we have, to determine if changes actually look 1014 * like a shrinking number of process due to lower RAM. 1015 */ 1016 int mLastNumProcesses; 1017 1018 /** 1019 * The uptime of the last time we performed idle maintenance. 1020 */ 1021 long mLastIdleTime = SystemClock.uptimeMillis(); 1022 1023 /** 1024 * Total time spent with RAM that has been added in the past since the last idle time. 1025 */ 1026 long mLowRamTimeSinceLastIdle = 0; 1027 1028 /** 1029 * If RAM is currently low, when that horrible situation started. 1030 */ 1031 long mLowRamStartTime = 0; 1032 1033 /** 1034 * For reporting to battery stats the current top application. 1035 */ 1036 private String mCurResumedPackage = null; 1037 private int mCurResumedUid = -1; 1038 1039 /** 1040 * For reporting to battery stats the apps currently running foreground 1041 * service. The ProcessMap is package/uid tuples; each of these contain 1042 * an array of the currently foreground processes. 1043 */ 1044 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1045 = new ProcessMap<ArrayList<ProcessRecord>>(); 1046 1047 /** 1048 * This is set if we had to do a delayed dexopt of an app before launching 1049 * it, to increase the ANR timeouts in that case. 1050 */ 1051 boolean mDidDexOpt; 1052 1053 /** 1054 * Set if the systemServer made a call to enterSafeMode. 1055 */ 1056 boolean mSafeMode; 1057 1058 String mDebugApp = null; 1059 boolean mWaitForDebugger = false; 1060 boolean mDebugTransient = false; 1061 String mOrigDebugApp = null; 1062 boolean mOrigWaitForDebugger = false; 1063 boolean mAlwaysFinishActivities = false; 1064 IActivityController mController = null; 1065 String mProfileApp = null; 1066 ProcessRecord mProfileProc = null; 1067 String mProfileFile; 1068 ParcelFileDescriptor mProfileFd; 1069 int mSamplingInterval = 0; 1070 boolean mAutoStopProfiler = false; 1071 int mProfileType = 0; 1072 String mOpenGlTraceApp = null; 1073 1074 static class ProcessChangeItem { 1075 static final int CHANGE_ACTIVITIES = 1<<0; 1076 static final int CHANGE_PROCESS_STATE = 1<<1; 1077 int changes; 1078 int uid; 1079 int pid; 1080 int processState; 1081 boolean foregroundActivities; 1082 } 1083 1084 final RemoteCallbackList<IProcessObserver> mProcessObservers 1085 = new RemoteCallbackList<IProcessObserver>(); 1086 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1087 1088 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1089 = new ArrayList<ProcessChangeItem>(); 1090 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1091 = new ArrayList<ProcessChangeItem>(); 1092 1093 /** 1094 * Runtime CPU use collection thread. This object's lock is used to 1095 * perform synchronization with the thread (notifying it to run). 1096 */ 1097 final Thread mProcessCpuThread; 1098 1099 /** 1100 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1101 * Must acquire this object's lock when accessing it. 1102 * NOTE: this lock will be held while doing long operations (trawling 1103 * through all processes in /proc), so it should never be acquired by 1104 * any critical paths such as when holding the main activity manager lock. 1105 */ 1106 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1107 MONITOR_THREAD_CPU_USAGE); 1108 final AtomicLong mLastCpuTime = new AtomicLong(0); 1109 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1110 1111 long mLastWriteTime = 0; 1112 1113 /** 1114 * Used to retain an update lock when the foreground activity is in 1115 * immersive mode. 1116 */ 1117 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1118 1119 /** 1120 * Set to true after the system has finished booting. 1121 */ 1122 boolean mBooted = false; 1123 1124 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1125 int mProcessLimitOverride = -1; 1126 1127 WindowManagerService mWindowManager; 1128 1129 final ActivityThread mSystemThread; 1130 1131 // Holds the current foreground user's id 1132 int mCurrentUserId = 0; 1133 // Holds the target user's id during a user switch 1134 int mTargetUserId = UserHandle.USER_NULL; 1135 // If there are multiple profiles for the current user, their ids are here 1136 // Currently only the primary user can have managed profiles 1137 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1138 1139 /** 1140 * Mapping from each known user ID to the profile group ID it is associated with. 1141 */ 1142 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1143 1144 private UserManagerService mUserManager; 1145 1146 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1147 final ProcessRecord mApp; 1148 final int mPid; 1149 final IApplicationThread mAppThread; 1150 1151 AppDeathRecipient(ProcessRecord app, int pid, 1152 IApplicationThread thread) { 1153 if (localLOGV) Slog.v( 1154 TAG, "New death recipient " + this 1155 + " for thread " + thread.asBinder()); 1156 mApp = app; 1157 mPid = pid; 1158 mAppThread = thread; 1159 } 1160 1161 @Override 1162 public void binderDied() { 1163 if (localLOGV) Slog.v( 1164 TAG, "Death received in " + this 1165 + " for thread " + mAppThread.asBinder()); 1166 synchronized(ActivityManagerService.this) { 1167 appDiedLocked(mApp, mPid, mAppThread); 1168 } 1169 } 1170 } 1171 1172 static final int SHOW_ERROR_MSG = 1; 1173 static final int SHOW_NOT_RESPONDING_MSG = 2; 1174 static final int SHOW_FACTORY_ERROR_MSG = 3; 1175 static final int UPDATE_CONFIGURATION_MSG = 4; 1176 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1177 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1178 static final int SERVICE_TIMEOUT_MSG = 12; 1179 static final int UPDATE_TIME_ZONE = 13; 1180 static final int SHOW_UID_ERROR_MSG = 14; 1181 static final int IM_FEELING_LUCKY_MSG = 15; 1182 static final int PROC_START_TIMEOUT_MSG = 20; 1183 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1184 static final int KILL_APPLICATION_MSG = 22; 1185 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1186 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1187 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1188 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1189 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1190 static final int CLEAR_DNS_CACHE_MSG = 28; 1191 static final int UPDATE_HTTP_PROXY_MSG = 29; 1192 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1193 static final int DISPATCH_PROCESSES_CHANGED = 31; 1194 static final int DISPATCH_PROCESS_DIED = 32; 1195 static final int REPORT_MEM_USAGE_MSG = 33; 1196 static final int REPORT_USER_SWITCH_MSG = 34; 1197 static final int CONTINUE_USER_SWITCH_MSG = 35; 1198 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1199 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1200 static final int PERSIST_URI_GRANTS_MSG = 38; 1201 static final int REQUEST_ALL_PSS_MSG = 39; 1202 static final int START_PROFILES_MSG = 40; 1203 static final int UPDATE_TIME = 41; 1204 static final int SYSTEM_USER_START_MSG = 42; 1205 static final int SYSTEM_USER_CURRENT_MSG = 43; 1206 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1207 static final int FINISH_BOOTING_MSG = 45; 1208 static final int START_USER_SWITCH_MSG = 46; 1209 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1210 1211 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1212 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1213 static final int FIRST_COMPAT_MODE_MSG = 300; 1214 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1215 1216 AlertDialog mUidAlert; 1217 CompatModeDialog mCompatModeDialog; 1218 long mLastMemUsageReportTime = 0; 1219 1220 private LockToAppRequestDialog mLockToAppRequest; 1221 1222 /** 1223 * Flag whether the current user is a "monkey", i.e. whether 1224 * the UI is driven by a UI automation tool. 1225 */ 1226 private boolean mUserIsMonkey; 1227 1228 /** Flag whether the device has a Recents UI */ 1229 boolean mHasRecents; 1230 1231 /** The dimensions of the thumbnails in the Recents UI. */ 1232 int mThumbnailWidth; 1233 int mThumbnailHeight; 1234 1235 final ServiceThread mHandlerThread; 1236 final MainHandler mHandler; 1237 1238 final class MainHandler extends Handler { 1239 public MainHandler(Looper looper) { 1240 super(looper, null, true); 1241 } 1242 1243 @Override 1244 public void handleMessage(Message msg) { 1245 switch (msg.what) { 1246 case SHOW_ERROR_MSG: { 1247 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1248 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1249 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord)data.get("app"); 1252 AppErrorResult res = (AppErrorResult) data.get("result"); 1253 if (proc != null && proc.crashDialog != null) { 1254 Slog.e(TAG, "App already has crash dialog: " + proc); 1255 if (res != null) { 1256 res.set(0); 1257 } 1258 return; 1259 } 1260 boolean isBackground = (UserHandle.getAppId(proc.uid) 1261 >= Process.FIRST_APPLICATION_UID 1262 && proc.pid != MY_PID); 1263 for (int userId : mCurrentProfileIds) { 1264 isBackground &= (proc.userId != userId); 1265 } 1266 if (isBackground && !showBackground) { 1267 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1268 if (res != null) { 1269 res.set(0); 1270 } 1271 return; 1272 } 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new AppErrorDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 if (res != null) { 1282 res.set(0); 1283 } 1284 } 1285 } 1286 1287 ensureBootCompleted(); 1288 } break; 1289 case SHOW_NOT_RESPONDING_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1292 ProcessRecord proc = (ProcessRecord)data.get("app"); 1293 if (proc != null && proc.anrDialog != null) { 1294 Slog.e(TAG, "App already has anr dialog: " + proc); 1295 return; 1296 } 1297 1298 Intent intent = new Intent("android.intent.action.ANR"); 1299 if (!mProcessesReady) { 1300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1301 | Intent.FLAG_RECEIVER_FOREGROUND); 1302 } 1303 broadcastIntentLocked(null, null, intent, 1304 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1305 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1306 1307 if (mShowDialogs) { 1308 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1309 mContext, proc, (ActivityRecord)data.get("activity"), 1310 msg.arg1 != 0); 1311 d.show(); 1312 proc.anrDialog = d; 1313 } else { 1314 // Just kill the app if there is no dialog to be shown. 1315 killAppAtUsersRequest(proc, null); 1316 } 1317 } 1318 1319 ensureBootCompleted(); 1320 } break; 1321 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1322 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 ProcessRecord proc = (ProcessRecord) data.get("app"); 1325 if (proc == null) { 1326 Slog.e(TAG, "App not found when showing strict mode dialog."); 1327 break; 1328 } 1329 if (proc.crashDialog != null) { 1330 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1331 return; 1332 } 1333 AppErrorResult res = (AppErrorResult) data.get("result"); 1334 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1335 Dialog d = new StrictModeViolationDialog(mContext, 1336 ActivityManagerService.this, res, proc); 1337 d.show(); 1338 proc.crashDialog = d; 1339 } else { 1340 // The device is asleep, so just pretend that the user 1341 // saw a crash dialog and hit "force quit". 1342 res.set(0); 1343 } 1344 } 1345 ensureBootCompleted(); 1346 } break; 1347 case SHOW_FACTORY_ERROR_MSG: { 1348 Dialog d = new FactoryErrorDialog( 1349 mContext, msg.getData().getCharSequence("msg")); 1350 d.show(); 1351 ensureBootCompleted(); 1352 } break; 1353 case UPDATE_CONFIGURATION_MSG: { 1354 final ContentResolver resolver = mContext.getContentResolver(); 1355 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1356 } break; 1357 case GC_BACKGROUND_PROCESSES_MSG: { 1358 synchronized (ActivityManagerService.this) { 1359 performAppGcsIfAppropriateLocked(); 1360 } 1361 } break; 1362 case WAIT_FOR_DEBUGGER_MSG: { 1363 synchronized (ActivityManagerService.this) { 1364 ProcessRecord app = (ProcessRecord)msg.obj; 1365 if (msg.arg1 != 0) { 1366 if (!app.waitedForDebugger) { 1367 Dialog d = new AppWaitingForDebuggerDialog( 1368 ActivityManagerService.this, 1369 mContext, app); 1370 app.waitDialog = d; 1371 app.waitedForDebugger = true; 1372 d.show(); 1373 } 1374 } else { 1375 if (app.waitDialog != null) { 1376 app.waitDialog.dismiss(); 1377 app.waitDialog = null; 1378 } 1379 } 1380 } 1381 } break; 1382 case SERVICE_TIMEOUT_MSG: { 1383 if (mDidDexOpt) { 1384 mDidDexOpt = false; 1385 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1386 nmsg.obj = msg.obj; 1387 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1388 return; 1389 } 1390 mServices.serviceTimeout((ProcessRecord)msg.obj); 1391 } break; 1392 case UPDATE_TIME_ZONE: { 1393 synchronized (ActivityManagerService.this) { 1394 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1395 ProcessRecord r = mLruProcesses.get(i); 1396 if (r.thread != null) { 1397 try { 1398 r.thread.updateTimeZone(); 1399 } catch (RemoteException ex) { 1400 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1401 } 1402 } 1403 } 1404 } 1405 } break; 1406 case CLEAR_DNS_CACHE_MSG: { 1407 synchronized (ActivityManagerService.this) { 1408 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1409 ProcessRecord r = mLruProcesses.get(i); 1410 if (r.thread != null) { 1411 try { 1412 r.thread.clearDnsCache(); 1413 } catch (RemoteException ex) { 1414 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1415 } 1416 } 1417 } 1418 } 1419 } break; 1420 case UPDATE_HTTP_PROXY_MSG: { 1421 ProxyInfo proxy = (ProxyInfo)msg.obj; 1422 String host = ""; 1423 String port = ""; 1424 String exclList = ""; 1425 Uri pacFileUrl = Uri.EMPTY; 1426 if (proxy != null) { 1427 host = proxy.getHost(); 1428 port = Integer.toString(proxy.getPort()); 1429 exclList = proxy.getExclusionListAsString(); 1430 pacFileUrl = proxy.getPacFileUrl(); 1431 } 1432 synchronized (ActivityManagerService.this) { 1433 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1434 ProcessRecord r = mLruProcesses.get(i); 1435 if (r.thread != null) { 1436 try { 1437 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1438 } catch (RemoteException ex) { 1439 Slog.w(TAG, "Failed to update http proxy for: " + 1440 r.info.processName); 1441 } 1442 } 1443 } 1444 } 1445 } break; 1446 case SHOW_UID_ERROR_MSG: { 1447 String title = "System UIDs Inconsistent"; 1448 String text = "UIDs on the system are inconsistent, you need to wipe your" 1449 + " data partition or your device will be unstable."; 1450 Log.e(TAG, title + ": " + text); 1451 if (mShowDialogs) { 1452 // XXX This is a temporary dialog, no need to localize. 1453 AlertDialog d = new BaseErrorDialog(mContext); 1454 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1455 d.setCancelable(false); 1456 d.setTitle(title); 1457 d.setMessage(text); 1458 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1459 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1460 mUidAlert = d; 1461 d.show(); 1462 } 1463 } break; 1464 case IM_FEELING_LUCKY_MSG: { 1465 if (mUidAlert != null) { 1466 mUidAlert.dismiss(); 1467 mUidAlert = null; 1468 } 1469 } break; 1470 case PROC_START_TIMEOUT_MSG: { 1471 if (mDidDexOpt) { 1472 mDidDexOpt = false; 1473 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1474 nmsg.obj = msg.obj; 1475 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1476 return; 1477 } 1478 ProcessRecord app = (ProcessRecord)msg.obj; 1479 synchronized (ActivityManagerService.this) { 1480 processStartTimedOutLocked(app); 1481 } 1482 } break; 1483 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1484 synchronized (ActivityManagerService.this) { 1485 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1486 } 1487 } break; 1488 case KILL_APPLICATION_MSG: { 1489 synchronized (ActivityManagerService.this) { 1490 int appid = msg.arg1; 1491 boolean restart = (msg.arg2 == 1); 1492 Bundle bundle = (Bundle)msg.obj; 1493 String pkg = bundle.getString("pkg"); 1494 String reason = bundle.getString("reason"); 1495 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1496 false, UserHandle.USER_ALL, reason); 1497 } 1498 } break; 1499 case FINALIZE_PENDING_INTENT_MSG: { 1500 ((PendingIntentRecord)msg.obj).completeFinalize(); 1501 } break; 1502 case POST_HEAVY_NOTIFICATION_MSG: { 1503 INotificationManager inm = NotificationManager.getService(); 1504 if (inm == null) { 1505 return; 1506 } 1507 1508 ActivityRecord root = (ActivityRecord)msg.obj; 1509 ProcessRecord process = root.app; 1510 if (process == null) { 1511 return; 1512 } 1513 1514 try { 1515 Context context = mContext.createPackageContext(process.info.packageName, 0); 1516 String text = mContext.getString(R.string.heavy_weight_notification, 1517 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1518 Notification notification = new Notification(); 1519 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1520 notification.when = 0; 1521 notification.flags = Notification.FLAG_ONGOING_EVENT; 1522 notification.tickerText = text; 1523 notification.defaults = 0; // please be quiet 1524 notification.sound = null; 1525 notification.vibrate = null; 1526 notification.color = mContext.getResources().getColor( 1527 com.android.internal.R.color.system_notification_accent_color); 1528 notification.setLatestEventInfo(context, text, 1529 mContext.getText(R.string.heavy_weight_notification_detail), 1530 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1531 PendingIntent.FLAG_CANCEL_CURRENT, null, 1532 new UserHandle(root.userId))); 1533 1534 try { 1535 int[] outId = new int[1]; 1536 inm.enqueueNotificationWithTag("android", "android", null, 1537 R.string.heavy_weight_notification, 1538 notification, outId, root.userId); 1539 } catch (RuntimeException e) { 1540 Slog.w(ActivityManagerService.TAG, 1541 "Error showing notification for heavy-weight app", e); 1542 } catch (RemoteException e) { 1543 } 1544 } catch (NameNotFoundException e) { 1545 Slog.w(TAG, "Unable to create context for heavy notification", e); 1546 } 1547 } break; 1548 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1549 INotificationManager inm = NotificationManager.getService(); 1550 if (inm == null) { 1551 return; 1552 } 1553 try { 1554 inm.cancelNotificationWithTag("android", null, 1555 R.string.heavy_weight_notification, msg.arg1); 1556 } catch (RuntimeException e) { 1557 Slog.w(ActivityManagerService.TAG, 1558 "Error canceling notification for service", e); 1559 } catch (RemoteException e) { 1560 } 1561 } break; 1562 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1563 synchronized (ActivityManagerService.this) { 1564 checkExcessivePowerUsageLocked(true); 1565 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1566 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1567 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1568 } 1569 } break; 1570 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1571 synchronized (ActivityManagerService.this) { 1572 ActivityRecord ar = (ActivityRecord)msg.obj; 1573 if (mCompatModeDialog != null) { 1574 if (mCompatModeDialog.mAppInfo.packageName.equals( 1575 ar.info.applicationInfo.packageName)) { 1576 return; 1577 } 1578 mCompatModeDialog.dismiss(); 1579 mCompatModeDialog = null; 1580 } 1581 if (ar != null && false) { 1582 if (mCompatModePackages.getPackageAskCompatModeLocked( 1583 ar.packageName)) { 1584 int mode = mCompatModePackages.computeCompatModeLocked( 1585 ar.info.applicationInfo); 1586 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1587 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1588 mCompatModeDialog = new CompatModeDialog( 1589 ActivityManagerService.this, mContext, 1590 ar.info.applicationInfo); 1591 mCompatModeDialog.show(); 1592 } 1593 } 1594 } 1595 } 1596 break; 1597 } 1598 case DISPATCH_PROCESSES_CHANGED: { 1599 dispatchProcessesChanged(); 1600 break; 1601 } 1602 case DISPATCH_PROCESS_DIED: { 1603 final int pid = msg.arg1; 1604 final int uid = msg.arg2; 1605 dispatchProcessDied(pid, uid); 1606 break; 1607 } 1608 case REPORT_MEM_USAGE_MSG: { 1609 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1610 Thread thread = new Thread() { 1611 @Override public void run() { 1612 reportMemUsage(memInfos); 1613 } 1614 }; 1615 thread.start(); 1616 break; 1617 } 1618 case START_USER_SWITCH_MSG: { 1619 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1620 break; 1621 } 1622 case REPORT_USER_SWITCH_MSG: { 1623 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1624 break; 1625 } 1626 case CONTINUE_USER_SWITCH_MSG: { 1627 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1628 break; 1629 } 1630 case USER_SWITCH_TIMEOUT_MSG: { 1631 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1632 break; 1633 } 1634 case IMMERSIVE_MODE_LOCK_MSG: { 1635 final boolean nextState = (msg.arg1 != 0); 1636 if (mUpdateLock.isHeld() != nextState) { 1637 if (DEBUG_IMMERSIVE) { 1638 final ActivityRecord r = (ActivityRecord) msg.obj; 1639 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1640 } 1641 if (nextState) { 1642 mUpdateLock.acquire(); 1643 } else { 1644 mUpdateLock.release(); 1645 } 1646 } 1647 break; 1648 } 1649 case PERSIST_URI_GRANTS_MSG: { 1650 writeGrantedUriPermissions(); 1651 break; 1652 } 1653 case REQUEST_ALL_PSS_MSG: { 1654 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1655 break; 1656 } 1657 case START_PROFILES_MSG: { 1658 synchronized (ActivityManagerService.this) { 1659 startProfilesLocked(); 1660 } 1661 break; 1662 } 1663 case UPDATE_TIME: { 1664 synchronized (ActivityManagerService.this) { 1665 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1666 ProcessRecord r = mLruProcesses.get(i); 1667 if (r.thread != null) { 1668 try { 1669 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1670 } catch (RemoteException ex) { 1671 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1672 } 1673 } 1674 } 1675 } 1676 break; 1677 } 1678 case SYSTEM_USER_START_MSG: { 1679 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1680 Integer.toString(msg.arg1), msg.arg1); 1681 mSystemServiceManager.startUser(msg.arg1); 1682 break; 1683 } 1684 case SYSTEM_USER_CURRENT_MSG: { 1685 mBatteryStatsService.noteEvent( 1686 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1687 Integer.toString(msg.arg2), msg.arg2); 1688 mBatteryStatsService.noteEvent( 1689 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1690 Integer.toString(msg.arg1), msg.arg1); 1691 mSystemServiceManager.switchUser(msg.arg1); 1692 mLockToAppRequest.clearPrompt(); 1693 break; 1694 } 1695 case ENTER_ANIMATION_COMPLETE_MSG: { 1696 synchronized (ActivityManagerService.this) { 1697 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1698 if (r != null && r.app != null && r.app.thread != null) { 1699 try { 1700 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1701 } catch (RemoteException e) { 1702 } 1703 } 1704 } 1705 break; 1706 } 1707 case FINISH_BOOTING_MSG: { 1708 if (msg.arg1 != 0) { 1709 finishBooting(); 1710 } 1711 if (msg.arg2 != 0) { 1712 enableScreenAfterBoot(); 1713 } 1714 break; 1715 } 1716 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1717 try { 1718 Locale l = (Locale) msg.obj; 1719 IBinder service = ServiceManager.getService("mount"); 1720 IMountService mountService = IMountService.Stub.asInterface(service); 1721 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1722 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1723 } catch (RemoteException e) { 1724 Log.e(TAG, "Error storing locale for decryption UI", e); 1725 } 1726 break; 1727 } 1728 } 1729 } 1730 }; 1731 1732 static final int COLLECT_PSS_BG_MSG = 1; 1733 1734 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1735 @Override 1736 public void handleMessage(Message msg) { 1737 switch (msg.what) { 1738 case COLLECT_PSS_BG_MSG: { 1739 long start = SystemClock.uptimeMillis(); 1740 MemInfoReader memInfo = null; 1741 synchronized (ActivityManagerService.this) { 1742 if (mFullPssPending) { 1743 mFullPssPending = false; 1744 memInfo = new MemInfoReader(); 1745 } 1746 } 1747 if (memInfo != null) { 1748 updateCpuStatsNow(); 1749 long nativeTotalPss = 0; 1750 synchronized (mProcessCpuTracker) { 1751 final int N = mProcessCpuTracker.countStats(); 1752 for (int j=0; j<N; j++) { 1753 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1754 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1755 // This is definitely an application process; skip it. 1756 continue; 1757 } 1758 synchronized (mPidsSelfLocked) { 1759 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1760 // This is one of our own processes; skip it. 1761 continue; 1762 } 1763 } 1764 nativeTotalPss += Debug.getPss(st.pid, null); 1765 } 1766 } 1767 memInfo.readMemInfo(); 1768 synchronized (ActivityManagerService.this) { 1769 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1770 + (SystemClock.uptimeMillis()-start) + "ms"); 1771 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1772 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1773 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1774 } 1775 } 1776 1777 int i=0, num=0; 1778 long[] tmp = new long[1]; 1779 do { 1780 ProcessRecord proc; 1781 int procState; 1782 int pid; 1783 synchronized (ActivityManagerService.this) { 1784 if (i >= mPendingPssProcesses.size()) { 1785 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1786 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1787 mPendingPssProcesses.clear(); 1788 return; 1789 } 1790 proc = mPendingPssProcesses.get(i); 1791 procState = proc.pssProcState; 1792 if (proc.thread != null && procState == proc.setProcState) { 1793 pid = proc.pid; 1794 } else { 1795 proc = null; 1796 pid = 0; 1797 } 1798 i++; 1799 } 1800 if (proc != null) { 1801 long pss = Debug.getPss(pid, tmp); 1802 synchronized (ActivityManagerService.this) { 1803 if (proc.thread != null && proc.setProcState == procState 1804 && proc.pid == pid) { 1805 num++; 1806 proc.lastPssTime = SystemClock.uptimeMillis(); 1807 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1808 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1809 + ": " + pss + " lastPss=" + proc.lastPss 1810 + " state=" + ProcessList.makeProcStateString(procState)); 1811 if (proc.initialIdlePss == 0) { 1812 proc.initialIdlePss = pss; 1813 } 1814 proc.lastPss = pss; 1815 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1816 proc.lastCachedPss = pss; 1817 } 1818 } 1819 } 1820 } 1821 } while (true); 1822 } 1823 } 1824 } 1825 }; 1826 1827 /** 1828 * Monitor for package changes and update our internal state. 1829 */ 1830 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1831 @Override 1832 public void onPackageRemoved(String packageName, int uid) { 1833 // Remove all tasks with activities in the specified package from the list of recent tasks 1834 final int eventUserId = getChangingUserId(); 1835 synchronized (ActivityManagerService.this) { 1836 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1837 TaskRecord tr = mRecentTasks.get(i); 1838 if (tr.userId != eventUserId) continue; 1839 1840 ComponentName cn = tr.intent.getComponent(); 1841 if (cn != null && cn.getPackageName().equals(packageName)) { 1842 // If the package name matches, remove the task 1843 removeTaskByIdLocked(tr.taskId, true); 1844 } 1845 } 1846 } 1847 } 1848 1849 @Override 1850 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1851 onPackageModified(packageName); 1852 return true; 1853 } 1854 1855 @Override 1856 public void onPackageModified(String packageName) { 1857 final int eventUserId = getChangingUserId(); 1858 final IPackageManager pm = AppGlobals.getPackageManager(); 1859 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1860 new ArrayList<Pair<Intent, Integer>>(); 1861 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1862 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1863 // Copy the list of recent tasks so that we don't hold onto the lock on 1864 // ActivityManagerService for long periods while checking if components exist. 1865 synchronized (ActivityManagerService.this) { 1866 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1867 TaskRecord tr = mRecentTasks.get(i); 1868 if (tr.userId != eventUserId) continue; 1869 1870 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1871 } 1872 } 1873 // Check the recent tasks and filter out all tasks with components that no longer exist. 1874 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1875 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1876 ComponentName cn = p.first.getComponent(); 1877 if (cn != null && cn.getPackageName().equals(packageName)) { 1878 if (componentsKnownToExist.contains(cn)) { 1879 // If we know that the component still exists in the package, then skip 1880 continue; 1881 } 1882 try { 1883 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1884 if (info != null) { 1885 componentsKnownToExist.add(cn); 1886 } else { 1887 tasksToRemove.add(p.second); 1888 } 1889 } catch (RemoteException e) { 1890 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1891 } 1892 } 1893 } 1894 // Prune all the tasks with removed components from the list of recent tasks 1895 synchronized (ActivityManagerService.this) { 1896 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1897 removeTaskByIdLocked(tasksToRemove.get(i), false); 1898 } 1899 } 1900 } 1901 1902 @Override 1903 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1904 // Force stop the specified packages 1905 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1906 if (packages != null) { 1907 for (String pkg : packages) { 1908 synchronized (ActivityManagerService.this) { 1909 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1910 userId, "finished booting")) { 1911 return true; 1912 } 1913 } 1914 } 1915 } 1916 return false; 1917 } 1918 }; 1919 1920 public void setSystemProcess() { 1921 try { 1922 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1923 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1924 ServiceManager.addService("meminfo", new MemBinder(this)); 1925 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1926 ServiceManager.addService("dbinfo", new DbBinder(this)); 1927 if (MONITOR_CPU_USAGE) { 1928 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1929 } 1930 ServiceManager.addService("permission", new PermissionController(this)); 1931 1932 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1933 "android", STOCK_PM_FLAGS); 1934 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1935 1936 synchronized (this) { 1937 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1938 app.persistent = true; 1939 app.pid = MY_PID; 1940 app.maxAdj = ProcessList.SYSTEM_ADJ; 1941 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1942 mProcessNames.put(app.processName, app.uid, app); 1943 synchronized (mPidsSelfLocked) { 1944 mPidsSelfLocked.put(app.pid, app); 1945 } 1946 updateLruProcessLocked(app, false, null); 1947 updateOomAdjLocked(); 1948 } 1949 } catch (PackageManager.NameNotFoundException e) { 1950 throw new RuntimeException( 1951 "Unable to find android system package", e); 1952 } 1953 } 1954 1955 public void setWindowManager(WindowManagerService wm) { 1956 mWindowManager = wm; 1957 mStackSupervisor.setWindowManager(wm); 1958 } 1959 1960 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1961 mUsageStatsService = usageStatsManager; 1962 } 1963 1964 public void startObservingNativeCrashes() { 1965 final NativeCrashListener ncl = new NativeCrashListener(this); 1966 ncl.start(); 1967 } 1968 1969 public IAppOpsService getAppOpsService() { 1970 return mAppOpsService; 1971 } 1972 1973 static class MemBinder extends Binder { 1974 ActivityManagerService mActivityManagerService; 1975 MemBinder(ActivityManagerService activityManagerService) { 1976 mActivityManagerService = activityManagerService; 1977 } 1978 1979 @Override 1980 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1981 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1982 != PackageManager.PERMISSION_GRANTED) { 1983 pw.println("Permission Denial: can't dump meminfo from from pid=" 1984 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1985 + " without permission " + android.Manifest.permission.DUMP); 1986 return; 1987 } 1988 1989 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1990 } 1991 } 1992 1993 static class GraphicsBinder extends Binder { 1994 ActivityManagerService mActivityManagerService; 1995 GraphicsBinder(ActivityManagerService activityManagerService) { 1996 mActivityManagerService = activityManagerService; 1997 } 1998 1999 @Override 2000 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2001 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2002 != PackageManager.PERMISSION_GRANTED) { 2003 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2004 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2005 + " without permission " + android.Manifest.permission.DUMP); 2006 return; 2007 } 2008 2009 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2010 } 2011 } 2012 2013 static class DbBinder extends Binder { 2014 ActivityManagerService mActivityManagerService; 2015 DbBinder(ActivityManagerService activityManagerService) { 2016 mActivityManagerService = activityManagerService; 2017 } 2018 2019 @Override 2020 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2021 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2022 != PackageManager.PERMISSION_GRANTED) { 2023 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2024 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2025 + " without permission " + android.Manifest.permission.DUMP); 2026 return; 2027 } 2028 2029 mActivityManagerService.dumpDbInfo(fd, pw, args); 2030 } 2031 } 2032 2033 static class CpuBinder extends Binder { 2034 ActivityManagerService mActivityManagerService; 2035 CpuBinder(ActivityManagerService activityManagerService) { 2036 mActivityManagerService = activityManagerService; 2037 } 2038 2039 @Override 2040 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2041 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2042 != PackageManager.PERMISSION_GRANTED) { 2043 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2044 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2045 + " without permission " + android.Manifest.permission.DUMP); 2046 return; 2047 } 2048 2049 synchronized (mActivityManagerService.mProcessCpuTracker) { 2050 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2051 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2052 SystemClock.uptimeMillis())); 2053 } 2054 } 2055 } 2056 2057 public static final class Lifecycle extends SystemService { 2058 private final ActivityManagerService mService; 2059 2060 public Lifecycle(Context context) { 2061 super(context); 2062 mService = new ActivityManagerService(context); 2063 } 2064 2065 @Override 2066 public void onStart() { 2067 mService.start(); 2068 } 2069 2070 public ActivityManagerService getService() { 2071 return mService; 2072 } 2073 } 2074 2075 // Note: This method is invoked on the main thread but may need to attach various 2076 // handlers to other threads. So take care to be explicit about the looper. 2077 public ActivityManagerService(Context systemContext) { 2078 mContext = systemContext; 2079 mFactoryTest = FactoryTest.getMode(); 2080 mSystemThread = ActivityThread.currentActivityThread(); 2081 2082 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2083 2084 mHandlerThread = new ServiceThread(TAG, 2085 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2086 mHandlerThread.start(); 2087 mHandler = new MainHandler(mHandlerThread.getLooper()); 2088 2089 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2090 "foreground", BROADCAST_FG_TIMEOUT, false); 2091 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2092 "background", BROADCAST_BG_TIMEOUT, true); 2093 mBroadcastQueues[0] = mFgBroadcastQueue; 2094 mBroadcastQueues[1] = mBgBroadcastQueue; 2095 2096 mServices = new ActiveServices(this); 2097 mProviderMap = new ProviderMap(this); 2098 2099 // TODO: Move creation of battery stats service outside of activity manager service. 2100 File dataDir = Environment.getDataDirectory(); 2101 File systemDir = new File(dataDir, "system"); 2102 systemDir.mkdirs(); 2103 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2104 mBatteryStatsService.getActiveStatistics().readLocked(); 2105 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2106 mOnBattery = DEBUG_POWER ? true 2107 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2108 mBatteryStatsService.getActiveStatistics().setCallback(this); 2109 2110 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2111 2112 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2113 2114 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2115 2116 // User 0 is the first and only user that runs at boot. 2117 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2118 mUserLru.add(Integer.valueOf(0)); 2119 updateStartedUserArrayLocked(); 2120 2121 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2122 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2123 2124 mConfiguration.setToDefaults(); 2125 mConfiguration.setLocale(Locale.getDefault()); 2126 2127 mConfigurationSeq = mConfiguration.seq = 1; 2128 mProcessCpuTracker.init(); 2129 2130 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2131 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2132 mStackSupervisor = new ActivityStackSupervisor(this); 2133 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2134 2135 mProcessCpuThread = new Thread("CpuTracker") { 2136 @Override 2137 public void run() { 2138 while (true) { 2139 try { 2140 try { 2141 synchronized(this) { 2142 final long now = SystemClock.uptimeMillis(); 2143 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2144 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2145 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2146 // + ", write delay=" + nextWriteDelay); 2147 if (nextWriteDelay < nextCpuDelay) { 2148 nextCpuDelay = nextWriteDelay; 2149 } 2150 if (nextCpuDelay > 0) { 2151 mProcessCpuMutexFree.set(true); 2152 this.wait(nextCpuDelay); 2153 } 2154 } 2155 } catch (InterruptedException e) { 2156 } 2157 updateCpuStatsNow(); 2158 } catch (Exception e) { 2159 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2160 } 2161 } 2162 } 2163 }; 2164 2165 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2166 2167 Watchdog.getInstance().addMonitor(this); 2168 Watchdog.getInstance().addThread(mHandler); 2169 } 2170 2171 public void setSystemServiceManager(SystemServiceManager mgr) { 2172 mSystemServiceManager = mgr; 2173 } 2174 2175 private void start() { 2176 Process.removeAllProcessGroups(); 2177 mProcessCpuThread.start(); 2178 2179 mBatteryStatsService.publish(mContext); 2180 mAppOpsService.publish(mContext); 2181 Slog.d("AppOps", "AppOpsService published"); 2182 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2183 } 2184 2185 public void initPowerManagement() { 2186 mStackSupervisor.initPowerManagement(); 2187 mBatteryStatsService.initPowerManagement(); 2188 } 2189 2190 @Override 2191 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2192 throws RemoteException { 2193 if (code == SYSPROPS_TRANSACTION) { 2194 // We need to tell all apps about the system property change. 2195 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2196 synchronized(this) { 2197 final int NP = mProcessNames.getMap().size(); 2198 for (int ip=0; ip<NP; ip++) { 2199 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2200 final int NA = apps.size(); 2201 for (int ia=0; ia<NA; ia++) { 2202 ProcessRecord app = apps.valueAt(ia); 2203 if (app.thread != null) { 2204 procs.add(app.thread.asBinder()); 2205 } 2206 } 2207 } 2208 } 2209 2210 int N = procs.size(); 2211 for (int i=0; i<N; i++) { 2212 Parcel data2 = Parcel.obtain(); 2213 try { 2214 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2215 } catch (RemoteException e) { 2216 } 2217 data2.recycle(); 2218 } 2219 } 2220 try { 2221 return super.onTransact(code, data, reply, flags); 2222 } catch (RuntimeException e) { 2223 // The activity manager only throws security exceptions, so let's 2224 // log all others. 2225 if (!(e instanceof SecurityException)) { 2226 Slog.wtf(TAG, "Activity Manager Crash", e); 2227 } 2228 throw e; 2229 } 2230 } 2231 2232 void updateCpuStats() { 2233 final long now = SystemClock.uptimeMillis(); 2234 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2235 return; 2236 } 2237 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2238 synchronized (mProcessCpuThread) { 2239 mProcessCpuThread.notify(); 2240 } 2241 } 2242 } 2243 2244 void updateCpuStatsNow() { 2245 synchronized (mProcessCpuTracker) { 2246 mProcessCpuMutexFree.set(false); 2247 final long now = SystemClock.uptimeMillis(); 2248 boolean haveNewCpuStats = false; 2249 2250 if (MONITOR_CPU_USAGE && 2251 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2252 mLastCpuTime.set(now); 2253 haveNewCpuStats = true; 2254 mProcessCpuTracker.update(); 2255 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2256 //Slog.i(TAG, "Total CPU usage: " 2257 // + mProcessCpu.getTotalCpuPercent() + "%"); 2258 2259 // Slog the cpu usage if the property is set. 2260 if ("true".equals(SystemProperties.get("events.cpu"))) { 2261 int user = mProcessCpuTracker.getLastUserTime(); 2262 int system = mProcessCpuTracker.getLastSystemTime(); 2263 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2264 int irq = mProcessCpuTracker.getLastIrqTime(); 2265 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2266 int idle = mProcessCpuTracker.getLastIdleTime(); 2267 2268 int total = user + system + iowait + irq + softIrq + idle; 2269 if (total == 0) total = 1; 2270 2271 EventLog.writeEvent(EventLogTags.CPU, 2272 ((user+system+iowait+irq+softIrq) * 100) / total, 2273 (user * 100) / total, 2274 (system * 100) / total, 2275 (iowait * 100) / total, 2276 (irq * 100) / total, 2277 (softIrq * 100) / total); 2278 } 2279 } 2280 2281 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2282 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2283 synchronized(bstats) { 2284 synchronized(mPidsSelfLocked) { 2285 if (haveNewCpuStats) { 2286 if (mOnBattery) { 2287 int perc = bstats.startAddingCpuLocked(); 2288 int totalUTime = 0; 2289 int totalSTime = 0; 2290 final int N = mProcessCpuTracker.countStats(); 2291 for (int i=0; i<N; i++) { 2292 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2293 if (!st.working) { 2294 continue; 2295 } 2296 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2297 int otherUTime = (st.rel_utime*perc)/100; 2298 int otherSTime = (st.rel_stime*perc)/100; 2299 totalUTime += otherUTime; 2300 totalSTime += otherSTime; 2301 if (pr != null) { 2302 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2303 if (ps == null || !ps.isActive()) { 2304 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2305 pr.info.uid, pr.processName); 2306 } 2307 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2308 st.rel_stime-otherSTime); 2309 ps.addSpeedStepTimes(cpuSpeedTimes); 2310 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2311 } else { 2312 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2313 if (ps == null || !ps.isActive()) { 2314 st.batteryStats = ps = bstats.getProcessStatsLocked( 2315 bstats.mapUid(st.uid), st.name); 2316 } 2317 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2318 st.rel_stime-otherSTime); 2319 ps.addSpeedStepTimes(cpuSpeedTimes); 2320 } 2321 } 2322 bstats.finishAddingCpuLocked(perc, totalUTime, 2323 totalSTime, cpuSpeedTimes); 2324 } 2325 } 2326 } 2327 2328 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2329 mLastWriteTime = now; 2330 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2331 } 2332 } 2333 } 2334 } 2335 2336 @Override 2337 public void batteryNeedsCpuUpdate() { 2338 updateCpuStatsNow(); 2339 } 2340 2341 @Override 2342 public void batteryPowerChanged(boolean onBattery) { 2343 // When plugging in, update the CPU stats first before changing 2344 // the plug state. 2345 updateCpuStatsNow(); 2346 synchronized (this) { 2347 synchronized(mPidsSelfLocked) { 2348 mOnBattery = DEBUG_POWER ? true : onBattery; 2349 } 2350 } 2351 } 2352 2353 /** 2354 * Initialize the application bind args. These are passed to each 2355 * process when the bindApplication() IPC is sent to the process. They're 2356 * lazily setup to make sure the services are running when they're asked for. 2357 */ 2358 private HashMap<String, IBinder> getCommonServicesLocked() { 2359 if (mAppBindArgs == null) { 2360 mAppBindArgs = new HashMap<String, IBinder>(); 2361 2362 // Setup the application init args 2363 mAppBindArgs.put("package", ServiceManager.getService("package")); 2364 mAppBindArgs.put("window", ServiceManager.getService("window")); 2365 mAppBindArgs.put(Context.ALARM_SERVICE, 2366 ServiceManager.getService(Context.ALARM_SERVICE)); 2367 } 2368 return mAppBindArgs; 2369 } 2370 2371 final void setFocusedActivityLocked(ActivityRecord r) { 2372 if (mFocusedActivity != r) { 2373 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2374 mFocusedActivity = r; 2375 if (r.task != null && r.task.voiceInteractor != null) { 2376 startRunningVoiceLocked(); 2377 } else { 2378 finishRunningVoiceLocked(); 2379 } 2380 mStackSupervisor.setFocusedStack(r); 2381 if (r != null) { 2382 mWindowManager.setFocusedApp(r.appToken, true); 2383 } 2384 applyUpdateLockStateLocked(r); 2385 } 2386 } 2387 2388 final void clearFocusedActivity(ActivityRecord r) { 2389 if (mFocusedActivity == r) { 2390 mFocusedActivity = null; 2391 } 2392 } 2393 2394 @Override 2395 public void setFocusedStack(int stackId) { 2396 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2397 synchronized (ActivityManagerService.this) { 2398 ActivityStack stack = mStackSupervisor.getStack(stackId); 2399 if (stack != null) { 2400 ActivityRecord r = stack.topRunningActivityLocked(null); 2401 if (r != null) { 2402 setFocusedActivityLocked(r); 2403 } 2404 } 2405 } 2406 } 2407 2408 @Override 2409 public void notifyActivityDrawn(IBinder token) { 2410 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2411 synchronized (this) { 2412 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2413 if (r != null) { 2414 r.task.stack.notifyActivityDrawnLocked(r); 2415 } 2416 } 2417 } 2418 2419 final void applyUpdateLockStateLocked(ActivityRecord r) { 2420 // Modifications to the UpdateLock state are done on our handler, outside 2421 // the activity manager's locks. The new state is determined based on the 2422 // state *now* of the relevant activity record. The object is passed to 2423 // the handler solely for logging detail, not to be consulted/modified. 2424 final boolean nextState = r != null && r.immersive; 2425 mHandler.sendMessage( 2426 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2427 } 2428 2429 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2430 Message msg = Message.obtain(); 2431 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2432 msg.obj = r.task.askedCompatMode ? null : r; 2433 mHandler.sendMessage(msg); 2434 } 2435 2436 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2437 String what, Object obj, ProcessRecord srcApp) { 2438 app.lastActivityTime = now; 2439 2440 if (app.activities.size() > 0) { 2441 // Don't want to touch dependent processes that are hosting activities. 2442 return index; 2443 } 2444 2445 int lrui = mLruProcesses.lastIndexOf(app); 2446 if (lrui < 0) { 2447 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2448 + what + " " + obj + " from " + srcApp); 2449 return index; 2450 } 2451 2452 if (lrui >= index) { 2453 // Don't want to cause this to move dependent processes *back* in the 2454 // list as if they were less frequently used. 2455 return index; 2456 } 2457 2458 if (lrui >= mLruProcessActivityStart) { 2459 // Don't want to touch dependent processes that are hosting activities. 2460 return index; 2461 } 2462 2463 mLruProcesses.remove(lrui); 2464 if (index > 0) { 2465 index--; 2466 } 2467 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2468 + " in LRU list: " + app); 2469 mLruProcesses.add(index, app); 2470 return index; 2471 } 2472 2473 final void removeLruProcessLocked(ProcessRecord app) { 2474 int lrui = mLruProcesses.lastIndexOf(app); 2475 if (lrui >= 0) { 2476 if (!app.killed) { 2477 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2478 Process.killProcessQuiet(app.pid); 2479 Process.killProcessGroup(app.info.uid, app.pid); 2480 } 2481 if (lrui <= mLruProcessActivityStart) { 2482 mLruProcessActivityStart--; 2483 } 2484 if (lrui <= mLruProcessServiceStart) { 2485 mLruProcessServiceStart--; 2486 } 2487 mLruProcesses.remove(lrui); 2488 } 2489 } 2490 2491 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2492 ProcessRecord client) { 2493 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2494 || app.treatLikeActivity; 2495 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2496 if (!activityChange && hasActivity) { 2497 // The process has activities, so we are only allowing activity-based adjustments 2498 // to move it. It should be kept in the front of the list with other 2499 // processes that have activities, and we don't want those to change their 2500 // order except due to activity operations. 2501 return; 2502 } 2503 2504 mLruSeq++; 2505 final long now = SystemClock.uptimeMillis(); 2506 app.lastActivityTime = now; 2507 2508 // First a quick reject: if the app is already at the position we will 2509 // put it, then there is nothing to do. 2510 if (hasActivity) { 2511 final int N = mLruProcesses.size(); 2512 if (N > 0 && mLruProcesses.get(N-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2514 return; 2515 } 2516 } else { 2517 if (mLruProcessServiceStart > 0 2518 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2519 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2520 return; 2521 } 2522 } 2523 2524 int lrui = mLruProcesses.lastIndexOf(app); 2525 2526 if (app.persistent && lrui >= 0) { 2527 // We don't care about the position of persistent processes, as long as 2528 // they are in the list. 2529 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2530 return; 2531 } 2532 2533 /* In progress: compute new position first, so we can avoid doing work 2534 if the process is not actually going to move. Not yet working. 2535 int addIndex; 2536 int nextIndex; 2537 boolean inActivity = false, inService = false; 2538 if (hasActivity) { 2539 // Process has activities, put it at the very tipsy-top. 2540 addIndex = mLruProcesses.size(); 2541 nextIndex = mLruProcessServiceStart; 2542 inActivity = true; 2543 } else if (hasService) { 2544 // Process has services, put it at the top of the service list. 2545 addIndex = mLruProcessActivityStart; 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 inService = true; 2549 } else { 2550 // Process not otherwise of interest, it goes to the top of the non-service area. 2551 addIndex = mLruProcessServiceStart; 2552 if (client != null) { 2553 int clientIndex = mLruProcesses.lastIndexOf(client); 2554 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2555 + app); 2556 if (clientIndex >= 0 && addIndex > clientIndex) { 2557 addIndex = clientIndex; 2558 } 2559 } 2560 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2561 } 2562 2563 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2564 + mLruProcessActivityStart + "): " + app); 2565 */ 2566 2567 if (lrui >= 0) { 2568 if (lrui < mLruProcessActivityStart) { 2569 mLruProcessActivityStart--; 2570 } 2571 if (lrui < mLruProcessServiceStart) { 2572 mLruProcessServiceStart--; 2573 } 2574 /* 2575 if (addIndex > lrui) { 2576 addIndex--; 2577 } 2578 if (nextIndex > lrui) { 2579 nextIndex--; 2580 } 2581 */ 2582 mLruProcesses.remove(lrui); 2583 } 2584 2585 /* 2586 mLruProcesses.add(addIndex, app); 2587 if (inActivity) { 2588 mLruProcessActivityStart++; 2589 } 2590 if (inService) { 2591 mLruProcessActivityStart++; 2592 } 2593 */ 2594 2595 int nextIndex; 2596 if (hasActivity) { 2597 final int N = mLruProcesses.size(); 2598 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2599 // Process doesn't have activities, but has clients with 2600 // activities... move it up, but one below the top (the top 2601 // should always have a real activity). 2602 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2603 mLruProcesses.add(N-1, app); 2604 // To keep it from spamming the LRU list (by making a bunch of clients), 2605 // we will push down any other entries owned by the app. 2606 final int uid = app.info.uid; 2607 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2608 ProcessRecord subProc = mLruProcesses.get(i); 2609 if (subProc.info.uid == uid) { 2610 // We want to push this one down the list. If the process after 2611 // it is for the same uid, however, don't do so, because we don't 2612 // want them internally to be re-ordered. 2613 if (mLruProcesses.get(i-1).info.uid != uid) { 2614 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2615 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2616 ProcessRecord tmp = mLruProcesses.get(i); 2617 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2618 mLruProcesses.set(i-1, tmp); 2619 i--; 2620 } 2621 } else { 2622 // A gap, we can stop here. 2623 break; 2624 } 2625 } 2626 } else { 2627 // Process has activities, put it at the very tipsy-top. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2629 mLruProcesses.add(app); 2630 } 2631 nextIndex = mLruProcessServiceStart; 2632 } else if (hasService) { 2633 // Process has services, put it at the top of the service list. 2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2635 mLruProcesses.add(mLruProcessActivityStart, app); 2636 nextIndex = mLruProcessServiceStart; 2637 mLruProcessActivityStart++; 2638 } else { 2639 // Process not otherwise of interest, it goes to the top of the non-service area. 2640 int index = mLruProcessServiceStart; 2641 if (client != null) { 2642 // If there is a client, don't allow the process to be moved up higher 2643 // in the list than that client. 2644 int clientIndex = mLruProcesses.lastIndexOf(client); 2645 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2646 + " when updating " + app); 2647 if (clientIndex <= lrui) { 2648 // Don't allow the client index restriction to push it down farther in the 2649 // list than it already is. 2650 clientIndex = lrui; 2651 } 2652 if (clientIndex >= 0 && index > clientIndex) { 2653 index = clientIndex; 2654 } 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2657 mLruProcesses.add(index, app); 2658 nextIndex = index-1; 2659 mLruProcessActivityStart++; 2660 mLruProcessServiceStart++; 2661 } 2662 2663 // If the app is currently using a content provider or service, 2664 // bump those processes as well. 2665 for (int j=app.connections.size()-1; j>=0; j--) { 2666 ConnectionRecord cr = app.connections.valueAt(j); 2667 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2668 && cr.binding.service.app != null 2669 && cr.binding.service.app.lruSeq != mLruSeq 2670 && !cr.binding.service.app.persistent) { 2671 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2672 "service connection", cr, app); 2673 } 2674 } 2675 for (int j=app.conProviders.size()-1; j>=0; j--) { 2676 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2677 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2679 "provider reference", cpr, app); 2680 } 2681 } 2682 } 2683 2684 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2685 if (uid == Process.SYSTEM_UID) { 2686 // The system gets to run in any process. If there are multiple 2687 // processes with the same uid, just pick the first (this 2688 // should never happen). 2689 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2690 if (procs == null) return null; 2691 final int N = procs.size(); 2692 for (int i = 0; i < N; i++) { 2693 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2694 } 2695 } 2696 ProcessRecord proc = mProcessNames.get(processName, uid); 2697 if (false && proc != null && !keepIfLarge 2698 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2699 && proc.lastCachedPss >= 4000) { 2700 // Turn this condition on to cause killing to happen regularly, for testing. 2701 if (proc.baseProcessTracker != null) { 2702 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2703 } 2704 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2705 } else if (proc != null && !keepIfLarge 2706 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2707 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2708 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2709 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2710 if (proc.baseProcessTracker != null) { 2711 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2712 } 2713 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2714 } 2715 } 2716 return proc; 2717 } 2718 2719 void ensurePackageDexOpt(String packageName) { 2720 IPackageManager pm = AppGlobals.getPackageManager(); 2721 try { 2722 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2723 mDidDexOpt = true; 2724 } 2725 } catch (RemoteException e) { 2726 } 2727 } 2728 2729 boolean isNextTransitionForward() { 2730 int transit = mWindowManager.getPendingAppTransition(); 2731 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2732 || transit == AppTransition.TRANSIT_TASK_OPEN 2733 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2734 } 2735 2736 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2737 String processName, String abiOverride, int uid, Runnable crashHandler) { 2738 synchronized(this) { 2739 ApplicationInfo info = new ApplicationInfo(); 2740 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2741 // For isolated processes, the former contains the parent's uid and the latter the 2742 // actual uid of the isolated process. 2743 // In the special case introduced by this method (which is, starting an isolated 2744 // process directly from the SystemServer without an actual parent app process) the 2745 // closest thing to a parent's uid is SYSTEM_UID. 2746 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2747 // the |isolated| logic in the ProcessRecord constructor. 2748 info.uid = Process.SYSTEM_UID; 2749 info.processName = processName; 2750 info.className = entryPoint; 2751 info.packageName = "android"; 2752 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2753 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2754 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2755 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2756 crashHandler); 2757 return proc != null ? proc.pid : 0; 2758 } 2759 } 2760 2761 final ProcessRecord startProcessLocked(String processName, 2762 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2763 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2764 boolean isolated, boolean keepIfLarge) { 2765 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2766 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2767 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2768 null /* crashHandler */); 2769 } 2770 2771 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2772 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2773 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2774 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2775 long startTime = SystemClock.elapsedRealtime(); 2776 ProcessRecord app; 2777 if (!isolated) { 2778 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2779 checkTime(startTime, "startProcess: after getProcessRecord"); 2780 } else { 2781 // If this is an isolated process, it can't re-use an existing process. 2782 app = null; 2783 } 2784 // We don't have to do anything more if: 2785 // (1) There is an existing application record; and 2786 // (2) The caller doesn't think it is dead, OR there is no thread 2787 // object attached to it so we know it couldn't have crashed; and 2788 // (3) There is a pid assigned to it, so it is either starting or 2789 // already running. 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2791 + " app=" + app + " knownToBeDead=" + knownToBeDead 2792 + " thread=" + (app != null ? app.thread : null) 2793 + " pid=" + (app != null ? app.pid : -1)); 2794 if (app != null && app.pid > 0) { 2795 if (!knownToBeDead || app.thread == null) { 2796 // We already have the app running, or are waiting for it to 2797 // come up (we have a pid but not yet its thread), so keep it. 2798 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2799 // If this is a new package in the process, add the package to the list 2800 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2801 checkTime(startTime, "startProcess: done, added package to proc"); 2802 return app; 2803 } 2804 2805 // An application record is attached to a previous process, 2806 // clean it up now. 2807 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2808 checkTime(startTime, "startProcess: bad proc running, killing"); 2809 Process.killProcessGroup(app.info.uid, app.pid); 2810 handleAppDiedLocked(app, true, true); 2811 checkTime(startTime, "startProcess: done killing old proc"); 2812 } 2813 2814 String hostingNameStr = hostingName != null 2815 ? hostingName.flattenToShortString() : null; 2816 2817 if (!isolated) { 2818 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2819 // If we are in the background, then check to see if this process 2820 // is bad. If so, we will just silently fail. 2821 if (mBadProcesses.get(info.processName, info.uid) != null) { 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2823 + "/" + info.processName); 2824 return null; 2825 } 2826 } else { 2827 // When the user is explicitly starting a process, then clear its 2828 // crash count so that we won't make it bad until they see at 2829 // least one crash dialog again, and make the process good again 2830 // if it had been bad. 2831 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2832 + "/" + info.processName); 2833 mProcessCrashTimes.remove(info.processName, info.uid); 2834 if (mBadProcesses.get(info.processName, info.uid) != null) { 2835 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2836 UserHandle.getUserId(info.uid), info.uid, 2837 info.processName); 2838 mBadProcesses.remove(info.processName, info.uid); 2839 if (app != null) { 2840 app.bad = false; 2841 } 2842 } 2843 } 2844 } 2845 2846 if (app == null) { 2847 checkTime(startTime, "startProcess: creating new process record"); 2848 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2849 app.crashHandler = crashHandler; 2850 if (app == null) { 2851 Slog.w(TAG, "Failed making new process record for " 2852 + processName + "/" + info.uid + " isolated=" + isolated); 2853 return null; 2854 } 2855 mProcessNames.put(processName, app.uid, app); 2856 if (isolated) { 2857 mIsolatedProcesses.put(app.uid, app); 2858 } 2859 checkTime(startTime, "startProcess: done creating new process record"); 2860 } else { 2861 // If this is a new package in the process, add the package to the list 2862 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2863 checkTime(startTime, "startProcess: added package to existing proc"); 2864 } 2865 2866 // If the system is not ready yet, then hold off on starting this 2867 // process until it is. 2868 if (!mProcessesReady 2869 && !isAllowedWhileBooting(info) 2870 && !allowWhileBooting) { 2871 if (!mProcessesOnHold.contains(app)) { 2872 mProcessesOnHold.add(app); 2873 } 2874 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2875 checkTime(startTime, "startProcess: returning with proc on hold"); 2876 return app; 2877 } 2878 2879 checkTime(startTime, "startProcess: stepping in to startProcess"); 2880 startProcessLocked( 2881 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2882 checkTime(startTime, "startProcess: done starting proc!"); 2883 return (app.pid != 0) ? app : null; 2884 } 2885 2886 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2887 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2888 } 2889 2890 private final void startProcessLocked(ProcessRecord app, 2891 String hostingType, String hostingNameStr) { 2892 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2893 null /* entryPoint */, null /* entryPointArgs */); 2894 } 2895 2896 private final void startProcessLocked(ProcessRecord app, String hostingType, 2897 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2898 long startTime = SystemClock.elapsedRealtime(); 2899 if (app.pid > 0 && app.pid != MY_PID) { 2900 checkTime(startTime, "startProcess: removing from pids map"); 2901 synchronized (mPidsSelfLocked) { 2902 mPidsSelfLocked.remove(app.pid); 2903 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2904 } 2905 checkTime(startTime, "startProcess: done removing from pids map"); 2906 app.setPid(0); 2907 } 2908 2909 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2910 "startProcessLocked removing on hold: " + app); 2911 mProcessesOnHold.remove(app); 2912 2913 checkTime(startTime, "startProcess: starting to update cpu stats"); 2914 updateCpuStats(); 2915 checkTime(startTime, "startProcess: done updating cpu stats"); 2916 2917 try { 2918 int uid = app.uid; 2919 2920 int[] gids = null; 2921 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2922 if (!app.isolated) { 2923 int[] permGids = null; 2924 try { 2925 checkTime(startTime, "startProcess: getting gids from package manager"); 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 checkTime(startTime, "startProcess: checking external storage perm"); 2931 if (pm.checkPermission( 2932 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2933 app.info.packageName) == PERMISSION_GRANTED) { 2934 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2935 } else { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2937 } 2938 } 2939 } catch (PackageManager.NameNotFoundException e) { 2940 Slog.w(TAG, "Unable to retrieve gids", e); 2941 } 2942 2943 /* 2944 * Add shared application and profile GIDs so applications can share some 2945 * resources like shared libraries and access user-wide resources 2946 */ 2947 if (permGids == null) { 2948 gids = new int[2]; 2949 } else { 2950 gids = new int[permGids.length + 2]; 2951 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2952 } 2953 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2954 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2955 } 2956 checkTime(startTime, "startProcess: building args"); 2957 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2958 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2959 && mTopComponent != null 2960 && app.processName.equals(mTopComponent.getPackageName())) { 2961 uid = 0; 2962 } 2963 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2964 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2965 uid = 0; 2966 } 2967 } 2968 int debugFlags = 0; 2969 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2970 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2971 // Also turn on CheckJNI for debuggable apps. It's quite 2972 // awkward to turn on otherwise. 2973 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2974 } 2975 // Run the app in safe mode if its manifest requests so or the 2976 // system is booted in safe mode. 2977 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2978 mSafeMode == true) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.assert"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2989 } 2990 2991 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2992 if (requiredAbi == null) { 2993 requiredAbi = Build.SUPPORTED_ABIS[0]; 2994 } 2995 2996 String instructionSet = null; 2997 if (app.info.primaryCpuAbi != null) { 2998 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2999 } 3000 3001 // Start the process. It will either succeed and return a result containing 3002 // the PID of the new process, or else throw a RuntimeException. 3003 boolean isActivityProcess = (entryPoint == null); 3004 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3005 checkTime(startTime, "startProcess: asking zygote to start proc"); 3006 Process.ProcessStartResult startResult = Process.start(entryPoint, 3007 app.processName, uid, uid, gids, debugFlags, mountExternal, 3008 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3009 app.info.dataDir, entryPointArgs); 3010 checkTime(startTime, "startProcess: returned from zygote!"); 3011 3012 if (app.isolated) { 3013 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3014 } 3015 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3016 checkTime(startTime, "startProcess: done updating battery stats"); 3017 3018 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3019 UserHandle.getUserId(uid), startResult.pid, uid, 3020 app.processName, hostingType, 3021 hostingNameStr != null ? hostingNameStr : ""); 3022 3023 if (app.persistent) { 3024 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3025 } 3026 3027 checkTime(startTime, "startProcess: building log message"); 3028 StringBuilder buf = mStringBuilder; 3029 buf.setLength(0); 3030 buf.append("Start proc "); 3031 buf.append(app.processName); 3032 if (!isActivityProcess) { 3033 buf.append(" ["); 3034 buf.append(entryPoint); 3035 buf.append("]"); 3036 } 3037 buf.append(" for "); 3038 buf.append(hostingType); 3039 if (hostingNameStr != null) { 3040 buf.append(" "); 3041 buf.append(hostingNameStr); 3042 } 3043 buf.append(": pid="); 3044 buf.append(startResult.pid); 3045 buf.append(" uid="); 3046 buf.append(uid); 3047 buf.append(" gids={"); 3048 if (gids != null) { 3049 for (int gi=0; gi<gids.length; gi++) { 3050 if (gi != 0) buf.append(", "); 3051 buf.append(gids[gi]); 3052 3053 } 3054 } 3055 buf.append("}"); 3056 if (requiredAbi != null) { 3057 buf.append(" abi="); 3058 buf.append(requiredAbi); 3059 } 3060 Slog.i(TAG, buf.toString()); 3061 app.setPid(startResult.pid); 3062 app.usingWrapper = startResult.usingWrapper; 3063 app.removed = false; 3064 app.killed = false; 3065 app.killedByAm = false; 3066 checkTime(startTime, "startProcess: starting to update pids map"); 3067 synchronized (mPidsSelfLocked) { 3068 this.mPidsSelfLocked.put(startResult.pid, app); 3069 if (isActivityProcess) { 3070 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3071 msg.obj = app; 3072 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3073 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3074 } 3075 } 3076 checkTime(startTime, "startProcess: done updating pids map"); 3077 } catch (RuntimeException e) { 3078 // XXX do better error recovery. 3079 app.setPid(0); 3080 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3081 if (app.isolated) { 3082 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3083 } 3084 Slog.e(TAG, "Failure starting process " + app.processName, e); 3085 } 3086 } 3087 3088 void updateUsageStats(ActivityRecord component, boolean resumed) { 3089 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3090 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3091 if (resumed) { 3092 if (mUsageStatsService != null) { 3093 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3094 UsageEvents.Event.MOVE_TO_FOREGROUND); 3095 } 3096 synchronized (stats) { 3097 stats.noteActivityResumedLocked(component.app.uid); 3098 } 3099 } else { 3100 if (mUsageStatsService != null) { 3101 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3102 UsageEvents.Event.MOVE_TO_BACKGROUND); 3103 } 3104 synchronized (stats) { 3105 stats.noteActivityPausedLocked(component.app.uid); 3106 } 3107 } 3108 } 3109 3110 Intent getHomeIntent() { 3111 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3112 intent.setComponent(mTopComponent); 3113 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3114 intent.addCategory(Intent.CATEGORY_HOME); 3115 } 3116 return intent; 3117 } 3118 3119 boolean startHomeActivityLocked(int userId) { 3120 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3121 && mTopAction == null) { 3122 // We are running in factory test mode, but unable to find 3123 // the factory test app, so just sit around displaying the 3124 // error message and don't try to start anything. 3125 return false; 3126 } 3127 Intent intent = getHomeIntent(); 3128 ActivityInfo aInfo = 3129 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3130 if (aInfo != null) { 3131 intent.setComponent(new ComponentName( 3132 aInfo.applicationInfo.packageName, aInfo.name)); 3133 // Don't do this if the home app is currently being 3134 // instrumented. 3135 aInfo = new ActivityInfo(aInfo); 3136 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3137 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3138 aInfo.applicationInfo.uid, true); 3139 if (app == null || app.instrumentationClass == null) { 3140 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3141 mStackSupervisor.startHomeActivity(intent, aInfo); 3142 } 3143 } 3144 3145 return true; 3146 } 3147 3148 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3149 ActivityInfo ai = null; 3150 ComponentName comp = intent.getComponent(); 3151 try { 3152 if (comp != null) { 3153 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3154 } else { 3155 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3156 intent, 3157 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3158 flags, userId); 3159 3160 if (info != null) { 3161 ai = info.activityInfo; 3162 } 3163 } 3164 } catch (RemoteException e) { 3165 // ignore 3166 } 3167 3168 return ai; 3169 } 3170 3171 /** 3172 * Starts the "new version setup screen" if appropriate. 3173 */ 3174 void startSetupActivityLocked() { 3175 // Only do this once per boot. 3176 if (mCheckedForSetup) { 3177 return; 3178 } 3179 3180 // We will show this screen if the current one is a different 3181 // version than the last one shown, and we are not running in 3182 // low-level factory test mode. 3183 final ContentResolver resolver = mContext.getContentResolver(); 3184 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3185 Settings.Global.getInt(resolver, 3186 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3187 mCheckedForSetup = true; 3188 3189 // See if we should be showing the platform update setup UI. 3190 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3191 List<ResolveInfo> ris = mContext.getPackageManager() 3192 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3193 3194 // We don't allow third party apps to replace this. 3195 ResolveInfo ri = null; 3196 for (int i=0; ris != null && i<ris.size(); i++) { 3197 if ((ris.get(i).activityInfo.applicationInfo.flags 3198 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3199 ri = ris.get(i); 3200 break; 3201 } 3202 } 3203 3204 if (ri != null) { 3205 String vers = ri.activityInfo.metaData != null 3206 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3207 : null; 3208 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3209 vers = ri.activityInfo.applicationInfo.metaData.getString( 3210 Intent.METADATA_SETUP_VERSION); 3211 } 3212 String lastVers = Settings.Secure.getString( 3213 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3214 if (vers != null && !vers.equals(lastVers)) { 3215 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3216 intent.setComponent(new ComponentName( 3217 ri.activityInfo.packageName, ri.activityInfo.name)); 3218 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3219 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3220 null); 3221 } 3222 } 3223 } 3224 } 3225 3226 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3227 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3228 } 3229 3230 void enforceNotIsolatedCaller(String caller) { 3231 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3232 throw new SecurityException("Isolated process not allowed to call " + caller); 3233 } 3234 } 3235 3236 void enforceShellRestriction(String restriction, int userHandle) { 3237 if (Binder.getCallingUid() == Process.SHELL_UID) { 3238 if (userHandle < 0 3239 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3240 throw new SecurityException("Shell does not have permission to access user " 3241 + userHandle); 3242 } 3243 } 3244 } 3245 3246 @Override 3247 public int getFrontActivityScreenCompatMode() { 3248 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3249 synchronized (this) { 3250 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3251 } 3252 } 3253 3254 @Override 3255 public void setFrontActivityScreenCompatMode(int mode) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setFrontActivityScreenCompatMode"); 3258 synchronized (this) { 3259 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3260 } 3261 } 3262 3263 @Override 3264 public int getPackageScreenCompatMode(String packageName) { 3265 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3266 synchronized (this) { 3267 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3268 } 3269 } 3270 3271 @Override 3272 public void setPackageScreenCompatMode(String packageName, int mode) { 3273 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3274 "setPackageScreenCompatMode"); 3275 synchronized (this) { 3276 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3277 } 3278 } 3279 3280 @Override 3281 public boolean getPackageAskScreenCompat(String packageName) { 3282 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3283 synchronized (this) { 3284 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3285 } 3286 } 3287 3288 @Override 3289 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3290 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3291 "setPackageAskScreenCompat"); 3292 synchronized (this) { 3293 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3294 } 3295 } 3296 3297 private void dispatchProcessesChanged() { 3298 int N; 3299 synchronized (this) { 3300 N = mPendingProcessChanges.size(); 3301 if (mActiveProcessChanges.length < N) { 3302 mActiveProcessChanges = new ProcessChangeItem[N]; 3303 } 3304 mPendingProcessChanges.toArray(mActiveProcessChanges); 3305 mAvailProcessChanges.addAll(mPendingProcessChanges); 3306 mPendingProcessChanges.clear(); 3307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3308 } 3309 3310 int i = mProcessObservers.beginBroadcast(); 3311 while (i > 0) { 3312 i--; 3313 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3314 if (observer != null) { 3315 try { 3316 for (int j=0; j<N; j++) { 3317 ProcessChangeItem item = mActiveProcessChanges[j]; 3318 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3320 + item.pid + " uid=" + item.uid + ": " 3321 + item.foregroundActivities); 3322 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3323 item.foregroundActivities); 3324 } 3325 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3326 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3327 + item.pid + " uid=" + item.uid + ": " + item.processState); 3328 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3329 } 3330 } 3331 } catch (RemoteException e) { 3332 } 3333 } 3334 } 3335 mProcessObservers.finishBroadcast(); 3336 } 3337 3338 private void dispatchProcessDied(int pid, int uid) { 3339 int i = mProcessObservers.beginBroadcast(); 3340 while (i > 0) { 3341 i--; 3342 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3343 if (observer != null) { 3344 try { 3345 observer.onProcessDied(pid, uid); 3346 } catch (RemoteException e) { 3347 } 3348 } 3349 } 3350 mProcessObservers.finishBroadcast(); 3351 } 3352 3353 @Override 3354 public final int startActivity(IApplicationThread caller, String callingPackage, 3355 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3356 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3357 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3358 resultWho, requestCode, startFlags, profilerInfo, options, 3359 UserHandle.getCallingUserId()); 3360 } 3361 3362 @Override 3363 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3364 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3365 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3366 enforceNotIsolatedCaller("startActivity"); 3367 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3368 false, ALLOW_FULL_ONLY, "startActivity", null); 3369 // TODO: Switch to user app stacks here. 3370 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3371 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3372 profilerInfo, null, null, options, userId, null, null); 3373 } 3374 3375 @Override 3376 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3377 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3378 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3379 3380 // This is very dangerous -- it allows you to perform a start activity (including 3381 // permission grants) as any app that may launch one of your own activities. So 3382 // we will only allow this to be done from activities that are part of the core framework, 3383 // and then only when they are running as the system. 3384 final ActivityRecord sourceRecord; 3385 final int targetUid; 3386 final String targetPackage; 3387 synchronized (this) { 3388 if (resultTo == null) { 3389 throw new SecurityException("Must be called from an activity"); 3390 } 3391 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3392 if (sourceRecord == null) { 3393 throw new SecurityException("Called with bad activity token: " + resultTo); 3394 } 3395 if (!sourceRecord.info.packageName.equals("android")) { 3396 throw new SecurityException( 3397 "Must be called from an activity that is declared in the android package"); 3398 } 3399 if (sourceRecord.app == null) { 3400 throw new SecurityException("Called without a process attached to activity"); 3401 } 3402 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3403 // This is still okay, as long as this activity is running under the 3404 // uid of the original calling activity. 3405 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3406 throw new SecurityException( 3407 "Calling activity in uid " + sourceRecord.app.uid 3408 + " must be system uid or original calling uid " 3409 + sourceRecord.launchedFromUid); 3410 } 3411 } 3412 targetUid = sourceRecord.launchedFromUid; 3413 targetPackage = sourceRecord.launchedFromPackage; 3414 } 3415 3416 if (userId == UserHandle.USER_NULL) { 3417 userId = UserHandle.getUserId(sourceRecord.app.uid); 3418 } 3419 3420 // TODO: Switch to user app stacks here. 3421 try { 3422 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3423 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3424 null, null, options, userId, null, null); 3425 return ret; 3426 } catch (SecurityException e) { 3427 // XXX need to figure out how to propagate to original app. 3428 // A SecurityException here is generally actually a fault of the original 3429 // calling activity (such as a fairly granting permissions), so propagate it 3430 // back to them. 3431 /* 3432 StringBuilder msg = new StringBuilder(); 3433 msg.append("While launching"); 3434 msg.append(intent.toString()); 3435 msg.append(": "); 3436 msg.append(e.getMessage()); 3437 */ 3438 throw e; 3439 } 3440 } 3441 3442 @Override 3443 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3444 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3445 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3446 enforceNotIsolatedCaller("startActivityAndWait"); 3447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3448 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3449 WaitResult res = new WaitResult(); 3450 // TODO: Switch to user app stacks here. 3451 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3452 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3453 options, userId, null, null); 3454 return res; 3455 } 3456 3457 @Override 3458 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3459 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3460 int startFlags, Configuration config, Bundle options, int userId) { 3461 enforceNotIsolatedCaller("startActivityWithConfig"); 3462 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3463 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3464 // TODO: Switch to user app stacks here. 3465 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3466 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3467 null, null, config, options, userId, null, null); 3468 return ret; 3469 } 3470 3471 @Override 3472 public int startActivityIntentSender(IApplicationThread caller, 3473 IntentSender intent, Intent fillInIntent, String resolvedType, 3474 IBinder resultTo, String resultWho, int requestCode, 3475 int flagsMask, int flagsValues, Bundle options) { 3476 enforceNotIsolatedCaller("startActivityIntentSender"); 3477 // Refuse possible leaked file descriptors 3478 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3479 throw new IllegalArgumentException("File descriptors passed in Intent"); 3480 } 3481 3482 IIntentSender sender = intent.getTarget(); 3483 if (!(sender instanceof PendingIntentRecord)) { 3484 throw new IllegalArgumentException("Bad PendingIntent object"); 3485 } 3486 3487 PendingIntentRecord pir = (PendingIntentRecord)sender; 3488 3489 synchronized (this) { 3490 // If this is coming from the currently resumed activity, it is 3491 // effectively saying that app switches are allowed at this point. 3492 final ActivityStack stack = getFocusedStack(); 3493 if (stack.mResumedActivity != null && 3494 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3495 mAppSwitchesAllowedTime = 0; 3496 } 3497 } 3498 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3499 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3500 return ret; 3501 } 3502 3503 @Override 3504 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3505 Intent intent, String resolvedType, IVoiceInteractionSession session, 3506 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3507 Bundle options, int userId) { 3508 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3509 != PackageManager.PERMISSION_GRANTED) { 3510 String msg = "Permission Denial: startVoiceActivity() from pid=" 3511 + Binder.getCallingPid() 3512 + ", uid=" + Binder.getCallingUid() 3513 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3514 Slog.w(TAG, msg); 3515 throw new SecurityException(msg); 3516 } 3517 if (session == null || interactor == null) { 3518 throw new NullPointerException("null session or interactor"); 3519 } 3520 userId = handleIncomingUser(callingPid, callingUid, userId, 3521 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3522 // TODO: Switch to user app stacks here. 3523 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3524 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3525 null, options, userId, null, null); 3526 } 3527 3528 @Override 3529 public boolean startNextMatchingActivity(IBinder callingActivity, 3530 Intent intent, Bundle options) { 3531 // Refuse possible leaked file descriptors 3532 if (intent != null && intent.hasFileDescriptors() == true) { 3533 throw new IllegalArgumentException("File descriptors passed in Intent"); 3534 } 3535 3536 synchronized (this) { 3537 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3538 if (r == null) { 3539 ActivityOptions.abort(options); 3540 return false; 3541 } 3542 if (r.app == null || r.app.thread == null) { 3543 // The caller is not running... d'oh! 3544 ActivityOptions.abort(options); 3545 return false; 3546 } 3547 intent = new Intent(intent); 3548 // The caller is not allowed to change the data. 3549 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3550 // And we are resetting to find the next component... 3551 intent.setComponent(null); 3552 3553 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3554 3555 ActivityInfo aInfo = null; 3556 try { 3557 List<ResolveInfo> resolves = 3558 AppGlobals.getPackageManager().queryIntentActivities( 3559 intent, r.resolvedType, 3560 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3561 UserHandle.getCallingUserId()); 3562 3563 // Look for the original activity in the list... 3564 final int N = resolves != null ? resolves.size() : 0; 3565 for (int i=0; i<N; i++) { 3566 ResolveInfo rInfo = resolves.get(i); 3567 if (rInfo.activityInfo.packageName.equals(r.packageName) 3568 && rInfo.activityInfo.name.equals(r.info.name)) { 3569 // We found the current one... the next matching is 3570 // after it. 3571 i++; 3572 if (i<N) { 3573 aInfo = resolves.get(i).activityInfo; 3574 } 3575 if (debug) { 3576 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3577 + "/" + r.info.name); 3578 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3579 + "/" + aInfo.name); 3580 } 3581 break; 3582 } 3583 } 3584 } catch (RemoteException e) { 3585 } 3586 3587 if (aInfo == null) { 3588 // Nobody who is next! 3589 ActivityOptions.abort(options); 3590 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3591 return false; 3592 } 3593 3594 intent.setComponent(new ComponentName( 3595 aInfo.applicationInfo.packageName, aInfo.name)); 3596 intent.setFlags(intent.getFlags()&~( 3597 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3598 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3599 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3600 Intent.FLAG_ACTIVITY_NEW_TASK)); 3601 3602 // Okay now we need to start the new activity, replacing the 3603 // currently running activity. This is a little tricky because 3604 // we want to start the new one as if the current one is finished, 3605 // but not finish the current one first so that there is no flicker. 3606 // And thus... 3607 final boolean wasFinishing = r.finishing; 3608 r.finishing = true; 3609 3610 // Propagate reply information over to the new activity. 3611 final ActivityRecord resultTo = r.resultTo; 3612 final String resultWho = r.resultWho; 3613 final int requestCode = r.requestCode; 3614 r.resultTo = null; 3615 if (resultTo != null) { 3616 resultTo.removeResultsLocked(r, resultWho, requestCode); 3617 } 3618 3619 final long origId = Binder.clearCallingIdentity(); 3620 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3621 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3622 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3623 -1, r.launchedFromUid, 0, options, false, null, null, null); 3624 Binder.restoreCallingIdentity(origId); 3625 3626 r.finishing = wasFinishing; 3627 if (res != ActivityManager.START_SUCCESS) { 3628 return false; 3629 } 3630 return true; 3631 } 3632 } 3633 3634 @Override 3635 public final int startActivityFromRecents(int taskId, Bundle options) { 3636 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3637 String msg = "Permission Denial: startActivityFromRecents called without " + 3638 START_TASKS_FROM_RECENTS; 3639 Slog.w(TAG, msg); 3640 throw new SecurityException(msg); 3641 } 3642 return startActivityFromRecentsInner(taskId, options); 3643 } 3644 3645 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3646 final TaskRecord task; 3647 final int callingUid; 3648 final String callingPackage; 3649 final Intent intent; 3650 final int userId; 3651 synchronized (this) { 3652 task = recentTaskForIdLocked(taskId); 3653 if (task == null) { 3654 throw new IllegalArgumentException("Task " + taskId + " not found."); 3655 } 3656 callingUid = task.mCallingUid; 3657 callingPackage = task.mCallingPackage; 3658 intent = task.intent; 3659 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3660 userId = task.userId; 3661 } 3662 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3663 options, userId, null, task); 3664 } 3665 3666 final int startActivityInPackage(int uid, String callingPackage, 3667 Intent intent, String resolvedType, IBinder resultTo, 3668 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3669 IActivityContainer container, TaskRecord inTask) { 3670 3671 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3672 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3673 3674 // TODO: Switch to user app stacks here. 3675 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3676 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3677 null, null, null, options, userId, container, inTask); 3678 return ret; 3679 } 3680 3681 @Override 3682 public final int startActivities(IApplicationThread caller, String callingPackage, 3683 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3684 int userId) { 3685 enforceNotIsolatedCaller("startActivities"); 3686 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3687 false, ALLOW_FULL_ONLY, "startActivity", null); 3688 // TODO: Switch to user app stacks here. 3689 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3690 resolvedTypes, resultTo, options, userId); 3691 return ret; 3692 } 3693 3694 final int startActivitiesInPackage(int uid, String callingPackage, 3695 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3696 Bundle options, int userId) { 3697 3698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3699 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3700 // TODO: Switch to user app stacks here. 3701 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3702 resultTo, options, userId); 3703 return ret; 3704 } 3705 3706 //explicitly remove thd old information in mRecentTasks when removing existing user. 3707 private void removeRecentTasksForUserLocked(int userId) { 3708 if(userId <= 0) { 3709 Slog.i(TAG, "Can't remove recent task on user " + userId); 3710 return; 3711 } 3712 3713 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3714 TaskRecord tr = mRecentTasks.get(i); 3715 if (tr.userId == userId) { 3716 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3717 + " when finishing user" + userId); 3718 mRecentTasks.remove(i); 3719 tr.removedFromRecents(mTaskPersister); 3720 } 3721 } 3722 3723 // Remove tasks from persistent storage. 3724 mTaskPersister.wakeup(null, true); 3725 } 3726 3727 // Sort by taskId 3728 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3729 @Override 3730 public int compare(TaskRecord lhs, TaskRecord rhs) { 3731 return rhs.taskId - lhs.taskId; 3732 } 3733 }; 3734 3735 // Extract the affiliates of the chain containing mRecentTasks[start]. 3736 private int processNextAffiliateChain(int start) { 3737 final TaskRecord startTask = mRecentTasks.get(start); 3738 final int affiliateId = startTask.mAffiliatedTaskId; 3739 3740 // Quick identification of isolated tasks. I.e. those not launched behind. 3741 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3742 startTask.mNextAffiliate == null) { 3743 // There is still a slim chance that there are other tasks that point to this task 3744 // and that the chain is so messed up that this task no longer points to them but 3745 // the gain of this optimization outweighs the risk. 3746 startTask.inRecents = true; 3747 return start + 1; 3748 } 3749 3750 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3751 mTmpRecents.clear(); 3752 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3753 final TaskRecord task = mRecentTasks.get(i); 3754 if (task.mAffiliatedTaskId == affiliateId) { 3755 mRecentTasks.remove(i); 3756 mTmpRecents.add(task); 3757 } 3758 } 3759 3760 // Sort them all by taskId. That is the order they were create in and that order will 3761 // always be correct. 3762 Collections.sort(mTmpRecents, mTaskRecordComparator); 3763 3764 // Go through and fix up the linked list. 3765 // The first one is the end of the chain and has no next. 3766 final TaskRecord first = mTmpRecents.get(0); 3767 first.inRecents = true; 3768 if (first.mNextAffiliate != null) { 3769 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3770 first.setNextAffiliate(null); 3771 mTaskPersister.wakeup(first, false); 3772 } 3773 // Everything in the middle is doubly linked from next to prev. 3774 final int tmpSize = mTmpRecents.size(); 3775 for (int i = 0; i < tmpSize - 1; ++i) { 3776 final TaskRecord next = mTmpRecents.get(i); 3777 final TaskRecord prev = mTmpRecents.get(i + 1); 3778 if (next.mPrevAffiliate != prev) { 3779 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3780 " setting prev=" + prev); 3781 next.setPrevAffiliate(prev); 3782 mTaskPersister.wakeup(next, false); 3783 } 3784 if (prev.mNextAffiliate != next) { 3785 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3786 " setting next=" + next); 3787 prev.setNextAffiliate(next); 3788 mTaskPersister.wakeup(prev, false); 3789 } 3790 prev.inRecents = true; 3791 } 3792 // The last one is the beginning of the list and has no prev. 3793 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3794 if (last.mPrevAffiliate != null) { 3795 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3796 last.setPrevAffiliate(null); 3797 mTaskPersister.wakeup(last, false); 3798 } 3799 3800 // Insert the group back into mRecentTasks at start. 3801 mRecentTasks.addAll(start, mTmpRecents); 3802 3803 // Let the caller know where we left off. 3804 return start + tmpSize; 3805 } 3806 3807 /** 3808 * Update the recent tasks lists: make sure tasks should still be here (their 3809 * applications / activities still exist), update their availability, fixup ordering 3810 * of affiliations. 3811 */ 3812 void cleanupRecentTasksLocked(int userId) { 3813 if (mRecentTasks == null) { 3814 // Happens when called from the packagemanager broadcast before boot. 3815 return; 3816 } 3817 3818 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3819 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3820 final IPackageManager pm = AppGlobals.getPackageManager(); 3821 final ActivityInfo dummyAct = new ActivityInfo(); 3822 final ApplicationInfo dummyApp = new ApplicationInfo(); 3823 3824 int N = mRecentTasks.size(); 3825 3826 int[] users = userId == UserHandle.USER_ALL 3827 ? getUsersLocked() : new int[] { userId }; 3828 for (int user : users) { 3829 for (int i = 0; i < N; i++) { 3830 TaskRecord task = mRecentTasks.get(i); 3831 if (task.userId != user) { 3832 // Only look at tasks for the user ID of interest. 3833 continue; 3834 } 3835 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3836 // This situation is broken, and we should just get rid of it now. 3837 mRecentTasks.remove(i); 3838 task.removedFromRecents(mTaskPersister); 3839 i--; 3840 N--; 3841 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3842 continue; 3843 } 3844 // Check whether this activity is currently available. 3845 if (task.realActivity != null) { 3846 ActivityInfo ai = availActCache.get(task.realActivity); 3847 if (ai == null) { 3848 try { 3849 ai = pm.getActivityInfo(task.realActivity, 3850 PackageManager.GET_UNINSTALLED_PACKAGES 3851 | PackageManager.GET_DISABLED_COMPONENTS, user); 3852 } catch (RemoteException e) { 3853 // Will never happen. 3854 continue; 3855 } 3856 if (ai == null) { 3857 ai = dummyAct; 3858 } 3859 availActCache.put(task.realActivity, ai); 3860 } 3861 if (ai == dummyAct) { 3862 // This could be either because the activity no longer exists, or the 3863 // app is temporarily gone. For the former we want to remove the recents 3864 // entry; for the latter we want to mark it as unavailable. 3865 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3866 if (app == null) { 3867 try { 3868 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3869 PackageManager.GET_UNINSTALLED_PACKAGES 3870 | PackageManager.GET_DISABLED_COMPONENTS, user); 3871 } catch (RemoteException e) { 3872 // Will never happen. 3873 continue; 3874 } 3875 if (app == null) { 3876 app = dummyApp; 3877 } 3878 availAppCache.put(task.realActivity.getPackageName(), app); 3879 } 3880 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3881 // Doesn't exist any more! Good-bye. 3882 mRecentTasks.remove(i); 3883 task.removedFromRecents(mTaskPersister); 3884 i--; 3885 N--; 3886 Slog.w(TAG, "Removing no longer valid recent: " + task); 3887 continue; 3888 } else { 3889 // Otherwise just not available for now. 3890 if (task.isAvailable) { 3891 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3892 + task); 3893 } 3894 task.isAvailable = false; 3895 } 3896 } else { 3897 if (!ai.enabled || !ai.applicationInfo.enabled 3898 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3899 if (task.isAvailable) { 3900 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3901 + task + " (enabled=" + ai.enabled + "/" 3902 + ai.applicationInfo.enabled + " flags=" 3903 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3904 } 3905 task.isAvailable = false; 3906 } else { 3907 if (!task.isAvailable) { 3908 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3909 + task); 3910 } 3911 task.isAvailable = true; 3912 } 3913 } 3914 } 3915 } 3916 } 3917 3918 // Verify the affiliate chain for each task. 3919 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3920 } 3921 3922 mTmpRecents.clear(); 3923 // mRecentTasks is now in sorted, affiliated order. 3924 } 3925 3926 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3927 int N = mRecentTasks.size(); 3928 TaskRecord top = task; 3929 int topIndex = taskIndex; 3930 while (top.mNextAffiliate != null && topIndex > 0) { 3931 top = top.mNextAffiliate; 3932 topIndex--; 3933 } 3934 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3935 + topIndex + " from intial " + taskIndex); 3936 // Find the end of the chain, doing a sanity check along the way. 3937 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3938 int endIndex = topIndex; 3939 TaskRecord prev = top; 3940 while (endIndex < N) { 3941 TaskRecord cur = mRecentTasks.get(endIndex); 3942 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3943 + endIndex + " " + cur); 3944 if (cur == top) { 3945 // Verify start of the chain. 3946 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3947 Slog.wtf(TAG, "Bad chain @" + endIndex 3948 + ": first task has next affiliate: " + prev); 3949 sane = false; 3950 break; 3951 } 3952 } else { 3953 // Verify middle of the chain's next points back to the one before. 3954 if (cur.mNextAffiliate != prev 3955 || cur.mNextAffiliateTaskId != prev.taskId) { 3956 Slog.wtf(TAG, "Bad chain @" + endIndex 3957 + ": middle task " + cur + " @" + endIndex 3958 + " has bad next affiliate " 3959 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3960 + ", expected " + prev); 3961 sane = false; 3962 break; 3963 } 3964 } 3965 if (cur.mPrevAffiliateTaskId == -1) { 3966 // Chain ends here. 3967 if (cur.mPrevAffiliate != null) { 3968 Slog.wtf(TAG, "Bad chain @" + endIndex 3969 + ": last task " + cur + " has previous affiliate " 3970 + cur.mPrevAffiliate); 3971 sane = false; 3972 } 3973 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3974 break; 3975 } else { 3976 // Verify middle of the chain's prev points to a valid item. 3977 if (cur.mPrevAffiliate == null) { 3978 Slog.wtf(TAG, "Bad chain @" + endIndex 3979 + ": task " + cur + " has previous affiliate " 3980 + cur.mPrevAffiliate + " but should be id " 3981 + cur.mPrevAffiliate); 3982 sane = false; 3983 break; 3984 } 3985 } 3986 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3987 Slog.wtf(TAG, "Bad chain @" + endIndex 3988 + ": task " + cur + " has affiliated id " 3989 + cur.mAffiliatedTaskId + " but should be " 3990 + task.mAffiliatedTaskId); 3991 sane = false; 3992 break; 3993 } 3994 prev = cur; 3995 endIndex++; 3996 if (endIndex >= N) { 3997 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3998 + ": last task " + prev); 3999 sane = false; 4000 break; 4001 } 4002 } 4003 if (sane) { 4004 if (endIndex < taskIndex) { 4005 Slog.wtf(TAG, "Bad chain @" + endIndex 4006 + ": did not extend to task " + task + " @" + taskIndex); 4007 sane = false; 4008 } 4009 } 4010 if (sane) { 4011 // All looks good, we can just move all of the affiliated tasks 4012 // to the top. 4013 for (int i=topIndex; i<=endIndex; i++) { 4014 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4015 + " from " + i + " to " + (i-topIndex)); 4016 TaskRecord cur = mRecentTasks.remove(i); 4017 mRecentTasks.add(i-topIndex, cur); 4018 } 4019 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4020 + " to " + endIndex); 4021 return true; 4022 } 4023 4024 // Whoops, couldn't do it. 4025 return false; 4026 } 4027 4028 final void addRecentTaskLocked(TaskRecord task) { 4029 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4030 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4031 4032 int N = mRecentTasks.size(); 4033 // Quick case: check if the top-most recent task is the same. 4034 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4035 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4036 return; 4037 } 4038 // Another quick case: check if this is part of a set of affiliated 4039 // tasks that are at the top. 4040 if (isAffiliated && N > 0 && task.inRecents 4041 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4042 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4043 + " at top when adding " + task); 4044 return; 4045 } 4046 // Another quick case: never add voice sessions. 4047 if (task.voiceSession != null) { 4048 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4049 return; 4050 } 4051 4052 boolean needAffiliationFix = false; 4053 4054 // Slightly less quick case: the task is already in recents, so all we need 4055 // to do is move it. 4056 if (task.inRecents) { 4057 int taskIndex = mRecentTasks.indexOf(task); 4058 if (taskIndex >= 0) { 4059 if (!isAffiliated) { 4060 // Simple case: this is not an affiliated task, so we just move it to the front. 4061 mRecentTasks.remove(taskIndex); 4062 mRecentTasks.add(0, task); 4063 notifyTaskPersisterLocked(task, false); 4064 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4065 + " from " + taskIndex); 4066 return; 4067 } else { 4068 // More complicated: need to keep all affiliated tasks together. 4069 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4070 // All went well. 4071 return; 4072 } 4073 4074 // Uh oh... something bad in the affiliation chain, try to rebuild 4075 // everything and then go through our general path of adding a new task. 4076 needAffiliationFix = true; 4077 } 4078 } else { 4079 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4080 needAffiliationFix = true; 4081 } 4082 } 4083 4084 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4085 trimRecentsForTask(task, true); 4086 4087 N = mRecentTasks.size(); 4088 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4089 final TaskRecord tr = mRecentTasks.remove(N - 1); 4090 tr.removedFromRecents(mTaskPersister); 4091 N--; 4092 } 4093 task.inRecents = true; 4094 if (!isAffiliated || needAffiliationFix) { 4095 // If this is a simple non-affiliated task, or we had some failure trying to 4096 // handle it as part of an affilated task, then just place it at the top. 4097 mRecentTasks.add(0, task); 4098 } else if (isAffiliated) { 4099 // If this is a new affiliated task, then move all of the affiliated tasks 4100 // to the front and insert this new one. 4101 TaskRecord other = task.mNextAffiliate; 4102 if (other == null) { 4103 other = task.mPrevAffiliate; 4104 } 4105 if (other != null) { 4106 int otherIndex = mRecentTasks.indexOf(other); 4107 if (otherIndex >= 0) { 4108 // Insert new task at appropriate location. 4109 int taskIndex; 4110 if (other == task.mNextAffiliate) { 4111 // We found the index of our next affiliation, which is who is 4112 // before us in the list, so add after that point. 4113 taskIndex = otherIndex+1; 4114 } else { 4115 // We found the index of our previous affiliation, which is who is 4116 // after us in the list, so add at their position. 4117 taskIndex = otherIndex; 4118 } 4119 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4120 + taskIndex + ": " + task); 4121 mRecentTasks.add(taskIndex, task); 4122 4123 // Now move everything to the front. 4124 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4125 // All went well. 4126 return; 4127 } 4128 4129 // Uh oh... something bad in the affiliation chain, try to rebuild 4130 // everything and then go through our general path of adding a new task. 4131 needAffiliationFix = true; 4132 } else { 4133 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4134 + other); 4135 needAffiliationFix = true; 4136 } 4137 } else { 4138 if (DEBUG_RECENTS) Slog.d(TAG, 4139 "addRecent: adding affiliated task without next/prev:" + task); 4140 needAffiliationFix = true; 4141 } 4142 } 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4144 4145 if (needAffiliationFix) { 4146 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4147 cleanupRecentTasksLocked(task.userId); 4148 } 4149 } 4150 4151 /** 4152 * If needed, remove oldest existing entries in recents that are for the same kind 4153 * of task as the given one. 4154 */ 4155 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4156 int N = mRecentTasks.size(); 4157 final Intent intent = task.intent; 4158 final boolean document = intent != null && intent.isDocument(); 4159 4160 int maxRecents = task.maxRecents - 1; 4161 for (int i=0; i<N; i++) { 4162 final TaskRecord tr = mRecentTasks.get(i); 4163 if (task != tr) { 4164 if (task.userId != tr.userId) { 4165 continue; 4166 } 4167 if (i > MAX_RECENT_BITMAPS) { 4168 tr.freeLastThumbnail(); 4169 } 4170 final Intent trIntent = tr.intent; 4171 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4172 (intent == null || !intent.filterEquals(trIntent))) { 4173 continue; 4174 } 4175 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4176 if (document && trIsDocument) { 4177 // These are the same document activity (not necessarily the same doc). 4178 if (maxRecents > 0) { 4179 --maxRecents; 4180 continue; 4181 } 4182 // Hit the maximum number of documents for this task. Fall through 4183 // and remove this document from recents. 4184 } else if (document || trIsDocument) { 4185 // Only one of these is a document. Not the droid we're looking for. 4186 continue; 4187 } 4188 } 4189 4190 if (!doTrim) { 4191 // If the caller is not actually asking for a trim, just tell them we reached 4192 // a point where the trim would happen. 4193 return i; 4194 } 4195 4196 // Either task and tr are the same or, their affinities match or their intents match 4197 // and neither of them is a document, or they are documents using the same activity 4198 // and their maxRecents has been reached. 4199 tr.disposeThumbnail(); 4200 mRecentTasks.remove(i); 4201 if (task != tr) { 4202 tr.removedFromRecents(mTaskPersister); 4203 } 4204 i--; 4205 N--; 4206 if (task.intent == null) { 4207 // If the new recent task we are adding is not fully 4208 // specified, then replace it with the existing recent task. 4209 task = tr; 4210 } 4211 notifyTaskPersisterLocked(tr, false); 4212 } 4213 4214 return -1; 4215 } 4216 4217 @Override 4218 public void reportActivityFullyDrawn(IBinder token) { 4219 synchronized (this) { 4220 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4221 if (r == null) { 4222 return; 4223 } 4224 r.reportFullyDrawnLocked(); 4225 } 4226 } 4227 4228 @Override 4229 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4230 synchronized (this) { 4231 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4232 if (r == null) { 4233 return; 4234 } 4235 final long origId = Binder.clearCallingIdentity(); 4236 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4237 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4238 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4239 if (config != null) { 4240 r.frozenBeforeDestroy = true; 4241 if (!updateConfigurationLocked(config, r, false, false)) { 4242 mStackSupervisor.resumeTopActivitiesLocked(); 4243 } 4244 } 4245 Binder.restoreCallingIdentity(origId); 4246 } 4247 } 4248 4249 @Override 4250 public int getRequestedOrientation(IBinder token) { 4251 synchronized (this) { 4252 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4253 if (r == null) { 4254 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4255 } 4256 return mWindowManager.getAppOrientation(r.appToken); 4257 } 4258 } 4259 4260 /** 4261 * This is the internal entry point for handling Activity.finish(). 4262 * 4263 * @param token The Binder token referencing the Activity we want to finish. 4264 * @param resultCode Result code, if any, from this Activity. 4265 * @param resultData Result data (Intent), if any, from this Activity. 4266 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4267 * the root Activity in the task. 4268 * 4269 * @return Returns true if the activity successfully finished, or false if it is still running. 4270 */ 4271 @Override 4272 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4273 boolean finishTask) { 4274 // Refuse possible leaked file descriptors 4275 if (resultData != null && resultData.hasFileDescriptors() == true) { 4276 throw new IllegalArgumentException("File descriptors passed in Intent"); 4277 } 4278 4279 synchronized(this) { 4280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4281 if (r == null) { 4282 return true; 4283 } 4284 // Keep track of the root activity of the task before we finish it 4285 TaskRecord tr = r.task; 4286 ActivityRecord rootR = tr.getRootActivity(); 4287 // Do not allow task to finish in Lock Task mode. 4288 if (tr == mStackSupervisor.mLockTaskModeTask) { 4289 if (rootR == r) { 4290 mStackSupervisor.showLockTaskToast(); 4291 return false; 4292 } 4293 } 4294 if (mController != null) { 4295 // Find the first activity that is not finishing. 4296 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4297 if (next != null) { 4298 // ask watcher if this is allowed 4299 boolean resumeOK = true; 4300 try { 4301 resumeOK = mController.activityResuming(next.packageName); 4302 } catch (RemoteException e) { 4303 mController = null; 4304 Watchdog.getInstance().setActivityController(null); 4305 } 4306 4307 if (!resumeOK) { 4308 return false; 4309 } 4310 } 4311 } 4312 final long origId = Binder.clearCallingIdentity(); 4313 try { 4314 boolean res; 4315 if (finishTask && r == rootR) { 4316 // If requested, remove the task that is associated to this activity only if it 4317 // was the root activity in the task. The result code and data is ignored 4318 // because we don't support returning them across task boundaries. 4319 res = removeTaskByIdLocked(tr.taskId, false); 4320 } else { 4321 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4322 resultData, "app-request", true); 4323 } 4324 return res; 4325 } finally { 4326 Binder.restoreCallingIdentity(origId); 4327 } 4328 } 4329 } 4330 4331 @Override 4332 public final void finishHeavyWeightApp() { 4333 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4334 != PackageManager.PERMISSION_GRANTED) { 4335 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4336 + Binder.getCallingPid() 4337 + ", uid=" + Binder.getCallingUid() 4338 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4339 Slog.w(TAG, msg); 4340 throw new SecurityException(msg); 4341 } 4342 4343 synchronized(this) { 4344 if (mHeavyWeightProcess == null) { 4345 return; 4346 } 4347 4348 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4349 mHeavyWeightProcess.activities); 4350 for (int i=0; i<activities.size(); i++) { 4351 ActivityRecord r = activities.get(i); 4352 if (!r.finishing) { 4353 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4354 null, "finish-heavy", true); 4355 } 4356 } 4357 4358 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4359 mHeavyWeightProcess.userId, 0)); 4360 mHeavyWeightProcess = null; 4361 } 4362 } 4363 4364 @Override 4365 public void crashApplication(int uid, int initialPid, String packageName, 4366 String message) { 4367 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4368 != PackageManager.PERMISSION_GRANTED) { 4369 String msg = "Permission Denial: crashApplication() from pid=" 4370 + Binder.getCallingPid() 4371 + ", uid=" + Binder.getCallingUid() 4372 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4373 Slog.w(TAG, msg); 4374 throw new SecurityException(msg); 4375 } 4376 4377 synchronized(this) { 4378 ProcessRecord proc = null; 4379 4380 // Figure out which process to kill. We don't trust that initialPid 4381 // still has any relation to current pids, so must scan through the 4382 // list. 4383 synchronized (mPidsSelfLocked) { 4384 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4385 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4386 if (p.uid != uid) { 4387 continue; 4388 } 4389 if (p.pid == initialPid) { 4390 proc = p; 4391 break; 4392 } 4393 if (p.pkgList.containsKey(packageName)) { 4394 proc = p; 4395 } 4396 } 4397 } 4398 4399 if (proc == null) { 4400 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4401 + " initialPid=" + initialPid 4402 + " packageName=" + packageName); 4403 return; 4404 } 4405 4406 if (proc.thread != null) { 4407 if (proc.pid == Process.myPid()) { 4408 Log.w(TAG, "crashApplication: trying to crash self!"); 4409 return; 4410 } 4411 long ident = Binder.clearCallingIdentity(); 4412 try { 4413 proc.thread.scheduleCrash(message); 4414 } catch (RemoteException e) { 4415 } 4416 Binder.restoreCallingIdentity(ident); 4417 } 4418 } 4419 } 4420 4421 @Override 4422 public final void finishSubActivity(IBinder token, String resultWho, 4423 int requestCode) { 4424 synchronized(this) { 4425 final long origId = Binder.clearCallingIdentity(); 4426 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4427 if (r != null) { 4428 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4429 } 4430 Binder.restoreCallingIdentity(origId); 4431 } 4432 } 4433 4434 @Override 4435 public boolean finishActivityAffinity(IBinder token) { 4436 synchronized(this) { 4437 final long origId = Binder.clearCallingIdentity(); 4438 try { 4439 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4440 4441 ActivityRecord rootR = r.task.getRootActivity(); 4442 // Do not allow task to finish in Lock Task mode. 4443 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4444 if (rootR == r) { 4445 mStackSupervisor.showLockTaskToast(); 4446 return false; 4447 } 4448 } 4449 boolean res = false; 4450 if (r != null) { 4451 res = r.task.stack.finishActivityAffinityLocked(r); 4452 } 4453 return res; 4454 } finally { 4455 Binder.restoreCallingIdentity(origId); 4456 } 4457 } 4458 } 4459 4460 @Override 4461 public void finishVoiceTask(IVoiceInteractionSession session) { 4462 synchronized(this) { 4463 final long origId = Binder.clearCallingIdentity(); 4464 try { 4465 mStackSupervisor.finishVoiceTask(session); 4466 } finally { 4467 Binder.restoreCallingIdentity(origId); 4468 } 4469 } 4470 4471 } 4472 4473 @Override 4474 public boolean releaseActivityInstance(IBinder token) { 4475 synchronized(this) { 4476 final long origId = Binder.clearCallingIdentity(); 4477 try { 4478 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4479 if (r.task == null || r.task.stack == null) { 4480 return false; 4481 } 4482 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4483 } finally { 4484 Binder.restoreCallingIdentity(origId); 4485 } 4486 } 4487 } 4488 4489 @Override 4490 public void releaseSomeActivities(IApplicationThread appInt) { 4491 synchronized(this) { 4492 final long origId = Binder.clearCallingIdentity(); 4493 try { 4494 ProcessRecord app = getRecordForAppLocked(appInt); 4495 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4496 } finally { 4497 Binder.restoreCallingIdentity(origId); 4498 } 4499 } 4500 } 4501 4502 @Override 4503 public boolean willActivityBeVisible(IBinder token) { 4504 synchronized(this) { 4505 ActivityStack stack = ActivityRecord.getStackLocked(token); 4506 if (stack != null) { 4507 return stack.willActivityBeVisibleLocked(token); 4508 } 4509 return false; 4510 } 4511 } 4512 4513 @Override 4514 public void overridePendingTransition(IBinder token, String packageName, 4515 int enterAnim, int exitAnim) { 4516 synchronized(this) { 4517 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4518 if (self == null) { 4519 return; 4520 } 4521 4522 final long origId = Binder.clearCallingIdentity(); 4523 4524 if (self.state == ActivityState.RESUMED 4525 || self.state == ActivityState.PAUSING) { 4526 mWindowManager.overridePendingAppTransition(packageName, 4527 enterAnim, exitAnim, null); 4528 } 4529 4530 Binder.restoreCallingIdentity(origId); 4531 } 4532 } 4533 4534 /** 4535 * Main function for removing an existing process from the activity manager 4536 * as a result of that process going away. Clears out all connections 4537 * to the process. 4538 */ 4539 private final void handleAppDiedLocked(ProcessRecord app, 4540 boolean restarting, boolean allowRestart) { 4541 int pid = app.pid; 4542 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4543 if (!kept && !restarting) { 4544 removeLruProcessLocked(app); 4545 if (pid > 0) { 4546 ProcessList.remove(pid); 4547 } 4548 } 4549 4550 if (mProfileProc == app) { 4551 clearProfilerLocked(); 4552 } 4553 4554 // Remove this application's activities from active lists. 4555 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4556 4557 app.activities.clear(); 4558 4559 if (app.instrumentationClass != null) { 4560 Slog.w(TAG, "Crash of app " + app.processName 4561 + " running instrumentation " + app.instrumentationClass); 4562 Bundle info = new Bundle(); 4563 info.putString("shortMsg", "Process crashed."); 4564 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4565 } 4566 4567 if (!restarting) { 4568 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4569 // If there was nothing to resume, and we are not already 4570 // restarting this process, but there is a visible activity that 4571 // is hosted by the process... then make sure all visible 4572 // activities are running, taking care of restarting this 4573 // process. 4574 if (hasVisibleActivities) { 4575 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4576 } 4577 } 4578 } 4579 } 4580 4581 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4582 IBinder threadBinder = thread.asBinder(); 4583 // Find the application record. 4584 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4585 ProcessRecord rec = mLruProcesses.get(i); 4586 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4587 return i; 4588 } 4589 } 4590 return -1; 4591 } 4592 4593 final ProcessRecord getRecordForAppLocked( 4594 IApplicationThread thread) { 4595 if (thread == null) { 4596 return null; 4597 } 4598 4599 int appIndex = getLRURecordIndexForAppLocked(thread); 4600 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4601 } 4602 4603 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4604 // If there are no longer any background processes running, 4605 // and the app that died was not running instrumentation, 4606 // then tell everyone we are now low on memory. 4607 boolean haveBg = false; 4608 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4609 ProcessRecord rec = mLruProcesses.get(i); 4610 if (rec.thread != null 4611 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4612 haveBg = true; 4613 break; 4614 } 4615 } 4616 4617 if (!haveBg) { 4618 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4619 if (doReport) { 4620 long now = SystemClock.uptimeMillis(); 4621 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4622 doReport = false; 4623 } else { 4624 mLastMemUsageReportTime = now; 4625 } 4626 } 4627 final ArrayList<ProcessMemInfo> memInfos 4628 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4629 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4630 long now = SystemClock.uptimeMillis(); 4631 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4632 ProcessRecord rec = mLruProcesses.get(i); 4633 if (rec == dyingProc || rec.thread == null) { 4634 continue; 4635 } 4636 if (doReport) { 4637 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4638 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4639 } 4640 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4641 // The low memory report is overriding any current 4642 // state for a GC request. Make sure to do 4643 // heavy/important/visible/foreground processes first. 4644 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4645 rec.lastRequestedGc = 0; 4646 } else { 4647 rec.lastRequestedGc = rec.lastLowMemory; 4648 } 4649 rec.reportLowMemory = true; 4650 rec.lastLowMemory = now; 4651 mProcessesToGc.remove(rec); 4652 addProcessToGcListLocked(rec); 4653 } 4654 } 4655 if (doReport) { 4656 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4657 mHandler.sendMessage(msg); 4658 } 4659 scheduleAppGcsLocked(); 4660 } 4661 } 4662 4663 final void appDiedLocked(ProcessRecord app) { 4664 appDiedLocked(app, app.pid, app.thread); 4665 } 4666 4667 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4668 // First check if this ProcessRecord is actually active for the pid. 4669 synchronized (mPidsSelfLocked) { 4670 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4671 if (curProc != app) { 4672 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4673 return; 4674 } 4675 } 4676 4677 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4678 synchronized (stats) { 4679 stats.noteProcessDiedLocked(app.info.uid, pid); 4680 } 4681 4682 Process.killProcessQuiet(pid); 4683 Process.killProcessGroup(app.info.uid, pid); 4684 app.killed = true; 4685 4686 // Clean up already done if the process has been re-started. 4687 if (app.pid == pid && app.thread != null && 4688 app.thread.asBinder() == thread.asBinder()) { 4689 boolean doLowMem = app.instrumentationClass == null; 4690 boolean doOomAdj = doLowMem; 4691 if (!app.killedByAm) { 4692 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4693 + ") has died"); 4694 mAllowLowerMemLevel = true; 4695 } else { 4696 // Note that we always want to do oom adj to update our state with the 4697 // new number of procs. 4698 mAllowLowerMemLevel = false; 4699 doLowMem = false; 4700 } 4701 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4702 if (DEBUG_CLEANUP) Slog.v( 4703 TAG, "Dying app: " + app + ", pid: " + pid 4704 + ", thread: " + thread.asBinder()); 4705 handleAppDiedLocked(app, false, true); 4706 4707 if (doOomAdj) { 4708 updateOomAdjLocked(); 4709 } 4710 if (doLowMem) { 4711 doLowMemReportIfNeededLocked(app); 4712 } 4713 } else if (app.pid != pid) { 4714 // A new process has already been started. 4715 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4716 + ") has died and restarted (pid " + app.pid + ")."); 4717 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4718 } else if (DEBUG_PROCESSES) { 4719 Slog.d(TAG, "Received spurious death notification for thread " 4720 + thread.asBinder()); 4721 } 4722 } 4723 4724 /** 4725 * If a stack trace dump file is configured, dump process stack traces. 4726 * @param clearTraces causes the dump file to be erased prior to the new 4727 * traces being written, if true; when false, the new traces will be 4728 * appended to any existing file content. 4729 * @param firstPids of dalvik VM processes to dump stack traces for first 4730 * @param lastPids of dalvik VM processes to dump stack traces for last 4731 * @param nativeProcs optional list of native process names to dump stack crawls 4732 * @return file containing stack traces, or null if no dump file is configured 4733 */ 4734 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4735 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4736 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4737 if (tracesPath == null || tracesPath.length() == 0) { 4738 return null; 4739 } 4740 4741 File tracesFile = new File(tracesPath); 4742 try { 4743 File tracesDir = tracesFile.getParentFile(); 4744 if (!tracesDir.exists()) { 4745 tracesDir.mkdirs(); 4746 if (!SELinux.restorecon(tracesDir)) { 4747 return null; 4748 } 4749 } 4750 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4751 4752 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4753 tracesFile.createNewFile(); 4754 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4755 } catch (IOException e) { 4756 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4757 return null; 4758 } 4759 4760 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4761 return tracesFile; 4762 } 4763 4764 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4765 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4766 // Use a FileObserver to detect when traces finish writing. 4767 // The order of traces is considered important to maintain for legibility. 4768 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4769 @Override 4770 public synchronized void onEvent(int event, String path) { notify(); } 4771 }; 4772 4773 try { 4774 observer.startWatching(); 4775 4776 // First collect all of the stacks of the most important pids. 4777 if (firstPids != null) { 4778 try { 4779 int num = firstPids.size(); 4780 for (int i = 0; i < num; i++) { 4781 synchronized (observer) { 4782 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4783 observer.wait(200); // Wait for write-close, give up after 200msec 4784 } 4785 } 4786 } catch (InterruptedException e) { 4787 Slog.wtf(TAG, e); 4788 } 4789 } 4790 4791 // Next collect the stacks of the native pids 4792 if (nativeProcs != null) { 4793 int[] pids = Process.getPidsForCommands(nativeProcs); 4794 if (pids != null) { 4795 for (int pid : pids) { 4796 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4797 } 4798 } 4799 } 4800 4801 // Lastly, measure CPU usage. 4802 if (processCpuTracker != null) { 4803 processCpuTracker.init(); 4804 System.gc(); 4805 processCpuTracker.update(); 4806 try { 4807 synchronized (processCpuTracker) { 4808 processCpuTracker.wait(500); // measure over 1/2 second. 4809 } 4810 } catch (InterruptedException e) { 4811 } 4812 processCpuTracker.update(); 4813 4814 // We'll take the stack crawls of just the top apps using CPU. 4815 final int N = processCpuTracker.countWorkingStats(); 4816 int numProcs = 0; 4817 for (int i=0; i<N && numProcs<5; i++) { 4818 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4819 if (lastPids.indexOfKey(stats.pid) >= 0) { 4820 numProcs++; 4821 try { 4822 synchronized (observer) { 4823 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4824 observer.wait(200); // Wait for write-close, give up after 200msec 4825 } 4826 } catch (InterruptedException e) { 4827 Slog.wtf(TAG, e); 4828 } 4829 4830 } 4831 } 4832 } 4833 } finally { 4834 observer.stopWatching(); 4835 } 4836 } 4837 4838 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4839 if (true || IS_USER_BUILD) { 4840 return; 4841 } 4842 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4843 if (tracesPath == null || tracesPath.length() == 0) { 4844 return; 4845 } 4846 4847 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4848 StrictMode.allowThreadDiskWrites(); 4849 try { 4850 final File tracesFile = new File(tracesPath); 4851 final File tracesDir = tracesFile.getParentFile(); 4852 final File tracesTmp = new File(tracesDir, "__tmp__"); 4853 try { 4854 if (!tracesDir.exists()) { 4855 tracesDir.mkdirs(); 4856 if (!SELinux.restorecon(tracesDir.getPath())) { 4857 return; 4858 } 4859 } 4860 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4861 4862 if (tracesFile.exists()) { 4863 tracesTmp.delete(); 4864 tracesFile.renameTo(tracesTmp); 4865 } 4866 StringBuilder sb = new StringBuilder(); 4867 Time tobj = new Time(); 4868 tobj.set(System.currentTimeMillis()); 4869 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4870 sb.append(": "); 4871 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4872 sb.append(" since "); 4873 sb.append(msg); 4874 FileOutputStream fos = new FileOutputStream(tracesFile); 4875 fos.write(sb.toString().getBytes()); 4876 if (app == null) { 4877 fos.write("\n*** No application process!".getBytes()); 4878 } 4879 fos.close(); 4880 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4881 } catch (IOException e) { 4882 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4883 return; 4884 } 4885 4886 if (app != null) { 4887 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4888 firstPids.add(app.pid); 4889 dumpStackTraces(tracesPath, firstPids, null, null, null); 4890 } 4891 4892 File lastTracesFile = null; 4893 File curTracesFile = null; 4894 for (int i=9; i>=0; i--) { 4895 String name = String.format(Locale.US, "slow%02d.txt", i); 4896 curTracesFile = new File(tracesDir, name); 4897 if (curTracesFile.exists()) { 4898 if (lastTracesFile != null) { 4899 curTracesFile.renameTo(lastTracesFile); 4900 } else { 4901 curTracesFile.delete(); 4902 } 4903 } 4904 lastTracesFile = curTracesFile; 4905 } 4906 tracesFile.renameTo(curTracesFile); 4907 if (tracesTmp.exists()) { 4908 tracesTmp.renameTo(tracesFile); 4909 } 4910 } finally { 4911 StrictMode.setThreadPolicy(oldPolicy); 4912 } 4913 } 4914 4915 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4916 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4917 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4918 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4919 4920 if (mController != null) { 4921 try { 4922 // 0 == continue, -1 = kill process immediately 4923 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4924 if (res < 0 && app.pid != MY_PID) { 4925 app.kill("anr", true); 4926 } 4927 } catch (RemoteException e) { 4928 mController = null; 4929 Watchdog.getInstance().setActivityController(null); 4930 } 4931 } 4932 4933 long anrTime = SystemClock.uptimeMillis(); 4934 if (MONITOR_CPU_USAGE) { 4935 updateCpuStatsNow(); 4936 } 4937 4938 synchronized (this) { 4939 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4940 if (mShuttingDown) { 4941 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4942 return; 4943 } else if (app.notResponding) { 4944 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4945 return; 4946 } else if (app.crashing) { 4947 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4948 return; 4949 } 4950 4951 // In case we come through here for the same app before completing 4952 // this one, mark as anring now so we will bail out. 4953 app.notResponding = true; 4954 4955 // Log the ANR to the event log. 4956 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4957 app.processName, app.info.flags, annotation); 4958 4959 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4960 firstPids.add(app.pid); 4961 4962 int parentPid = app.pid; 4963 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4964 if (parentPid != app.pid) firstPids.add(parentPid); 4965 4966 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4967 4968 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4969 ProcessRecord r = mLruProcesses.get(i); 4970 if (r != null && r.thread != null) { 4971 int pid = r.pid; 4972 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4973 if (r.persistent) { 4974 firstPids.add(pid); 4975 } else { 4976 lastPids.put(pid, Boolean.TRUE); 4977 } 4978 } 4979 } 4980 } 4981 } 4982 4983 // Log the ANR to the main log. 4984 StringBuilder info = new StringBuilder(); 4985 info.setLength(0); 4986 info.append("ANR in ").append(app.processName); 4987 if (activity != null && activity.shortComponentName != null) { 4988 info.append(" (").append(activity.shortComponentName).append(")"); 4989 } 4990 info.append("\n"); 4991 info.append("PID: ").append(app.pid).append("\n"); 4992 if (annotation != null) { 4993 info.append("Reason: ").append(annotation).append("\n"); 4994 } 4995 if (parent != null && parent != activity) { 4996 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4997 } 4998 4999 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5000 5001 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5002 NATIVE_STACKS_OF_INTEREST); 5003 5004 String cpuInfo = null; 5005 if (MONITOR_CPU_USAGE) { 5006 updateCpuStatsNow(); 5007 synchronized (mProcessCpuTracker) { 5008 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5009 } 5010 info.append(processCpuTracker.printCurrentLoad()); 5011 info.append(cpuInfo); 5012 } 5013 5014 info.append(processCpuTracker.printCurrentState(anrTime)); 5015 5016 Slog.e(TAG, info.toString()); 5017 if (tracesFile == null) { 5018 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5019 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5020 } 5021 5022 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5023 cpuInfo, tracesFile, null); 5024 5025 if (mController != null) { 5026 try { 5027 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5028 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5029 if (res != 0) { 5030 if (res < 0 && app.pid != MY_PID) { 5031 app.kill("anr", true); 5032 } else { 5033 synchronized (this) { 5034 mServices.scheduleServiceTimeoutLocked(app); 5035 } 5036 } 5037 return; 5038 } 5039 } catch (RemoteException e) { 5040 mController = null; 5041 Watchdog.getInstance().setActivityController(null); 5042 } 5043 } 5044 5045 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5046 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5047 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5048 5049 synchronized (this) { 5050 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5051 app.kill("bg anr", true); 5052 return; 5053 } 5054 5055 // Set the app's notResponding state, and look up the errorReportReceiver 5056 makeAppNotRespondingLocked(app, 5057 activity != null ? activity.shortComponentName : null, 5058 annotation != null ? "ANR " + annotation : "ANR", 5059 info.toString()); 5060 5061 // Bring up the infamous App Not Responding dialog 5062 Message msg = Message.obtain(); 5063 HashMap<String, Object> map = new HashMap<String, Object>(); 5064 msg.what = SHOW_NOT_RESPONDING_MSG; 5065 msg.obj = map; 5066 msg.arg1 = aboveSystem ? 1 : 0; 5067 map.put("app", app); 5068 if (activity != null) { 5069 map.put("activity", activity); 5070 } 5071 5072 mHandler.sendMessage(msg); 5073 } 5074 } 5075 5076 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5077 if (!mLaunchWarningShown) { 5078 mLaunchWarningShown = true; 5079 mHandler.post(new Runnable() { 5080 @Override 5081 public void run() { 5082 synchronized (ActivityManagerService.this) { 5083 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5084 d.show(); 5085 mHandler.postDelayed(new Runnable() { 5086 @Override 5087 public void run() { 5088 synchronized (ActivityManagerService.this) { 5089 d.dismiss(); 5090 mLaunchWarningShown = false; 5091 } 5092 } 5093 }, 4000); 5094 } 5095 } 5096 }); 5097 } 5098 } 5099 5100 @Override 5101 public boolean clearApplicationUserData(final String packageName, 5102 final IPackageDataObserver observer, int userId) { 5103 enforceNotIsolatedCaller("clearApplicationUserData"); 5104 int uid = Binder.getCallingUid(); 5105 int pid = Binder.getCallingPid(); 5106 userId = handleIncomingUser(pid, uid, 5107 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5108 long callingId = Binder.clearCallingIdentity(); 5109 try { 5110 IPackageManager pm = AppGlobals.getPackageManager(); 5111 int pkgUid = -1; 5112 synchronized(this) { 5113 try { 5114 pkgUid = pm.getPackageUid(packageName, userId); 5115 } catch (RemoteException e) { 5116 } 5117 if (pkgUid == -1) { 5118 Slog.w(TAG, "Invalid packageName: " + packageName); 5119 if (observer != null) { 5120 try { 5121 observer.onRemoveCompleted(packageName, false); 5122 } catch (RemoteException e) { 5123 Slog.i(TAG, "Observer no longer exists."); 5124 } 5125 } 5126 return false; 5127 } 5128 if (uid == pkgUid || checkComponentPermission( 5129 android.Manifest.permission.CLEAR_APP_USER_DATA, 5130 pid, uid, -1, true) 5131 == PackageManager.PERMISSION_GRANTED) { 5132 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5133 } else { 5134 throw new SecurityException("PID " + pid + " does not have permission " 5135 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5136 + " of package " + packageName); 5137 } 5138 5139 // Remove all tasks match the cleared application package and user 5140 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5141 final TaskRecord tr = mRecentTasks.get(i); 5142 final String taskPackageName = 5143 tr.getBaseIntent().getComponent().getPackageName(); 5144 if (tr.userId != userId) continue; 5145 if (!taskPackageName.equals(packageName)) continue; 5146 removeTaskByIdLocked(tr.taskId, false); 5147 } 5148 } 5149 5150 try { 5151 // Clear application user data 5152 pm.clearApplicationUserData(packageName, observer, userId); 5153 5154 synchronized(this) { 5155 // Remove all permissions granted from/to this package 5156 removeUriPermissionsForPackageLocked(packageName, userId, true); 5157 } 5158 5159 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5160 Uri.fromParts("package", packageName, null)); 5161 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5162 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5163 null, null, 0, null, null, null, false, false, userId); 5164 } catch (RemoteException e) { 5165 } 5166 } finally { 5167 Binder.restoreCallingIdentity(callingId); 5168 } 5169 return true; 5170 } 5171 5172 @Override 5173 public void killBackgroundProcesses(final String packageName, int userId) { 5174 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5175 != PackageManager.PERMISSION_GRANTED && 5176 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5177 != PackageManager.PERMISSION_GRANTED) { 5178 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5179 + Binder.getCallingPid() 5180 + ", uid=" + Binder.getCallingUid() 5181 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5182 Slog.w(TAG, msg); 5183 throw new SecurityException(msg); 5184 } 5185 5186 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5187 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5188 long callingId = Binder.clearCallingIdentity(); 5189 try { 5190 IPackageManager pm = AppGlobals.getPackageManager(); 5191 synchronized(this) { 5192 int appId = -1; 5193 try { 5194 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5195 } catch (RemoteException e) { 5196 } 5197 if (appId == -1) { 5198 Slog.w(TAG, "Invalid packageName: " + packageName); 5199 return; 5200 } 5201 killPackageProcessesLocked(packageName, appId, userId, 5202 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5203 } 5204 } finally { 5205 Binder.restoreCallingIdentity(callingId); 5206 } 5207 } 5208 5209 @Override 5210 public void killAllBackgroundProcesses() { 5211 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5212 != PackageManager.PERMISSION_GRANTED) { 5213 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5214 + Binder.getCallingPid() 5215 + ", uid=" + Binder.getCallingUid() 5216 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5217 Slog.w(TAG, msg); 5218 throw new SecurityException(msg); 5219 } 5220 5221 long callingId = Binder.clearCallingIdentity(); 5222 try { 5223 synchronized(this) { 5224 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5225 final int NP = mProcessNames.getMap().size(); 5226 for (int ip=0; ip<NP; ip++) { 5227 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5228 final int NA = apps.size(); 5229 for (int ia=0; ia<NA; ia++) { 5230 ProcessRecord app = apps.valueAt(ia); 5231 if (app.persistent) { 5232 // we don't kill persistent processes 5233 continue; 5234 } 5235 if (app.removed) { 5236 procs.add(app); 5237 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5238 app.removed = true; 5239 procs.add(app); 5240 } 5241 } 5242 } 5243 5244 int N = procs.size(); 5245 for (int i=0; i<N; i++) { 5246 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5247 } 5248 mAllowLowerMemLevel = true; 5249 updateOomAdjLocked(); 5250 doLowMemReportIfNeededLocked(null); 5251 } 5252 } finally { 5253 Binder.restoreCallingIdentity(callingId); 5254 } 5255 } 5256 5257 @Override 5258 public void forceStopPackage(final String packageName, int userId) { 5259 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5260 != PackageManager.PERMISSION_GRANTED) { 5261 String msg = "Permission Denial: forceStopPackage() from pid=" 5262 + Binder.getCallingPid() 5263 + ", uid=" + Binder.getCallingUid() 5264 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5265 Slog.w(TAG, msg); 5266 throw new SecurityException(msg); 5267 } 5268 final int callingPid = Binder.getCallingPid(); 5269 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5270 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5271 long callingId = Binder.clearCallingIdentity(); 5272 try { 5273 IPackageManager pm = AppGlobals.getPackageManager(); 5274 synchronized(this) { 5275 int[] users = userId == UserHandle.USER_ALL 5276 ? getUsersLocked() : new int[] { userId }; 5277 for (int user : users) { 5278 int pkgUid = -1; 5279 try { 5280 pkgUid = pm.getPackageUid(packageName, user); 5281 } catch (RemoteException e) { 5282 } 5283 if (pkgUid == -1) { 5284 Slog.w(TAG, "Invalid packageName: " + packageName); 5285 continue; 5286 } 5287 try { 5288 pm.setPackageStoppedState(packageName, true, user); 5289 } catch (RemoteException e) { 5290 } catch (IllegalArgumentException e) { 5291 Slog.w(TAG, "Failed trying to unstop package " 5292 + packageName + ": " + e); 5293 } 5294 if (isUserRunningLocked(user, false)) { 5295 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5296 } 5297 } 5298 } 5299 } finally { 5300 Binder.restoreCallingIdentity(callingId); 5301 } 5302 } 5303 5304 @Override 5305 public void addPackageDependency(String packageName) { 5306 synchronized (this) { 5307 int callingPid = Binder.getCallingPid(); 5308 if (callingPid == Process.myPid()) { 5309 // Yeah, um, no. 5310 Slog.w(TAG, "Can't addPackageDependency on system process"); 5311 return; 5312 } 5313 ProcessRecord proc; 5314 synchronized (mPidsSelfLocked) { 5315 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5316 } 5317 if (proc != null) { 5318 if (proc.pkgDeps == null) { 5319 proc.pkgDeps = new ArraySet<String>(1); 5320 } 5321 proc.pkgDeps.add(packageName); 5322 } 5323 } 5324 } 5325 5326 /* 5327 * The pkg name and app id have to be specified. 5328 */ 5329 @Override 5330 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5331 if (pkg == null) { 5332 return; 5333 } 5334 // Make sure the uid is valid. 5335 if (appid < 0) { 5336 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5337 return; 5338 } 5339 int callerUid = Binder.getCallingUid(); 5340 // Only the system server can kill an application 5341 if (callerUid == Process.SYSTEM_UID) { 5342 // Post an aysnc message to kill the application 5343 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5344 msg.arg1 = appid; 5345 msg.arg2 = 0; 5346 Bundle bundle = new Bundle(); 5347 bundle.putString("pkg", pkg); 5348 bundle.putString("reason", reason); 5349 msg.obj = bundle; 5350 mHandler.sendMessage(msg); 5351 } else { 5352 throw new SecurityException(callerUid + " cannot kill pkg: " + 5353 pkg); 5354 } 5355 } 5356 5357 @Override 5358 public void closeSystemDialogs(String reason) { 5359 enforceNotIsolatedCaller("closeSystemDialogs"); 5360 5361 final int pid = Binder.getCallingPid(); 5362 final int uid = Binder.getCallingUid(); 5363 final long origId = Binder.clearCallingIdentity(); 5364 try { 5365 synchronized (this) { 5366 // Only allow this from foreground processes, so that background 5367 // applications can't abuse it to prevent system UI from being shown. 5368 if (uid >= Process.FIRST_APPLICATION_UID) { 5369 ProcessRecord proc; 5370 synchronized (mPidsSelfLocked) { 5371 proc = mPidsSelfLocked.get(pid); 5372 } 5373 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5374 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5375 + " from background process " + proc); 5376 return; 5377 } 5378 } 5379 closeSystemDialogsLocked(reason); 5380 } 5381 } finally { 5382 Binder.restoreCallingIdentity(origId); 5383 } 5384 } 5385 5386 void closeSystemDialogsLocked(String reason) { 5387 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5388 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5389 | Intent.FLAG_RECEIVER_FOREGROUND); 5390 if (reason != null) { 5391 intent.putExtra("reason", reason); 5392 } 5393 mWindowManager.closeSystemDialogs(reason); 5394 5395 mStackSupervisor.closeSystemDialogsLocked(); 5396 5397 broadcastIntentLocked(null, null, intent, null, 5398 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5399 Process.SYSTEM_UID, UserHandle.USER_ALL); 5400 } 5401 5402 @Override 5403 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5404 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5405 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5406 for (int i=pids.length-1; i>=0; i--) { 5407 ProcessRecord proc; 5408 int oomAdj; 5409 synchronized (this) { 5410 synchronized (mPidsSelfLocked) { 5411 proc = mPidsSelfLocked.get(pids[i]); 5412 oomAdj = proc != null ? proc.setAdj : 0; 5413 } 5414 } 5415 infos[i] = new Debug.MemoryInfo(); 5416 Debug.getMemoryInfo(pids[i], infos[i]); 5417 if (proc != null) { 5418 synchronized (this) { 5419 if (proc.thread != null && proc.setAdj == oomAdj) { 5420 // Record this for posterity if the process has been stable. 5421 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5422 infos[i].getTotalUss(), false, proc.pkgList); 5423 } 5424 } 5425 } 5426 } 5427 return infos; 5428 } 5429 5430 @Override 5431 public long[] getProcessPss(int[] pids) { 5432 enforceNotIsolatedCaller("getProcessPss"); 5433 long[] pss = new long[pids.length]; 5434 for (int i=pids.length-1; i>=0; i--) { 5435 ProcessRecord proc; 5436 int oomAdj; 5437 synchronized (this) { 5438 synchronized (mPidsSelfLocked) { 5439 proc = mPidsSelfLocked.get(pids[i]); 5440 oomAdj = proc != null ? proc.setAdj : 0; 5441 } 5442 } 5443 long[] tmpUss = new long[1]; 5444 pss[i] = Debug.getPss(pids[i], tmpUss); 5445 if (proc != null) { 5446 synchronized (this) { 5447 if (proc.thread != null && proc.setAdj == oomAdj) { 5448 // Record this for posterity if the process has been stable. 5449 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5450 } 5451 } 5452 } 5453 } 5454 return pss; 5455 } 5456 5457 @Override 5458 public void killApplicationProcess(String processName, int uid) { 5459 if (processName == null) { 5460 return; 5461 } 5462 5463 int callerUid = Binder.getCallingUid(); 5464 // Only the system server can kill an application 5465 if (callerUid == Process.SYSTEM_UID) { 5466 synchronized (this) { 5467 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5468 if (app != null && app.thread != null) { 5469 try { 5470 app.thread.scheduleSuicide(); 5471 } catch (RemoteException e) { 5472 // If the other end already died, then our work here is done. 5473 } 5474 } else { 5475 Slog.w(TAG, "Process/uid not found attempting kill of " 5476 + processName + " / " + uid); 5477 } 5478 } 5479 } else { 5480 throw new SecurityException(callerUid + " cannot kill app process: " + 5481 processName); 5482 } 5483 } 5484 5485 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5486 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5487 false, true, false, false, UserHandle.getUserId(uid), reason); 5488 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5489 Uri.fromParts("package", packageName, null)); 5490 if (!mProcessesReady) { 5491 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5492 | Intent.FLAG_RECEIVER_FOREGROUND); 5493 } 5494 intent.putExtra(Intent.EXTRA_UID, uid); 5495 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5496 broadcastIntentLocked(null, null, intent, 5497 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5498 false, false, 5499 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5500 } 5501 5502 private void forceStopUserLocked(int userId, String reason) { 5503 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5504 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5506 | Intent.FLAG_RECEIVER_FOREGROUND); 5507 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5508 broadcastIntentLocked(null, null, intent, 5509 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5510 false, false, 5511 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5512 } 5513 5514 private final boolean killPackageProcessesLocked(String packageName, int appId, 5515 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5516 boolean doit, boolean evenPersistent, String reason) { 5517 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5518 5519 // Remove all processes this package may have touched: all with the 5520 // same UID (except for the system or root user), and all whose name 5521 // matches the package name. 5522 final int NP = mProcessNames.getMap().size(); 5523 for (int ip=0; ip<NP; ip++) { 5524 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5525 final int NA = apps.size(); 5526 for (int ia=0; ia<NA; ia++) { 5527 ProcessRecord app = apps.valueAt(ia); 5528 if (app.persistent && !evenPersistent) { 5529 // we don't kill persistent processes 5530 continue; 5531 } 5532 if (app.removed) { 5533 if (doit) { 5534 procs.add(app); 5535 } 5536 continue; 5537 } 5538 5539 // Skip process if it doesn't meet our oom adj requirement. 5540 if (app.setAdj < minOomAdj) { 5541 continue; 5542 } 5543 5544 // If no package is specified, we call all processes under the 5545 // give user id. 5546 if (packageName == null) { 5547 if (app.userId != userId) { 5548 continue; 5549 } 5550 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5551 continue; 5552 } 5553 // Package has been specified, we want to hit all processes 5554 // that match it. We need to qualify this by the processes 5555 // that are running under the specified app and user ID. 5556 } else { 5557 final boolean isDep = app.pkgDeps != null 5558 && app.pkgDeps.contains(packageName); 5559 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5560 continue; 5561 } 5562 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5563 continue; 5564 } 5565 if (!app.pkgList.containsKey(packageName) && !isDep) { 5566 continue; 5567 } 5568 } 5569 5570 // Process has passed all conditions, kill it! 5571 if (!doit) { 5572 return true; 5573 } 5574 app.removed = true; 5575 procs.add(app); 5576 } 5577 } 5578 5579 int N = procs.size(); 5580 for (int i=0; i<N; i++) { 5581 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5582 } 5583 updateOomAdjLocked(); 5584 return N > 0; 5585 } 5586 5587 private final boolean forceStopPackageLocked(String name, int appId, 5588 boolean callerWillRestart, boolean purgeCache, boolean doit, 5589 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5590 int i; 5591 int N; 5592 5593 if (userId == UserHandle.USER_ALL && name == null) { 5594 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5595 } 5596 5597 if (appId < 0 && name != null) { 5598 try { 5599 appId = UserHandle.getAppId( 5600 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5601 } catch (RemoteException e) { 5602 } 5603 } 5604 5605 if (doit) { 5606 if (name != null) { 5607 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5608 + " user=" + userId + ": " + reason); 5609 } else { 5610 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5611 } 5612 5613 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5614 for (int ip=pmap.size()-1; ip>=0; ip--) { 5615 SparseArray<Long> ba = pmap.valueAt(ip); 5616 for (i=ba.size()-1; i>=0; i--) { 5617 boolean remove = false; 5618 final int entUid = ba.keyAt(i); 5619 if (name != null) { 5620 if (userId == UserHandle.USER_ALL) { 5621 if (UserHandle.getAppId(entUid) == appId) { 5622 remove = true; 5623 } 5624 } else { 5625 if (entUid == UserHandle.getUid(userId, appId)) { 5626 remove = true; 5627 } 5628 } 5629 } else if (UserHandle.getUserId(entUid) == userId) { 5630 remove = true; 5631 } 5632 if (remove) { 5633 ba.removeAt(i); 5634 } 5635 } 5636 if (ba.size() == 0) { 5637 pmap.removeAt(ip); 5638 } 5639 } 5640 } 5641 5642 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5643 -100, callerWillRestart, true, doit, evenPersistent, 5644 name == null ? ("stop user " + userId) : ("stop " + name)); 5645 5646 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5647 if (!doit) { 5648 return true; 5649 } 5650 didSomething = true; 5651 } 5652 5653 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5654 if (!doit) { 5655 return true; 5656 } 5657 didSomething = true; 5658 } 5659 5660 if (name == null) { 5661 // Remove all sticky broadcasts from this user. 5662 mStickyBroadcasts.remove(userId); 5663 } 5664 5665 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5666 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5667 userId, providers)) { 5668 if (!doit) { 5669 return true; 5670 } 5671 didSomething = true; 5672 } 5673 N = providers.size(); 5674 for (i=0; i<N; i++) { 5675 removeDyingProviderLocked(null, providers.get(i), true); 5676 } 5677 5678 // Remove transient permissions granted from/to this package/user 5679 removeUriPermissionsForPackageLocked(name, userId, false); 5680 5681 if (name == null || uninstalling) { 5682 // Remove pending intents. For now we only do this when force 5683 // stopping users, because we have some problems when doing this 5684 // for packages -- app widgets are not currently cleaned up for 5685 // such packages, so they can be left with bad pending intents. 5686 if (mIntentSenderRecords.size() > 0) { 5687 Iterator<WeakReference<PendingIntentRecord>> it 5688 = mIntentSenderRecords.values().iterator(); 5689 while (it.hasNext()) { 5690 WeakReference<PendingIntentRecord> wpir = it.next(); 5691 if (wpir == null) { 5692 it.remove(); 5693 continue; 5694 } 5695 PendingIntentRecord pir = wpir.get(); 5696 if (pir == null) { 5697 it.remove(); 5698 continue; 5699 } 5700 if (name == null) { 5701 // Stopping user, remove all objects for the user. 5702 if (pir.key.userId != userId) { 5703 // Not the same user, skip it. 5704 continue; 5705 } 5706 } else { 5707 if (UserHandle.getAppId(pir.uid) != appId) { 5708 // Different app id, skip it. 5709 continue; 5710 } 5711 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5712 // Different user, skip it. 5713 continue; 5714 } 5715 if (!pir.key.packageName.equals(name)) { 5716 // Different package, skip it. 5717 continue; 5718 } 5719 } 5720 if (!doit) { 5721 return true; 5722 } 5723 didSomething = true; 5724 it.remove(); 5725 pir.canceled = true; 5726 if (pir.key.activity != null) { 5727 pir.key.activity.pendingResults.remove(pir.ref); 5728 } 5729 } 5730 } 5731 } 5732 5733 if (doit) { 5734 if (purgeCache && name != null) { 5735 AttributeCache ac = AttributeCache.instance(); 5736 if (ac != null) { 5737 ac.removePackage(name); 5738 } 5739 } 5740 if (mBooted) { 5741 mStackSupervisor.resumeTopActivitiesLocked(); 5742 mStackSupervisor.scheduleIdleLocked(); 5743 } 5744 } 5745 5746 return didSomething; 5747 } 5748 5749 private final boolean removeProcessLocked(ProcessRecord app, 5750 boolean callerWillRestart, boolean allowRestart, String reason) { 5751 final String name = app.processName; 5752 final int uid = app.uid; 5753 if (DEBUG_PROCESSES) Slog.d( 5754 TAG, "Force removing proc " + app.toShortString() + " (" + name 5755 + "/" + uid + ")"); 5756 5757 mProcessNames.remove(name, uid); 5758 mIsolatedProcesses.remove(app.uid); 5759 if (mHeavyWeightProcess == app) { 5760 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5761 mHeavyWeightProcess.userId, 0)); 5762 mHeavyWeightProcess = null; 5763 } 5764 boolean needRestart = false; 5765 if (app.pid > 0 && app.pid != MY_PID) { 5766 int pid = app.pid; 5767 synchronized (mPidsSelfLocked) { 5768 mPidsSelfLocked.remove(pid); 5769 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5770 } 5771 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5772 if (app.isolated) { 5773 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5774 } 5775 app.kill(reason, true); 5776 handleAppDiedLocked(app, true, allowRestart); 5777 removeLruProcessLocked(app); 5778 5779 if (app.persistent && !app.isolated) { 5780 if (!callerWillRestart) { 5781 addAppLocked(app.info, false, null /* ABI override */); 5782 } else { 5783 needRestart = true; 5784 } 5785 } 5786 } else { 5787 mRemovedProcesses.add(app); 5788 } 5789 5790 return needRestart; 5791 } 5792 5793 private final void processStartTimedOutLocked(ProcessRecord app) { 5794 final int pid = app.pid; 5795 boolean gone = false; 5796 synchronized (mPidsSelfLocked) { 5797 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5798 if (knownApp != null && knownApp.thread == null) { 5799 mPidsSelfLocked.remove(pid); 5800 gone = true; 5801 } 5802 } 5803 5804 if (gone) { 5805 Slog.w(TAG, "Process " + app + " failed to attach"); 5806 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5807 pid, app.uid, app.processName); 5808 mProcessNames.remove(app.processName, app.uid); 5809 mIsolatedProcesses.remove(app.uid); 5810 if (mHeavyWeightProcess == app) { 5811 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5812 mHeavyWeightProcess.userId, 0)); 5813 mHeavyWeightProcess = null; 5814 } 5815 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5816 if (app.isolated) { 5817 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5818 } 5819 // Take care of any launching providers waiting for this process. 5820 checkAppInLaunchingProvidersLocked(app, true); 5821 // Take care of any services that are waiting for the process. 5822 mServices.processStartTimedOutLocked(app); 5823 app.kill("start timeout", true); 5824 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5825 Slog.w(TAG, "Unattached app died before backup, skipping"); 5826 try { 5827 IBackupManager bm = IBackupManager.Stub.asInterface( 5828 ServiceManager.getService(Context.BACKUP_SERVICE)); 5829 bm.agentDisconnected(app.info.packageName); 5830 } catch (RemoteException e) { 5831 // Can't happen; the backup manager is local 5832 } 5833 } 5834 if (isPendingBroadcastProcessLocked(pid)) { 5835 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5836 skipPendingBroadcastLocked(pid); 5837 } 5838 } else { 5839 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5840 } 5841 } 5842 5843 private final boolean attachApplicationLocked(IApplicationThread thread, 5844 int pid) { 5845 5846 // Find the application record that is being attached... either via 5847 // the pid if we are running in multiple processes, or just pull the 5848 // next app record if we are emulating process with anonymous threads. 5849 ProcessRecord app; 5850 if (pid != MY_PID && pid >= 0) { 5851 synchronized (mPidsSelfLocked) { 5852 app = mPidsSelfLocked.get(pid); 5853 } 5854 } else { 5855 app = null; 5856 } 5857 5858 if (app == null) { 5859 Slog.w(TAG, "No pending application record for pid " + pid 5860 + " (IApplicationThread " + thread + "); dropping process"); 5861 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5862 if (pid > 0 && pid != MY_PID) { 5863 Process.killProcessQuiet(pid); 5864 //TODO: Process.killProcessGroup(app.info.uid, pid); 5865 } else { 5866 try { 5867 thread.scheduleExit(); 5868 } catch (Exception e) { 5869 // Ignore exceptions. 5870 } 5871 } 5872 return false; 5873 } 5874 5875 // If this application record is still attached to a previous 5876 // process, clean it up now. 5877 if (app.thread != null) { 5878 handleAppDiedLocked(app, true, true); 5879 } 5880 5881 // Tell the process all about itself. 5882 5883 if (localLOGV) Slog.v( 5884 TAG, "Binding process pid " + pid + " to record " + app); 5885 5886 final String processName = app.processName; 5887 try { 5888 AppDeathRecipient adr = new AppDeathRecipient( 5889 app, pid, thread); 5890 thread.asBinder().linkToDeath(adr, 0); 5891 app.deathRecipient = adr; 5892 } catch (RemoteException e) { 5893 app.resetPackageList(mProcessStats); 5894 startProcessLocked(app, "link fail", processName); 5895 return false; 5896 } 5897 5898 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5899 5900 app.makeActive(thread, mProcessStats); 5901 app.curAdj = app.setAdj = -100; 5902 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5903 app.forcingToForeground = null; 5904 updateProcessForegroundLocked(app, false, false); 5905 app.hasShownUi = false; 5906 app.debugging = false; 5907 app.cached = false; 5908 5909 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5910 5911 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5912 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5913 5914 if (!normalMode) { 5915 Slog.i(TAG, "Launching preboot mode app: " + app); 5916 } 5917 5918 if (localLOGV) Slog.v( 5919 TAG, "New app record " + app 5920 + " thread=" + thread.asBinder() + " pid=" + pid); 5921 try { 5922 int testMode = IApplicationThread.DEBUG_OFF; 5923 if (mDebugApp != null && mDebugApp.equals(processName)) { 5924 testMode = mWaitForDebugger 5925 ? IApplicationThread.DEBUG_WAIT 5926 : IApplicationThread.DEBUG_ON; 5927 app.debugging = true; 5928 if (mDebugTransient) { 5929 mDebugApp = mOrigDebugApp; 5930 mWaitForDebugger = mOrigWaitForDebugger; 5931 } 5932 } 5933 String profileFile = app.instrumentationProfileFile; 5934 ParcelFileDescriptor profileFd = null; 5935 int samplingInterval = 0; 5936 boolean profileAutoStop = false; 5937 if (mProfileApp != null && mProfileApp.equals(processName)) { 5938 mProfileProc = app; 5939 profileFile = mProfileFile; 5940 profileFd = mProfileFd; 5941 samplingInterval = mSamplingInterval; 5942 profileAutoStop = mAutoStopProfiler; 5943 } 5944 boolean enableOpenGlTrace = false; 5945 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5946 enableOpenGlTrace = true; 5947 mOpenGlTraceApp = null; 5948 } 5949 5950 // If the app is being launched for restore or full backup, set it up specially 5951 boolean isRestrictedBackupMode = false; 5952 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5953 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5954 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5955 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5956 } 5957 5958 ensurePackageDexOpt(app.instrumentationInfo != null 5959 ? app.instrumentationInfo.packageName 5960 : app.info.packageName); 5961 if (app.instrumentationClass != null) { 5962 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5963 } 5964 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5965 + processName + " with config " + mConfiguration); 5966 ApplicationInfo appInfo = app.instrumentationInfo != null 5967 ? app.instrumentationInfo : app.info; 5968 app.compat = compatibilityInfoForPackageLocked(appInfo); 5969 if (profileFd != null) { 5970 profileFd = profileFd.dup(); 5971 } 5972 ProfilerInfo profilerInfo = profileFile == null ? null 5973 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5974 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5975 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5976 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5977 isRestrictedBackupMode || !normalMode, app.persistent, 5978 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5979 mCoreSettingsObserver.getCoreSettingsLocked()); 5980 updateLruProcessLocked(app, false, null); 5981 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5982 } catch (Exception e) { 5983 // todo: Yikes! What should we do? For now we will try to 5984 // start another process, but that could easily get us in 5985 // an infinite loop of restarting processes... 5986 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5987 5988 app.resetPackageList(mProcessStats); 5989 app.unlinkDeathRecipient(); 5990 startProcessLocked(app, "bind fail", processName); 5991 return false; 5992 } 5993 5994 // Remove this record from the list of starting applications. 5995 mPersistentStartingProcesses.remove(app); 5996 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5997 "Attach application locked removing on hold: " + app); 5998 mProcessesOnHold.remove(app); 5999 6000 boolean badApp = false; 6001 boolean didSomething = false; 6002 6003 // See if the top visible activity is waiting to run in this process... 6004 if (normalMode) { 6005 try { 6006 if (mStackSupervisor.attachApplicationLocked(app)) { 6007 didSomething = true; 6008 } 6009 } catch (Exception e) { 6010 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6011 badApp = true; 6012 } 6013 } 6014 6015 // Find any services that should be running in this process... 6016 if (!badApp) { 6017 try { 6018 didSomething |= mServices.attachApplicationLocked(app, processName); 6019 } catch (Exception e) { 6020 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6021 badApp = true; 6022 } 6023 } 6024 6025 // Check if a next-broadcast receiver is in this process... 6026 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6027 try { 6028 didSomething |= sendPendingBroadcastsLocked(app); 6029 } catch (Exception e) { 6030 // If the app died trying to launch the receiver we declare it 'bad' 6031 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6032 badApp = true; 6033 } 6034 } 6035 6036 // Check whether the next backup agent is in this process... 6037 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6038 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6039 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6040 try { 6041 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6042 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6043 mBackupTarget.backupMode); 6044 } catch (Exception e) { 6045 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6046 badApp = true; 6047 } 6048 } 6049 6050 if (badApp) { 6051 app.kill("error during init", true); 6052 handleAppDiedLocked(app, false, true); 6053 return false; 6054 } 6055 6056 if (!didSomething) { 6057 updateOomAdjLocked(); 6058 } 6059 6060 return true; 6061 } 6062 6063 @Override 6064 public final void attachApplication(IApplicationThread thread) { 6065 synchronized (this) { 6066 int callingPid = Binder.getCallingPid(); 6067 final long origId = Binder.clearCallingIdentity(); 6068 attachApplicationLocked(thread, callingPid); 6069 Binder.restoreCallingIdentity(origId); 6070 } 6071 } 6072 6073 @Override 6074 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6075 final long origId = Binder.clearCallingIdentity(); 6076 synchronized (this) { 6077 ActivityStack stack = ActivityRecord.getStackLocked(token); 6078 if (stack != null) { 6079 ActivityRecord r = 6080 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6081 if (stopProfiling) { 6082 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6083 try { 6084 mProfileFd.close(); 6085 } catch (IOException e) { 6086 } 6087 clearProfilerLocked(); 6088 } 6089 } 6090 } 6091 } 6092 Binder.restoreCallingIdentity(origId); 6093 } 6094 6095 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6096 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6097 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6098 } 6099 6100 void enableScreenAfterBoot() { 6101 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6102 SystemClock.uptimeMillis()); 6103 mWindowManager.enableScreenAfterBoot(); 6104 6105 synchronized (this) { 6106 updateEventDispatchingLocked(); 6107 } 6108 } 6109 6110 @Override 6111 public void showBootMessage(final CharSequence msg, final boolean always) { 6112 enforceNotIsolatedCaller("showBootMessage"); 6113 mWindowManager.showBootMessage(msg, always); 6114 } 6115 6116 @Override 6117 public void keyguardWaitingForActivityDrawn() { 6118 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6119 final long token = Binder.clearCallingIdentity(); 6120 try { 6121 synchronized (this) { 6122 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6123 mWindowManager.keyguardWaitingForActivityDrawn(); 6124 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6125 mLockScreenShown = LOCK_SCREEN_LEAVING; 6126 } 6127 } 6128 } finally { 6129 Binder.restoreCallingIdentity(token); 6130 } 6131 } 6132 6133 final void finishBooting() { 6134 synchronized (this) { 6135 if (!mBootAnimationComplete) { 6136 mCallFinishBooting = true; 6137 return; 6138 } 6139 mCallFinishBooting = false; 6140 } 6141 6142 // Register receivers to handle package update events 6143 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6144 6145 // Let system services know. 6146 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6147 6148 synchronized (this) { 6149 // Ensure that any processes we had put on hold are now started 6150 // up. 6151 final int NP = mProcessesOnHold.size(); 6152 if (NP > 0) { 6153 ArrayList<ProcessRecord> procs = 6154 new ArrayList<ProcessRecord>(mProcessesOnHold); 6155 for (int ip=0; ip<NP; ip++) { 6156 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6157 + procs.get(ip)); 6158 startProcessLocked(procs.get(ip), "on-hold", null); 6159 } 6160 } 6161 6162 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6163 // Start looking for apps that are abusing wake locks. 6164 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6165 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6166 // Tell anyone interested that we are done booting! 6167 SystemProperties.set("sys.boot_completed", "1"); 6168 6169 // And trigger dev.bootcomplete if we are not showing encryption progress 6170 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6171 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6172 SystemProperties.set("dev.bootcomplete", "1"); 6173 } 6174 for (int i=0; i<mStartedUsers.size(); i++) { 6175 UserStartedState uss = mStartedUsers.valueAt(i); 6176 if (uss.mState == UserStartedState.STATE_BOOTING) { 6177 uss.mState = UserStartedState.STATE_RUNNING; 6178 final int userId = mStartedUsers.keyAt(i); 6179 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6180 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6181 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6182 broadcastIntentLocked(null, null, intent, null, 6183 new IIntentReceiver.Stub() { 6184 @Override 6185 public void performReceive(Intent intent, int resultCode, 6186 String data, Bundle extras, boolean ordered, 6187 boolean sticky, int sendingUser) { 6188 synchronized (ActivityManagerService.this) { 6189 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6190 true, false); 6191 } 6192 } 6193 }, 6194 0, null, null, 6195 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6196 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6197 userId); 6198 } 6199 } 6200 scheduleStartProfilesLocked(); 6201 } 6202 } 6203 } 6204 6205 @Override 6206 public void bootAnimationComplete() { 6207 final boolean callFinishBooting; 6208 synchronized (this) { 6209 callFinishBooting = mCallFinishBooting; 6210 mBootAnimationComplete = true; 6211 } 6212 if (callFinishBooting) { 6213 finishBooting(); 6214 } 6215 } 6216 6217 final void ensureBootCompleted() { 6218 boolean booting; 6219 boolean enableScreen; 6220 synchronized (this) { 6221 booting = mBooting; 6222 mBooting = false; 6223 enableScreen = !mBooted; 6224 mBooted = true; 6225 } 6226 6227 if (booting) { 6228 finishBooting(); 6229 } 6230 6231 if (enableScreen) { 6232 enableScreenAfterBoot(); 6233 } 6234 } 6235 6236 @Override 6237 public final void activityResumed(IBinder token) { 6238 final long origId = Binder.clearCallingIdentity(); 6239 synchronized(this) { 6240 ActivityStack stack = ActivityRecord.getStackLocked(token); 6241 if (stack != null) { 6242 ActivityRecord.activityResumedLocked(token); 6243 } 6244 } 6245 Binder.restoreCallingIdentity(origId); 6246 } 6247 6248 @Override 6249 public final void activityPaused(IBinder token) { 6250 final long origId = Binder.clearCallingIdentity(); 6251 synchronized(this) { 6252 ActivityStack stack = ActivityRecord.getStackLocked(token); 6253 if (stack != null) { 6254 stack.activityPausedLocked(token, false); 6255 } 6256 } 6257 Binder.restoreCallingIdentity(origId); 6258 } 6259 6260 @Override 6261 public final void activityStopped(IBinder token, Bundle icicle, 6262 PersistableBundle persistentState, CharSequence description) { 6263 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6264 6265 // Refuse possible leaked file descriptors 6266 if (icicle != null && icicle.hasFileDescriptors()) { 6267 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6268 } 6269 6270 final long origId = Binder.clearCallingIdentity(); 6271 6272 synchronized (this) { 6273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6274 if (r != null) { 6275 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6276 } 6277 } 6278 6279 trimApplications(); 6280 6281 Binder.restoreCallingIdentity(origId); 6282 } 6283 6284 @Override 6285 public final void activityDestroyed(IBinder token) { 6286 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6287 synchronized (this) { 6288 ActivityStack stack = ActivityRecord.getStackLocked(token); 6289 if (stack != null) { 6290 stack.activityDestroyedLocked(token); 6291 } 6292 } 6293 } 6294 6295 @Override 6296 public final void backgroundResourcesReleased(IBinder token) { 6297 final long origId = Binder.clearCallingIdentity(); 6298 try { 6299 synchronized (this) { 6300 ActivityStack stack = ActivityRecord.getStackLocked(token); 6301 if (stack != null) { 6302 stack.backgroundResourcesReleased(token); 6303 } 6304 } 6305 } finally { 6306 Binder.restoreCallingIdentity(origId); 6307 } 6308 } 6309 6310 @Override 6311 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6312 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6313 } 6314 6315 @Override 6316 public final void notifyEnterAnimationComplete(IBinder token) { 6317 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6318 } 6319 6320 @Override 6321 public String getCallingPackage(IBinder token) { 6322 synchronized (this) { 6323 ActivityRecord r = getCallingRecordLocked(token); 6324 return r != null ? r.info.packageName : null; 6325 } 6326 } 6327 6328 @Override 6329 public ComponentName getCallingActivity(IBinder token) { 6330 synchronized (this) { 6331 ActivityRecord r = getCallingRecordLocked(token); 6332 return r != null ? r.intent.getComponent() : null; 6333 } 6334 } 6335 6336 private ActivityRecord getCallingRecordLocked(IBinder token) { 6337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6338 if (r == null) { 6339 return null; 6340 } 6341 return r.resultTo; 6342 } 6343 6344 @Override 6345 public ComponentName getActivityClassForToken(IBinder token) { 6346 synchronized(this) { 6347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6348 if (r == null) { 6349 return null; 6350 } 6351 return r.intent.getComponent(); 6352 } 6353 } 6354 6355 @Override 6356 public String getPackageForToken(IBinder token) { 6357 synchronized(this) { 6358 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6359 if (r == null) { 6360 return null; 6361 } 6362 return r.packageName; 6363 } 6364 } 6365 6366 @Override 6367 public IIntentSender getIntentSender(int type, 6368 String packageName, IBinder token, String resultWho, 6369 int requestCode, Intent[] intents, String[] resolvedTypes, 6370 int flags, Bundle options, int userId) { 6371 enforceNotIsolatedCaller("getIntentSender"); 6372 // Refuse possible leaked file descriptors 6373 if (intents != null) { 6374 if (intents.length < 1) { 6375 throw new IllegalArgumentException("Intents array length must be >= 1"); 6376 } 6377 for (int i=0; i<intents.length; i++) { 6378 Intent intent = intents[i]; 6379 if (intent != null) { 6380 if (intent.hasFileDescriptors()) { 6381 throw new IllegalArgumentException("File descriptors passed in Intent"); 6382 } 6383 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6384 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6385 throw new IllegalArgumentException( 6386 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6387 } 6388 intents[i] = new Intent(intent); 6389 } 6390 } 6391 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6392 throw new IllegalArgumentException( 6393 "Intent array length does not match resolvedTypes length"); 6394 } 6395 } 6396 if (options != null) { 6397 if (options.hasFileDescriptors()) { 6398 throw new IllegalArgumentException("File descriptors passed in options"); 6399 } 6400 } 6401 6402 synchronized(this) { 6403 int callingUid = Binder.getCallingUid(); 6404 int origUserId = userId; 6405 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6406 type == ActivityManager.INTENT_SENDER_BROADCAST, 6407 ALLOW_NON_FULL, "getIntentSender", null); 6408 if (origUserId == UserHandle.USER_CURRENT) { 6409 // We don't want to evaluate this until the pending intent is 6410 // actually executed. However, we do want to always do the 6411 // security checking for it above. 6412 userId = UserHandle.USER_CURRENT; 6413 } 6414 try { 6415 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6416 int uid = AppGlobals.getPackageManager() 6417 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6418 if (!UserHandle.isSameApp(callingUid, uid)) { 6419 String msg = "Permission Denial: getIntentSender() from pid=" 6420 + Binder.getCallingPid() 6421 + ", uid=" + Binder.getCallingUid() 6422 + ", (need uid=" + uid + ")" 6423 + " is not allowed to send as package " + packageName; 6424 Slog.w(TAG, msg); 6425 throw new SecurityException(msg); 6426 } 6427 } 6428 6429 return getIntentSenderLocked(type, packageName, callingUid, userId, 6430 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6431 6432 } catch (RemoteException e) { 6433 throw new SecurityException(e); 6434 } 6435 } 6436 } 6437 6438 IIntentSender getIntentSenderLocked(int type, String packageName, 6439 int callingUid, int userId, IBinder token, String resultWho, 6440 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6441 Bundle options) { 6442 if (DEBUG_MU) 6443 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6444 ActivityRecord activity = null; 6445 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6446 activity = ActivityRecord.isInStackLocked(token); 6447 if (activity == null) { 6448 return null; 6449 } 6450 if (activity.finishing) { 6451 return null; 6452 } 6453 } 6454 6455 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6456 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6457 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6458 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6459 |PendingIntent.FLAG_UPDATE_CURRENT); 6460 6461 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6462 type, packageName, activity, resultWho, 6463 requestCode, intents, resolvedTypes, flags, options, userId); 6464 WeakReference<PendingIntentRecord> ref; 6465 ref = mIntentSenderRecords.get(key); 6466 PendingIntentRecord rec = ref != null ? ref.get() : null; 6467 if (rec != null) { 6468 if (!cancelCurrent) { 6469 if (updateCurrent) { 6470 if (rec.key.requestIntent != null) { 6471 rec.key.requestIntent.replaceExtras(intents != null ? 6472 intents[intents.length - 1] : null); 6473 } 6474 if (intents != null) { 6475 intents[intents.length-1] = rec.key.requestIntent; 6476 rec.key.allIntents = intents; 6477 rec.key.allResolvedTypes = resolvedTypes; 6478 } else { 6479 rec.key.allIntents = null; 6480 rec.key.allResolvedTypes = null; 6481 } 6482 } 6483 return rec; 6484 } 6485 rec.canceled = true; 6486 mIntentSenderRecords.remove(key); 6487 } 6488 if (noCreate) { 6489 return rec; 6490 } 6491 rec = new PendingIntentRecord(this, key, callingUid); 6492 mIntentSenderRecords.put(key, rec.ref); 6493 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6494 if (activity.pendingResults == null) { 6495 activity.pendingResults 6496 = new HashSet<WeakReference<PendingIntentRecord>>(); 6497 } 6498 activity.pendingResults.add(rec.ref); 6499 } 6500 return rec; 6501 } 6502 6503 @Override 6504 public void cancelIntentSender(IIntentSender sender) { 6505 if (!(sender instanceof PendingIntentRecord)) { 6506 return; 6507 } 6508 synchronized(this) { 6509 PendingIntentRecord rec = (PendingIntentRecord)sender; 6510 try { 6511 int uid = AppGlobals.getPackageManager() 6512 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6513 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6514 String msg = "Permission Denial: cancelIntentSender() from pid=" 6515 + Binder.getCallingPid() 6516 + ", uid=" + Binder.getCallingUid() 6517 + " is not allowed to cancel packges " 6518 + rec.key.packageName; 6519 Slog.w(TAG, msg); 6520 throw new SecurityException(msg); 6521 } 6522 } catch (RemoteException e) { 6523 throw new SecurityException(e); 6524 } 6525 cancelIntentSenderLocked(rec, true); 6526 } 6527 } 6528 6529 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6530 rec.canceled = true; 6531 mIntentSenderRecords.remove(rec.key); 6532 if (cleanActivity && rec.key.activity != null) { 6533 rec.key.activity.pendingResults.remove(rec.ref); 6534 } 6535 } 6536 6537 @Override 6538 public String getPackageForIntentSender(IIntentSender pendingResult) { 6539 if (!(pendingResult instanceof PendingIntentRecord)) { 6540 return null; 6541 } 6542 try { 6543 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6544 return res.key.packageName; 6545 } catch (ClassCastException e) { 6546 } 6547 return null; 6548 } 6549 6550 @Override 6551 public int getUidForIntentSender(IIntentSender sender) { 6552 if (sender instanceof PendingIntentRecord) { 6553 try { 6554 PendingIntentRecord res = (PendingIntentRecord)sender; 6555 return res.uid; 6556 } catch (ClassCastException e) { 6557 } 6558 } 6559 return -1; 6560 } 6561 6562 @Override 6563 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6564 if (!(pendingResult instanceof PendingIntentRecord)) { 6565 return false; 6566 } 6567 try { 6568 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6569 if (res.key.allIntents == null) { 6570 return false; 6571 } 6572 for (int i=0; i<res.key.allIntents.length; i++) { 6573 Intent intent = res.key.allIntents[i]; 6574 if (intent.getPackage() != null && intent.getComponent() != null) { 6575 return false; 6576 } 6577 } 6578 return true; 6579 } catch (ClassCastException e) { 6580 } 6581 return false; 6582 } 6583 6584 @Override 6585 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6586 if (!(pendingResult instanceof PendingIntentRecord)) { 6587 return false; 6588 } 6589 try { 6590 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6591 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6592 return true; 6593 } 6594 return false; 6595 } catch (ClassCastException e) { 6596 } 6597 return false; 6598 } 6599 6600 @Override 6601 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6602 if (!(pendingResult instanceof PendingIntentRecord)) { 6603 return null; 6604 } 6605 try { 6606 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6607 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6608 } catch (ClassCastException e) { 6609 } 6610 return null; 6611 } 6612 6613 @Override 6614 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6615 if (!(pendingResult instanceof PendingIntentRecord)) { 6616 return null; 6617 } 6618 try { 6619 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6620 Intent intent = res.key.requestIntent; 6621 if (intent != null) { 6622 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6623 || res.lastTagPrefix.equals(prefix))) { 6624 return res.lastTag; 6625 } 6626 res.lastTagPrefix = prefix; 6627 StringBuilder sb = new StringBuilder(128); 6628 if (prefix != null) { 6629 sb.append(prefix); 6630 } 6631 if (intent.getAction() != null) { 6632 sb.append(intent.getAction()); 6633 } else if (intent.getComponent() != null) { 6634 intent.getComponent().appendShortString(sb); 6635 } else { 6636 sb.append("?"); 6637 } 6638 return res.lastTag = sb.toString(); 6639 } 6640 } catch (ClassCastException e) { 6641 } 6642 return null; 6643 } 6644 6645 @Override 6646 public void setProcessLimit(int max) { 6647 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6648 "setProcessLimit()"); 6649 synchronized (this) { 6650 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6651 mProcessLimitOverride = max; 6652 } 6653 trimApplications(); 6654 } 6655 6656 @Override 6657 public int getProcessLimit() { 6658 synchronized (this) { 6659 return mProcessLimitOverride; 6660 } 6661 } 6662 6663 void foregroundTokenDied(ForegroundToken token) { 6664 synchronized (ActivityManagerService.this) { 6665 synchronized (mPidsSelfLocked) { 6666 ForegroundToken cur 6667 = mForegroundProcesses.get(token.pid); 6668 if (cur != token) { 6669 return; 6670 } 6671 mForegroundProcesses.remove(token.pid); 6672 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6673 if (pr == null) { 6674 return; 6675 } 6676 pr.forcingToForeground = null; 6677 updateProcessForegroundLocked(pr, false, false); 6678 } 6679 updateOomAdjLocked(); 6680 } 6681 } 6682 6683 @Override 6684 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6685 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6686 "setProcessForeground()"); 6687 synchronized(this) { 6688 boolean changed = false; 6689 6690 synchronized (mPidsSelfLocked) { 6691 ProcessRecord pr = mPidsSelfLocked.get(pid); 6692 if (pr == null && isForeground) { 6693 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6694 return; 6695 } 6696 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6697 if (oldToken != null) { 6698 oldToken.token.unlinkToDeath(oldToken, 0); 6699 mForegroundProcesses.remove(pid); 6700 if (pr != null) { 6701 pr.forcingToForeground = null; 6702 } 6703 changed = true; 6704 } 6705 if (isForeground && token != null) { 6706 ForegroundToken newToken = new ForegroundToken() { 6707 @Override 6708 public void binderDied() { 6709 foregroundTokenDied(this); 6710 } 6711 }; 6712 newToken.pid = pid; 6713 newToken.token = token; 6714 try { 6715 token.linkToDeath(newToken, 0); 6716 mForegroundProcesses.put(pid, newToken); 6717 pr.forcingToForeground = token; 6718 changed = true; 6719 } catch (RemoteException e) { 6720 // If the process died while doing this, we will later 6721 // do the cleanup with the process death link. 6722 } 6723 } 6724 } 6725 6726 if (changed) { 6727 updateOomAdjLocked(); 6728 } 6729 } 6730 } 6731 6732 // ========================================================= 6733 // PERMISSIONS 6734 // ========================================================= 6735 6736 static class PermissionController extends IPermissionController.Stub { 6737 ActivityManagerService mActivityManagerService; 6738 PermissionController(ActivityManagerService activityManagerService) { 6739 mActivityManagerService = activityManagerService; 6740 } 6741 6742 @Override 6743 public boolean checkPermission(String permission, int pid, int uid) { 6744 return mActivityManagerService.checkPermission(permission, pid, 6745 uid) == PackageManager.PERMISSION_GRANTED; 6746 } 6747 } 6748 6749 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6750 @Override 6751 public int checkComponentPermission(String permission, int pid, int uid, 6752 int owningUid, boolean exported) { 6753 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6754 owningUid, exported); 6755 } 6756 6757 @Override 6758 public Object getAMSLock() { 6759 return ActivityManagerService.this; 6760 } 6761 } 6762 6763 /** 6764 * This can be called with or without the global lock held. 6765 */ 6766 int checkComponentPermission(String permission, int pid, int uid, 6767 int owningUid, boolean exported) { 6768 // We might be performing an operation on behalf of an indirect binder 6769 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6770 // client identity accordingly before proceeding. 6771 Identity tlsIdentity = sCallerIdentity.get(); 6772 if (tlsIdentity != null) { 6773 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6774 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6775 uid = tlsIdentity.uid; 6776 pid = tlsIdentity.pid; 6777 } 6778 6779 if (pid == MY_PID) { 6780 return PackageManager.PERMISSION_GRANTED; 6781 } 6782 6783 return ActivityManager.checkComponentPermission(permission, uid, 6784 owningUid, exported); 6785 } 6786 6787 /** 6788 * As the only public entry point for permissions checking, this method 6789 * can enforce the semantic that requesting a check on a null global 6790 * permission is automatically denied. (Internally a null permission 6791 * string is used when calling {@link #checkComponentPermission} in cases 6792 * when only uid-based security is needed.) 6793 * 6794 * This can be called with or without the global lock held. 6795 */ 6796 @Override 6797 public int checkPermission(String permission, int pid, int uid) { 6798 if (permission == null) { 6799 return PackageManager.PERMISSION_DENIED; 6800 } 6801 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6802 } 6803 6804 /** 6805 * Binder IPC calls go through the public entry point. 6806 * This can be called with or without the global lock held. 6807 */ 6808 int checkCallingPermission(String permission) { 6809 return checkPermission(permission, 6810 Binder.getCallingPid(), 6811 UserHandle.getAppId(Binder.getCallingUid())); 6812 } 6813 6814 /** 6815 * This can be called with or without the global lock held. 6816 */ 6817 void enforceCallingPermission(String permission, String func) { 6818 if (checkCallingPermission(permission) 6819 == PackageManager.PERMISSION_GRANTED) { 6820 return; 6821 } 6822 6823 String msg = "Permission Denial: " + func + " from pid=" 6824 + Binder.getCallingPid() 6825 + ", uid=" + Binder.getCallingUid() 6826 + " requires " + permission; 6827 Slog.w(TAG, msg); 6828 throw new SecurityException(msg); 6829 } 6830 6831 /** 6832 * Determine if UID is holding permissions required to access {@link Uri} in 6833 * the given {@link ProviderInfo}. Final permission checking is always done 6834 * in {@link ContentProvider}. 6835 */ 6836 private final boolean checkHoldingPermissionsLocked( 6837 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6838 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6839 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6840 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6841 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6842 != PERMISSION_GRANTED) { 6843 return false; 6844 } 6845 } 6846 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6847 } 6848 6849 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6850 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6851 if (pi.applicationInfo.uid == uid) { 6852 return true; 6853 } else if (!pi.exported) { 6854 return false; 6855 } 6856 6857 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6858 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6859 try { 6860 // check if target holds top-level <provider> permissions 6861 if (!readMet && pi.readPermission != null && considerUidPermissions 6862 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6863 readMet = true; 6864 } 6865 if (!writeMet && pi.writePermission != null && considerUidPermissions 6866 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6867 writeMet = true; 6868 } 6869 6870 // track if unprotected read/write is allowed; any denied 6871 // <path-permission> below removes this ability 6872 boolean allowDefaultRead = pi.readPermission == null; 6873 boolean allowDefaultWrite = pi.writePermission == null; 6874 6875 // check if target holds any <path-permission> that match uri 6876 final PathPermission[] pps = pi.pathPermissions; 6877 if (pps != null) { 6878 final String path = grantUri.uri.getPath(); 6879 int i = pps.length; 6880 while (i > 0 && (!readMet || !writeMet)) { 6881 i--; 6882 PathPermission pp = pps[i]; 6883 if (pp.match(path)) { 6884 if (!readMet) { 6885 final String pprperm = pp.getReadPermission(); 6886 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6887 + pprperm + " for " + pp.getPath() 6888 + ": match=" + pp.match(path) 6889 + " check=" + pm.checkUidPermission(pprperm, uid)); 6890 if (pprperm != null) { 6891 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6892 == PERMISSION_GRANTED) { 6893 readMet = true; 6894 } else { 6895 allowDefaultRead = false; 6896 } 6897 } 6898 } 6899 if (!writeMet) { 6900 final String ppwperm = pp.getWritePermission(); 6901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6902 + ppwperm + " for " + pp.getPath() 6903 + ": match=" + pp.match(path) 6904 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6905 if (ppwperm != null) { 6906 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6907 == PERMISSION_GRANTED) { 6908 writeMet = true; 6909 } else { 6910 allowDefaultWrite = false; 6911 } 6912 } 6913 } 6914 } 6915 } 6916 } 6917 6918 // grant unprotected <provider> read/write, if not blocked by 6919 // <path-permission> above 6920 if (allowDefaultRead) readMet = true; 6921 if (allowDefaultWrite) writeMet = true; 6922 6923 } catch (RemoteException e) { 6924 return false; 6925 } 6926 6927 return readMet && writeMet; 6928 } 6929 6930 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6931 ProviderInfo pi = null; 6932 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6933 if (cpr != null) { 6934 pi = cpr.info; 6935 } else { 6936 try { 6937 pi = AppGlobals.getPackageManager().resolveContentProvider( 6938 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6939 } catch (RemoteException ex) { 6940 } 6941 } 6942 return pi; 6943 } 6944 6945 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6946 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6947 if (targetUris != null) { 6948 return targetUris.get(grantUri); 6949 } 6950 return null; 6951 } 6952 6953 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6954 String targetPkg, int targetUid, GrantUri grantUri) { 6955 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6956 if (targetUris == null) { 6957 targetUris = Maps.newArrayMap(); 6958 mGrantedUriPermissions.put(targetUid, targetUris); 6959 } 6960 6961 UriPermission perm = targetUris.get(grantUri); 6962 if (perm == null) { 6963 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6964 targetUris.put(grantUri, perm); 6965 } 6966 6967 return perm; 6968 } 6969 6970 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6971 final int modeFlags) { 6972 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6973 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6974 : UriPermission.STRENGTH_OWNED; 6975 6976 // Root gets to do everything. 6977 if (uid == 0) { 6978 return true; 6979 } 6980 6981 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6982 if (perms == null) return false; 6983 6984 // First look for exact match 6985 final UriPermission exactPerm = perms.get(grantUri); 6986 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6987 return true; 6988 } 6989 6990 // No exact match, look for prefixes 6991 final int N = perms.size(); 6992 for (int i = 0; i < N; i++) { 6993 final UriPermission perm = perms.valueAt(i); 6994 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6995 && perm.getStrength(modeFlags) >= minStrength) { 6996 return true; 6997 } 6998 } 6999 7000 return false; 7001 } 7002 7003 /** 7004 * @param uri This uri must NOT contain an embedded userId. 7005 * @param userId The userId in which the uri is to be resolved. 7006 */ 7007 @Override 7008 public int checkUriPermission(Uri uri, int pid, int uid, 7009 final int modeFlags, int userId) { 7010 enforceNotIsolatedCaller("checkUriPermission"); 7011 7012 // Another redirected-binder-call permissions check as in 7013 // {@link checkComponentPermission}. 7014 Identity tlsIdentity = sCallerIdentity.get(); 7015 if (tlsIdentity != null) { 7016 uid = tlsIdentity.uid; 7017 pid = tlsIdentity.pid; 7018 } 7019 7020 // Our own process gets to do everything. 7021 if (pid == MY_PID) { 7022 return PackageManager.PERMISSION_GRANTED; 7023 } 7024 synchronized (this) { 7025 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7026 ? PackageManager.PERMISSION_GRANTED 7027 : PackageManager.PERMISSION_DENIED; 7028 } 7029 } 7030 7031 /** 7032 * Check if the targetPkg can be granted permission to access uri by 7033 * the callingUid using the given modeFlags. Throws a security exception 7034 * if callingUid is not allowed to do this. Returns the uid of the target 7035 * if the URI permission grant should be performed; returns -1 if it is not 7036 * needed (for example targetPkg already has permission to access the URI). 7037 * If you already know the uid of the target, you can supply it in 7038 * lastTargetUid else set that to -1. 7039 */ 7040 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7041 final int modeFlags, int lastTargetUid) { 7042 if (!Intent.isAccessUriMode(modeFlags)) { 7043 return -1; 7044 } 7045 7046 if (targetPkg != null) { 7047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7048 "Checking grant " + targetPkg + " permission to " + grantUri); 7049 } 7050 7051 final IPackageManager pm = AppGlobals.getPackageManager(); 7052 7053 // If this is not a content: uri, we can't do anything with it. 7054 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7055 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7056 "Can't grant URI permission for non-content URI: " + grantUri); 7057 return -1; 7058 } 7059 7060 final String authority = grantUri.uri.getAuthority(); 7061 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7062 if (pi == null) { 7063 Slog.w(TAG, "No content provider found for permission check: " + 7064 grantUri.uri.toSafeString()); 7065 return -1; 7066 } 7067 7068 int targetUid = lastTargetUid; 7069 if (targetUid < 0 && targetPkg != null) { 7070 try { 7071 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7072 if (targetUid < 0) { 7073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7074 "Can't grant URI permission no uid for: " + targetPkg); 7075 return -1; 7076 } 7077 } catch (RemoteException ex) { 7078 return -1; 7079 } 7080 } 7081 7082 if (targetUid >= 0) { 7083 // First... does the target actually need this permission? 7084 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7085 // No need to grant the target this permission. 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Target " + targetPkg + " already has full permission to " + grantUri); 7088 return -1; 7089 } 7090 } else { 7091 // First... there is no target package, so can anyone access it? 7092 boolean allowed = pi.exported; 7093 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7094 if (pi.readPermission != null) { 7095 allowed = false; 7096 } 7097 } 7098 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7099 if (pi.writePermission != null) { 7100 allowed = false; 7101 } 7102 } 7103 if (allowed) { 7104 return -1; 7105 } 7106 } 7107 7108 /* There is a special cross user grant if: 7109 * - The target is on another user. 7110 * - Apps on the current user can access the uri without any uid permissions. 7111 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7112 * grant uri permissions. 7113 */ 7114 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7115 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7116 modeFlags, false /*without considering the uid permissions*/); 7117 7118 // Second... is the provider allowing granting of URI permissions? 7119 if (!specialCrossUserGrant) { 7120 if (!pi.grantUriPermissions) { 7121 throw new SecurityException("Provider " + pi.packageName 7122 + "/" + pi.name 7123 + " does not allow granting of Uri permissions (uri " 7124 + grantUri + ")"); 7125 } 7126 if (pi.uriPermissionPatterns != null) { 7127 final int N = pi.uriPermissionPatterns.length; 7128 boolean allowed = false; 7129 for (int i=0; i<N; i++) { 7130 if (pi.uriPermissionPatterns[i] != null 7131 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7132 allowed = true; 7133 break; 7134 } 7135 } 7136 if (!allowed) { 7137 throw new SecurityException("Provider " + pi.packageName 7138 + "/" + pi.name 7139 + " does not allow granting of permission to path of Uri " 7140 + grantUri); 7141 } 7142 } 7143 } 7144 7145 // Third... does the caller itself have permission to access 7146 // this uri? 7147 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7148 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7149 // Require they hold a strong enough Uri permission 7150 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7151 throw new SecurityException("Uid " + callingUid 7152 + " does not have permission to uri " + grantUri); 7153 } 7154 } 7155 } 7156 return targetUid; 7157 } 7158 7159 /** 7160 * @param uri This uri must NOT contain an embedded userId. 7161 * @param userId The userId in which the uri is to be resolved. 7162 */ 7163 @Override 7164 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7165 final int modeFlags, int userId) { 7166 enforceNotIsolatedCaller("checkGrantUriPermission"); 7167 synchronized(this) { 7168 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7169 new GrantUri(userId, uri, false), modeFlags, -1); 7170 } 7171 } 7172 7173 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7174 final int modeFlags, UriPermissionOwner owner) { 7175 if (!Intent.isAccessUriMode(modeFlags)) { 7176 return; 7177 } 7178 7179 // So here we are: the caller has the assumed permission 7180 // to the uri, and the target doesn't. Let's now give this to 7181 // the target. 7182 7183 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7184 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7185 7186 final String authority = grantUri.uri.getAuthority(); 7187 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7188 if (pi == null) { 7189 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7190 return; 7191 } 7192 7193 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7194 grantUri.prefix = true; 7195 } 7196 final UriPermission perm = findOrCreateUriPermissionLocked( 7197 pi.packageName, targetPkg, targetUid, grantUri); 7198 perm.grantModes(modeFlags, owner); 7199 } 7200 7201 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7202 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7203 if (targetPkg == null) { 7204 throw new NullPointerException("targetPkg"); 7205 } 7206 int targetUid; 7207 final IPackageManager pm = AppGlobals.getPackageManager(); 7208 try { 7209 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7210 } catch (RemoteException ex) { 7211 return; 7212 } 7213 7214 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7215 targetUid); 7216 if (targetUid < 0) { 7217 return; 7218 } 7219 7220 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7221 owner); 7222 } 7223 7224 static class NeededUriGrants extends ArrayList<GrantUri> { 7225 final String targetPkg; 7226 final int targetUid; 7227 final int flags; 7228 7229 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7230 this.targetPkg = targetPkg; 7231 this.targetUid = targetUid; 7232 this.flags = flags; 7233 } 7234 } 7235 7236 /** 7237 * Like checkGrantUriPermissionLocked, but takes an Intent. 7238 */ 7239 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7240 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7241 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7242 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7243 + " clip=" + (intent != null ? intent.getClipData() : null) 7244 + " from " + intent + "; flags=0x" 7245 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7246 7247 if (targetPkg == null) { 7248 throw new NullPointerException("targetPkg"); 7249 } 7250 7251 if (intent == null) { 7252 return null; 7253 } 7254 Uri data = intent.getData(); 7255 ClipData clip = intent.getClipData(); 7256 if (data == null && clip == null) { 7257 return null; 7258 } 7259 // Default userId for uris in the intent (if they don't specify it themselves) 7260 int contentUserHint = intent.getContentUserHint(); 7261 if (contentUserHint == UserHandle.USER_CURRENT) { 7262 contentUserHint = UserHandle.getUserId(callingUid); 7263 } 7264 final IPackageManager pm = AppGlobals.getPackageManager(); 7265 int targetUid; 7266 if (needed != null) { 7267 targetUid = needed.targetUid; 7268 } else { 7269 try { 7270 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7271 } catch (RemoteException ex) { 7272 return null; 7273 } 7274 if (targetUid < 0) { 7275 if (DEBUG_URI_PERMISSION) { 7276 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7277 + " on user " + targetUserId); 7278 } 7279 return null; 7280 } 7281 } 7282 if (data != null) { 7283 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7284 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7285 targetUid); 7286 if (targetUid > 0) { 7287 if (needed == null) { 7288 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7289 } 7290 needed.add(grantUri); 7291 } 7292 } 7293 if (clip != null) { 7294 for (int i=0; i<clip.getItemCount(); i++) { 7295 Uri uri = clip.getItemAt(i).getUri(); 7296 if (uri != null) { 7297 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7298 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7299 targetUid); 7300 if (targetUid > 0) { 7301 if (needed == null) { 7302 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7303 } 7304 needed.add(grantUri); 7305 } 7306 } else { 7307 Intent clipIntent = clip.getItemAt(i).getIntent(); 7308 if (clipIntent != null) { 7309 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7310 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7311 if (newNeeded != null) { 7312 needed = newNeeded; 7313 } 7314 } 7315 } 7316 } 7317 } 7318 7319 return needed; 7320 } 7321 7322 /** 7323 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7324 */ 7325 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7326 UriPermissionOwner owner) { 7327 if (needed != null) { 7328 for (int i=0; i<needed.size(); i++) { 7329 GrantUri grantUri = needed.get(i); 7330 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7331 grantUri, needed.flags, owner); 7332 } 7333 } 7334 } 7335 7336 void grantUriPermissionFromIntentLocked(int callingUid, 7337 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7338 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7339 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7340 if (needed == null) { 7341 return; 7342 } 7343 7344 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7345 } 7346 7347 /** 7348 * @param uri This uri must NOT contain an embedded userId. 7349 * @param userId The userId in which the uri is to be resolved. 7350 */ 7351 @Override 7352 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7353 final int modeFlags, int userId) { 7354 enforceNotIsolatedCaller("grantUriPermission"); 7355 GrantUri grantUri = new GrantUri(userId, uri, false); 7356 synchronized(this) { 7357 final ProcessRecord r = getRecordForAppLocked(caller); 7358 if (r == null) { 7359 throw new SecurityException("Unable to find app for caller " 7360 + caller 7361 + " when granting permission to uri " + grantUri); 7362 } 7363 if (targetPkg == null) { 7364 throw new IllegalArgumentException("null target"); 7365 } 7366 if (grantUri == null) { 7367 throw new IllegalArgumentException("null uri"); 7368 } 7369 7370 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7371 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7372 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7373 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7374 7375 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7376 UserHandle.getUserId(r.uid)); 7377 } 7378 } 7379 7380 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7381 if (perm.modeFlags == 0) { 7382 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7383 perm.targetUid); 7384 if (perms != null) { 7385 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7386 "Removing " + perm.targetUid + " permission to " + perm.uri); 7387 7388 perms.remove(perm.uri); 7389 if (perms.isEmpty()) { 7390 mGrantedUriPermissions.remove(perm.targetUid); 7391 } 7392 } 7393 } 7394 } 7395 7396 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7397 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7398 7399 final IPackageManager pm = AppGlobals.getPackageManager(); 7400 final String authority = grantUri.uri.getAuthority(); 7401 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7402 if (pi == null) { 7403 Slog.w(TAG, "No content provider found for permission revoke: " 7404 + grantUri.toSafeString()); 7405 return; 7406 } 7407 7408 // Does the caller have this permission on the URI? 7409 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7410 // If they don't have direct access to the URI, then revoke any 7411 // ownerless URI permissions that have been granted to them. 7412 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7413 if (perms != null) { 7414 boolean persistChanged = false; 7415 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7416 final UriPermission perm = it.next(); 7417 if (perm.uri.sourceUserId == grantUri.sourceUserId 7418 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7419 if (DEBUG_URI_PERMISSION) 7420 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7421 " permission to " + perm.uri); 7422 persistChanged |= perm.revokeModes( 7423 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7424 if (perm.modeFlags == 0) { 7425 it.remove(); 7426 } 7427 } 7428 } 7429 if (perms.isEmpty()) { 7430 mGrantedUriPermissions.remove(callingUid); 7431 } 7432 if (persistChanged) { 7433 schedulePersistUriGrants(); 7434 } 7435 } 7436 return; 7437 } 7438 7439 boolean persistChanged = false; 7440 7441 // Go through all of the permissions and remove any that match. 7442 int N = mGrantedUriPermissions.size(); 7443 for (int i = 0; i < N; i++) { 7444 final int targetUid = mGrantedUriPermissions.keyAt(i); 7445 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7446 7447 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7448 final UriPermission perm = it.next(); 7449 if (perm.uri.sourceUserId == grantUri.sourceUserId 7450 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7451 if (DEBUG_URI_PERMISSION) 7452 Slog.v(TAG, 7453 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7454 persistChanged |= perm.revokeModes( 7455 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7456 if (perm.modeFlags == 0) { 7457 it.remove(); 7458 } 7459 } 7460 } 7461 7462 if (perms.isEmpty()) { 7463 mGrantedUriPermissions.remove(targetUid); 7464 N--; 7465 i--; 7466 } 7467 } 7468 7469 if (persistChanged) { 7470 schedulePersistUriGrants(); 7471 } 7472 } 7473 7474 /** 7475 * @param uri This uri must NOT contain an embedded userId. 7476 * @param userId The userId in which the uri is to be resolved. 7477 */ 7478 @Override 7479 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7480 int userId) { 7481 enforceNotIsolatedCaller("revokeUriPermission"); 7482 synchronized(this) { 7483 final ProcessRecord r = getRecordForAppLocked(caller); 7484 if (r == null) { 7485 throw new SecurityException("Unable to find app for caller " 7486 + caller 7487 + " when revoking permission to uri " + uri); 7488 } 7489 if (uri == null) { 7490 Slog.w(TAG, "revokeUriPermission: null uri"); 7491 return; 7492 } 7493 7494 if (!Intent.isAccessUriMode(modeFlags)) { 7495 return; 7496 } 7497 7498 final IPackageManager pm = AppGlobals.getPackageManager(); 7499 final String authority = uri.getAuthority(); 7500 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7501 if (pi == null) { 7502 Slog.w(TAG, "No content provider found for permission revoke: " 7503 + uri.toSafeString()); 7504 return; 7505 } 7506 7507 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7508 } 7509 } 7510 7511 /** 7512 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7513 * given package. 7514 * 7515 * @param packageName Package name to match, or {@code null} to apply to all 7516 * packages. 7517 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7518 * to all users. 7519 * @param persistable If persistable grants should be removed. 7520 */ 7521 private void removeUriPermissionsForPackageLocked( 7522 String packageName, int userHandle, boolean persistable) { 7523 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7524 throw new IllegalArgumentException("Must narrow by either package or user"); 7525 } 7526 7527 boolean persistChanged = false; 7528 7529 int N = mGrantedUriPermissions.size(); 7530 for (int i = 0; i < N; i++) { 7531 final int targetUid = mGrantedUriPermissions.keyAt(i); 7532 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7533 7534 // Only inspect grants matching user 7535 if (userHandle == UserHandle.USER_ALL 7536 || userHandle == UserHandle.getUserId(targetUid)) { 7537 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7538 final UriPermission perm = it.next(); 7539 7540 // Only inspect grants matching package 7541 if (packageName == null || perm.sourcePkg.equals(packageName) 7542 || perm.targetPkg.equals(packageName)) { 7543 persistChanged |= perm.revokeModes(persistable 7544 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7545 7546 // Only remove when no modes remain; any persisted grants 7547 // will keep this alive. 7548 if (perm.modeFlags == 0) { 7549 it.remove(); 7550 } 7551 } 7552 } 7553 7554 if (perms.isEmpty()) { 7555 mGrantedUriPermissions.remove(targetUid); 7556 N--; 7557 i--; 7558 } 7559 } 7560 } 7561 7562 if (persistChanged) { 7563 schedulePersistUriGrants(); 7564 } 7565 } 7566 7567 @Override 7568 public IBinder newUriPermissionOwner(String name) { 7569 enforceNotIsolatedCaller("newUriPermissionOwner"); 7570 synchronized(this) { 7571 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7572 return owner.getExternalTokenLocked(); 7573 } 7574 } 7575 7576 /** 7577 * @param uri This uri must NOT contain an embedded userId. 7578 * @param sourceUserId The userId in which the uri is to be resolved. 7579 * @param targetUserId The userId of the app that receives the grant. 7580 */ 7581 @Override 7582 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7583 final int modeFlags, int sourceUserId, int targetUserId) { 7584 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7585 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7586 synchronized(this) { 7587 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7588 if (owner == null) { 7589 throw new IllegalArgumentException("Unknown owner: " + token); 7590 } 7591 if (fromUid != Binder.getCallingUid()) { 7592 if (Binder.getCallingUid() != Process.myUid()) { 7593 // Only system code can grant URI permissions on behalf 7594 // of other users. 7595 throw new SecurityException("nice try"); 7596 } 7597 } 7598 if (targetPkg == null) { 7599 throw new IllegalArgumentException("null target"); 7600 } 7601 if (uri == null) { 7602 throw new IllegalArgumentException("null uri"); 7603 } 7604 7605 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7606 modeFlags, owner, targetUserId); 7607 } 7608 } 7609 7610 /** 7611 * @param uri This uri must NOT contain an embedded userId. 7612 * @param userId The userId in which the uri is to be resolved. 7613 */ 7614 @Override 7615 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7616 synchronized(this) { 7617 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7618 if (owner == null) { 7619 throw new IllegalArgumentException("Unknown owner: " + token); 7620 } 7621 7622 if (uri == null) { 7623 owner.removeUriPermissionsLocked(mode); 7624 } else { 7625 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7626 } 7627 } 7628 } 7629 7630 private void schedulePersistUriGrants() { 7631 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7632 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7633 10 * DateUtils.SECOND_IN_MILLIS); 7634 } 7635 } 7636 7637 private void writeGrantedUriPermissions() { 7638 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7639 7640 // Snapshot permissions so we can persist without lock 7641 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7642 synchronized (this) { 7643 final int size = mGrantedUriPermissions.size(); 7644 for (int i = 0; i < size; i++) { 7645 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7646 for (UriPermission perm : perms.values()) { 7647 if (perm.persistedModeFlags != 0) { 7648 persist.add(perm.snapshot()); 7649 } 7650 } 7651 } 7652 } 7653 7654 FileOutputStream fos = null; 7655 try { 7656 fos = mGrantFile.startWrite(); 7657 7658 XmlSerializer out = new FastXmlSerializer(); 7659 out.setOutput(fos, "utf-8"); 7660 out.startDocument(null, true); 7661 out.startTag(null, TAG_URI_GRANTS); 7662 for (UriPermission.Snapshot perm : persist) { 7663 out.startTag(null, TAG_URI_GRANT); 7664 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7665 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7666 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7667 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7668 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7669 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7670 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7671 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7672 out.endTag(null, TAG_URI_GRANT); 7673 } 7674 out.endTag(null, TAG_URI_GRANTS); 7675 out.endDocument(); 7676 7677 mGrantFile.finishWrite(fos); 7678 } catch (IOException e) { 7679 if (fos != null) { 7680 mGrantFile.failWrite(fos); 7681 } 7682 } 7683 } 7684 7685 private void readGrantedUriPermissionsLocked() { 7686 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7687 7688 final long now = System.currentTimeMillis(); 7689 7690 FileInputStream fis = null; 7691 try { 7692 fis = mGrantFile.openRead(); 7693 final XmlPullParser in = Xml.newPullParser(); 7694 in.setInput(fis, null); 7695 7696 int type; 7697 while ((type = in.next()) != END_DOCUMENT) { 7698 final String tag = in.getName(); 7699 if (type == START_TAG) { 7700 if (TAG_URI_GRANT.equals(tag)) { 7701 final int sourceUserId; 7702 final int targetUserId; 7703 final int userHandle = readIntAttribute(in, 7704 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7705 if (userHandle != UserHandle.USER_NULL) { 7706 // For backwards compatibility. 7707 sourceUserId = userHandle; 7708 targetUserId = userHandle; 7709 } else { 7710 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7711 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7712 } 7713 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7714 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7715 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7716 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7717 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7718 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7719 7720 // Sanity check that provider still belongs to source package 7721 final ProviderInfo pi = getProviderInfoLocked( 7722 uri.getAuthority(), sourceUserId); 7723 if (pi != null && sourcePkg.equals(pi.packageName)) { 7724 int targetUid = -1; 7725 try { 7726 targetUid = AppGlobals.getPackageManager() 7727 .getPackageUid(targetPkg, targetUserId); 7728 } catch (RemoteException e) { 7729 } 7730 if (targetUid != -1) { 7731 final UriPermission perm = findOrCreateUriPermissionLocked( 7732 sourcePkg, targetPkg, targetUid, 7733 new GrantUri(sourceUserId, uri, prefix)); 7734 perm.initPersistedModes(modeFlags, createdTime); 7735 } 7736 } else { 7737 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7738 + " but instead found " + pi); 7739 } 7740 } 7741 } 7742 } 7743 } catch (FileNotFoundException e) { 7744 // Missing grants is okay 7745 } catch (IOException e) { 7746 Slog.wtf(TAG, "Failed reading Uri grants", e); 7747 } catch (XmlPullParserException e) { 7748 Slog.wtf(TAG, "Failed reading Uri grants", e); 7749 } finally { 7750 IoUtils.closeQuietly(fis); 7751 } 7752 } 7753 7754 /** 7755 * @param uri This uri must NOT contain an embedded userId. 7756 * @param userId The userId in which the uri is to be resolved. 7757 */ 7758 @Override 7759 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7760 enforceNotIsolatedCaller("takePersistableUriPermission"); 7761 7762 Preconditions.checkFlagsArgument(modeFlags, 7763 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7764 7765 synchronized (this) { 7766 final int callingUid = Binder.getCallingUid(); 7767 boolean persistChanged = false; 7768 GrantUri grantUri = new GrantUri(userId, uri, false); 7769 7770 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7771 new GrantUri(userId, uri, false)); 7772 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7773 new GrantUri(userId, uri, true)); 7774 7775 final boolean exactValid = (exactPerm != null) 7776 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7777 final boolean prefixValid = (prefixPerm != null) 7778 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7779 7780 if (!(exactValid || prefixValid)) { 7781 throw new SecurityException("No persistable permission grants found for UID " 7782 + callingUid + " and Uri " + grantUri.toSafeString()); 7783 } 7784 7785 if (exactValid) { 7786 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7787 } 7788 if (prefixValid) { 7789 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7790 } 7791 7792 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7793 7794 if (persistChanged) { 7795 schedulePersistUriGrants(); 7796 } 7797 } 7798 } 7799 7800 /** 7801 * @param uri This uri must NOT contain an embedded userId. 7802 * @param userId The userId in which the uri is to be resolved. 7803 */ 7804 @Override 7805 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7806 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7807 7808 Preconditions.checkFlagsArgument(modeFlags, 7809 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7810 7811 synchronized (this) { 7812 final int callingUid = Binder.getCallingUid(); 7813 boolean persistChanged = false; 7814 7815 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7816 new GrantUri(userId, uri, false)); 7817 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7818 new GrantUri(userId, uri, true)); 7819 if (exactPerm == null && prefixPerm == null) { 7820 throw new SecurityException("No permission grants found for UID " + callingUid 7821 + " and Uri " + uri.toSafeString()); 7822 } 7823 7824 if (exactPerm != null) { 7825 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7826 removeUriPermissionIfNeededLocked(exactPerm); 7827 } 7828 if (prefixPerm != null) { 7829 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7830 removeUriPermissionIfNeededLocked(prefixPerm); 7831 } 7832 7833 if (persistChanged) { 7834 schedulePersistUriGrants(); 7835 } 7836 } 7837 } 7838 7839 /** 7840 * Prune any older {@link UriPermission} for the given UID until outstanding 7841 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7842 * 7843 * @return if any mutations occured that require persisting. 7844 */ 7845 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7846 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7847 if (perms == null) return false; 7848 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7849 7850 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7851 for (UriPermission perm : perms.values()) { 7852 if (perm.persistedModeFlags != 0) { 7853 persisted.add(perm); 7854 } 7855 } 7856 7857 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7858 if (trimCount <= 0) return false; 7859 7860 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7861 for (int i = 0; i < trimCount; i++) { 7862 final UriPermission perm = persisted.get(i); 7863 7864 if (DEBUG_URI_PERMISSION) { 7865 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7866 } 7867 7868 perm.releasePersistableModes(~0); 7869 removeUriPermissionIfNeededLocked(perm); 7870 } 7871 7872 return true; 7873 } 7874 7875 @Override 7876 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7877 String packageName, boolean incoming) { 7878 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7879 Preconditions.checkNotNull(packageName, "packageName"); 7880 7881 final int callingUid = Binder.getCallingUid(); 7882 final IPackageManager pm = AppGlobals.getPackageManager(); 7883 try { 7884 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7885 if (packageUid != callingUid) { 7886 throw new SecurityException( 7887 "Package " + packageName + " does not belong to calling UID " + callingUid); 7888 } 7889 } catch (RemoteException e) { 7890 throw new SecurityException("Failed to verify package name ownership"); 7891 } 7892 7893 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7894 synchronized (this) { 7895 if (incoming) { 7896 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7897 callingUid); 7898 if (perms == null) { 7899 Slog.w(TAG, "No permission grants found for " + packageName); 7900 } else { 7901 for (UriPermission perm : perms.values()) { 7902 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7903 result.add(perm.buildPersistedPublicApiObject()); 7904 } 7905 } 7906 } 7907 } else { 7908 final int size = mGrantedUriPermissions.size(); 7909 for (int i = 0; i < size; i++) { 7910 final ArrayMap<GrantUri, UriPermission> perms = 7911 mGrantedUriPermissions.valueAt(i); 7912 for (UriPermission perm : perms.values()) { 7913 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7914 result.add(perm.buildPersistedPublicApiObject()); 7915 } 7916 } 7917 } 7918 } 7919 } 7920 return new ParceledListSlice<android.content.UriPermission>(result); 7921 } 7922 7923 @Override 7924 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7925 synchronized (this) { 7926 ProcessRecord app = 7927 who != null ? getRecordForAppLocked(who) : null; 7928 if (app == null) return; 7929 7930 Message msg = Message.obtain(); 7931 msg.what = WAIT_FOR_DEBUGGER_MSG; 7932 msg.obj = app; 7933 msg.arg1 = waiting ? 1 : 0; 7934 mHandler.sendMessage(msg); 7935 } 7936 } 7937 7938 @Override 7939 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7940 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7941 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7942 outInfo.availMem = Process.getFreeMemory(); 7943 outInfo.totalMem = Process.getTotalMemory(); 7944 outInfo.threshold = homeAppMem; 7945 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7946 outInfo.hiddenAppThreshold = cachedAppMem; 7947 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7948 ProcessList.SERVICE_ADJ); 7949 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7950 ProcessList.VISIBLE_APP_ADJ); 7951 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7952 ProcessList.FOREGROUND_APP_ADJ); 7953 } 7954 7955 // ========================================================= 7956 // TASK MANAGEMENT 7957 // ========================================================= 7958 7959 @Override 7960 public List<IAppTask> getAppTasks(String callingPackage) { 7961 int callingUid = Binder.getCallingUid(); 7962 long ident = Binder.clearCallingIdentity(); 7963 7964 synchronized(this) { 7965 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7966 try { 7967 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7968 7969 final int N = mRecentTasks.size(); 7970 for (int i = 0; i < N; i++) { 7971 TaskRecord tr = mRecentTasks.get(i); 7972 // Skip tasks that do not match the caller. We don't need to verify 7973 // callingPackage, because we are also limiting to callingUid and know 7974 // that will limit to the correct security sandbox. 7975 if (tr.effectiveUid != callingUid) { 7976 continue; 7977 } 7978 Intent intent = tr.getBaseIntent(); 7979 if (intent == null || 7980 !callingPackage.equals(intent.getComponent().getPackageName())) { 7981 continue; 7982 } 7983 ActivityManager.RecentTaskInfo taskInfo = 7984 createRecentTaskInfoFromTaskRecord(tr); 7985 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7986 list.add(taskImpl); 7987 } 7988 } finally { 7989 Binder.restoreCallingIdentity(ident); 7990 } 7991 return list; 7992 } 7993 } 7994 7995 @Override 7996 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7997 final int callingUid = Binder.getCallingUid(); 7998 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7999 8000 synchronized(this) { 8001 if (localLOGV) Slog.v( 8002 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8003 8004 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8005 callingUid); 8006 8007 // TODO: Improve with MRU list from all ActivityStacks. 8008 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8009 } 8010 8011 return list; 8012 } 8013 8014 TaskRecord getMostRecentTask() { 8015 return mRecentTasks.get(0); 8016 } 8017 8018 /** 8019 * Creates a new RecentTaskInfo from a TaskRecord. 8020 */ 8021 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8022 // Update the task description to reflect any changes in the task stack 8023 tr.updateTaskDescription(); 8024 8025 // Compose the recent task info 8026 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8027 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8028 rti.persistentId = tr.taskId; 8029 rti.baseIntent = new Intent(tr.getBaseIntent()); 8030 rti.origActivity = tr.origActivity; 8031 rti.description = tr.lastDescription; 8032 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8033 rti.userId = tr.userId; 8034 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8035 rti.firstActiveTime = tr.firstActiveTime; 8036 rti.lastActiveTime = tr.lastActiveTime; 8037 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8038 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8039 return rti; 8040 } 8041 8042 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8043 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8044 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8045 if (!allowed) { 8046 if (checkPermission(android.Manifest.permission.GET_TASKS, 8047 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8048 // Temporary compatibility: some existing apps on the system image may 8049 // still be requesting the old permission and not switched to the new 8050 // one; if so, we'll still allow them full access. This means we need 8051 // to see if they are holding the old permission and are a system app. 8052 try { 8053 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8054 allowed = true; 8055 Slog.w(TAG, caller + ": caller " + callingUid 8056 + " is using old GET_TASKS but privileged; allowing"); 8057 } 8058 } catch (RemoteException e) { 8059 } 8060 } 8061 } 8062 if (!allowed) { 8063 Slog.w(TAG, caller + ": caller " + callingUid 8064 + " does not hold GET_TASKS; limiting output"); 8065 } 8066 return allowed; 8067 } 8068 8069 @Override 8070 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8071 final int callingUid = Binder.getCallingUid(); 8072 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8073 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8074 8075 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8076 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8077 synchronized (this) { 8078 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8079 callingUid); 8080 final boolean detailed = checkCallingPermission( 8081 android.Manifest.permission.GET_DETAILED_TASKS) 8082 == PackageManager.PERMISSION_GRANTED; 8083 8084 final int N = mRecentTasks.size(); 8085 ArrayList<ActivityManager.RecentTaskInfo> res 8086 = new ArrayList<ActivityManager.RecentTaskInfo>( 8087 maxNum < N ? maxNum : N); 8088 8089 final Set<Integer> includedUsers; 8090 if (includeProfiles) { 8091 includedUsers = getProfileIdsLocked(userId); 8092 } else { 8093 includedUsers = new HashSet<Integer>(); 8094 } 8095 includedUsers.add(Integer.valueOf(userId)); 8096 8097 for (int i=0; i<N && maxNum > 0; i++) { 8098 TaskRecord tr = mRecentTasks.get(i); 8099 // Only add calling user or related users recent tasks 8100 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8101 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8102 continue; 8103 } 8104 8105 // Return the entry if desired by the caller. We always return 8106 // the first entry, because callers always expect this to be the 8107 // foreground app. We may filter others if the caller has 8108 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8109 // we should exclude the entry. 8110 8111 if (i == 0 8112 || withExcluded 8113 || (tr.intent == null) 8114 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8115 == 0)) { 8116 if (!allowed) { 8117 // If the caller doesn't have the GET_TASKS permission, then only 8118 // allow them to see a small subset of tasks -- their own and home. 8119 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8120 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8121 continue; 8122 } 8123 } 8124 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8125 if (tr.stack != null && tr.stack.isHomeStack()) { 8126 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8127 continue; 8128 } 8129 } 8130 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8131 // Don't include auto remove tasks that are finished or finishing. 8132 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8133 + tr); 8134 continue; 8135 } 8136 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8137 && !tr.isAvailable) { 8138 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8139 continue; 8140 } 8141 8142 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8143 if (!detailed) { 8144 rti.baseIntent.replaceExtras((Bundle)null); 8145 } 8146 8147 res.add(rti); 8148 maxNum--; 8149 } 8150 } 8151 return res; 8152 } 8153 } 8154 8155 private TaskRecord recentTaskForIdLocked(int id) { 8156 final int N = mRecentTasks.size(); 8157 for (int i=0; i<N; i++) { 8158 TaskRecord tr = mRecentTasks.get(i); 8159 if (tr.taskId == id) { 8160 return tr; 8161 } 8162 } 8163 return null; 8164 } 8165 8166 @Override 8167 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8168 synchronized (this) { 8169 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8170 "getTaskThumbnail()"); 8171 TaskRecord tr = recentTaskForIdLocked(id); 8172 if (tr != null) { 8173 return tr.getTaskThumbnailLocked(); 8174 } 8175 } 8176 return null; 8177 } 8178 8179 @Override 8180 public int addAppTask(IBinder activityToken, Intent intent, 8181 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8182 final int callingUid = Binder.getCallingUid(); 8183 final long callingIdent = Binder.clearCallingIdentity(); 8184 8185 try { 8186 synchronized (this) { 8187 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8188 if (r == null) { 8189 throw new IllegalArgumentException("Activity does not exist; token=" 8190 + activityToken); 8191 } 8192 ComponentName comp = intent.getComponent(); 8193 if (comp == null) { 8194 throw new IllegalArgumentException("Intent " + intent 8195 + " must specify explicit component"); 8196 } 8197 if (thumbnail.getWidth() != mThumbnailWidth 8198 || thumbnail.getHeight() != mThumbnailHeight) { 8199 throw new IllegalArgumentException("Bad thumbnail size: got " 8200 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8201 + mThumbnailWidth + "x" + mThumbnailHeight); 8202 } 8203 if (intent.getSelector() != null) { 8204 intent.setSelector(null); 8205 } 8206 if (intent.getSourceBounds() != null) { 8207 intent.setSourceBounds(null); 8208 } 8209 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8210 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8211 // The caller has added this as an auto-remove task... that makes no 8212 // sense, so turn off auto-remove. 8213 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8214 } 8215 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8216 // Must be a new task. 8217 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8218 } 8219 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8220 mLastAddedTaskActivity = null; 8221 } 8222 ActivityInfo ainfo = mLastAddedTaskActivity; 8223 if (ainfo == null) { 8224 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8225 comp, 0, UserHandle.getUserId(callingUid)); 8226 if (ainfo.applicationInfo.uid != callingUid) { 8227 throw new SecurityException( 8228 "Can't add task for another application: target uid=" 8229 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8230 } 8231 } 8232 8233 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8234 intent, description); 8235 8236 int trimIdx = trimRecentsForTask(task, false); 8237 if (trimIdx >= 0) { 8238 // If this would have caused a trim, then we'll abort because that 8239 // means it would be added at the end of the list but then just removed. 8240 return -1; 8241 } 8242 8243 final int N = mRecentTasks.size(); 8244 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8245 final TaskRecord tr = mRecentTasks.remove(N - 1); 8246 tr.removedFromRecents(mTaskPersister); 8247 } 8248 8249 task.inRecents = true; 8250 mRecentTasks.add(task); 8251 r.task.stack.addTask(task, false, false); 8252 8253 task.setLastThumbnail(thumbnail); 8254 task.freeLastThumbnail(); 8255 8256 return task.taskId; 8257 } 8258 } finally { 8259 Binder.restoreCallingIdentity(callingIdent); 8260 } 8261 } 8262 8263 @Override 8264 public Point getAppTaskThumbnailSize() { 8265 synchronized (this) { 8266 return new Point(mThumbnailWidth, mThumbnailHeight); 8267 } 8268 } 8269 8270 @Override 8271 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8272 synchronized (this) { 8273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8274 if (r != null) { 8275 r.setTaskDescription(td); 8276 r.task.updateTaskDescription(); 8277 } 8278 } 8279 } 8280 8281 @Override 8282 public Bitmap getTaskDescriptionIcon(String filename) { 8283 if (!FileUtils.isValidExtFilename(filename) 8284 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8285 throw new IllegalArgumentException("Bad filename: " + filename); 8286 } 8287 return mTaskPersister.getTaskDescriptionIcon(filename); 8288 } 8289 8290 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8291 mRecentTasks.remove(tr); 8292 tr.removedFromRecents(mTaskPersister); 8293 ComponentName component = tr.getBaseIntent().getComponent(); 8294 if (component == null) { 8295 Slog.w(TAG, "No component for base intent of task: " + tr); 8296 return; 8297 } 8298 8299 if (!killProcess) { 8300 return; 8301 } 8302 8303 // Determine if the process(es) for this task should be killed. 8304 final String pkg = component.getPackageName(); 8305 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8306 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8307 for (int i = 0; i < pmap.size(); i++) { 8308 8309 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8310 for (int j = 0; j < uids.size(); j++) { 8311 ProcessRecord proc = uids.valueAt(j); 8312 if (proc.userId != tr.userId) { 8313 // Don't kill process for a different user. 8314 continue; 8315 } 8316 if (proc == mHomeProcess) { 8317 // Don't kill the home process along with tasks from the same package. 8318 continue; 8319 } 8320 if (!proc.pkgList.containsKey(pkg)) { 8321 // Don't kill process that is not associated with this task. 8322 continue; 8323 } 8324 8325 for (int k = 0; k < proc.activities.size(); k++) { 8326 TaskRecord otherTask = proc.activities.get(k).task; 8327 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8328 // Don't kill process(es) that has an activity in a different task that is 8329 // also in recents. 8330 return; 8331 } 8332 } 8333 8334 // Add process to kill list. 8335 procsToKill.add(proc); 8336 } 8337 } 8338 8339 // Find any running services associated with this app and stop if needed. 8340 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8341 8342 // Kill the running processes. 8343 for (int i = 0; i < procsToKill.size(); i++) { 8344 ProcessRecord pr = procsToKill.get(i); 8345 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8346 pr.kill("remove task", true); 8347 } else { 8348 pr.waitingToKill = "remove task"; 8349 } 8350 } 8351 } 8352 8353 /** 8354 * Removes the task with the specified task id. 8355 * 8356 * @param taskId Identifier of the task to be removed. 8357 * @param killProcess Kill any process associated with the task if possible. 8358 * @return Returns true if the given task was found and removed. 8359 */ 8360 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8361 TaskRecord tr = recentTaskForIdLocked(taskId); 8362 if (tr != null) { 8363 tr.removeTaskActivitiesLocked(); 8364 cleanUpRemovedTaskLocked(tr, killProcess); 8365 if (tr.isPersistable) { 8366 notifyTaskPersisterLocked(null, true); 8367 } 8368 return true; 8369 } 8370 return false; 8371 } 8372 8373 @Override 8374 public boolean removeTask(int taskId) { 8375 synchronized (this) { 8376 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8377 "removeTask()"); 8378 long ident = Binder.clearCallingIdentity(); 8379 try { 8380 return removeTaskByIdLocked(taskId, true); 8381 } finally { 8382 Binder.restoreCallingIdentity(ident); 8383 } 8384 } 8385 } 8386 8387 /** 8388 * TODO: Add mController hook 8389 */ 8390 @Override 8391 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8392 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8393 "moveTaskToFront()"); 8394 8395 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8396 synchronized(this) { 8397 moveTaskToFrontLocked(taskId, flags, options); 8398 } 8399 } 8400 8401 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8402 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8403 Binder.getCallingUid(), -1, -1, "Task to front")) { 8404 ActivityOptions.abort(options); 8405 return; 8406 } 8407 final long origId = Binder.clearCallingIdentity(); 8408 try { 8409 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8410 if (task == null) { 8411 return; 8412 } 8413 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8414 mStackSupervisor.showLockTaskToast(); 8415 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8416 return; 8417 } 8418 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8419 if (prev != null && prev.isRecentsActivity()) { 8420 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8421 } 8422 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8423 } finally { 8424 Binder.restoreCallingIdentity(origId); 8425 } 8426 ActivityOptions.abort(options); 8427 } 8428 8429 @Override 8430 public void moveTaskToBack(int taskId) { 8431 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8432 "moveTaskToBack()"); 8433 8434 synchronized(this) { 8435 TaskRecord tr = recentTaskForIdLocked(taskId); 8436 if (tr != null) { 8437 if (tr == mStackSupervisor.mLockTaskModeTask) { 8438 mStackSupervisor.showLockTaskToast(); 8439 return; 8440 } 8441 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8442 ActivityStack stack = tr.stack; 8443 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8444 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8445 Binder.getCallingUid(), -1, -1, "Task to back")) { 8446 return; 8447 } 8448 } 8449 final long origId = Binder.clearCallingIdentity(); 8450 try { 8451 stack.moveTaskToBackLocked(taskId, null); 8452 } finally { 8453 Binder.restoreCallingIdentity(origId); 8454 } 8455 } 8456 } 8457 } 8458 8459 /** 8460 * Moves an activity, and all of the other activities within the same task, to the bottom 8461 * of the history stack. The activity's order within the task is unchanged. 8462 * 8463 * @param token A reference to the activity we wish to move 8464 * @param nonRoot If false then this only works if the activity is the root 8465 * of a task; if true it will work for any activity in a task. 8466 * @return Returns true if the move completed, false if not. 8467 */ 8468 @Override 8469 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8470 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8471 synchronized(this) { 8472 final long origId = Binder.clearCallingIdentity(); 8473 try { 8474 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8475 if (taskId >= 0) { 8476 if ((mStackSupervisor.mLockTaskModeTask != null) 8477 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8478 mStackSupervisor.showLockTaskToast(); 8479 return false; 8480 } 8481 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8482 } 8483 } finally { 8484 Binder.restoreCallingIdentity(origId); 8485 } 8486 } 8487 return false; 8488 } 8489 8490 @Override 8491 public void moveTaskBackwards(int task) { 8492 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8493 "moveTaskBackwards()"); 8494 8495 synchronized(this) { 8496 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8497 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8498 return; 8499 } 8500 final long origId = Binder.clearCallingIdentity(); 8501 moveTaskBackwardsLocked(task); 8502 Binder.restoreCallingIdentity(origId); 8503 } 8504 } 8505 8506 private final void moveTaskBackwardsLocked(int task) { 8507 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8508 } 8509 8510 @Override 8511 public IBinder getHomeActivityToken() throws RemoteException { 8512 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8513 "getHomeActivityToken()"); 8514 synchronized (this) { 8515 return mStackSupervisor.getHomeActivityToken(); 8516 } 8517 } 8518 8519 @Override 8520 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8521 IActivityContainerCallback callback) throws RemoteException { 8522 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8523 "createActivityContainer()"); 8524 synchronized (this) { 8525 if (parentActivityToken == null) { 8526 throw new IllegalArgumentException("parent token must not be null"); 8527 } 8528 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8529 if (r == null) { 8530 return null; 8531 } 8532 if (callback == null) { 8533 throw new IllegalArgumentException("callback must not be null"); 8534 } 8535 return mStackSupervisor.createActivityContainer(r, callback); 8536 } 8537 } 8538 8539 @Override 8540 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8541 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8542 "deleteActivityContainer()"); 8543 synchronized (this) { 8544 mStackSupervisor.deleteActivityContainer(container); 8545 } 8546 } 8547 8548 @Override 8549 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8550 throws RemoteException { 8551 synchronized (this) { 8552 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8553 if (stack != null) { 8554 return stack.mActivityContainer; 8555 } 8556 return null; 8557 } 8558 } 8559 8560 @Override 8561 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8562 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8563 "moveTaskToStack()"); 8564 if (stackId == HOME_STACK_ID) { 8565 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8566 new RuntimeException("here").fillInStackTrace()); 8567 } 8568 synchronized (this) { 8569 long ident = Binder.clearCallingIdentity(); 8570 try { 8571 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8572 + stackId + " toTop=" + toTop); 8573 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8574 } finally { 8575 Binder.restoreCallingIdentity(ident); 8576 } 8577 } 8578 } 8579 8580 @Override 8581 public void resizeStack(int stackBoxId, Rect bounds) { 8582 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8583 "resizeStackBox()"); 8584 long ident = Binder.clearCallingIdentity(); 8585 try { 8586 mWindowManager.resizeStack(stackBoxId, bounds); 8587 } finally { 8588 Binder.restoreCallingIdentity(ident); 8589 } 8590 } 8591 8592 @Override 8593 public List<StackInfo> getAllStackInfos() { 8594 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8595 "getAllStackInfos()"); 8596 long ident = Binder.clearCallingIdentity(); 8597 try { 8598 synchronized (this) { 8599 return mStackSupervisor.getAllStackInfosLocked(); 8600 } 8601 } finally { 8602 Binder.restoreCallingIdentity(ident); 8603 } 8604 } 8605 8606 @Override 8607 public StackInfo getStackInfo(int stackId) { 8608 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8609 "getStackInfo()"); 8610 long ident = Binder.clearCallingIdentity(); 8611 try { 8612 synchronized (this) { 8613 return mStackSupervisor.getStackInfoLocked(stackId); 8614 } 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public boolean isInHomeStack(int taskId) { 8622 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8623 "getStackInfo()"); 8624 long ident = Binder.clearCallingIdentity(); 8625 try { 8626 synchronized (this) { 8627 TaskRecord tr = recentTaskForIdLocked(taskId); 8628 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8629 } 8630 } finally { 8631 Binder.restoreCallingIdentity(ident); 8632 } 8633 } 8634 8635 @Override 8636 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8637 synchronized(this) { 8638 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8639 } 8640 } 8641 8642 private boolean isLockTaskAuthorized(String pkg) { 8643 final DevicePolicyManager dpm = (DevicePolicyManager) 8644 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8645 try { 8646 int uid = mContext.getPackageManager().getPackageUid(pkg, 8647 Binder.getCallingUserHandle().getIdentifier()); 8648 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8649 } catch (NameNotFoundException e) { 8650 return false; 8651 } 8652 } 8653 8654 void startLockTaskMode(TaskRecord task) { 8655 final String pkg; 8656 synchronized (this) { 8657 pkg = task.intent.getComponent().getPackageName(); 8658 } 8659 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8660 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8661 final TaskRecord taskRecord = task; 8662 mHandler.post(new Runnable() { 8663 @Override 8664 public void run() { 8665 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8666 } 8667 }); 8668 return; 8669 } 8670 long ident = Binder.clearCallingIdentity(); 8671 try { 8672 synchronized (this) { 8673 // Since we lost lock on task, make sure it is still there. 8674 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8675 if (task != null) { 8676 if (!isSystemInitiated 8677 && ((mStackSupervisor.getFocusedStack() == null) 8678 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8679 throw new IllegalArgumentException("Invalid task, not in foreground"); 8680 } 8681 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8682 } 8683 } 8684 } finally { 8685 Binder.restoreCallingIdentity(ident); 8686 } 8687 } 8688 8689 @Override 8690 public void startLockTaskMode(int taskId) { 8691 final TaskRecord task; 8692 long ident = Binder.clearCallingIdentity(); 8693 try { 8694 synchronized (this) { 8695 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8696 } 8697 } finally { 8698 Binder.restoreCallingIdentity(ident); 8699 } 8700 if (task != null) { 8701 startLockTaskMode(task); 8702 } 8703 } 8704 8705 @Override 8706 public void startLockTaskMode(IBinder token) { 8707 final TaskRecord task; 8708 long ident = Binder.clearCallingIdentity(); 8709 try { 8710 synchronized (this) { 8711 final ActivityRecord r = ActivityRecord.forToken(token); 8712 if (r == null) { 8713 return; 8714 } 8715 task = r.task; 8716 } 8717 } finally { 8718 Binder.restoreCallingIdentity(ident); 8719 } 8720 if (task != null) { 8721 startLockTaskMode(task); 8722 } 8723 } 8724 8725 @Override 8726 public void startLockTaskModeOnCurrent() throws RemoteException { 8727 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8728 "startLockTaskModeOnCurrent"); 8729 ActivityRecord r = null; 8730 synchronized (this) { 8731 r = mStackSupervisor.topRunningActivityLocked(); 8732 } 8733 startLockTaskMode(r.task); 8734 } 8735 8736 @Override 8737 public void stopLockTaskMode() { 8738 // Verify that the user matches the package of the intent for the TaskRecord 8739 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8740 // and stopLockTaskMode. 8741 final int callingUid = Binder.getCallingUid(); 8742 if (callingUid != Process.SYSTEM_UID) { 8743 try { 8744 String pkg = 8745 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8746 int uid = mContext.getPackageManager().getPackageUid(pkg, 8747 Binder.getCallingUserHandle().getIdentifier()); 8748 if (uid != callingUid) { 8749 throw new SecurityException("Invalid uid, expected " + uid); 8750 } 8751 } catch (NameNotFoundException e) { 8752 Log.d(TAG, "stopLockTaskMode " + e); 8753 return; 8754 } 8755 } 8756 long ident = Binder.clearCallingIdentity(); 8757 try { 8758 Log.d(TAG, "stopLockTaskMode"); 8759 // Stop lock task 8760 synchronized (this) { 8761 mStackSupervisor.setLockTaskModeLocked(null, false); 8762 } 8763 } finally { 8764 Binder.restoreCallingIdentity(ident); 8765 } 8766 } 8767 8768 @Override 8769 public void stopLockTaskModeOnCurrent() throws RemoteException { 8770 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8771 "stopLockTaskModeOnCurrent"); 8772 long ident = Binder.clearCallingIdentity(); 8773 try { 8774 stopLockTaskMode(); 8775 } finally { 8776 Binder.restoreCallingIdentity(ident); 8777 } 8778 } 8779 8780 @Override 8781 public boolean isInLockTaskMode() { 8782 synchronized (this) { 8783 return mStackSupervisor.isInLockTaskMode(); 8784 } 8785 } 8786 8787 // ========================================================= 8788 // CONTENT PROVIDERS 8789 // ========================================================= 8790 8791 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8792 List<ProviderInfo> providers = null; 8793 try { 8794 providers = AppGlobals.getPackageManager(). 8795 queryContentProviders(app.processName, app.uid, 8796 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8797 } catch (RemoteException ex) { 8798 } 8799 if (DEBUG_MU) 8800 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8801 int userId = app.userId; 8802 if (providers != null) { 8803 int N = providers.size(); 8804 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8805 for (int i=0; i<N; i++) { 8806 ProviderInfo cpi = 8807 (ProviderInfo)providers.get(i); 8808 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8809 cpi.name, cpi.flags); 8810 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8811 // This is a singleton provider, but a user besides the 8812 // default user is asking to initialize a process it runs 8813 // in... well, no, it doesn't actually run in this process, 8814 // it runs in the process of the default user. Get rid of it. 8815 providers.remove(i); 8816 N--; 8817 i--; 8818 continue; 8819 } 8820 8821 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8822 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8823 if (cpr == null) { 8824 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8825 mProviderMap.putProviderByClass(comp, cpr); 8826 } 8827 if (DEBUG_MU) 8828 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8829 app.pubProviders.put(cpi.name, cpr); 8830 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8831 // Don't add this if it is a platform component that is marked 8832 // to run in multiple processes, because this is actually 8833 // part of the framework so doesn't make sense to track as a 8834 // separate apk in the process. 8835 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8836 mProcessStats); 8837 } 8838 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8839 } 8840 } 8841 return providers; 8842 } 8843 8844 /** 8845 * Check if {@link ProcessRecord} has a possible chance at accessing the 8846 * given {@link ProviderInfo}. Final permission checking is always done 8847 * in {@link ContentProvider}. 8848 */ 8849 private final String checkContentProviderPermissionLocked( 8850 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8851 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8852 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8853 boolean checkedGrants = false; 8854 if (checkUser) { 8855 // Looking for cross-user grants before enforcing the typical cross-users permissions 8856 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8857 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8858 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8859 return null; 8860 } 8861 checkedGrants = true; 8862 } 8863 userId = handleIncomingUser(callingPid, callingUid, userId, 8864 false, ALLOW_NON_FULL, 8865 "checkContentProviderPermissionLocked " + cpi.authority, null); 8866 if (userId != tmpTargetUserId) { 8867 // When we actually went to determine the final targer user ID, this ended 8868 // up different than our initial check for the authority. This is because 8869 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8870 // SELF. So we need to re-check the grants again. 8871 checkedGrants = false; 8872 } 8873 } 8874 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8875 cpi.applicationInfo.uid, cpi.exported) 8876 == PackageManager.PERMISSION_GRANTED) { 8877 return null; 8878 } 8879 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8880 cpi.applicationInfo.uid, cpi.exported) 8881 == PackageManager.PERMISSION_GRANTED) { 8882 return null; 8883 } 8884 8885 PathPermission[] pps = cpi.pathPermissions; 8886 if (pps != null) { 8887 int i = pps.length; 8888 while (i > 0) { 8889 i--; 8890 PathPermission pp = pps[i]; 8891 String pprperm = pp.getReadPermission(); 8892 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8893 cpi.applicationInfo.uid, cpi.exported) 8894 == PackageManager.PERMISSION_GRANTED) { 8895 return null; 8896 } 8897 String ppwperm = pp.getWritePermission(); 8898 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8899 cpi.applicationInfo.uid, cpi.exported) 8900 == PackageManager.PERMISSION_GRANTED) { 8901 return null; 8902 } 8903 } 8904 } 8905 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8906 return null; 8907 } 8908 8909 String msg; 8910 if (!cpi.exported) { 8911 msg = "Permission Denial: opening provider " + cpi.name 8912 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8913 + ", uid=" + callingUid + ") that is not exported from uid " 8914 + cpi.applicationInfo.uid; 8915 } else { 8916 msg = "Permission Denial: opening provider " + cpi.name 8917 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8918 + ", uid=" + callingUid + ") requires " 8919 + cpi.readPermission + " or " + cpi.writePermission; 8920 } 8921 Slog.w(TAG, msg); 8922 return msg; 8923 } 8924 8925 /** 8926 * Returns if the ContentProvider has granted a uri to callingUid 8927 */ 8928 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8929 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8930 if (perms != null) { 8931 for (int i=perms.size()-1; i>=0; i--) { 8932 GrantUri grantUri = perms.keyAt(i); 8933 if (grantUri.sourceUserId == userId || !checkUser) { 8934 if (matchesProvider(grantUri.uri, cpi)) { 8935 return true; 8936 } 8937 } 8938 } 8939 } 8940 return false; 8941 } 8942 8943 /** 8944 * Returns true if the uri authority is one of the authorities specified in the provider. 8945 */ 8946 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8947 String uriAuth = uri.getAuthority(); 8948 String cpiAuth = cpi.authority; 8949 if (cpiAuth.indexOf(';') == -1) { 8950 return cpiAuth.equals(uriAuth); 8951 } 8952 String[] cpiAuths = cpiAuth.split(";"); 8953 int length = cpiAuths.length; 8954 for (int i = 0; i < length; i++) { 8955 if (cpiAuths[i].equals(uriAuth)) return true; 8956 } 8957 return false; 8958 } 8959 8960 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8961 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8962 if (r != null) { 8963 for (int i=0; i<r.conProviders.size(); i++) { 8964 ContentProviderConnection conn = r.conProviders.get(i); 8965 if (conn.provider == cpr) { 8966 if (DEBUG_PROVIDER) Slog.v(TAG, 8967 "Adding provider requested by " 8968 + r.processName + " from process " 8969 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8970 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8971 if (stable) { 8972 conn.stableCount++; 8973 conn.numStableIncs++; 8974 } else { 8975 conn.unstableCount++; 8976 conn.numUnstableIncs++; 8977 } 8978 return conn; 8979 } 8980 } 8981 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8982 if (stable) { 8983 conn.stableCount = 1; 8984 conn.numStableIncs = 1; 8985 } else { 8986 conn.unstableCount = 1; 8987 conn.numUnstableIncs = 1; 8988 } 8989 cpr.connections.add(conn); 8990 r.conProviders.add(conn); 8991 return conn; 8992 } 8993 cpr.addExternalProcessHandleLocked(externalProcessToken); 8994 return null; 8995 } 8996 8997 boolean decProviderCountLocked(ContentProviderConnection conn, 8998 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8999 if (conn != null) { 9000 cpr = conn.provider; 9001 if (DEBUG_PROVIDER) Slog.v(TAG, 9002 "Removing provider requested by " 9003 + conn.client.processName + " from process " 9004 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9005 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9006 if (stable) { 9007 conn.stableCount--; 9008 } else { 9009 conn.unstableCount--; 9010 } 9011 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9012 cpr.connections.remove(conn); 9013 conn.client.conProviders.remove(conn); 9014 return true; 9015 } 9016 return false; 9017 } 9018 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9019 return false; 9020 } 9021 9022 private void checkTime(long startTime, String where) { 9023 long now = SystemClock.elapsedRealtime(); 9024 if ((now-startTime) > 1000) { 9025 // If we are taking more than a second, log about it. 9026 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9027 } 9028 } 9029 9030 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9031 String name, IBinder token, boolean stable, int userId) { 9032 ContentProviderRecord cpr; 9033 ContentProviderConnection conn = null; 9034 ProviderInfo cpi = null; 9035 9036 synchronized(this) { 9037 long startTime = SystemClock.elapsedRealtime(); 9038 9039 ProcessRecord r = null; 9040 if (caller != null) { 9041 r = getRecordForAppLocked(caller); 9042 if (r == null) { 9043 throw new SecurityException( 9044 "Unable to find app for caller " + caller 9045 + " (pid=" + Binder.getCallingPid() 9046 + ") when getting content provider " + name); 9047 } 9048 } 9049 9050 boolean checkCrossUser = true; 9051 9052 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9053 9054 // First check if this content provider has been published... 9055 cpr = mProviderMap.getProviderByName(name, userId); 9056 // If that didn't work, check if it exists for user 0 and then 9057 // verify that it's a singleton provider before using it. 9058 if (cpr == null && userId != UserHandle.USER_OWNER) { 9059 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9060 if (cpr != null) { 9061 cpi = cpr.info; 9062 if (isSingleton(cpi.processName, cpi.applicationInfo, 9063 cpi.name, cpi.flags) 9064 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9065 userId = UserHandle.USER_OWNER; 9066 checkCrossUser = false; 9067 } else { 9068 cpr = null; 9069 cpi = null; 9070 } 9071 } 9072 } 9073 9074 boolean providerRunning = cpr != null; 9075 if (providerRunning) { 9076 cpi = cpr.info; 9077 String msg; 9078 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9079 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9080 != null) { 9081 throw new SecurityException(msg); 9082 } 9083 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9084 9085 if (r != null && cpr.canRunHere(r)) { 9086 // This provider has been published or is in the process 9087 // of being published... but it is also allowed to run 9088 // in the caller's process, so don't make a connection 9089 // and just let the caller instantiate its own instance. 9090 ContentProviderHolder holder = cpr.newHolder(null); 9091 // don't give caller the provider object, it needs 9092 // to make its own. 9093 holder.provider = null; 9094 return holder; 9095 } 9096 9097 final long origId = Binder.clearCallingIdentity(); 9098 9099 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9100 9101 // In this case the provider instance already exists, so we can 9102 // return it right away. 9103 conn = incProviderCountLocked(r, cpr, token, stable); 9104 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9105 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9106 // If this is a perceptible app accessing the provider, 9107 // make sure to count it as being accessed and thus 9108 // back up on the LRU list. This is good because 9109 // content providers are often expensive to start. 9110 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9111 updateLruProcessLocked(cpr.proc, false, null); 9112 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9113 } 9114 } 9115 9116 if (cpr.proc != null) { 9117 if (false) { 9118 if (cpr.name.flattenToShortString().equals( 9119 "com.android.providers.calendar/.CalendarProvider2")) { 9120 Slog.v(TAG, "****************** KILLING " 9121 + cpr.name.flattenToShortString()); 9122 Process.killProcess(cpr.proc.pid); 9123 } 9124 } 9125 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9126 boolean success = updateOomAdjLocked(cpr.proc); 9127 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9128 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9129 // NOTE: there is still a race here where a signal could be 9130 // pending on the process even though we managed to update its 9131 // adj level. Not sure what to do about this, but at least 9132 // the race is now smaller. 9133 if (!success) { 9134 // Uh oh... it looks like the provider's process 9135 // has been killed on us. We need to wait for a new 9136 // process to be started, and make sure its death 9137 // doesn't kill our process. 9138 Slog.i(TAG, 9139 "Existing provider " + cpr.name.flattenToShortString() 9140 + " is crashing; detaching " + r); 9141 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9142 checkTime(startTime, "getContentProviderImpl: before appDied"); 9143 appDiedLocked(cpr.proc); 9144 checkTime(startTime, "getContentProviderImpl: after appDied"); 9145 if (!lastRef) { 9146 // This wasn't the last ref our process had on 9147 // the provider... we have now been killed, bail. 9148 return null; 9149 } 9150 providerRunning = false; 9151 conn = null; 9152 } 9153 } 9154 9155 Binder.restoreCallingIdentity(origId); 9156 } 9157 9158 boolean singleton; 9159 if (!providerRunning) { 9160 try { 9161 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9162 cpi = AppGlobals.getPackageManager(). 9163 resolveContentProvider(name, 9164 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9165 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9166 } catch (RemoteException ex) { 9167 } 9168 if (cpi == null) { 9169 return null; 9170 } 9171 // If the provider is a singleton AND 9172 // (it's a call within the same user || the provider is a 9173 // privileged app) 9174 // Then allow connecting to the singleton provider 9175 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9176 cpi.name, cpi.flags) 9177 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9178 if (singleton) { 9179 userId = UserHandle.USER_OWNER; 9180 } 9181 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9182 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9183 9184 String msg; 9185 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9186 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9187 != null) { 9188 throw new SecurityException(msg); 9189 } 9190 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9191 9192 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9193 && !cpi.processName.equals("system")) { 9194 // If this content provider does not run in the system 9195 // process, and the system is not yet ready to run other 9196 // processes, then fail fast instead of hanging. 9197 throw new IllegalArgumentException( 9198 "Attempt to launch content provider before system ready"); 9199 } 9200 9201 // Make sure that the user who owns this provider is started. If not, 9202 // we don't want to allow it to run. 9203 if (mStartedUsers.get(userId) == null) { 9204 Slog.w(TAG, "Unable to launch app " 9205 + cpi.applicationInfo.packageName + "/" 9206 + cpi.applicationInfo.uid + " for provider " 9207 + name + ": user " + userId + " is stopped"); 9208 return null; 9209 } 9210 9211 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9212 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9213 cpr = mProviderMap.getProviderByClass(comp, userId); 9214 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9215 final boolean firstClass = cpr == null; 9216 if (firstClass) { 9217 final long ident = Binder.clearCallingIdentity(); 9218 try { 9219 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9220 ApplicationInfo ai = 9221 AppGlobals.getPackageManager(). 9222 getApplicationInfo( 9223 cpi.applicationInfo.packageName, 9224 STOCK_PM_FLAGS, userId); 9225 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9226 if (ai == null) { 9227 Slog.w(TAG, "No package info for content provider " 9228 + cpi.name); 9229 return null; 9230 } 9231 ai = getAppInfoForUser(ai, userId); 9232 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9233 } catch (RemoteException ex) { 9234 // pm is in same process, this will never happen. 9235 } finally { 9236 Binder.restoreCallingIdentity(ident); 9237 } 9238 } 9239 9240 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9241 9242 if (r != null && cpr.canRunHere(r)) { 9243 // If this is a multiprocess provider, then just return its 9244 // info and allow the caller to instantiate it. Only do 9245 // this if the provider is the same user as the caller's 9246 // process, or can run as root (so can be in any process). 9247 return cpr.newHolder(null); 9248 } 9249 9250 if (DEBUG_PROVIDER) { 9251 RuntimeException e = new RuntimeException("here"); 9252 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9253 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9254 } 9255 9256 // This is single process, and our app is now connecting to it. 9257 // See if we are already in the process of launching this 9258 // provider. 9259 final int N = mLaunchingProviders.size(); 9260 int i; 9261 for (i=0; i<N; i++) { 9262 if (mLaunchingProviders.get(i) == cpr) { 9263 break; 9264 } 9265 } 9266 9267 // If the provider is not already being launched, then get it 9268 // started. 9269 if (i >= N) { 9270 final long origId = Binder.clearCallingIdentity(); 9271 9272 try { 9273 // Content provider is now in use, its package can't be stopped. 9274 try { 9275 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9276 AppGlobals.getPackageManager().setPackageStoppedState( 9277 cpr.appInfo.packageName, false, userId); 9278 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9279 } catch (RemoteException e) { 9280 } catch (IllegalArgumentException e) { 9281 Slog.w(TAG, "Failed trying to unstop package " 9282 + cpr.appInfo.packageName + ": " + e); 9283 } 9284 9285 // Use existing process if already started 9286 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9287 ProcessRecord proc = getProcessRecordLocked( 9288 cpi.processName, cpr.appInfo.uid, false); 9289 if (proc != null && proc.thread != null) { 9290 if (DEBUG_PROVIDER) { 9291 Slog.d(TAG, "Installing in existing process " + proc); 9292 } 9293 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9294 proc.pubProviders.put(cpi.name, cpr); 9295 try { 9296 proc.thread.scheduleInstallProvider(cpi); 9297 } catch (RemoteException e) { 9298 } 9299 } else { 9300 checkTime(startTime, "getContentProviderImpl: before start process"); 9301 proc = startProcessLocked(cpi.processName, 9302 cpr.appInfo, false, 0, "content provider", 9303 new ComponentName(cpi.applicationInfo.packageName, 9304 cpi.name), false, false, false); 9305 checkTime(startTime, "getContentProviderImpl: after start process"); 9306 if (proc == null) { 9307 Slog.w(TAG, "Unable to launch app " 9308 + cpi.applicationInfo.packageName + "/" 9309 + cpi.applicationInfo.uid + " for provider " 9310 + name + ": process is bad"); 9311 return null; 9312 } 9313 } 9314 cpr.launchingApp = proc; 9315 mLaunchingProviders.add(cpr); 9316 } finally { 9317 Binder.restoreCallingIdentity(origId); 9318 } 9319 } 9320 9321 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9322 9323 // Make sure the provider is published (the same provider class 9324 // may be published under multiple names). 9325 if (firstClass) { 9326 mProviderMap.putProviderByClass(comp, cpr); 9327 } 9328 9329 mProviderMap.putProviderByName(name, cpr); 9330 conn = incProviderCountLocked(r, cpr, token, stable); 9331 if (conn != null) { 9332 conn.waiting = true; 9333 } 9334 } 9335 checkTime(startTime, "getContentProviderImpl: done!"); 9336 } 9337 9338 // Wait for the provider to be published... 9339 synchronized (cpr) { 9340 while (cpr.provider == null) { 9341 if (cpr.launchingApp == null) { 9342 Slog.w(TAG, "Unable to launch app " 9343 + cpi.applicationInfo.packageName + "/" 9344 + cpi.applicationInfo.uid + " for provider " 9345 + name + ": launching app became null"); 9346 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9347 UserHandle.getUserId(cpi.applicationInfo.uid), 9348 cpi.applicationInfo.packageName, 9349 cpi.applicationInfo.uid, name); 9350 return null; 9351 } 9352 try { 9353 if (DEBUG_MU) { 9354 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9355 + cpr.launchingApp); 9356 } 9357 if (conn != null) { 9358 conn.waiting = true; 9359 } 9360 cpr.wait(); 9361 } catch (InterruptedException ex) { 9362 } finally { 9363 if (conn != null) { 9364 conn.waiting = false; 9365 } 9366 } 9367 } 9368 } 9369 return cpr != null ? cpr.newHolder(conn) : null; 9370 } 9371 9372 @Override 9373 public final ContentProviderHolder getContentProvider( 9374 IApplicationThread caller, String name, int userId, boolean stable) { 9375 enforceNotIsolatedCaller("getContentProvider"); 9376 if (caller == null) { 9377 String msg = "null IApplicationThread when getting content provider " 9378 + name; 9379 Slog.w(TAG, msg); 9380 throw new SecurityException(msg); 9381 } 9382 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9383 // with cross-user grant. 9384 return getContentProviderImpl(caller, name, null, stable, userId); 9385 } 9386 9387 public ContentProviderHolder getContentProviderExternal( 9388 String name, int userId, IBinder token) { 9389 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9390 "Do not have permission in call getContentProviderExternal()"); 9391 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9392 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9393 return getContentProviderExternalUnchecked(name, token, userId); 9394 } 9395 9396 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9397 IBinder token, int userId) { 9398 return getContentProviderImpl(null, name, token, true, userId); 9399 } 9400 9401 /** 9402 * Drop a content provider from a ProcessRecord's bookkeeping 9403 */ 9404 public void removeContentProvider(IBinder connection, boolean stable) { 9405 enforceNotIsolatedCaller("removeContentProvider"); 9406 long ident = Binder.clearCallingIdentity(); 9407 try { 9408 synchronized (this) { 9409 ContentProviderConnection conn; 9410 try { 9411 conn = (ContentProviderConnection)connection; 9412 } catch (ClassCastException e) { 9413 String msg ="removeContentProvider: " + connection 9414 + " not a ContentProviderConnection"; 9415 Slog.w(TAG, msg); 9416 throw new IllegalArgumentException(msg); 9417 } 9418 if (conn == null) { 9419 throw new NullPointerException("connection is null"); 9420 } 9421 if (decProviderCountLocked(conn, null, null, stable)) { 9422 updateOomAdjLocked(); 9423 } 9424 } 9425 } finally { 9426 Binder.restoreCallingIdentity(ident); 9427 } 9428 } 9429 9430 public void removeContentProviderExternal(String name, IBinder token) { 9431 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9432 "Do not have permission in call removeContentProviderExternal()"); 9433 int userId = UserHandle.getCallingUserId(); 9434 long ident = Binder.clearCallingIdentity(); 9435 try { 9436 removeContentProviderExternalUnchecked(name, token, userId); 9437 } finally { 9438 Binder.restoreCallingIdentity(ident); 9439 } 9440 } 9441 9442 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9443 synchronized (this) { 9444 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9445 if(cpr == null) { 9446 //remove from mProvidersByClass 9447 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9448 return; 9449 } 9450 9451 //update content provider record entry info 9452 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9453 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9454 if (localCpr.hasExternalProcessHandles()) { 9455 if (localCpr.removeExternalProcessHandleLocked(token)) { 9456 updateOomAdjLocked(); 9457 } else { 9458 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9459 + " with no external reference for token: " 9460 + token + "."); 9461 } 9462 } else { 9463 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9464 + " with no external references."); 9465 } 9466 } 9467 } 9468 9469 public final void publishContentProviders(IApplicationThread caller, 9470 List<ContentProviderHolder> providers) { 9471 if (providers == null) { 9472 return; 9473 } 9474 9475 enforceNotIsolatedCaller("publishContentProviders"); 9476 synchronized (this) { 9477 final ProcessRecord r = getRecordForAppLocked(caller); 9478 if (DEBUG_MU) 9479 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9480 if (r == null) { 9481 throw new SecurityException( 9482 "Unable to find app for caller " + caller 9483 + " (pid=" + Binder.getCallingPid() 9484 + ") when publishing content providers"); 9485 } 9486 9487 final long origId = Binder.clearCallingIdentity(); 9488 9489 final int N = providers.size(); 9490 for (int i=0; i<N; i++) { 9491 ContentProviderHolder src = providers.get(i); 9492 if (src == null || src.info == null || src.provider == null) { 9493 continue; 9494 } 9495 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9496 if (DEBUG_MU) 9497 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9498 if (dst != null) { 9499 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9500 mProviderMap.putProviderByClass(comp, dst); 9501 String names[] = dst.info.authority.split(";"); 9502 for (int j = 0; j < names.length; j++) { 9503 mProviderMap.putProviderByName(names[j], dst); 9504 } 9505 9506 int NL = mLaunchingProviders.size(); 9507 int j; 9508 for (j=0; j<NL; j++) { 9509 if (mLaunchingProviders.get(j) == dst) { 9510 mLaunchingProviders.remove(j); 9511 j--; 9512 NL--; 9513 } 9514 } 9515 synchronized (dst) { 9516 dst.provider = src.provider; 9517 dst.proc = r; 9518 dst.notifyAll(); 9519 } 9520 updateOomAdjLocked(r); 9521 } 9522 } 9523 9524 Binder.restoreCallingIdentity(origId); 9525 } 9526 } 9527 9528 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9529 ContentProviderConnection conn; 9530 try { 9531 conn = (ContentProviderConnection)connection; 9532 } catch (ClassCastException e) { 9533 String msg ="refContentProvider: " + connection 9534 + " not a ContentProviderConnection"; 9535 Slog.w(TAG, msg); 9536 throw new IllegalArgumentException(msg); 9537 } 9538 if (conn == null) { 9539 throw new NullPointerException("connection is null"); 9540 } 9541 9542 synchronized (this) { 9543 if (stable > 0) { 9544 conn.numStableIncs += stable; 9545 } 9546 stable = conn.stableCount + stable; 9547 if (stable < 0) { 9548 throw new IllegalStateException("stableCount < 0: " + stable); 9549 } 9550 9551 if (unstable > 0) { 9552 conn.numUnstableIncs += unstable; 9553 } 9554 unstable = conn.unstableCount + unstable; 9555 if (unstable < 0) { 9556 throw new IllegalStateException("unstableCount < 0: " + unstable); 9557 } 9558 9559 if ((stable+unstable) <= 0) { 9560 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9561 + stable + " unstable=" + unstable); 9562 } 9563 conn.stableCount = stable; 9564 conn.unstableCount = unstable; 9565 return !conn.dead; 9566 } 9567 } 9568 9569 public void unstableProviderDied(IBinder connection) { 9570 ContentProviderConnection conn; 9571 try { 9572 conn = (ContentProviderConnection)connection; 9573 } catch (ClassCastException e) { 9574 String msg ="refContentProvider: " + connection 9575 + " not a ContentProviderConnection"; 9576 Slog.w(TAG, msg); 9577 throw new IllegalArgumentException(msg); 9578 } 9579 if (conn == null) { 9580 throw new NullPointerException("connection is null"); 9581 } 9582 9583 // Safely retrieve the content provider associated with the connection. 9584 IContentProvider provider; 9585 synchronized (this) { 9586 provider = conn.provider.provider; 9587 } 9588 9589 if (provider == null) { 9590 // Um, yeah, we're way ahead of you. 9591 return; 9592 } 9593 9594 // Make sure the caller is being honest with us. 9595 if (provider.asBinder().pingBinder()) { 9596 // Er, no, still looks good to us. 9597 synchronized (this) { 9598 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9599 + " says " + conn + " died, but we don't agree"); 9600 return; 9601 } 9602 } 9603 9604 // Well look at that! It's dead! 9605 synchronized (this) { 9606 if (conn.provider.provider != provider) { 9607 // But something changed... good enough. 9608 return; 9609 } 9610 9611 ProcessRecord proc = conn.provider.proc; 9612 if (proc == null || proc.thread == null) { 9613 // Seems like the process is already cleaned up. 9614 return; 9615 } 9616 9617 // As far as we're concerned, this is just like receiving a 9618 // death notification... just a bit prematurely. 9619 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9620 + ") early provider death"); 9621 final long ident = Binder.clearCallingIdentity(); 9622 try { 9623 appDiedLocked(proc); 9624 } finally { 9625 Binder.restoreCallingIdentity(ident); 9626 } 9627 } 9628 } 9629 9630 @Override 9631 public void appNotRespondingViaProvider(IBinder connection) { 9632 enforceCallingPermission( 9633 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9634 9635 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9636 if (conn == null) { 9637 Slog.w(TAG, "ContentProviderConnection is null"); 9638 return; 9639 } 9640 9641 final ProcessRecord host = conn.provider.proc; 9642 if (host == null) { 9643 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9644 return; 9645 } 9646 9647 final long token = Binder.clearCallingIdentity(); 9648 try { 9649 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9650 } finally { 9651 Binder.restoreCallingIdentity(token); 9652 } 9653 } 9654 9655 public final void installSystemProviders() { 9656 List<ProviderInfo> providers; 9657 synchronized (this) { 9658 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9659 providers = generateApplicationProvidersLocked(app); 9660 if (providers != null) { 9661 for (int i=providers.size()-1; i>=0; i--) { 9662 ProviderInfo pi = (ProviderInfo)providers.get(i); 9663 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9664 Slog.w(TAG, "Not installing system proc provider " + pi.name 9665 + ": not system .apk"); 9666 providers.remove(i); 9667 } 9668 } 9669 } 9670 } 9671 if (providers != null) { 9672 mSystemThread.installSystemProviders(providers); 9673 } 9674 9675 mCoreSettingsObserver = new CoreSettingsObserver(this); 9676 9677 //mUsageStatsService.monitorPackages(); 9678 } 9679 9680 /** 9681 * Allows apps to retrieve the MIME type of a URI. 9682 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9683 * users, then it does not need permission to access the ContentProvider. 9684 * Either, it needs cross-user uri grants. 9685 * 9686 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9687 * 9688 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9689 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9690 */ 9691 public String getProviderMimeType(Uri uri, int userId) { 9692 enforceNotIsolatedCaller("getProviderMimeType"); 9693 final String name = uri.getAuthority(); 9694 int callingUid = Binder.getCallingUid(); 9695 int callingPid = Binder.getCallingPid(); 9696 long ident = 0; 9697 boolean clearedIdentity = false; 9698 userId = unsafeConvertIncomingUser(userId); 9699 if (canClearIdentity(callingPid, callingUid, userId)) { 9700 clearedIdentity = true; 9701 ident = Binder.clearCallingIdentity(); 9702 } 9703 ContentProviderHolder holder = null; 9704 try { 9705 holder = getContentProviderExternalUnchecked(name, null, userId); 9706 if (holder != null) { 9707 return holder.provider.getType(uri); 9708 } 9709 } catch (RemoteException e) { 9710 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9711 return null; 9712 } finally { 9713 // We need to clear the identity to call removeContentProviderExternalUnchecked 9714 if (!clearedIdentity) { 9715 ident = Binder.clearCallingIdentity(); 9716 } 9717 try { 9718 if (holder != null) { 9719 removeContentProviderExternalUnchecked(name, null, userId); 9720 } 9721 } finally { 9722 Binder.restoreCallingIdentity(ident); 9723 } 9724 } 9725 9726 return null; 9727 } 9728 9729 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9730 if (UserHandle.getUserId(callingUid) == userId) { 9731 return true; 9732 } 9733 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9734 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9735 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9736 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9737 return true; 9738 } 9739 return false; 9740 } 9741 9742 // ========================================================= 9743 // GLOBAL MANAGEMENT 9744 // ========================================================= 9745 9746 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9747 boolean isolated, int isolatedUid) { 9748 String proc = customProcess != null ? customProcess : info.processName; 9749 BatteryStatsImpl.Uid.Proc ps = null; 9750 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9751 int uid = info.uid; 9752 if (isolated) { 9753 if (isolatedUid == 0) { 9754 int userId = UserHandle.getUserId(uid); 9755 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9756 while (true) { 9757 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9758 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9759 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9760 } 9761 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9762 mNextIsolatedProcessUid++; 9763 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9764 // No process for this uid, use it. 9765 break; 9766 } 9767 stepsLeft--; 9768 if (stepsLeft <= 0) { 9769 return null; 9770 } 9771 } 9772 } else { 9773 // Special case for startIsolatedProcess (internal only), where 9774 // the uid of the isolated process is specified by the caller. 9775 uid = isolatedUid; 9776 } 9777 } 9778 return new ProcessRecord(stats, info, proc, uid); 9779 } 9780 9781 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9782 String abiOverride) { 9783 ProcessRecord app; 9784 if (!isolated) { 9785 app = getProcessRecordLocked(info.processName, info.uid, true); 9786 } else { 9787 app = null; 9788 } 9789 9790 if (app == null) { 9791 app = newProcessRecordLocked(info, null, isolated, 0); 9792 mProcessNames.put(info.processName, app.uid, app); 9793 if (isolated) { 9794 mIsolatedProcesses.put(app.uid, app); 9795 } 9796 updateLruProcessLocked(app, false, null); 9797 updateOomAdjLocked(); 9798 } 9799 9800 // This package really, really can not be stopped. 9801 try { 9802 AppGlobals.getPackageManager().setPackageStoppedState( 9803 info.packageName, false, UserHandle.getUserId(app.uid)); 9804 } catch (RemoteException e) { 9805 } catch (IllegalArgumentException e) { 9806 Slog.w(TAG, "Failed trying to unstop package " 9807 + info.packageName + ": " + e); 9808 } 9809 9810 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9811 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9812 app.persistent = true; 9813 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9814 } 9815 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9816 mPersistentStartingProcesses.add(app); 9817 startProcessLocked(app, "added application", app.processName, abiOverride, 9818 null /* entryPoint */, null /* entryPointArgs */); 9819 } 9820 9821 return app; 9822 } 9823 9824 public void unhandledBack() { 9825 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9826 "unhandledBack()"); 9827 9828 synchronized(this) { 9829 final long origId = Binder.clearCallingIdentity(); 9830 try { 9831 getFocusedStack().unhandledBackLocked(); 9832 } finally { 9833 Binder.restoreCallingIdentity(origId); 9834 } 9835 } 9836 } 9837 9838 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9839 enforceNotIsolatedCaller("openContentUri"); 9840 final int userId = UserHandle.getCallingUserId(); 9841 String name = uri.getAuthority(); 9842 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9843 ParcelFileDescriptor pfd = null; 9844 if (cph != null) { 9845 // We record the binder invoker's uid in thread-local storage before 9846 // going to the content provider to open the file. Later, in the code 9847 // that handles all permissions checks, we look for this uid and use 9848 // that rather than the Activity Manager's own uid. The effect is that 9849 // we do the check against the caller's permissions even though it looks 9850 // to the content provider like the Activity Manager itself is making 9851 // the request. 9852 sCallerIdentity.set(new Identity( 9853 Binder.getCallingPid(), Binder.getCallingUid())); 9854 try { 9855 pfd = cph.provider.openFile(null, uri, "r", null); 9856 } catch (FileNotFoundException e) { 9857 // do nothing; pfd will be returned null 9858 } finally { 9859 // Ensure that whatever happens, we clean up the identity state 9860 sCallerIdentity.remove(); 9861 } 9862 9863 // We've got the fd now, so we're done with the provider. 9864 removeContentProviderExternalUnchecked(name, null, userId); 9865 } else { 9866 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9867 } 9868 return pfd; 9869 } 9870 9871 // Actually is sleeping or shutting down or whatever else in the future 9872 // is an inactive state. 9873 public boolean isSleepingOrShuttingDown() { 9874 return isSleeping() || mShuttingDown; 9875 } 9876 9877 public boolean isSleeping() { 9878 return mSleeping; 9879 } 9880 9881 void goingToSleep() { 9882 synchronized(this) { 9883 mWentToSleep = true; 9884 goToSleepIfNeededLocked(); 9885 } 9886 } 9887 9888 void finishRunningVoiceLocked() { 9889 if (mRunningVoice) { 9890 mRunningVoice = false; 9891 goToSleepIfNeededLocked(); 9892 } 9893 } 9894 9895 void goToSleepIfNeededLocked() { 9896 if (mWentToSleep && !mRunningVoice) { 9897 if (!mSleeping) { 9898 mSleeping = true; 9899 mStackSupervisor.goingToSleepLocked(); 9900 9901 // Initialize the wake times of all processes. 9902 checkExcessivePowerUsageLocked(false); 9903 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9904 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9905 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9906 } 9907 } 9908 } 9909 9910 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9911 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9912 // Never persist the home stack. 9913 return; 9914 } 9915 mTaskPersister.wakeup(task, flush); 9916 } 9917 9918 @Override 9919 public boolean shutdown(int timeout) { 9920 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9921 != PackageManager.PERMISSION_GRANTED) { 9922 throw new SecurityException("Requires permission " 9923 + android.Manifest.permission.SHUTDOWN); 9924 } 9925 9926 boolean timedout = false; 9927 9928 synchronized(this) { 9929 mShuttingDown = true; 9930 updateEventDispatchingLocked(); 9931 timedout = mStackSupervisor.shutdownLocked(timeout); 9932 } 9933 9934 mAppOpsService.shutdown(); 9935 if (mUsageStatsService != null) { 9936 mUsageStatsService.prepareShutdown(); 9937 } 9938 mBatteryStatsService.shutdown(); 9939 synchronized (this) { 9940 mProcessStats.shutdownLocked(); 9941 } 9942 notifyTaskPersisterLocked(null, true); 9943 9944 return timedout; 9945 } 9946 9947 public final void activitySlept(IBinder token) { 9948 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9949 9950 final long origId = Binder.clearCallingIdentity(); 9951 9952 synchronized (this) { 9953 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9954 if (r != null) { 9955 mStackSupervisor.activitySleptLocked(r); 9956 } 9957 } 9958 9959 Binder.restoreCallingIdentity(origId); 9960 } 9961 9962 private String lockScreenShownToString() { 9963 switch (mLockScreenShown) { 9964 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9965 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9966 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9967 default: return "Unknown=" + mLockScreenShown; 9968 } 9969 } 9970 9971 void logLockScreen(String msg) { 9972 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9973 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 9974 mWentToSleep + " mSleeping=" + mSleeping); 9975 } 9976 9977 void comeOutOfSleepIfNeededLocked() { 9978 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 9979 if (mSleeping) { 9980 mSleeping = false; 9981 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9982 } 9983 } 9984 } 9985 9986 void wakingUp() { 9987 synchronized(this) { 9988 mWentToSleep = false; 9989 comeOutOfSleepIfNeededLocked(); 9990 } 9991 } 9992 9993 void startRunningVoiceLocked() { 9994 if (!mRunningVoice) { 9995 mRunningVoice = true; 9996 comeOutOfSleepIfNeededLocked(); 9997 } 9998 } 9999 10000 private void updateEventDispatchingLocked() { 10001 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10002 } 10003 10004 public void setLockScreenShown(boolean shown) { 10005 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10006 != PackageManager.PERMISSION_GRANTED) { 10007 throw new SecurityException("Requires permission " 10008 + android.Manifest.permission.DEVICE_POWER); 10009 } 10010 10011 synchronized(this) { 10012 long ident = Binder.clearCallingIdentity(); 10013 try { 10014 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10015 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10016 comeOutOfSleepIfNeededLocked(); 10017 } finally { 10018 Binder.restoreCallingIdentity(ident); 10019 } 10020 } 10021 } 10022 10023 @Override 10024 public void stopAppSwitches() { 10025 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10026 != PackageManager.PERMISSION_GRANTED) { 10027 throw new SecurityException("Requires permission " 10028 + android.Manifest.permission.STOP_APP_SWITCHES); 10029 } 10030 10031 synchronized(this) { 10032 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10033 + APP_SWITCH_DELAY_TIME; 10034 mDidAppSwitch = false; 10035 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10036 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10037 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10038 } 10039 } 10040 10041 public void resumeAppSwitches() { 10042 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10043 != PackageManager.PERMISSION_GRANTED) { 10044 throw new SecurityException("Requires permission " 10045 + android.Manifest.permission.STOP_APP_SWITCHES); 10046 } 10047 10048 synchronized(this) { 10049 // Note that we don't execute any pending app switches... we will 10050 // let those wait until either the timeout, or the next start 10051 // activity request. 10052 mAppSwitchesAllowedTime = 0; 10053 } 10054 } 10055 10056 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10057 int callingPid, int callingUid, String name) { 10058 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10059 return true; 10060 } 10061 10062 int perm = checkComponentPermission( 10063 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10064 sourceUid, -1, true); 10065 if (perm == PackageManager.PERMISSION_GRANTED) { 10066 return true; 10067 } 10068 10069 // If the actual IPC caller is different from the logical source, then 10070 // also see if they are allowed to control app switches. 10071 if (callingUid != -1 && callingUid != sourceUid) { 10072 perm = checkComponentPermission( 10073 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10074 callingUid, -1, true); 10075 if (perm == PackageManager.PERMISSION_GRANTED) { 10076 return true; 10077 } 10078 } 10079 10080 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10081 return false; 10082 } 10083 10084 public void setDebugApp(String packageName, boolean waitForDebugger, 10085 boolean persistent) { 10086 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10087 "setDebugApp()"); 10088 10089 long ident = Binder.clearCallingIdentity(); 10090 try { 10091 // Note that this is not really thread safe if there are multiple 10092 // callers into it at the same time, but that's not a situation we 10093 // care about. 10094 if (persistent) { 10095 final ContentResolver resolver = mContext.getContentResolver(); 10096 Settings.Global.putString( 10097 resolver, Settings.Global.DEBUG_APP, 10098 packageName); 10099 Settings.Global.putInt( 10100 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10101 waitForDebugger ? 1 : 0); 10102 } 10103 10104 synchronized (this) { 10105 if (!persistent) { 10106 mOrigDebugApp = mDebugApp; 10107 mOrigWaitForDebugger = mWaitForDebugger; 10108 } 10109 mDebugApp = packageName; 10110 mWaitForDebugger = waitForDebugger; 10111 mDebugTransient = !persistent; 10112 if (packageName != null) { 10113 forceStopPackageLocked(packageName, -1, false, false, true, true, 10114 false, UserHandle.USER_ALL, "set debug app"); 10115 } 10116 } 10117 } finally { 10118 Binder.restoreCallingIdentity(ident); 10119 } 10120 } 10121 10122 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10123 synchronized (this) { 10124 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10125 if (!isDebuggable) { 10126 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10127 throw new SecurityException("Process not debuggable: " + app.packageName); 10128 } 10129 } 10130 10131 mOpenGlTraceApp = processName; 10132 } 10133 } 10134 10135 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10136 synchronized (this) { 10137 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10138 if (!isDebuggable) { 10139 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10140 throw new SecurityException("Process not debuggable: " + app.packageName); 10141 } 10142 } 10143 mProfileApp = processName; 10144 mProfileFile = profilerInfo.profileFile; 10145 if (mProfileFd != null) { 10146 try { 10147 mProfileFd.close(); 10148 } catch (IOException e) { 10149 } 10150 mProfileFd = null; 10151 } 10152 mProfileFd = profilerInfo.profileFd; 10153 mSamplingInterval = profilerInfo.samplingInterval; 10154 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10155 mProfileType = 0; 10156 } 10157 } 10158 10159 @Override 10160 public void setAlwaysFinish(boolean enabled) { 10161 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10162 "setAlwaysFinish()"); 10163 10164 Settings.Global.putInt( 10165 mContext.getContentResolver(), 10166 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10167 10168 synchronized (this) { 10169 mAlwaysFinishActivities = enabled; 10170 } 10171 } 10172 10173 @Override 10174 public void setActivityController(IActivityController controller) { 10175 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10176 "setActivityController()"); 10177 synchronized (this) { 10178 mController = controller; 10179 Watchdog.getInstance().setActivityController(controller); 10180 } 10181 } 10182 10183 @Override 10184 public void setUserIsMonkey(boolean userIsMonkey) { 10185 synchronized (this) { 10186 synchronized (mPidsSelfLocked) { 10187 final int callingPid = Binder.getCallingPid(); 10188 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10189 if (precessRecord == null) { 10190 throw new SecurityException("Unknown process: " + callingPid); 10191 } 10192 if (precessRecord.instrumentationUiAutomationConnection == null) { 10193 throw new SecurityException("Only an instrumentation process " 10194 + "with a UiAutomation can call setUserIsMonkey"); 10195 } 10196 } 10197 mUserIsMonkey = userIsMonkey; 10198 } 10199 } 10200 10201 @Override 10202 public boolean isUserAMonkey() { 10203 synchronized (this) { 10204 // If there is a controller also implies the user is a monkey. 10205 return (mUserIsMonkey || mController != null); 10206 } 10207 } 10208 10209 public void requestBugReport() { 10210 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10211 SystemProperties.set("ctl.start", "bugreport"); 10212 } 10213 10214 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10215 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10216 } 10217 10218 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10219 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10220 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10221 } 10222 return KEY_DISPATCHING_TIMEOUT; 10223 } 10224 10225 @Override 10226 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10227 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10228 != PackageManager.PERMISSION_GRANTED) { 10229 throw new SecurityException("Requires permission " 10230 + android.Manifest.permission.FILTER_EVENTS); 10231 } 10232 ProcessRecord proc; 10233 long timeout; 10234 synchronized (this) { 10235 synchronized (mPidsSelfLocked) { 10236 proc = mPidsSelfLocked.get(pid); 10237 } 10238 timeout = getInputDispatchingTimeoutLocked(proc); 10239 } 10240 10241 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10242 return -1; 10243 } 10244 10245 return timeout; 10246 } 10247 10248 /** 10249 * Handle input dispatching timeouts. 10250 * Returns whether input dispatching should be aborted or not. 10251 */ 10252 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10253 final ActivityRecord activity, final ActivityRecord parent, 10254 final boolean aboveSystem, String reason) { 10255 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10256 != PackageManager.PERMISSION_GRANTED) { 10257 throw new SecurityException("Requires permission " 10258 + android.Manifest.permission.FILTER_EVENTS); 10259 } 10260 10261 final String annotation; 10262 if (reason == null) { 10263 annotation = "Input dispatching timed out"; 10264 } else { 10265 annotation = "Input dispatching timed out (" + reason + ")"; 10266 } 10267 10268 if (proc != null) { 10269 synchronized (this) { 10270 if (proc.debugging) { 10271 return false; 10272 } 10273 10274 if (mDidDexOpt) { 10275 // Give more time since we were dexopting. 10276 mDidDexOpt = false; 10277 return false; 10278 } 10279 10280 if (proc.instrumentationClass != null) { 10281 Bundle info = new Bundle(); 10282 info.putString("shortMsg", "keyDispatchingTimedOut"); 10283 info.putString("longMsg", annotation); 10284 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10285 return true; 10286 } 10287 } 10288 mHandler.post(new Runnable() { 10289 @Override 10290 public void run() { 10291 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10292 } 10293 }); 10294 } 10295 10296 return true; 10297 } 10298 10299 public Bundle getAssistContextExtras(int requestType) { 10300 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10301 UserHandle.getCallingUserId()); 10302 if (pae == null) { 10303 return null; 10304 } 10305 synchronized (pae) { 10306 while (!pae.haveResult) { 10307 try { 10308 pae.wait(); 10309 } catch (InterruptedException e) { 10310 } 10311 } 10312 if (pae.result != null) { 10313 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10314 } 10315 } 10316 synchronized (this) { 10317 mPendingAssistExtras.remove(pae); 10318 mHandler.removeCallbacks(pae); 10319 } 10320 return pae.extras; 10321 } 10322 10323 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10324 int userHandle) { 10325 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10326 "getAssistContextExtras()"); 10327 PendingAssistExtras pae; 10328 Bundle extras = new Bundle(); 10329 synchronized (this) { 10330 ActivityRecord activity = getFocusedStack().mResumedActivity; 10331 if (activity == null) { 10332 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10333 return null; 10334 } 10335 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10336 if (activity.app == null || activity.app.thread == null) { 10337 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10338 return null; 10339 } 10340 if (activity.app.pid == Binder.getCallingPid()) { 10341 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10342 return null; 10343 } 10344 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10345 try { 10346 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10347 requestType); 10348 mPendingAssistExtras.add(pae); 10349 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10350 } catch (RemoteException e) { 10351 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10352 return null; 10353 } 10354 return pae; 10355 } 10356 } 10357 10358 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10359 PendingAssistExtras pae = (PendingAssistExtras)token; 10360 synchronized (pae) { 10361 pae.result = extras; 10362 pae.haveResult = true; 10363 pae.notifyAll(); 10364 if (pae.intent == null) { 10365 // Caller is just waiting for the result. 10366 return; 10367 } 10368 } 10369 10370 // We are now ready to launch the assist activity. 10371 synchronized (this) { 10372 boolean exists = mPendingAssistExtras.remove(pae); 10373 mHandler.removeCallbacks(pae); 10374 if (!exists) { 10375 // Timed out. 10376 return; 10377 } 10378 } 10379 pae.intent.replaceExtras(extras); 10380 if (pae.hint != null) { 10381 pae.intent.putExtra(pae.hint, true); 10382 } 10383 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10384 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10385 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10386 closeSystemDialogs("assist"); 10387 try { 10388 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10389 } catch (ActivityNotFoundException e) { 10390 Slog.w(TAG, "No activity to handle assist action.", e); 10391 } 10392 } 10393 10394 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10395 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10396 } 10397 10398 public void registerProcessObserver(IProcessObserver observer) { 10399 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10400 "registerProcessObserver()"); 10401 synchronized (this) { 10402 mProcessObservers.register(observer); 10403 } 10404 } 10405 10406 @Override 10407 public void unregisterProcessObserver(IProcessObserver observer) { 10408 synchronized (this) { 10409 mProcessObservers.unregister(observer); 10410 } 10411 } 10412 10413 @Override 10414 public boolean convertFromTranslucent(IBinder token) { 10415 final long origId = Binder.clearCallingIdentity(); 10416 try { 10417 synchronized (this) { 10418 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10419 if (r == null) { 10420 return false; 10421 } 10422 final boolean translucentChanged = r.changeWindowTranslucency(true); 10423 if (translucentChanged) { 10424 r.task.stack.releaseBackgroundResources(); 10425 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10426 } 10427 mWindowManager.setAppFullscreen(token, true); 10428 return translucentChanged; 10429 } 10430 } finally { 10431 Binder.restoreCallingIdentity(origId); 10432 } 10433 } 10434 10435 @Override 10436 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10437 final long origId = Binder.clearCallingIdentity(); 10438 try { 10439 synchronized (this) { 10440 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10441 if (r == null) { 10442 return false; 10443 } 10444 int index = r.task.mActivities.lastIndexOf(r); 10445 if (index > 0) { 10446 ActivityRecord under = r.task.mActivities.get(index - 1); 10447 under.returningOptions = options; 10448 } 10449 final boolean translucentChanged = r.changeWindowTranslucency(false); 10450 if (translucentChanged) { 10451 r.task.stack.convertToTranslucent(r); 10452 } 10453 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10454 mWindowManager.setAppFullscreen(token, false); 10455 return translucentChanged; 10456 } 10457 } finally { 10458 Binder.restoreCallingIdentity(origId); 10459 } 10460 } 10461 10462 @Override 10463 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10464 final long origId = Binder.clearCallingIdentity(); 10465 try { 10466 synchronized (this) { 10467 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10468 if (r != null) { 10469 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10470 } 10471 } 10472 return false; 10473 } finally { 10474 Binder.restoreCallingIdentity(origId); 10475 } 10476 } 10477 10478 @Override 10479 public boolean isBackgroundVisibleBehind(IBinder token) { 10480 final long origId = Binder.clearCallingIdentity(); 10481 try { 10482 synchronized (this) { 10483 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10484 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10485 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10486 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10487 return visible; 10488 } 10489 } finally { 10490 Binder.restoreCallingIdentity(origId); 10491 } 10492 } 10493 10494 @Override 10495 public ActivityOptions getActivityOptions(IBinder token) { 10496 final long origId = Binder.clearCallingIdentity(); 10497 try { 10498 synchronized (this) { 10499 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10500 if (r != null) { 10501 final ActivityOptions activityOptions = r.pendingOptions; 10502 r.pendingOptions = null; 10503 return activityOptions; 10504 } 10505 return null; 10506 } 10507 } finally { 10508 Binder.restoreCallingIdentity(origId); 10509 } 10510 } 10511 10512 @Override 10513 public void setImmersive(IBinder token, boolean immersive) { 10514 synchronized(this) { 10515 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10516 if (r == null) { 10517 throw new IllegalArgumentException(); 10518 } 10519 r.immersive = immersive; 10520 10521 // update associated state if we're frontmost 10522 if (r == mFocusedActivity) { 10523 if (DEBUG_IMMERSIVE) { 10524 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10525 } 10526 applyUpdateLockStateLocked(r); 10527 } 10528 } 10529 } 10530 10531 @Override 10532 public boolean isImmersive(IBinder token) { 10533 synchronized (this) { 10534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10535 if (r == null) { 10536 throw new IllegalArgumentException(); 10537 } 10538 return r.immersive; 10539 } 10540 } 10541 10542 public boolean isTopActivityImmersive() { 10543 enforceNotIsolatedCaller("startActivity"); 10544 synchronized (this) { 10545 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10546 return (r != null) ? r.immersive : false; 10547 } 10548 } 10549 10550 @Override 10551 public boolean isTopOfTask(IBinder token) { 10552 synchronized (this) { 10553 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10554 if (r == null) { 10555 throw new IllegalArgumentException(); 10556 } 10557 return r.task.getTopActivity() == r; 10558 } 10559 } 10560 10561 public final void enterSafeMode() { 10562 synchronized(this) { 10563 // It only makes sense to do this before the system is ready 10564 // and started launching other packages. 10565 if (!mSystemReady) { 10566 try { 10567 AppGlobals.getPackageManager().enterSafeMode(); 10568 } catch (RemoteException e) { 10569 } 10570 } 10571 10572 mSafeMode = true; 10573 } 10574 } 10575 10576 public final void showSafeModeOverlay() { 10577 View v = LayoutInflater.from(mContext).inflate( 10578 com.android.internal.R.layout.safe_mode, null); 10579 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10580 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10581 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10582 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10583 lp.gravity = Gravity.BOTTOM | Gravity.START; 10584 lp.format = v.getBackground().getOpacity(); 10585 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10586 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10587 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10588 ((WindowManager)mContext.getSystemService( 10589 Context.WINDOW_SERVICE)).addView(v, lp); 10590 } 10591 10592 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10593 if (!(sender instanceof PendingIntentRecord)) { 10594 return; 10595 } 10596 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10597 synchronized (stats) { 10598 if (mBatteryStatsService.isOnBattery()) { 10599 mBatteryStatsService.enforceCallingPermission(); 10600 PendingIntentRecord rec = (PendingIntentRecord)sender; 10601 int MY_UID = Binder.getCallingUid(); 10602 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10603 BatteryStatsImpl.Uid.Pkg pkg = 10604 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10605 sourcePkg != null ? sourcePkg : rec.key.packageName); 10606 pkg.incWakeupsLocked(); 10607 } 10608 } 10609 } 10610 10611 public boolean killPids(int[] pids, String pReason, boolean secure) { 10612 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10613 throw new SecurityException("killPids only available to the system"); 10614 } 10615 String reason = (pReason == null) ? "Unknown" : pReason; 10616 // XXX Note: don't acquire main activity lock here, because the window 10617 // manager calls in with its locks held. 10618 10619 boolean killed = false; 10620 synchronized (mPidsSelfLocked) { 10621 int[] types = new int[pids.length]; 10622 int worstType = 0; 10623 for (int i=0; i<pids.length; i++) { 10624 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10625 if (proc != null) { 10626 int type = proc.setAdj; 10627 types[i] = type; 10628 if (type > worstType) { 10629 worstType = type; 10630 } 10631 } 10632 } 10633 10634 // If the worst oom_adj is somewhere in the cached proc LRU range, 10635 // then constrain it so we will kill all cached procs. 10636 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10637 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10638 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10639 } 10640 10641 // If this is not a secure call, don't let it kill processes that 10642 // are important. 10643 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10644 worstType = ProcessList.SERVICE_ADJ; 10645 } 10646 10647 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10648 for (int i=0; i<pids.length; i++) { 10649 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10650 if (proc == null) { 10651 continue; 10652 } 10653 int adj = proc.setAdj; 10654 if (adj >= worstType && !proc.killedByAm) { 10655 proc.kill(reason, true); 10656 killed = true; 10657 } 10658 } 10659 } 10660 return killed; 10661 } 10662 10663 @Override 10664 public void killUid(int uid, String reason) { 10665 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10666 throw new SecurityException("killUid only available to the system"); 10667 } 10668 synchronized (this) { 10669 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10670 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10671 reason != null ? reason : "kill uid"); 10672 } 10673 } 10674 10675 @Override 10676 public boolean killProcessesBelowForeground(String reason) { 10677 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10678 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10679 } 10680 10681 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10682 } 10683 10684 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10685 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10686 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10687 } 10688 10689 boolean killed = false; 10690 synchronized (mPidsSelfLocked) { 10691 final int size = mPidsSelfLocked.size(); 10692 for (int i = 0; i < size; i++) { 10693 final int pid = mPidsSelfLocked.keyAt(i); 10694 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10695 if (proc == null) continue; 10696 10697 final int adj = proc.setAdj; 10698 if (adj > belowAdj && !proc.killedByAm) { 10699 proc.kill(reason, true); 10700 killed = true; 10701 } 10702 } 10703 } 10704 return killed; 10705 } 10706 10707 @Override 10708 public void hang(final IBinder who, boolean allowRestart) { 10709 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10710 != PackageManager.PERMISSION_GRANTED) { 10711 throw new SecurityException("Requires permission " 10712 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10713 } 10714 10715 final IBinder.DeathRecipient death = new DeathRecipient() { 10716 @Override 10717 public void binderDied() { 10718 synchronized (this) { 10719 notifyAll(); 10720 } 10721 } 10722 }; 10723 10724 try { 10725 who.linkToDeath(death, 0); 10726 } catch (RemoteException e) { 10727 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10728 return; 10729 } 10730 10731 synchronized (this) { 10732 Watchdog.getInstance().setAllowRestart(allowRestart); 10733 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10734 synchronized (death) { 10735 while (who.isBinderAlive()) { 10736 try { 10737 death.wait(); 10738 } catch (InterruptedException e) { 10739 } 10740 } 10741 } 10742 Watchdog.getInstance().setAllowRestart(true); 10743 } 10744 } 10745 10746 @Override 10747 public void restart() { 10748 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10749 != PackageManager.PERMISSION_GRANTED) { 10750 throw new SecurityException("Requires permission " 10751 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10752 } 10753 10754 Log.i(TAG, "Sending shutdown broadcast..."); 10755 10756 BroadcastReceiver br = new BroadcastReceiver() { 10757 @Override public void onReceive(Context context, Intent intent) { 10758 // Now the broadcast is done, finish up the low-level shutdown. 10759 Log.i(TAG, "Shutting down activity manager..."); 10760 shutdown(10000); 10761 Log.i(TAG, "Shutdown complete, restarting!"); 10762 Process.killProcess(Process.myPid()); 10763 System.exit(10); 10764 } 10765 }; 10766 10767 // First send the high-level shut down broadcast. 10768 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10769 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10770 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10771 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10772 mContext.sendOrderedBroadcastAsUser(intent, 10773 UserHandle.ALL, null, br, mHandler, 0, null, null); 10774 */ 10775 br.onReceive(mContext, intent); 10776 } 10777 10778 private long getLowRamTimeSinceIdle(long now) { 10779 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10780 } 10781 10782 @Override 10783 public void performIdleMaintenance() { 10784 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10785 != PackageManager.PERMISSION_GRANTED) { 10786 throw new SecurityException("Requires permission " 10787 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10788 } 10789 10790 synchronized (this) { 10791 final long now = SystemClock.uptimeMillis(); 10792 final long timeSinceLastIdle = now - mLastIdleTime; 10793 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10794 mLastIdleTime = now; 10795 mLowRamTimeSinceLastIdle = 0; 10796 if (mLowRamStartTime != 0) { 10797 mLowRamStartTime = now; 10798 } 10799 10800 StringBuilder sb = new StringBuilder(128); 10801 sb.append("Idle maintenance over "); 10802 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10803 sb.append(" low RAM for "); 10804 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10805 Slog.i(TAG, sb.toString()); 10806 10807 // If at least 1/3 of our time since the last idle period has been spent 10808 // with RAM low, then we want to kill processes. 10809 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10810 10811 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10812 ProcessRecord proc = mLruProcesses.get(i); 10813 if (proc.notCachedSinceIdle) { 10814 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10815 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10816 if (doKilling && proc.initialIdlePss != 0 10817 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10818 proc.kill("idle maint (pss " + proc.lastPss 10819 + " from " + proc.initialIdlePss + ")", true); 10820 } 10821 } 10822 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10823 proc.notCachedSinceIdle = true; 10824 proc.initialIdlePss = 0; 10825 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10826 isSleeping(), now); 10827 } 10828 } 10829 10830 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10831 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10832 } 10833 } 10834 10835 private void retrieveSettings() { 10836 final ContentResolver resolver = mContext.getContentResolver(); 10837 String debugApp = Settings.Global.getString( 10838 resolver, Settings.Global.DEBUG_APP); 10839 boolean waitForDebugger = Settings.Global.getInt( 10840 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10841 boolean alwaysFinishActivities = Settings.Global.getInt( 10842 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10843 boolean forceRtl = Settings.Global.getInt( 10844 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10845 // Transfer any global setting for forcing RTL layout, into a System Property 10846 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10847 10848 Configuration configuration = new Configuration(); 10849 Settings.System.getConfiguration(resolver, configuration); 10850 if (forceRtl) { 10851 // This will take care of setting the correct layout direction flags 10852 configuration.setLayoutDirection(configuration.locale); 10853 } 10854 10855 synchronized (this) { 10856 mDebugApp = mOrigDebugApp = debugApp; 10857 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10858 mAlwaysFinishActivities = alwaysFinishActivities; 10859 // This happens before any activities are started, so we can 10860 // change mConfiguration in-place. 10861 updateConfigurationLocked(configuration, null, false, true); 10862 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10863 } 10864 } 10865 10866 /** Loads resources after the current configuration has been set. */ 10867 private void loadResourcesOnSystemReady() { 10868 final Resources res = mContext.getResources(); 10869 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10870 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10871 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10872 } 10873 10874 public boolean testIsSystemReady() { 10875 // no need to synchronize(this) just to read & return the value 10876 return mSystemReady; 10877 } 10878 10879 private static File getCalledPreBootReceiversFile() { 10880 File dataDir = Environment.getDataDirectory(); 10881 File systemDir = new File(dataDir, "system"); 10882 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10883 return fname; 10884 } 10885 10886 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10887 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10888 File file = getCalledPreBootReceiversFile(); 10889 FileInputStream fis = null; 10890 try { 10891 fis = new FileInputStream(file); 10892 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10893 int fvers = dis.readInt(); 10894 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10895 String vers = dis.readUTF(); 10896 String codename = dis.readUTF(); 10897 String build = dis.readUTF(); 10898 if (android.os.Build.VERSION.RELEASE.equals(vers) 10899 && android.os.Build.VERSION.CODENAME.equals(codename) 10900 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10901 int num = dis.readInt(); 10902 while (num > 0) { 10903 num--; 10904 String pkg = dis.readUTF(); 10905 String cls = dis.readUTF(); 10906 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10907 } 10908 } 10909 } 10910 } catch (FileNotFoundException e) { 10911 } catch (IOException e) { 10912 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10913 } finally { 10914 if (fis != null) { 10915 try { 10916 fis.close(); 10917 } catch (IOException e) { 10918 } 10919 } 10920 } 10921 return lastDoneReceivers; 10922 } 10923 10924 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10925 File file = getCalledPreBootReceiversFile(); 10926 FileOutputStream fos = null; 10927 DataOutputStream dos = null; 10928 try { 10929 fos = new FileOutputStream(file); 10930 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10931 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10932 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10933 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10934 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10935 dos.writeInt(list.size()); 10936 for (int i=0; i<list.size(); i++) { 10937 dos.writeUTF(list.get(i).getPackageName()); 10938 dos.writeUTF(list.get(i).getClassName()); 10939 } 10940 } catch (IOException e) { 10941 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10942 file.delete(); 10943 } finally { 10944 FileUtils.sync(fos); 10945 if (dos != null) { 10946 try { 10947 dos.close(); 10948 } catch (IOException e) { 10949 // TODO Auto-generated catch block 10950 e.printStackTrace(); 10951 } 10952 } 10953 } 10954 } 10955 10956 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10957 ArrayList<ComponentName> doneReceivers, int userId) { 10958 boolean waitingUpdate = false; 10959 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10960 List<ResolveInfo> ris = null; 10961 try { 10962 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10963 intent, null, 0, userId); 10964 } catch (RemoteException e) { 10965 } 10966 if (ris != null) { 10967 for (int i=ris.size()-1; i>=0; i--) { 10968 if ((ris.get(i).activityInfo.applicationInfo.flags 10969 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10970 ris.remove(i); 10971 } 10972 } 10973 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10974 10975 // For User 0, load the version number. When delivering to a new user, deliver 10976 // to all receivers. 10977 if (userId == UserHandle.USER_OWNER) { 10978 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10979 for (int i=0; i<ris.size(); i++) { 10980 ActivityInfo ai = ris.get(i).activityInfo; 10981 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10982 if (lastDoneReceivers.contains(comp)) { 10983 // We already did the pre boot receiver for this app with the current 10984 // platform version, so don't do it again... 10985 ris.remove(i); 10986 i--; 10987 // ...however, do keep it as one that has been done, so we don't 10988 // forget about it when rewriting the file of last done receivers. 10989 doneReceivers.add(comp); 10990 } 10991 } 10992 } 10993 10994 // If primary user, send broadcast to all available users, else just to userId 10995 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10996 : new int[] { userId }; 10997 for (int i = 0; i < ris.size(); i++) { 10998 ActivityInfo ai = ris.get(i).activityInfo; 10999 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11000 doneReceivers.add(comp); 11001 intent.setComponent(comp); 11002 for (int j=0; j<users.length; j++) { 11003 IIntentReceiver finisher = null; 11004 // On last receiver and user, set up a completion callback 11005 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11006 finisher = new IIntentReceiver.Stub() { 11007 public void performReceive(Intent intent, int resultCode, 11008 String data, Bundle extras, boolean ordered, 11009 boolean sticky, int sendingUser) { 11010 // The raw IIntentReceiver interface is called 11011 // with the AM lock held, so redispatch to 11012 // execute our code without the lock. 11013 mHandler.post(onFinishCallback); 11014 } 11015 }; 11016 } 11017 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11018 + " for user " + users[j]); 11019 broadcastIntentLocked(null, null, intent, null, finisher, 11020 0, null, null, null, AppOpsManager.OP_NONE, 11021 true, false, MY_PID, Process.SYSTEM_UID, 11022 users[j]); 11023 if (finisher != null) { 11024 waitingUpdate = true; 11025 } 11026 } 11027 } 11028 } 11029 11030 return waitingUpdate; 11031 } 11032 11033 public void systemReady(final Runnable goingCallback) { 11034 synchronized(this) { 11035 if (mSystemReady) { 11036 // If we're done calling all the receivers, run the next "boot phase" passed in 11037 // by the SystemServer 11038 if (goingCallback != null) { 11039 goingCallback.run(); 11040 } 11041 return; 11042 } 11043 11044 // Make sure we have the current profile info, since it is needed for 11045 // security checks. 11046 updateCurrentProfileIdsLocked(); 11047 11048 if (mRecentTasks == null) { 11049 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11050 if (!mRecentTasks.isEmpty()) { 11051 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11052 } 11053 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11054 mTaskPersister.startPersisting(); 11055 } 11056 11057 // Check to see if there are any update receivers to run. 11058 if (!mDidUpdate) { 11059 if (mWaitingUpdate) { 11060 return; 11061 } 11062 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11063 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11064 public void run() { 11065 synchronized (ActivityManagerService.this) { 11066 mDidUpdate = true; 11067 } 11068 writeLastDonePreBootReceivers(doneReceivers); 11069 showBootMessage(mContext.getText( 11070 R.string.android_upgrading_complete), 11071 false); 11072 systemReady(goingCallback); 11073 } 11074 }, doneReceivers, UserHandle.USER_OWNER); 11075 11076 if (mWaitingUpdate) { 11077 return; 11078 } 11079 mDidUpdate = true; 11080 } 11081 11082 mAppOpsService.systemReady(); 11083 mSystemReady = true; 11084 } 11085 11086 ArrayList<ProcessRecord> procsToKill = null; 11087 synchronized(mPidsSelfLocked) { 11088 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11089 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11090 if (!isAllowedWhileBooting(proc.info)){ 11091 if (procsToKill == null) { 11092 procsToKill = new ArrayList<ProcessRecord>(); 11093 } 11094 procsToKill.add(proc); 11095 } 11096 } 11097 } 11098 11099 synchronized(this) { 11100 if (procsToKill != null) { 11101 for (int i=procsToKill.size()-1; i>=0; i--) { 11102 ProcessRecord proc = procsToKill.get(i); 11103 Slog.i(TAG, "Removing system update proc: " + proc); 11104 removeProcessLocked(proc, true, false, "system update done"); 11105 } 11106 } 11107 11108 // Now that we have cleaned up any update processes, we 11109 // are ready to start launching real processes and know that 11110 // we won't trample on them any more. 11111 mProcessesReady = true; 11112 } 11113 11114 Slog.i(TAG, "System now ready"); 11115 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11116 SystemClock.uptimeMillis()); 11117 11118 synchronized(this) { 11119 // Make sure we have no pre-ready processes sitting around. 11120 11121 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11122 ResolveInfo ri = mContext.getPackageManager() 11123 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11124 STOCK_PM_FLAGS); 11125 CharSequence errorMsg = null; 11126 if (ri != null) { 11127 ActivityInfo ai = ri.activityInfo; 11128 ApplicationInfo app = ai.applicationInfo; 11129 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11130 mTopAction = Intent.ACTION_FACTORY_TEST; 11131 mTopData = null; 11132 mTopComponent = new ComponentName(app.packageName, 11133 ai.name); 11134 } else { 11135 errorMsg = mContext.getResources().getText( 11136 com.android.internal.R.string.factorytest_not_system); 11137 } 11138 } else { 11139 errorMsg = mContext.getResources().getText( 11140 com.android.internal.R.string.factorytest_no_action); 11141 } 11142 if (errorMsg != null) { 11143 mTopAction = null; 11144 mTopData = null; 11145 mTopComponent = null; 11146 Message msg = Message.obtain(); 11147 msg.what = SHOW_FACTORY_ERROR_MSG; 11148 msg.getData().putCharSequence("msg", errorMsg); 11149 mHandler.sendMessage(msg); 11150 } 11151 } 11152 } 11153 11154 retrieveSettings(); 11155 loadResourcesOnSystemReady(); 11156 11157 synchronized (this) { 11158 readGrantedUriPermissionsLocked(); 11159 } 11160 11161 if (goingCallback != null) goingCallback.run(); 11162 11163 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11164 Integer.toString(mCurrentUserId), mCurrentUserId); 11165 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11166 Integer.toString(mCurrentUserId), mCurrentUserId); 11167 mSystemServiceManager.startUser(mCurrentUserId); 11168 11169 synchronized (this) { 11170 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11171 try { 11172 List apps = AppGlobals.getPackageManager(). 11173 getPersistentApplications(STOCK_PM_FLAGS); 11174 if (apps != null) { 11175 int N = apps.size(); 11176 int i; 11177 for (i=0; i<N; i++) { 11178 ApplicationInfo info 11179 = (ApplicationInfo)apps.get(i); 11180 if (info != null && 11181 !info.packageName.equals("android")) { 11182 addAppLocked(info, false, null /* ABI override */); 11183 } 11184 } 11185 } 11186 } catch (RemoteException ex) { 11187 // pm is in same process, this will never happen. 11188 } 11189 } 11190 11191 // Start up initial activity. 11192 mBooting = true; 11193 startHomeActivityLocked(mCurrentUserId); 11194 11195 try { 11196 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11197 Message msg = Message.obtain(); 11198 msg.what = SHOW_UID_ERROR_MSG; 11199 mHandler.sendMessage(msg); 11200 } 11201 } catch (RemoteException e) { 11202 } 11203 11204 long ident = Binder.clearCallingIdentity(); 11205 try { 11206 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11207 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11208 | Intent.FLAG_RECEIVER_FOREGROUND); 11209 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11210 broadcastIntentLocked(null, null, intent, 11211 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11212 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11213 intent = new Intent(Intent.ACTION_USER_STARTING); 11214 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11215 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11216 broadcastIntentLocked(null, null, intent, 11217 null, new IIntentReceiver.Stub() { 11218 @Override 11219 public void performReceive(Intent intent, int resultCode, String data, 11220 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11221 throws RemoteException { 11222 } 11223 }, 0, null, null, 11224 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11225 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11226 } catch (Throwable t) { 11227 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11228 } finally { 11229 Binder.restoreCallingIdentity(ident); 11230 } 11231 mStackSupervisor.resumeTopActivitiesLocked(); 11232 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11233 } 11234 } 11235 11236 private boolean makeAppCrashingLocked(ProcessRecord app, 11237 String shortMsg, String longMsg, String stackTrace) { 11238 app.crashing = true; 11239 app.crashingReport = generateProcessError(app, 11240 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11241 startAppProblemLocked(app); 11242 app.stopFreezingAllLocked(); 11243 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11244 } 11245 11246 private void makeAppNotRespondingLocked(ProcessRecord app, 11247 String activity, String shortMsg, String longMsg) { 11248 app.notResponding = true; 11249 app.notRespondingReport = generateProcessError(app, 11250 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11251 activity, shortMsg, longMsg, null); 11252 startAppProblemLocked(app); 11253 app.stopFreezingAllLocked(); 11254 } 11255 11256 /** 11257 * Generate a process error record, suitable for attachment to a ProcessRecord. 11258 * 11259 * @param app The ProcessRecord in which the error occurred. 11260 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11261 * ActivityManager.AppErrorStateInfo 11262 * @param activity The activity associated with the crash, if known. 11263 * @param shortMsg Short message describing the crash. 11264 * @param longMsg Long message describing the crash. 11265 * @param stackTrace Full crash stack trace, may be null. 11266 * 11267 * @return Returns a fully-formed AppErrorStateInfo record. 11268 */ 11269 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11270 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11271 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11272 11273 report.condition = condition; 11274 report.processName = app.processName; 11275 report.pid = app.pid; 11276 report.uid = app.info.uid; 11277 report.tag = activity; 11278 report.shortMsg = shortMsg; 11279 report.longMsg = longMsg; 11280 report.stackTrace = stackTrace; 11281 11282 return report; 11283 } 11284 11285 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11286 synchronized (this) { 11287 app.crashing = false; 11288 app.crashingReport = null; 11289 app.notResponding = false; 11290 app.notRespondingReport = null; 11291 if (app.anrDialog == fromDialog) { 11292 app.anrDialog = null; 11293 } 11294 if (app.waitDialog == fromDialog) { 11295 app.waitDialog = null; 11296 } 11297 if (app.pid > 0 && app.pid != MY_PID) { 11298 handleAppCrashLocked(app, null, null, null); 11299 app.kill("user request after error", true); 11300 } 11301 } 11302 } 11303 11304 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11305 String stackTrace) { 11306 long now = SystemClock.uptimeMillis(); 11307 11308 Long crashTime; 11309 if (!app.isolated) { 11310 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11311 } else { 11312 crashTime = null; 11313 } 11314 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11315 // This process loses! 11316 Slog.w(TAG, "Process " + app.info.processName 11317 + " has crashed too many times: killing!"); 11318 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11319 app.userId, app.info.processName, app.uid); 11320 mStackSupervisor.handleAppCrashLocked(app); 11321 if (!app.persistent) { 11322 // We don't want to start this process again until the user 11323 // explicitly does so... but for persistent process, we really 11324 // need to keep it running. If a persistent process is actually 11325 // repeatedly crashing, then badness for everyone. 11326 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11327 app.info.processName); 11328 if (!app.isolated) { 11329 // XXX We don't have a way to mark isolated processes 11330 // as bad, since they don't have a peristent identity. 11331 mBadProcesses.put(app.info.processName, app.uid, 11332 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11333 mProcessCrashTimes.remove(app.info.processName, app.uid); 11334 } 11335 app.bad = true; 11336 app.removed = true; 11337 // Don't let services in this process be restarted and potentially 11338 // annoy the user repeatedly. Unless it is persistent, since those 11339 // processes run critical code. 11340 removeProcessLocked(app, false, false, "crash"); 11341 mStackSupervisor.resumeTopActivitiesLocked(); 11342 return false; 11343 } 11344 mStackSupervisor.resumeTopActivitiesLocked(); 11345 } else { 11346 mStackSupervisor.finishTopRunningActivityLocked(app); 11347 } 11348 11349 // Bump up the crash count of any services currently running in the proc. 11350 for (int i=app.services.size()-1; i>=0; i--) { 11351 // Any services running in the application need to be placed 11352 // back in the pending list. 11353 ServiceRecord sr = app.services.valueAt(i); 11354 sr.crashCount++; 11355 } 11356 11357 // If the crashing process is what we consider to be the "home process" and it has been 11358 // replaced by a third-party app, clear the package preferred activities from packages 11359 // with a home activity running in the process to prevent a repeatedly crashing app 11360 // from blocking the user to manually clear the list. 11361 final ArrayList<ActivityRecord> activities = app.activities; 11362 if (app == mHomeProcess && activities.size() > 0 11363 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11364 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11365 final ActivityRecord r = activities.get(activityNdx); 11366 if (r.isHomeActivity()) { 11367 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11368 try { 11369 ActivityThread.getPackageManager() 11370 .clearPackagePreferredActivities(r.packageName); 11371 } catch (RemoteException c) { 11372 // pm is in same process, this will never happen. 11373 } 11374 } 11375 } 11376 } 11377 11378 if (!app.isolated) { 11379 // XXX Can't keep track of crash times for isolated processes, 11380 // because they don't have a perisistent identity. 11381 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11382 } 11383 11384 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11385 return true; 11386 } 11387 11388 void startAppProblemLocked(ProcessRecord app) { 11389 // If this app is not running under the current user, then we 11390 // can't give it a report button because that would require 11391 // launching the report UI under a different user. 11392 app.errorReportReceiver = null; 11393 11394 for (int userId : mCurrentProfileIds) { 11395 if (app.userId == userId) { 11396 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11397 mContext, app.info.packageName, app.info.flags); 11398 } 11399 } 11400 skipCurrentReceiverLocked(app); 11401 } 11402 11403 void skipCurrentReceiverLocked(ProcessRecord app) { 11404 for (BroadcastQueue queue : mBroadcastQueues) { 11405 queue.skipCurrentReceiverLocked(app); 11406 } 11407 } 11408 11409 /** 11410 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11411 * The application process will exit immediately after this call returns. 11412 * @param app object of the crashing app, null for the system server 11413 * @param crashInfo describing the exception 11414 */ 11415 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11416 ProcessRecord r = findAppProcess(app, "Crash"); 11417 final String processName = app == null ? "system_server" 11418 : (r == null ? "unknown" : r.processName); 11419 11420 handleApplicationCrashInner("crash", r, processName, crashInfo); 11421 } 11422 11423 /* Native crash reporting uses this inner version because it needs to be somewhat 11424 * decoupled from the AM-managed cleanup lifecycle 11425 */ 11426 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11427 ApplicationErrorReport.CrashInfo crashInfo) { 11428 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11429 UserHandle.getUserId(Binder.getCallingUid()), processName, 11430 r == null ? -1 : r.info.flags, 11431 crashInfo.exceptionClassName, 11432 crashInfo.exceptionMessage, 11433 crashInfo.throwFileName, 11434 crashInfo.throwLineNumber); 11435 11436 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11437 11438 crashApplication(r, crashInfo); 11439 } 11440 11441 public void handleApplicationStrictModeViolation( 11442 IBinder app, 11443 int violationMask, 11444 StrictMode.ViolationInfo info) { 11445 ProcessRecord r = findAppProcess(app, "StrictMode"); 11446 if (r == null) { 11447 return; 11448 } 11449 11450 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11451 Integer stackFingerprint = info.hashCode(); 11452 boolean logIt = true; 11453 synchronized (mAlreadyLoggedViolatedStacks) { 11454 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11455 logIt = false; 11456 // TODO: sub-sample into EventLog for these, with 11457 // the info.durationMillis? Then we'd get 11458 // the relative pain numbers, without logging all 11459 // the stack traces repeatedly. We'd want to do 11460 // likewise in the client code, which also does 11461 // dup suppression, before the Binder call. 11462 } else { 11463 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11464 mAlreadyLoggedViolatedStacks.clear(); 11465 } 11466 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11467 } 11468 } 11469 if (logIt) { 11470 logStrictModeViolationToDropBox(r, info); 11471 } 11472 } 11473 11474 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11475 AppErrorResult result = new AppErrorResult(); 11476 synchronized (this) { 11477 final long origId = Binder.clearCallingIdentity(); 11478 11479 Message msg = Message.obtain(); 11480 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11481 HashMap<String, Object> data = new HashMap<String, Object>(); 11482 data.put("result", result); 11483 data.put("app", r); 11484 data.put("violationMask", violationMask); 11485 data.put("info", info); 11486 msg.obj = data; 11487 mHandler.sendMessage(msg); 11488 11489 Binder.restoreCallingIdentity(origId); 11490 } 11491 int res = result.get(); 11492 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11493 } 11494 } 11495 11496 // Depending on the policy in effect, there could be a bunch of 11497 // these in quick succession so we try to batch these together to 11498 // minimize disk writes, number of dropbox entries, and maximize 11499 // compression, by having more fewer, larger records. 11500 private void logStrictModeViolationToDropBox( 11501 ProcessRecord process, 11502 StrictMode.ViolationInfo info) { 11503 if (info == null) { 11504 return; 11505 } 11506 final boolean isSystemApp = process == null || 11507 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11508 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11509 final String processName = process == null ? "unknown" : process.processName; 11510 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11511 final DropBoxManager dbox = (DropBoxManager) 11512 mContext.getSystemService(Context.DROPBOX_SERVICE); 11513 11514 // Exit early if the dropbox isn't configured to accept this report type. 11515 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11516 11517 boolean bufferWasEmpty; 11518 boolean needsFlush; 11519 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11520 synchronized (sb) { 11521 bufferWasEmpty = sb.length() == 0; 11522 appendDropBoxProcessHeaders(process, processName, sb); 11523 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11524 sb.append("System-App: ").append(isSystemApp).append("\n"); 11525 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11526 if (info.violationNumThisLoop != 0) { 11527 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11528 } 11529 if (info.numAnimationsRunning != 0) { 11530 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11531 } 11532 if (info.broadcastIntentAction != null) { 11533 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11534 } 11535 if (info.durationMillis != -1) { 11536 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11537 } 11538 if (info.numInstances != -1) { 11539 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11540 } 11541 if (info.tags != null) { 11542 for (String tag : info.tags) { 11543 sb.append("Span-Tag: ").append(tag).append("\n"); 11544 } 11545 } 11546 sb.append("\n"); 11547 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11548 sb.append(info.crashInfo.stackTrace); 11549 } 11550 sb.append("\n"); 11551 11552 // Only buffer up to ~64k. Various logging bits truncate 11553 // things at 128k. 11554 needsFlush = (sb.length() > 64 * 1024); 11555 } 11556 11557 // Flush immediately if the buffer's grown too large, or this 11558 // is a non-system app. Non-system apps are isolated with a 11559 // different tag & policy and not batched. 11560 // 11561 // Batching is useful during internal testing with 11562 // StrictMode settings turned up high. Without batching, 11563 // thousands of separate files could be created on boot. 11564 if (!isSystemApp || needsFlush) { 11565 new Thread("Error dump: " + dropboxTag) { 11566 @Override 11567 public void run() { 11568 String report; 11569 synchronized (sb) { 11570 report = sb.toString(); 11571 sb.delete(0, sb.length()); 11572 sb.trimToSize(); 11573 } 11574 if (report.length() != 0) { 11575 dbox.addText(dropboxTag, report); 11576 } 11577 } 11578 }.start(); 11579 return; 11580 } 11581 11582 // System app batching: 11583 if (!bufferWasEmpty) { 11584 // An existing dropbox-writing thread is outstanding, so 11585 // we don't need to start it up. The existing thread will 11586 // catch the buffer appends we just did. 11587 return; 11588 } 11589 11590 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11591 // (After this point, we shouldn't access AMS internal data structures.) 11592 new Thread("Error dump: " + dropboxTag) { 11593 @Override 11594 public void run() { 11595 // 5 second sleep to let stacks arrive and be batched together 11596 try { 11597 Thread.sleep(5000); // 5 seconds 11598 } catch (InterruptedException e) {} 11599 11600 String errorReport; 11601 synchronized (mStrictModeBuffer) { 11602 errorReport = mStrictModeBuffer.toString(); 11603 if (errorReport.length() == 0) { 11604 return; 11605 } 11606 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11607 mStrictModeBuffer.trimToSize(); 11608 } 11609 dbox.addText(dropboxTag, errorReport); 11610 } 11611 }.start(); 11612 } 11613 11614 /** 11615 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11616 * @param app object of the crashing app, null for the system server 11617 * @param tag reported by the caller 11618 * @param system whether this wtf is coming from the system 11619 * @param crashInfo describing the context of the error 11620 * @return true if the process should exit immediately (WTF is fatal) 11621 */ 11622 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11623 final ApplicationErrorReport.CrashInfo crashInfo) { 11624 final int callingUid = Binder.getCallingUid(); 11625 final int callingPid = Binder.getCallingPid(); 11626 11627 if (system) { 11628 // If this is coming from the system, we could very well have low-level 11629 // system locks held, so we want to do this all asynchronously. And we 11630 // never want this to become fatal, so there is that too. 11631 mHandler.post(new Runnable() { 11632 @Override public void run() { 11633 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11634 } 11635 }); 11636 return false; 11637 } 11638 11639 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11640 crashInfo); 11641 11642 if (r != null && r.pid != Process.myPid() && 11643 Settings.Global.getInt(mContext.getContentResolver(), 11644 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11645 crashApplication(r, crashInfo); 11646 return true; 11647 } else { 11648 return false; 11649 } 11650 } 11651 11652 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11653 final ApplicationErrorReport.CrashInfo crashInfo) { 11654 final ProcessRecord r = findAppProcess(app, "WTF"); 11655 final String processName = app == null ? "system_server" 11656 : (r == null ? "unknown" : r.processName); 11657 11658 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11659 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11660 11661 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11662 11663 return r; 11664 } 11665 11666 /** 11667 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11668 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11669 */ 11670 private ProcessRecord findAppProcess(IBinder app, String reason) { 11671 if (app == null) { 11672 return null; 11673 } 11674 11675 synchronized (this) { 11676 final int NP = mProcessNames.getMap().size(); 11677 for (int ip=0; ip<NP; ip++) { 11678 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11679 final int NA = apps.size(); 11680 for (int ia=0; ia<NA; ia++) { 11681 ProcessRecord p = apps.valueAt(ia); 11682 if (p.thread != null && p.thread.asBinder() == app) { 11683 return p; 11684 } 11685 } 11686 } 11687 11688 Slog.w(TAG, "Can't find mystery application for " + reason 11689 + " from pid=" + Binder.getCallingPid() 11690 + " uid=" + Binder.getCallingUid() + ": " + app); 11691 return null; 11692 } 11693 } 11694 11695 /** 11696 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11697 * to append various headers to the dropbox log text. 11698 */ 11699 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11700 StringBuilder sb) { 11701 // Watchdog thread ends up invoking this function (with 11702 // a null ProcessRecord) to add the stack file to dropbox. 11703 // Do not acquire a lock on this (am) in such cases, as it 11704 // could cause a potential deadlock, if and when watchdog 11705 // is invoked due to unavailability of lock on am and it 11706 // would prevent watchdog from killing system_server. 11707 if (process == null) { 11708 sb.append("Process: ").append(processName).append("\n"); 11709 return; 11710 } 11711 // Note: ProcessRecord 'process' is guarded by the service 11712 // instance. (notably process.pkgList, which could otherwise change 11713 // concurrently during execution of this method) 11714 synchronized (this) { 11715 sb.append("Process: ").append(processName).append("\n"); 11716 int flags = process.info.flags; 11717 IPackageManager pm = AppGlobals.getPackageManager(); 11718 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11719 for (int ip=0; ip<process.pkgList.size(); ip++) { 11720 String pkg = process.pkgList.keyAt(ip); 11721 sb.append("Package: ").append(pkg); 11722 try { 11723 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11724 if (pi != null) { 11725 sb.append(" v").append(pi.versionCode); 11726 if (pi.versionName != null) { 11727 sb.append(" (").append(pi.versionName).append(")"); 11728 } 11729 } 11730 } catch (RemoteException e) { 11731 Slog.e(TAG, "Error getting package info: " + pkg, e); 11732 } 11733 sb.append("\n"); 11734 } 11735 } 11736 } 11737 11738 private static String processClass(ProcessRecord process) { 11739 if (process == null || process.pid == MY_PID) { 11740 return "system_server"; 11741 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11742 return "system_app"; 11743 } else { 11744 return "data_app"; 11745 } 11746 } 11747 11748 /** 11749 * Write a description of an error (crash, WTF, ANR) to the drop box. 11750 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11751 * @param process which caused the error, null means the system server 11752 * @param activity which triggered the error, null if unknown 11753 * @param parent activity related to the error, null if unknown 11754 * @param subject line related to the error, null if absent 11755 * @param report in long form describing the error, null if absent 11756 * @param logFile to include in the report, null if none 11757 * @param crashInfo giving an application stack trace, null if absent 11758 */ 11759 public void addErrorToDropBox(String eventType, 11760 ProcessRecord process, String processName, ActivityRecord activity, 11761 ActivityRecord parent, String subject, 11762 final String report, final File logFile, 11763 final ApplicationErrorReport.CrashInfo crashInfo) { 11764 // NOTE -- this must never acquire the ActivityManagerService lock, 11765 // otherwise the watchdog may be prevented from resetting the system. 11766 11767 final String dropboxTag = processClass(process) + "_" + eventType; 11768 final DropBoxManager dbox = (DropBoxManager) 11769 mContext.getSystemService(Context.DROPBOX_SERVICE); 11770 11771 // Exit early if the dropbox isn't configured to accept this report type. 11772 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11773 11774 final StringBuilder sb = new StringBuilder(1024); 11775 appendDropBoxProcessHeaders(process, processName, sb); 11776 if (activity != null) { 11777 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11778 } 11779 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11780 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11781 } 11782 if (parent != null && parent != activity) { 11783 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11784 } 11785 if (subject != null) { 11786 sb.append("Subject: ").append(subject).append("\n"); 11787 } 11788 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11789 if (Debug.isDebuggerConnected()) { 11790 sb.append("Debugger: Connected\n"); 11791 } 11792 sb.append("\n"); 11793 11794 // Do the rest in a worker thread to avoid blocking the caller on I/O 11795 // (After this point, we shouldn't access AMS internal data structures.) 11796 Thread worker = new Thread("Error dump: " + dropboxTag) { 11797 @Override 11798 public void run() { 11799 if (report != null) { 11800 sb.append(report); 11801 } 11802 if (logFile != null) { 11803 try { 11804 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11805 "\n\n[[TRUNCATED]]")); 11806 } catch (IOException e) { 11807 Slog.e(TAG, "Error reading " + logFile, e); 11808 } 11809 } 11810 if (crashInfo != null && crashInfo.stackTrace != null) { 11811 sb.append(crashInfo.stackTrace); 11812 } 11813 11814 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11815 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11816 if (lines > 0) { 11817 sb.append("\n"); 11818 11819 // Merge several logcat streams, and take the last N lines 11820 InputStreamReader input = null; 11821 try { 11822 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11823 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11824 "-b", "crash", 11825 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11826 11827 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11828 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11829 input = new InputStreamReader(logcat.getInputStream()); 11830 11831 int num; 11832 char[] buf = new char[8192]; 11833 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11834 } catch (IOException e) { 11835 Slog.e(TAG, "Error running logcat", e); 11836 } finally { 11837 if (input != null) try { input.close(); } catch (IOException e) {} 11838 } 11839 } 11840 11841 dbox.addText(dropboxTag, sb.toString()); 11842 } 11843 }; 11844 11845 if (process == null) { 11846 // If process is null, we are being called from some internal code 11847 // and may be about to die -- run this synchronously. 11848 worker.run(); 11849 } else { 11850 worker.start(); 11851 } 11852 } 11853 11854 /** 11855 * Bring up the "unexpected error" dialog box for a crashing app. 11856 * Deal with edge cases (intercepts from instrumented applications, 11857 * ActivityController, error intent receivers, that sort of thing). 11858 * @param r the application crashing 11859 * @param crashInfo describing the failure 11860 */ 11861 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11862 long timeMillis = System.currentTimeMillis(); 11863 String shortMsg = crashInfo.exceptionClassName; 11864 String longMsg = crashInfo.exceptionMessage; 11865 String stackTrace = crashInfo.stackTrace; 11866 if (shortMsg != null && longMsg != null) { 11867 longMsg = shortMsg + ": " + longMsg; 11868 } else if (shortMsg != null) { 11869 longMsg = shortMsg; 11870 } 11871 11872 AppErrorResult result = new AppErrorResult(); 11873 synchronized (this) { 11874 if (mController != null) { 11875 try { 11876 String name = r != null ? r.processName : null; 11877 int pid = r != null ? r.pid : Binder.getCallingPid(); 11878 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11879 if (!mController.appCrashed(name, pid, 11880 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11881 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11882 && "Native crash".equals(crashInfo.exceptionClassName)) { 11883 Slog.w(TAG, "Skip killing native crashed app " + name 11884 + "(" + pid + ") during testing"); 11885 } else { 11886 Slog.w(TAG, "Force-killing crashed app " + name 11887 + " at watcher's request"); 11888 if (r != null) { 11889 r.kill("crash", true); 11890 } else { 11891 // Huh. 11892 Process.killProcess(pid); 11893 Process.killProcessGroup(uid, pid); 11894 } 11895 } 11896 return; 11897 } 11898 } catch (RemoteException e) { 11899 mController = null; 11900 Watchdog.getInstance().setActivityController(null); 11901 } 11902 } 11903 11904 final long origId = Binder.clearCallingIdentity(); 11905 11906 // If this process is running instrumentation, finish it. 11907 if (r != null && r.instrumentationClass != null) { 11908 Slog.w(TAG, "Error in app " + r.processName 11909 + " running instrumentation " + r.instrumentationClass + ":"); 11910 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11911 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11912 Bundle info = new Bundle(); 11913 info.putString("shortMsg", shortMsg); 11914 info.putString("longMsg", longMsg); 11915 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11916 Binder.restoreCallingIdentity(origId); 11917 return; 11918 } 11919 11920 // If we can't identify the process or it's already exceeded its crash quota, 11921 // quit right away without showing a crash dialog. 11922 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11923 Binder.restoreCallingIdentity(origId); 11924 return; 11925 } 11926 11927 Message msg = Message.obtain(); 11928 msg.what = SHOW_ERROR_MSG; 11929 HashMap data = new HashMap(); 11930 data.put("result", result); 11931 data.put("app", r); 11932 msg.obj = data; 11933 mHandler.sendMessage(msg); 11934 11935 Binder.restoreCallingIdentity(origId); 11936 } 11937 11938 int res = result.get(); 11939 11940 Intent appErrorIntent = null; 11941 synchronized (this) { 11942 if (r != null && !r.isolated) { 11943 // XXX Can't keep track of crash time for isolated processes, 11944 // since they don't have a persistent identity. 11945 mProcessCrashTimes.put(r.info.processName, r.uid, 11946 SystemClock.uptimeMillis()); 11947 } 11948 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11949 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11950 } 11951 } 11952 11953 if (appErrorIntent != null) { 11954 try { 11955 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11956 } catch (ActivityNotFoundException e) { 11957 Slog.w(TAG, "bug report receiver dissappeared", e); 11958 } 11959 } 11960 } 11961 11962 Intent createAppErrorIntentLocked(ProcessRecord r, 11963 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11964 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11965 if (report == null) { 11966 return null; 11967 } 11968 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11969 result.setComponent(r.errorReportReceiver); 11970 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11971 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11972 return result; 11973 } 11974 11975 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11976 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11977 if (r.errorReportReceiver == null) { 11978 return null; 11979 } 11980 11981 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11982 return null; 11983 } 11984 11985 ApplicationErrorReport report = new ApplicationErrorReport(); 11986 report.packageName = r.info.packageName; 11987 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11988 report.processName = r.processName; 11989 report.time = timeMillis; 11990 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11991 11992 if (r.crashing || r.forceCrashReport) { 11993 report.type = ApplicationErrorReport.TYPE_CRASH; 11994 report.crashInfo = crashInfo; 11995 } else if (r.notResponding) { 11996 report.type = ApplicationErrorReport.TYPE_ANR; 11997 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11998 11999 report.anrInfo.activity = r.notRespondingReport.tag; 12000 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12001 report.anrInfo.info = r.notRespondingReport.longMsg; 12002 } 12003 12004 return report; 12005 } 12006 12007 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12008 enforceNotIsolatedCaller("getProcessesInErrorState"); 12009 // assume our apps are happy - lazy create the list 12010 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12011 12012 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12013 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12014 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12015 12016 synchronized (this) { 12017 12018 // iterate across all processes 12019 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12020 ProcessRecord app = mLruProcesses.get(i); 12021 if (!allUsers && app.userId != userId) { 12022 continue; 12023 } 12024 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12025 // This one's in trouble, so we'll generate a report for it 12026 // crashes are higher priority (in case there's a crash *and* an anr) 12027 ActivityManager.ProcessErrorStateInfo report = null; 12028 if (app.crashing) { 12029 report = app.crashingReport; 12030 } else if (app.notResponding) { 12031 report = app.notRespondingReport; 12032 } 12033 12034 if (report != null) { 12035 if (errList == null) { 12036 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12037 } 12038 errList.add(report); 12039 } else { 12040 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12041 " crashing = " + app.crashing + 12042 " notResponding = " + app.notResponding); 12043 } 12044 } 12045 } 12046 } 12047 12048 return errList; 12049 } 12050 12051 static int procStateToImportance(int procState, int memAdj, 12052 ActivityManager.RunningAppProcessInfo currApp) { 12053 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12054 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12055 currApp.lru = memAdj; 12056 } else { 12057 currApp.lru = 0; 12058 } 12059 return imp; 12060 } 12061 12062 private void fillInProcMemInfo(ProcessRecord app, 12063 ActivityManager.RunningAppProcessInfo outInfo) { 12064 outInfo.pid = app.pid; 12065 outInfo.uid = app.info.uid; 12066 if (mHeavyWeightProcess == app) { 12067 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12068 } 12069 if (app.persistent) { 12070 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12071 } 12072 if (app.activities.size() > 0) { 12073 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12074 } 12075 outInfo.lastTrimLevel = app.trimMemoryLevel; 12076 int adj = app.curAdj; 12077 int procState = app.curProcState; 12078 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12079 outInfo.importanceReasonCode = app.adjTypeCode; 12080 outInfo.processState = app.curProcState; 12081 } 12082 12083 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12084 enforceNotIsolatedCaller("getRunningAppProcesses"); 12085 // Lazy instantiation of list 12086 List<ActivityManager.RunningAppProcessInfo> runList = null; 12087 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12088 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12089 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12090 synchronized (this) { 12091 // Iterate across all processes 12092 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12093 ProcessRecord app = mLruProcesses.get(i); 12094 if (!allUsers && app.userId != userId) { 12095 continue; 12096 } 12097 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12098 // Generate process state info for running application 12099 ActivityManager.RunningAppProcessInfo currApp = 12100 new ActivityManager.RunningAppProcessInfo(app.processName, 12101 app.pid, app.getPackageList()); 12102 fillInProcMemInfo(app, currApp); 12103 if (app.adjSource instanceof ProcessRecord) { 12104 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12105 currApp.importanceReasonImportance = 12106 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12107 app.adjSourceProcState); 12108 } else if (app.adjSource instanceof ActivityRecord) { 12109 ActivityRecord r = (ActivityRecord)app.adjSource; 12110 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12111 } 12112 if (app.adjTarget instanceof ComponentName) { 12113 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12114 } 12115 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12116 // + " lru=" + currApp.lru); 12117 if (runList == null) { 12118 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12119 } 12120 runList.add(currApp); 12121 } 12122 } 12123 } 12124 return runList; 12125 } 12126 12127 public List<ApplicationInfo> getRunningExternalApplications() { 12128 enforceNotIsolatedCaller("getRunningExternalApplications"); 12129 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12130 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12131 if (runningApps != null && runningApps.size() > 0) { 12132 Set<String> extList = new HashSet<String>(); 12133 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12134 if (app.pkgList != null) { 12135 for (String pkg : app.pkgList) { 12136 extList.add(pkg); 12137 } 12138 } 12139 } 12140 IPackageManager pm = AppGlobals.getPackageManager(); 12141 for (String pkg : extList) { 12142 try { 12143 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12144 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12145 retList.add(info); 12146 } 12147 } catch (RemoteException e) { 12148 } 12149 } 12150 } 12151 return retList; 12152 } 12153 12154 @Override 12155 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12156 enforceNotIsolatedCaller("getMyMemoryState"); 12157 synchronized (this) { 12158 ProcessRecord proc; 12159 synchronized (mPidsSelfLocked) { 12160 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12161 } 12162 fillInProcMemInfo(proc, outInfo); 12163 } 12164 } 12165 12166 @Override 12167 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12168 if (checkCallingPermission(android.Manifest.permission.DUMP) 12169 != PackageManager.PERMISSION_GRANTED) { 12170 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12171 + Binder.getCallingPid() 12172 + ", uid=" + Binder.getCallingUid() 12173 + " without permission " 12174 + android.Manifest.permission.DUMP); 12175 return; 12176 } 12177 12178 boolean dumpAll = false; 12179 boolean dumpClient = false; 12180 String dumpPackage = null; 12181 12182 int opti = 0; 12183 while (opti < args.length) { 12184 String opt = args[opti]; 12185 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12186 break; 12187 } 12188 opti++; 12189 if ("-a".equals(opt)) { 12190 dumpAll = true; 12191 } else if ("-c".equals(opt)) { 12192 dumpClient = true; 12193 } else if ("-h".equals(opt)) { 12194 pw.println("Activity manager dump options:"); 12195 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12196 pw.println(" cmd may be one of:"); 12197 pw.println(" a[ctivities]: activity stack state"); 12198 pw.println(" r[recents]: recent activities state"); 12199 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12200 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12201 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12202 pw.println(" o[om]: out of memory management"); 12203 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12204 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12205 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12206 pw.println(" service [COMP_SPEC]: service client-side state"); 12207 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12208 pw.println(" all: dump all activities"); 12209 pw.println(" top: dump the top activity"); 12210 pw.println(" write: write all pending state to storage"); 12211 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12212 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12213 pw.println(" a partial substring in a component name, a"); 12214 pw.println(" hex object identifier."); 12215 pw.println(" -a: include all available server state."); 12216 pw.println(" -c: include client state."); 12217 return; 12218 } else { 12219 pw.println("Unknown argument: " + opt + "; use -h for help"); 12220 } 12221 } 12222 12223 long origId = Binder.clearCallingIdentity(); 12224 boolean more = false; 12225 // Is the caller requesting to dump a particular piece of data? 12226 if (opti < args.length) { 12227 String cmd = args[opti]; 12228 opti++; 12229 if ("activities".equals(cmd) || "a".equals(cmd)) { 12230 synchronized (this) { 12231 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12232 } 12233 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12234 synchronized (this) { 12235 dumpRecentsLocked(fd, pw, args, opti, true, null); 12236 } 12237 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12238 String[] newArgs; 12239 String name; 12240 if (opti >= args.length) { 12241 name = null; 12242 newArgs = EMPTY_STRING_ARRAY; 12243 } else { 12244 name = args[opti]; 12245 opti++; 12246 newArgs = new String[args.length - opti]; 12247 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12248 args.length - opti); 12249 } 12250 synchronized (this) { 12251 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12252 } 12253 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12254 String[] newArgs; 12255 String name; 12256 if (opti >= args.length) { 12257 name = null; 12258 newArgs = EMPTY_STRING_ARRAY; 12259 } else { 12260 name = args[opti]; 12261 opti++; 12262 newArgs = new String[args.length - opti]; 12263 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12264 args.length - opti); 12265 } 12266 synchronized (this) { 12267 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12268 } 12269 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12270 String[] newArgs; 12271 String name; 12272 if (opti >= args.length) { 12273 name = null; 12274 newArgs = EMPTY_STRING_ARRAY; 12275 } else { 12276 name = args[opti]; 12277 opti++; 12278 newArgs = new String[args.length - opti]; 12279 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12280 args.length - opti); 12281 } 12282 synchronized (this) { 12283 dumpProcessesLocked(fd, pw, args, opti, true, name); 12284 } 12285 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12286 synchronized (this) { 12287 dumpOomLocked(fd, pw, args, opti, true); 12288 } 12289 } else if ("provider".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, args.length - opti); 12300 } 12301 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12302 pw.println("No providers match: " + name); 12303 pw.println("Use -h for help."); 12304 } 12305 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12306 synchronized (this) { 12307 dumpProvidersLocked(fd, pw, args, opti, true, null); 12308 } 12309 } else if ("service".equals(cmd)) { 12310 String[] newArgs; 12311 String name; 12312 if (opti >= args.length) { 12313 name = null; 12314 newArgs = EMPTY_STRING_ARRAY; 12315 } else { 12316 name = args[opti]; 12317 opti++; 12318 newArgs = new String[args.length - opti]; 12319 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12320 args.length - opti); 12321 } 12322 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12323 pw.println("No services match: " + name); 12324 pw.println("Use -h for help."); 12325 } 12326 } else if ("package".equals(cmd)) { 12327 String[] newArgs; 12328 if (opti >= args.length) { 12329 pw.println("package: no package name specified"); 12330 pw.println("Use -h for help."); 12331 } else { 12332 dumpPackage = args[opti]; 12333 opti++; 12334 newArgs = new String[args.length - opti]; 12335 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12336 args.length - opti); 12337 args = newArgs; 12338 opti = 0; 12339 more = true; 12340 } 12341 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12342 synchronized (this) { 12343 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12344 } 12345 } else if ("write".equals(cmd)) { 12346 mTaskPersister.flush(); 12347 pw.println("All tasks persisted."); 12348 return; 12349 } else { 12350 // Dumping a single activity? 12351 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12352 pw.println("Bad activity command, or no activities match: " + cmd); 12353 pw.println("Use -h for help."); 12354 } 12355 } 12356 if (!more) { 12357 Binder.restoreCallingIdentity(origId); 12358 return; 12359 } 12360 } 12361 12362 // No piece of data specified, dump everything. 12363 synchronized (this) { 12364 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12365 pw.println(); 12366 if (dumpAll) { 12367 pw.println("-------------------------------------------------------------------------------"); 12368 } 12369 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12370 pw.println(); 12371 if (dumpAll) { 12372 pw.println("-------------------------------------------------------------------------------"); 12373 } 12374 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12375 pw.println(); 12376 if (dumpAll) { 12377 pw.println("-------------------------------------------------------------------------------"); 12378 } 12379 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12380 pw.println(); 12381 if (dumpAll) { 12382 pw.println("-------------------------------------------------------------------------------"); 12383 } 12384 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12385 pw.println(); 12386 if (dumpAll) { 12387 pw.println("-------------------------------------------------------------------------------"); 12388 } 12389 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12390 pw.println(); 12391 if (dumpAll) { 12392 pw.println("-------------------------------------------------------------------------------"); 12393 } 12394 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12395 } 12396 Binder.restoreCallingIdentity(origId); 12397 } 12398 12399 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12400 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12401 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12402 12403 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12404 dumpPackage); 12405 boolean needSep = printedAnything; 12406 12407 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12408 dumpPackage, needSep, " mFocusedActivity: "); 12409 if (printed) { 12410 printedAnything = true; 12411 needSep = false; 12412 } 12413 12414 if (dumpPackage == null) { 12415 if (needSep) { 12416 pw.println(); 12417 } 12418 needSep = true; 12419 printedAnything = true; 12420 mStackSupervisor.dump(pw, " "); 12421 } 12422 12423 if (!printedAnything) { 12424 pw.println(" (nothing)"); 12425 } 12426 } 12427 12428 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12429 int opti, boolean dumpAll, String dumpPackage) { 12430 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12431 12432 boolean printedAnything = false; 12433 12434 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12435 boolean printedHeader = false; 12436 12437 final int N = mRecentTasks.size(); 12438 for (int i=0; i<N; i++) { 12439 TaskRecord tr = mRecentTasks.get(i); 12440 if (dumpPackage != null) { 12441 if (tr.realActivity == null || 12442 !dumpPackage.equals(tr.realActivity)) { 12443 continue; 12444 } 12445 } 12446 if (!printedHeader) { 12447 pw.println(" Recent tasks:"); 12448 printedHeader = true; 12449 printedAnything = true; 12450 } 12451 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12452 pw.println(tr); 12453 if (dumpAll) { 12454 mRecentTasks.get(i).dump(pw, " "); 12455 } 12456 } 12457 } 12458 12459 if (!printedAnything) { 12460 pw.println(" (nothing)"); 12461 } 12462 } 12463 12464 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12465 int opti, boolean dumpAll, String dumpPackage) { 12466 boolean needSep = false; 12467 boolean printedAnything = false; 12468 int numPers = 0; 12469 12470 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12471 12472 if (dumpAll) { 12473 final int NP = mProcessNames.getMap().size(); 12474 for (int ip=0; ip<NP; ip++) { 12475 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12476 final int NA = procs.size(); 12477 for (int ia=0; ia<NA; ia++) { 12478 ProcessRecord r = procs.valueAt(ia); 12479 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12480 continue; 12481 } 12482 if (!needSep) { 12483 pw.println(" All known processes:"); 12484 needSep = true; 12485 printedAnything = true; 12486 } 12487 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12488 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12489 pw.print(" "); pw.println(r); 12490 r.dump(pw, " "); 12491 if (r.persistent) { 12492 numPers++; 12493 } 12494 } 12495 } 12496 } 12497 12498 if (mIsolatedProcesses.size() > 0) { 12499 boolean printed = false; 12500 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12501 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12502 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12503 continue; 12504 } 12505 if (!printed) { 12506 if (needSep) { 12507 pw.println(); 12508 } 12509 pw.println(" Isolated process list (sorted by uid):"); 12510 printedAnything = true; 12511 printed = true; 12512 needSep = true; 12513 } 12514 pw.println(String.format("%sIsolated #%2d: %s", 12515 " ", i, r.toString())); 12516 } 12517 } 12518 12519 if (mLruProcesses.size() > 0) { 12520 if (needSep) { 12521 pw.println(); 12522 } 12523 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12524 pw.print(" total, non-act at "); 12525 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12526 pw.print(", non-svc at "); 12527 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12528 pw.println("):"); 12529 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12530 needSep = true; 12531 printedAnything = true; 12532 } 12533 12534 if (dumpAll || dumpPackage != null) { 12535 synchronized (mPidsSelfLocked) { 12536 boolean printed = false; 12537 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12538 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12539 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12540 continue; 12541 } 12542 if (!printed) { 12543 if (needSep) pw.println(); 12544 needSep = true; 12545 pw.println(" PID mappings:"); 12546 printed = true; 12547 printedAnything = true; 12548 } 12549 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12550 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12551 } 12552 } 12553 } 12554 12555 if (mForegroundProcesses.size() > 0) { 12556 synchronized (mPidsSelfLocked) { 12557 boolean printed = false; 12558 for (int i=0; i<mForegroundProcesses.size(); i++) { 12559 ProcessRecord r = mPidsSelfLocked.get( 12560 mForegroundProcesses.valueAt(i).pid); 12561 if (dumpPackage != null && (r == null 12562 || !r.pkgList.containsKey(dumpPackage))) { 12563 continue; 12564 } 12565 if (!printed) { 12566 if (needSep) pw.println(); 12567 needSep = true; 12568 pw.println(" Foreground Processes:"); 12569 printed = true; 12570 printedAnything = true; 12571 } 12572 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12573 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12574 } 12575 } 12576 } 12577 12578 if (mPersistentStartingProcesses.size() > 0) { 12579 if (needSep) pw.println(); 12580 needSep = true; 12581 printedAnything = true; 12582 pw.println(" Persisent processes that are starting:"); 12583 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12584 "Starting Norm", "Restarting PERS", dumpPackage); 12585 } 12586 12587 if (mRemovedProcesses.size() > 0) { 12588 if (needSep) pw.println(); 12589 needSep = true; 12590 printedAnything = true; 12591 pw.println(" Processes that are being removed:"); 12592 dumpProcessList(pw, this, mRemovedProcesses, " ", 12593 "Removed Norm", "Removed PERS", dumpPackage); 12594 } 12595 12596 if (mProcessesOnHold.size() > 0) { 12597 if (needSep) pw.println(); 12598 needSep = true; 12599 printedAnything = true; 12600 pw.println(" Processes that are on old until the system is ready:"); 12601 dumpProcessList(pw, this, mProcessesOnHold, " ", 12602 "OnHold Norm", "OnHold PERS", dumpPackage); 12603 } 12604 12605 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12606 12607 if (mProcessCrashTimes.getMap().size() > 0) { 12608 boolean printed = false; 12609 long now = SystemClock.uptimeMillis(); 12610 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12611 final int NP = pmap.size(); 12612 for (int ip=0; ip<NP; ip++) { 12613 String pname = pmap.keyAt(ip); 12614 SparseArray<Long> uids = pmap.valueAt(ip); 12615 final int N = uids.size(); 12616 for (int i=0; i<N; i++) { 12617 int puid = uids.keyAt(i); 12618 ProcessRecord r = mProcessNames.get(pname, puid); 12619 if (dumpPackage != null && (r == null 12620 || !r.pkgList.containsKey(dumpPackage))) { 12621 continue; 12622 } 12623 if (!printed) { 12624 if (needSep) pw.println(); 12625 needSep = true; 12626 pw.println(" Time since processes crashed:"); 12627 printed = true; 12628 printedAnything = true; 12629 } 12630 pw.print(" Process "); pw.print(pname); 12631 pw.print(" uid "); pw.print(puid); 12632 pw.print(": last crashed "); 12633 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12634 pw.println(" ago"); 12635 } 12636 } 12637 } 12638 12639 if (mBadProcesses.getMap().size() > 0) { 12640 boolean printed = false; 12641 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12642 final int NP = pmap.size(); 12643 for (int ip=0; ip<NP; ip++) { 12644 String pname = pmap.keyAt(ip); 12645 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12646 final int N = uids.size(); 12647 for (int i=0; i<N; i++) { 12648 int puid = uids.keyAt(i); 12649 ProcessRecord r = mProcessNames.get(pname, puid); 12650 if (dumpPackage != null && (r == null 12651 || !r.pkgList.containsKey(dumpPackage))) { 12652 continue; 12653 } 12654 if (!printed) { 12655 if (needSep) pw.println(); 12656 needSep = true; 12657 pw.println(" Bad processes:"); 12658 printedAnything = true; 12659 } 12660 BadProcessInfo info = uids.valueAt(i); 12661 pw.print(" Bad process "); pw.print(pname); 12662 pw.print(" uid "); pw.print(puid); 12663 pw.print(": crashed at time "); pw.println(info.time); 12664 if (info.shortMsg != null) { 12665 pw.print(" Short msg: "); pw.println(info.shortMsg); 12666 } 12667 if (info.longMsg != null) { 12668 pw.print(" Long msg: "); pw.println(info.longMsg); 12669 } 12670 if (info.stack != null) { 12671 pw.println(" Stack:"); 12672 int lastPos = 0; 12673 for (int pos=0; pos<info.stack.length(); pos++) { 12674 if (info.stack.charAt(pos) == '\n') { 12675 pw.print(" "); 12676 pw.write(info.stack, lastPos, pos-lastPos); 12677 pw.println(); 12678 lastPos = pos+1; 12679 } 12680 } 12681 if (lastPos < info.stack.length()) { 12682 pw.print(" "); 12683 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12684 pw.println(); 12685 } 12686 } 12687 } 12688 } 12689 } 12690 12691 if (dumpPackage == null) { 12692 pw.println(); 12693 needSep = false; 12694 pw.println(" mStartedUsers:"); 12695 for (int i=0; i<mStartedUsers.size(); i++) { 12696 UserStartedState uss = mStartedUsers.valueAt(i); 12697 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12698 pw.print(": "); uss.dump("", pw); 12699 } 12700 pw.print(" mStartedUserArray: ["); 12701 for (int i=0; i<mStartedUserArray.length; i++) { 12702 if (i > 0) pw.print(", "); 12703 pw.print(mStartedUserArray[i]); 12704 } 12705 pw.println("]"); 12706 pw.print(" mUserLru: ["); 12707 for (int i=0; i<mUserLru.size(); i++) { 12708 if (i > 0) pw.print(", "); 12709 pw.print(mUserLru.get(i)); 12710 } 12711 pw.println("]"); 12712 if (dumpAll) { 12713 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12714 } 12715 synchronized (mUserProfileGroupIdsSelfLocked) { 12716 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12717 pw.println(" mUserProfileGroupIds:"); 12718 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12719 pw.print(" User #"); 12720 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12721 pw.print(" -> profile #"); 12722 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12723 } 12724 } 12725 } 12726 } 12727 if (mHomeProcess != null && (dumpPackage == null 12728 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12729 if (needSep) { 12730 pw.println(); 12731 needSep = false; 12732 } 12733 pw.println(" mHomeProcess: " + mHomeProcess); 12734 } 12735 if (mPreviousProcess != null && (dumpPackage == null 12736 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12737 if (needSep) { 12738 pw.println(); 12739 needSep = false; 12740 } 12741 pw.println(" mPreviousProcess: " + mPreviousProcess); 12742 } 12743 if (dumpAll) { 12744 StringBuilder sb = new StringBuilder(128); 12745 sb.append(" mPreviousProcessVisibleTime: "); 12746 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12747 pw.println(sb); 12748 } 12749 if (mHeavyWeightProcess != null && (dumpPackage == null 12750 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12751 if (needSep) { 12752 pw.println(); 12753 needSep = false; 12754 } 12755 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12756 } 12757 if (dumpPackage == null) { 12758 pw.println(" mConfiguration: " + mConfiguration); 12759 } 12760 if (dumpAll) { 12761 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12762 if (mCompatModePackages.getPackages().size() > 0) { 12763 boolean printed = false; 12764 for (Map.Entry<String, Integer> entry 12765 : mCompatModePackages.getPackages().entrySet()) { 12766 String pkg = entry.getKey(); 12767 int mode = entry.getValue(); 12768 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12769 continue; 12770 } 12771 if (!printed) { 12772 pw.println(" mScreenCompatPackages:"); 12773 printed = true; 12774 } 12775 pw.print(" "); pw.print(pkg); pw.print(": "); 12776 pw.print(mode); pw.println(); 12777 } 12778 } 12779 } 12780 if (dumpPackage == null) { 12781 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12782 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12783 + " mLockScreenShown " + lockScreenShownToString()); 12784 } 12785 if (mShuttingDown || mRunningVoice) { 12786 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12787 } 12788 } 12789 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12790 || mOrigWaitForDebugger) { 12791 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12792 || dumpPackage.equals(mOrigDebugApp)) { 12793 if (needSep) { 12794 pw.println(); 12795 needSep = false; 12796 } 12797 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12798 + " mDebugTransient=" + mDebugTransient 12799 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12800 } 12801 } 12802 if (mOpenGlTraceApp != null) { 12803 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12804 if (needSep) { 12805 pw.println(); 12806 needSep = false; 12807 } 12808 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12809 } 12810 } 12811 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12812 || mProfileFd != null) { 12813 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12814 if (needSep) { 12815 pw.println(); 12816 needSep = false; 12817 } 12818 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12819 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12820 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12821 + mAutoStopProfiler); 12822 pw.println(" mProfileType=" + mProfileType); 12823 } 12824 } 12825 if (dumpPackage == null) { 12826 if (mAlwaysFinishActivities || mController != null) { 12827 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12828 + " mController=" + mController); 12829 } 12830 if (dumpAll) { 12831 pw.println(" Total persistent processes: " + numPers); 12832 pw.println(" mProcessesReady=" + mProcessesReady 12833 + " mSystemReady=" + mSystemReady 12834 + " mBooted=" + mBooted 12835 + " mFactoryTest=" + mFactoryTest); 12836 pw.println(" mBooting=" + mBooting 12837 + " mCallFinishBooting=" + mCallFinishBooting 12838 + " mBootAnimationComplete=" + mBootAnimationComplete); 12839 pw.print(" mLastPowerCheckRealtime="); 12840 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12841 pw.println(""); 12842 pw.print(" mLastPowerCheckUptime="); 12843 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12844 pw.println(""); 12845 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12846 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12847 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12848 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12849 + " (" + mLruProcesses.size() + " total)" 12850 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12851 + " mNumServiceProcs=" + mNumServiceProcs 12852 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12853 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12854 + " mLastMemoryLevel" + mLastMemoryLevel 12855 + " mLastNumProcesses" + mLastNumProcesses); 12856 long now = SystemClock.uptimeMillis(); 12857 pw.print(" mLastIdleTime="); 12858 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12859 pw.print(" mLowRamSinceLastIdle="); 12860 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12861 pw.println(); 12862 } 12863 } 12864 12865 if (!printedAnything) { 12866 pw.println(" (nothing)"); 12867 } 12868 } 12869 12870 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12871 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12872 if (mProcessesToGc.size() > 0) { 12873 boolean printed = false; 12874 long now = SystemClock.uptimeMillis(); 12875 for (int i=0; i<mProcessesToGc.size(); i++) { 12876 ProcessRecord proc = mProcessesToGc.get(i); 12877 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12878 continue; 12879 } 12880 if (!printed) { 12881 if (needSep) pw.println(); 12882 needSep = true; 12883 pw.println(" Processes that are waiting to GC:"); 12884 printed = true; 12885 } 12886 pw.print(" Process "); pw.println(proc); 12887 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12888 pw.print(", last gced="); 12889 pw.print(now-proc.lastRequestedGc); 12890 pw.print(" ms ago, last lowMem="); 12891 pw.print(now-proc.lastLowMemory); 12892 pw.println(" ms ago"); 12893 12894 } 12895 } 12896 return needSep; 12897 } 12898 12899 void printOomLevel(PrintWriter pw, String name, int adj) { 12900 pw.print(" "); 12901 if (adj >= 0) { 12902 pw.print(' '); 12903 if (adj < 10) pw.print(' '); 12904 } else { 12905 if (adj > -10) pw.print(' '); 12906 } 12907 pw.print(adj); 12908 pw.print(": "); 12909 pw.print(name); 12910 pw.print(" ("); 12911 pw.print(mProcessList.getMemLevel(adj)/1024); 12912 pw.println(" kB)"); 12913 } 12914 12915 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12916 int opti, boolean dumpAll) { 12917 boolean needSep = false; 12918 12919 if (mLruProcesses.size() > 0) { 12920 if (needSep) pw.println(); 12921 needSep = true; 12922 pw.println(" OOM levels:"); 12923 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12924 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12925 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12926 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12927 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12928 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12929 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12930 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12931 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12932 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12933 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12934 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12935 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12936 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12937 12938 if (needSep) pw.println(); 12939 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12940 pw.print(" total, non-act at "); 12941 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12942 pw.print(", non-svc at "); 12943 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12944 pw.println("):"); 12945 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12946 needSep = true; 12947 } 12948 12949 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12950 12951 pw.println(); 12952 pw.println(" mHomeProcess: " + mHomeProcess); 12953 pw.println(" mPreviousProcess: " + mPreviousProcess); 12954 if (mHeavyWeightProcess != null) { 12955 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12956 } 12957 12958 return true; 12959 } 12960 12961 /** 12962 * There are three ways to call this: 12963 * - no provider specified: dump all the providers 12964 * - a flattened component name that matched an existing provider was specified as the 12965 * first arg: dump that one provider 12966 * - the first arg isn't the flattened component name of an existing provider: 12967 * dump all providers whose component contains the first arg as a substring 12968 */ 12969 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12970 int opti, boolean dumpAll) { 12971 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12972 } 12973 12974 static class ItemMatcher { 12975 ArrayList<ComponentName> components; 12976 ArrayList<String> strings; 12977 ArrayList<Integer> objects; 12978 boolean all; 12979 12980 ItemMatcher() { 12981 all = true; 12982 } 12983 12984 void build(String name) { 12985 ComponentName componentName = ComponentName.unflattenFromString(name); 12986 if (componentName != null) { 12987 if (components == null) { 12988 components = new ArrayList<ComponentName>(); 12989 } 12990 components.add(componentName); 12991 all = false; 12992 } else { 12993 int objectId = 0; 12994 // Not a '/' separated full component name; maybe an object ID? 12995 try { 12996 objectId = Integer.parseInt(name, 16); 12997 if (objects == null) { 12998 objects = new ArrayList<Integer>(); 12999 } 13000 objects.add(objectId); 13001 all = false; 13002 } catch (RuntimeException e) { 13003 // Not an integer; just do string match. 13004 if (strings == null) { 13005 strings = new ArrayList<String>(); 13006 } 13007 strings.add(name); 13008 all = false; 13009 } 13010 } 13011 } 13012 13013 int build(String[] args, int opti) { 13014 for (; opti<args.length; opti++) { 13015 String name = args[opti]; 13016 if ("--".equals(name)) { 13017 return opti+1; 13018 } 13019 build(name); 13020 } 13021 return opti; 13022 } 13023 13024 boolean match(Object object, ComponentName comp) { 13025 if (all) { 13026 return true; 13027 } 13028 if (components != null) { 13029 for (int i=0; i<components.size(); i++) { 13030 if (components.get(i).equals(comp)) { 13031 return true; 13032 } 13033 } 13034 } 13035 if (objects != null) { 13036 for (int i=0; i<objects.size(); i++) { 13037 if (System.identityHashCode(object) == objects.get(i)) { 13038 return true; 13039 } 13040 } 13041 } 13042 if (strings != null) { 13043 String flat = comp.flattenToString(); 13044 for (int i=0; i<strings.size(); i++) { 13045 if (flat.contains(strings.get(i))) { 13046 return true; 13047 } 13048 } 13049 } 13050 return false; 13051 } 13052 } 13053 13054 /** 13055 * There are three things that cmd can be: 13056 * - a flattened component name that matches an existing activity 13057 * - the cmd arg isn't the flattened component name of an existing activity: 13058 * dump all activity whose component contains the cmd as a substring 13059 * - A hex number of the ActivityRecord object instance. 13060 */ 13061 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13062 int opti, boolean dumpAll) { 13063 ArrayList<ActivityRecord> activities; 13064 13065 synchronized (this) { 13066 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13067 } 13068 13069 if (activities.size() <= 0) { 13070 return false; 13071 } 13072 13073 String[] newArgs = new String[args.length - opti]; 13074 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13075 13076 TaskRecord lastTask = null; 13077 boolean needSep = false; 13078 for (int i=activities.size()-1; i>=0; i--) { 13079 ActivityRecord r = activities.get(i); 13080 if (needSep) { 13081 pw.println(); 13082 } 13083 needSep = true; 13084 synchronized (this) { 13085 if (lastTask != r.task) { 13086 lastTask = r.task; 13087 pw.print("TASK "); pw.print(lastTask.affinity); 13088 pw.print(" id="); pw.println(lastTask.taskId); 13089 if (dumpAll) { 13090 lastTask.dump(pw, " "); 13091 } 13092 } 13093 } 13094 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13095 } 13096 return true; 13097 } 13098 13099 /** 13100 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13101 * there is a thread associated with the activity. 13102 */ 13103 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13104 final ActivityRecord r, String[] args, boolean dumpAll) { 13105 String innerPrefix = prefix + " "; 13106 synchronized (this) { 13107 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13108 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13109 pw.print(" pid="); 13110 if (r.app != null) pw.println(r.app.pid); 13111 else pw.println("(not running)"); 13112 if (dumpAll) { 13113 r.dump(pw, innerPrefix); 13114 } 13115 } 13116 if (r.app != null && r.app.thread != null) { 13117 // flush anything that is already in the PrintWriter since the thread is going 13118 // to write to the file descriptor directly 13119 pw.flush(); 13120 try { 13121 TransferPipe tp = new TransferPipe(); 13122 try { 13123 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13124 r.appToken, innerPrefix, args); 13125 tp.go(fd); 13126 } finally { 13127 tp.kill(); 13128 } 13129 } catch (IOException e) { 13130 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13131 } catch (RemoteException e) { 13132 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13133 } 13134 } 13135 } 13136 13137 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13138 int opti, boolean dumpAll, String dumpPackage) { 13139 boolean needSep = false; 13140 boolean onlyHistory = false; 13141 boolean printedAnything = false; 13142 13143 if ("history".equals(dumpPackage)) { 13144 if (opti < args.length && "-s".equals(args[opti])) { 13145 dumpAll = false; 13146 } 13147 onlyHistory = true; 13148 dumpPackage = null; 13149 } 13150 13151 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13152 if (!onlyHistory && dumpAll) { 13153 if (mRegisteredReceivers.size() > 0) { 13154 boolean printed = false; 13155 Iterator it = mRegisteredReceivers.values().iterator(); 13156 while (it.hasNext()) { 13157 ReceiverList r = (ReceiverList)it.next(); 13158 if (dumpPackage != null && (r.app == null || 13159 !dumpPackage.equals(r.app.info.packageName))) { 13160 continue; 13161 } 13162 if (!printed) { 13163 pw.println(" Registered Receivers:"); 13164 needSep = true; 13165 printed = true; 13166 printedAnything = true; 13167 } 13168 pw.print(" * "); pw.println(r); 13169 r.dump(pw, " "); 13170 } 13171 } 13172 13173 if (mReceiverResolver.dump(pw, needSep ? 13174 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13175 " ", dumpPackage, false)) { 13176 needSep = true; 13177 printedAnything = true; 13178 } 13179 } 13180 13181 for (BroadcastQueue q : mBroadcastQueues) { 13182 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13183 printedAnything |= needSep; 13184 } 13185 13186 needSep = true; 13187 13188 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13189 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13190 if (needSep) { 13191 pw.println(); 13192 } 13193 needSep = true; 13194 printedAnything = true; 13195 pw.print(" Sticky broadcasts for user "); 13196 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13197 StringBuilder sb = new StringBuilder(128); 13198 for (Map.Entry<String, ArrayList<Intent>> ent 13199 : mStickyBroadcasts.valueAt(user).entrySet()) { 13200 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13201 if (dumpAll) { 13202 pw.println(":"); 13203 ArrayList<Intent> intents = ent.getValue(); 13204 final int N = intents.size(); 13205 for (int i=0; i<N; i++) { 13206 sb.setLength(0); 13207 sb.append(" Intent: "); 13208 intents.get(i).toShortString(sb, false, true, false, false); 13209 pw.println(sb.toString()); 13210 Bundle bundle = intents.get(i).getExtras(); 13211 if (bundle != null) { 13212 pw.print(" "); 13213 pw.println(bundle.toString()); 13214 } 13215 } 13216 } else { 13217 pw.println(""); 13218 } 13219 } 13220 } 13221 } 13222 13223 if (!onlyHistory && dumpAll) { 13224 pw.println(); 13225 for (BroadcastQueue queue : mBroadcastQueues) { 13226 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13227 + queue.mBroadcastsScheduled); 13228 } 13229 pw.println(" mHandler:"); 13230 mHandler.dump(new PrintWriterPrinter(pw), " "); 13231 needSep = true; 13232 printedAnything = true; 13233 } 13234 13235 if (!printedAnything) { 13236 pw.println(" (nothing)"); 13237 } 13238 } 13239 13240 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13241 int opti, boolean dumpAll, String dumpPackage) { 13242 boolean needSep; 13243 boolean printedAnything = false; 13244 13245 ItemMatcher matcher = new ItemMatcher(); 13246 matcher.build(args, opti); 13247 13248 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13249 13250 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13251 printedAnything |= needSep; 13252 13253 if (mLaunchingProviders.size() > 0) { 13254 boolean printed = false; 13255 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13256 ContentProviderRecord r = mLaunchingProviders.get(i); 13257 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13258 continue; 13259 } 13260 if (!printed) { 13261 if (needSep) pw.println(); 13262 needSep = true; 13263 pw.println(" Launching content providers:"); 13264 printed = true; 13265 printedAnything = true; 13266 } 13267 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13268 pw.println(r); 13269 } 13270 } 13271 13272 if (mGrantedUriPermissions.size() > 0) { 13273 boolean printed = false; 13274 int dumpUid = -2; 13275 if (dumpPackage != null) { 13276 try { 13277 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13278 } catch (NameNotFoundException e) { 13279 dumpUid = -1; 13280 } 13281 } 13282 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13283 int uid = mGrantedUriPermissions.keyAt(i); 13284 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13285 continue; 13286 } 13287 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13288 if (!printed) { 13289 if (needSep) pw.println(); 13290 needSep = true; 13291 pw.println(" Granted Uri Permissions:"); 13292 printed = true; 13293 printedAnything = true; 13294 } 13295 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13296 for (UriPermission perm : perms.values()) { 13297 pw.print(" "); pw.println(perm); 13298 if (dumpAll) { 13299 perm.dump(pw, " "); 13300 } 13301 } 13302 } 13303 } 13304 13305 if (!printedAnything) { 13306 pw.println(" (nothing)"); 13307 } 13308 } 13309 13310 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13311 int opti, boolean dumpAll, String dumpPackage) { 13312 boolean printed = false; 13313 13314 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13315 13316 if (mIntentSenderRecords.size() > 0) { 13317 Iterator<WeakReference<PendingIntentRecord>> it 13318 = mIntentSenderRecords.values().iterator(); 13319 while (it.hasNext()) { 13320 WeakReference<PendingIntentRecord> ref = it.next(); 13321 PendingIntentRecord rec = ref != null ? ref.get(): null; 13322 if (dumpPackage != null && (rec == null 13323 || !dumpPackage.equals(rec.key.packageName))) { 13324 continue; 13325 } 13326 printed = true; 13327 if (rec != null) { 13328 pw.print(" * "); pw.println(rec); 13329 if (dumpAll) { 13330 rec.dump(pw, " "); 13331 } 13332 } else { 13333 pw.print(" * "); pw.println(ref); 13334 } 13335 } 13336 } 13337 13338 if (!printed) { 13339 pw.println(" (nothing)"); 13340 } 13341 } 13342 13343 private static final int dumpProcessList(PrintWriter pw, 13344 ActivityManagerService service, List list, 13345 String prefix, String normalLabel, String persistentLabel, 13346 String dumpPackage) { 13347 int numPers = 0; 13348 final int N = list.size()-1; 13349 for (int i=N; i>=0; i--) { 13350 ProcessRecord r = (ProcessRecord)list.get(i); 13351 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13352 continue; 13353 } 13354 pw.println(String.format("%s%s #%2d: %s", 13355 prefix, (r.persistent ? persistentLabel : normalLabel), 13356 i, r.toString())); 13357 if (r.persistent) { 13358 numPers++; 13359 } 13360 } 13361 return numPers; 13362 } 13363 13364 private static final boolean dumpProcessOomList(PrintWriter pw, 13365 ActivityManagerService service, List<ProcessRecord> origList, 13366 String prefix, String normalLabel, String persistentLabel, 13367 boolean inclDetails, String dumpPackage) { 13368 13369 ArrayList<Pair<ProcessRecord, Integer>> list 13370 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13371 for (int i=0; i<origList.size(); i++) { 13372 ProcessRecord r = origList.get(i); 13373 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13374 continue; 13375 } 13376 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13377 } 13378 13379 if (list.size() <= 0) { 13380 return false; 13381 } 13382 13383 Comparator<Pair<ProcessRecord, Integer>> comparator 13384 = new Comparator<Pair<ProcessRecord, Integer>>() { 13385 @Override 13386 public int compare(Pair<ProcessRecord, Integer> object1, 13387 Pair<ProcessRecord, Integer> object2) { 13388 if (object1.first.setAdj != object2.first.setAdj) { 13389 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13390 } 13391 if (object1.second.intValue() != object2.second.intValue()) { 13392 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13393 } 13394 return 0; 13395 } 13396 }; 13397 13398 Collections.sort(list, comparator); 13399 13400 final long curRealtime = SystemClock.elapsedRealtime(); 13401 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13402 final long curUptime = SystemClock.uptimeMillis(); 13403 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13404 13405 for (int i=list.size()-1; i>=0; i--) { 13406 ProcessRecord r = list.get(i).first; 13407 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13408 char schedGroup; 13409 switch (r.setSchedGroup) { 13410 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13411 schedGroup = 'B'; 13412 break; 13413 case Process.THREAD_GROUP_DEFAULT: 13414 schedGroup = 'F'; 13415 break; 13416 default: 13417 schedGroup = '?'; 13418 break; 13419 } 13420 char foreground; 13421 if (r.foregroundActivities) { 13422 foreground = 'A'; 13423 } else if (r.foregroundServices) { 13424 foreground = 'S'; 13425 } else { 13426 foreground = ' '; 13427 } 13428 String procState = ProcessList.makeProcStateString(r.curProcState); 13429 pw.print(prefix); 13430 pw.print(r.persistent ? persistentLabel : normalLabel); 13431 pw.print(" #"); 13432 int num = (origList.size()-1)-list.get(i).second; 13433 if (num < 10) pw.print(' '); 13434 pw.print(num); 13435 pw.print(": "); 13436 pw.print(oomAdj); 13437 pw.print(' '); 13438 pw.print(schedGroup); 13439 pw.print('/'); 13440 pw.print(foreground); 13441 pw.print('/'); 13442 pw.print(procState); 13443 pw.print(" trm:"); 13444 if (r.trimMemoryLevel < 10) pw.print(' '); 13445 pw.print(r.trimMemoryLevel); 13446 pw.print(' '); 13447 pw.print(r.toShortString()); 13448 pw.print(" ("); 13449 pw.print(r.adjType); 13450 pw.println(')'); 13451 if (r.adjSource != null || r.adjTarget != null) { 13452 pw.print(prefix); 13453 pw.print(" "); 13454 if (r.adjTarget instanceof ComponentName) { 13455 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13456 } else if (r.adjTarget != null) { 13457 pw.print(r.adjTarget.toString()); 13458 } else { 13459 pw.print("{null}"); 13460 } 13461 pw.print("<="); 13462 if (r.adjSource instanceof ProcessRecord) { 13463 pw.print("Proc{"); 13464 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13465 pw.println("}"); 13466 } else if (r.adjSource != null) { 13467 pw.println(r.adjSource.toString()); 13468 } else { 13469 pw.println("{null}"); 13470 } 13471 } 13472 if (inclDetails) { 13473 pw.print(prefix); 13474 pw.print(" "); 13475 pw.print("oom: max="); pw.print(r.maxAdj); 13476 pw.print(" curRaw="); pw.print(r.curRawAdj); 13477 pw.print(" setRaw="); pw.print(r.setRawAdj); 13478 pw.print(" cur="); pw.print(r.curAdj); 13479 pw.print(" set="); pw.println(r.setAdj); 13480 pw.print(prefix); 13481 pw.print(" "); 13482 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13483 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13484 pw.print(" lastPss="); pw.print(r.lastPss); 13485 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13486 pw.print(prefix); 13487 pw.print(" "); 13488 pw.print("cached="); pw.print(r.cached); 13489 pw.print(" empty="); pw.print(r.empty); 13490 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13491 13492 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13493 if (r.lastWakeTime != 0) { 13494 long wtime; 13495 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13496 synchronized (stats) { 13497 wtime = stats.getProcessWakeTime(r.info.uid, 13498 r.pid, curRealtime); 13499 } 13500 long timeUsed = wtime - r.lastWakeTime; 13501 pw.print(prefix); 13502 pw.print(" "); 13503 pw.print("keep awake over "); 13504 TimeUtils.formatDuration(realtimeSince, pw); 13505 pw.print(" used "); 13506 TimeUtils.formatDuration(timeUsed, pw); 13507 pw.print(" ("); 13508 pw.print((timeUsed*100)/realtimeSince); 13509 pw.println("%)"); 13510 } 13511 if (r.lastCpuTime != 0) { 13512 long timeUsed = r.curCpuTime - r.lastCpuTime; 13513 pw.print(prefix); 13514 pw.print(" "); 13515 pw.print("run cpu over "); 13516 TimeUtils.formatDuration(uptimeSince, pw); 13517 pw.print(" used "); 13518 TimeUtils.formatDuration(timeUsed, pw); 13519 pw.print(" ("); 13520 pw.print((timeUsed*100)/uptimeSince); 13521 pw.println("%)"); 13522 } 13523 } 13524 } 13525 } 13526 return true; 13527 } 13528 13529 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13530 String[] args) { 13531 ArrayList<ProcessRecord> procs; 13532 synchronized (this) { 13533 if (args != null && args.length > start 13534 && args[start].charAt(0) != '-') { 13535 procs = new ArrayList<ProcessRecord>(); 13536 int pid = -1; 13537 try { 13538 pid = Integer.parseInt(args[start]); 13539 } catch (NumberFormatException e) { 13540 } 13541 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13542 ProcessRecord proc = mLruProcesses.get(i); 13543 if (proc.pid == pid) { 13544 procs.add(proc); 13545 } else if (allPkgs && proc.pkgList != null 13546 && proc.pkgList.containsKey(args[start])) { 13547 procs.add(proc); 13548 } else if (proc.processName.equals(args[start])) { 13549 procs.add(proc); 13550 } 13551 } 13552 if (procs.size() <= 0) { 13553 return null; 13554 } 13555 } else { 13556 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13557 } 13558 } 13559 return procs; 13560 } 13561 13562 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13563 PrintWriter pw, String[] args) { 13564 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13565 if (procs == null) { 13566 pw.println("No process found for: " + args[0]); 13567 return; 13568 } 13569 13570 long uptime = SystemClock.uptimeMillis(); 13571 long realtime = SystemClock.elapsedRealtime(); 13572 pw.println("Applications Graphics Acceleration Info:"); 13573 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13574 13575 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13576 ProcessRecord r = procs.get(i); 13577 if (r.thread != null) { 13578 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13579 pw.flush(); 13580 try { 13581 TransferPipe tp = new TransferPipe(); 13582 try { 13583 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13584 tp.go(fd); 13585 } finally { 13586 tp.kill(); 13587 } 13588 } catch (IOException e) { 13589 pw.println("Failure while dumping the app: " + r); 13590 pw.flush(); 13591 } catch (RemoteException e) { 13592 pw.println("Got a RemoteException while dumping the app " + r); 13593 pw.flush(); 13594 } 13595 } 13596 } 13597 } 13598 13599 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13600 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13601 if (procs == null) { 13602 pw.println("No process found for: " + args[0]); 13603 return; 13604 } 13605 13606 pw.println("Applications Database Info:"); 13607 13608 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13609 ProcessRecord r = procs.get(i); 13610 if (r.thread != null) { 13611 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13612 pw.flush(); 13613 try { 13614 TransferPipe tp = new TransferPipe(); 13615 try { 13616 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13617 tp.go(fd); 13618 } finally { 13619 tp.kill(); 13620 } 13621 } catch (IOException e) { 13622 pw.println("Failure while dumping the app: " + r); 13623 pw.flush(); 13624 } catch (RemoteException e) { 13625 pw.println("Got a RemoteException while dumping the app " + r); 13626 pw.flush(); 13627 } 13628 } 13629 } 13630 } 13631 13632 final static class MemItem { 13633 final boolean isProc; 13634 final String label; 13635 final String shortLabel; 13636 final long pss; 13637 final int id; 13638 final boolean hasActivities; 13639 ArrayList<MemItem> subitems; 13640 13641 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13642 boolean _hasActivities) { 13643 isProc = true; 13644 label = _label; 13645 shortLabel = _shortLabel; 13646 pss = _pss; 13647 id = _id; 13648 hasActivities = _hasActivities; 13649 } 13650 13651 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13652 isProc = false; 13653 label = _label; 13654 shortLabel = _shortLabel; 13655 pss = _pss; 13656 id = _id; 13657 hasActivities = false; 13658 } 13659 } 13660 13661 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13662 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13663 if (sort && !isCompact) { 13664 Collections.sort(items, new Comparator<MemItem>() { 13665 @Override 13666 public int compare(MemItem lhs, MemItem rhs) { 13667 if (lhs.pss < rhs.pss) { 13668 return 1; 13669 } else if (lhs.pss > rhs.pss) { 13670 return -1; 13671 } 13672 return 0; 13673 } 13674 }); 13675 } 13676 13677 for (int i=0; i<items.size(); i++) { 13678 MemItem mi = items.get(i); 13679 if (!isCompact) { 13680 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13681 } else if (mi.isProc) { 13682 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13683 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13684 pw.println(mi.hasActivities ? ",a" : ",e"); 13685 } else { 13686 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13687 pw.println(mi.pss); 13688 } 13689 if (mi.subitems != null) { 13690 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13691 true, isCompact); 13692 } 13693 } 13694 } 13695 13696 // These are in KB. 13697 static final long[] DUMP_MEM_BUCKETS = new long[] { 13698 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13699 120*1024, 160*1024, 200*1024, 13700 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13701 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13702 }; 13703 13704 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13705 boolean stackLike) { 13706 int start = label.lastIndexOf('.'); 13707 if (start >= 0) start++; 13708 else start = 0; 13709 int end = label.length(); 13710 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13711 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13712 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13713 out.append(bucket); 13714 out.append(stackLike ? "MB." : "MB "); 13715 out.append(label, start, end); 13716 return; 13717 } 13718 } 13719 out.append(memKB/1024); 13720 out.append(stackLike ? "MB." : "MB "); 13721 out.append(label, start, end); 13722 } 13723 13724 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13725 ProcessList.NATIVE_ADJ, 13726 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13727 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13728 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13729 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13730 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13731 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13732 }; 13733 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13734 "Native", 13735 "System", "Persistent", "Persistent Service", "Foreground", 13736 "Visible", "Perceptible", 13737 "Heavy Weight", "Backup", 13738 "A Services", "Home", 13739 "Previous", "B Services", "Cached" 13740 }; 13741 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13742 "native", 13743 "sys", "pers", "persvc", "fore", 13744 "vis", "percept", 13745 "heavy", "backup", 13746 "servicea", "home", 13747 "prev", "serviceb", "cached" 13748 }; 13749 13750 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13751 long realtime, boolean isCheckinRequest, boolean isCompact) { 13752 if (isCheckinRequest || isCompact) { 13753 // short checkin version 13754 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13755 } else { 13756 pw.println("Applications Memory Usage (kB):"); 13757 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13758 } 13759 } 13760 13761 private static final int KSM_SHARED = 0; 13762 private static final int KSM_SHARING = 1; 13763 private static final int KSM_UNSHARED = 2; 13764 private static final int KSM_VOLATILE = 3; 13765 13766 private final long[] getKsmInfo() { 13767 long[] longOut = new long[4]; 13768 final int[] SINGLE_LONG_FORMAT = new int[] { 13769 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13770 }; 13771 long[] longTmp = new long[1]; 13772 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13773 SINGLE_LONG_FORMAT, null, longTmp, null); 13774 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13775 longTmp[0] = 0; 13776 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13777 SINGLE_LONG_FORMAT, null, longTmp, null); 13778 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13779 longTmp[0] = 0; 13780 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13781 SINGLE_LONG_FORMAT, null, longTmp, null); 13782 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13783 longTmp[0] = 0; 13784 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13785 SINGLE_LONG_FORMAT, null, longTmp, null); 13786 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13787 return longOut; 13788 } 13789 13790 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13791 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13792 boolean dumpDetails = false; 13793 boolean dumpFullDetails = false; 13794 boolean dumpDalvik = false; 13795 boolean oomOnly = false; 13796 boolean isCompact = false; 13797 boolean localOnly = false; 13798 boolean packages = false; 13799 13800 int opti = 0; 13801 while (opti < args.length) { 13802 String opt = args[opti]; 13803 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13804 break; 13805 } 13806 opti++; 13807 if ("-a".equals(opt)) { 13808 dumpDetails = true; 13809 dumpFullDetails = true; 13810 dumpDalvik = true; 13811 } else if ("-d".equals(opt)) { 13812 dumpDalvik = true; 13813 } else if ("-c".equals(opt)) { 13814 isCompact = true; 13815 } else if ("--oom".equals(opt)) { 13816 oomOnly = true; 13817 } else if ("--local".equals(opt)) { 13818 localOnly = true; 13819 } else if ("--package".equals(opt)) { 13820 packages = true; 13821 } else if ("-h".equals(opt)) { 13822 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13823 pw.println(" -a: include all available information for each process."); 13824 pw.println(" -d: include dalvik details when dumping process details."); 13825 pw.println(" -c: dump in a compact machine-parseable representation."); 13826 pw.println(" --oom: only show processes organized by oom adj."); 13827 pw.println(" --local: only collect details locally, don't call process."); 13828 pw.println(" --package: interpret process arg as package, dumping all"); 13829 pw.println(" processes that have loaded that package."); 13830 pw.println("If [process] is specified it can be the name or "); 13831 pw.println("pid of a specific process to dump."); 13832 return; 13833 } else { 13834 pw.println("Unknown argument: " + opt + "; use -h for help"); 13835 } 13836 } 13837 13838 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13839 long uptime = SystemClock.uptimeMillis(); 13840 long realtime = SystemClock.elapsedRealtime(); 13841 final long[] tmpLong = new long[1]; 13842 13843 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13844 if (procs == null) { 13845 // No Java processes. Maybe they want to print a native process. 13846 if (args != null && args.length > opti 13847 && args[opti].charAt(0) != '-') { 13848 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13849 = new ArrayList<ProcessCpuTracker.Stats>(); 13850 updateCpuStatsNow(); 13851 int findPid = -1; 13852 try { 13853 findPid = Integer.parseInt(args[opti]); 13854 } catch (NumberFormatException e) { 13855 } 13856 synchronized (mProcessCpuTracker) { 13857 final int N = mProcessCpuTracker.countStats(); 13858 for (int i=0; i<N; i++) { 13859 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13860 if (st.pid == findPid || (st.baseName != null 13861 && st.baseName.equals(args[opti]))) { 13862 nativeProcs.add(st); 13863 } 13864 } 13865 } 13866 if (nativeProcs.size() > 0) { 13867 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13868 isCompact); 13869 Debug.MemoryInfo mi = null; 13870 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13871 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13872 final int pid = r.pid; 13873 if (!isCheckinRequest && dumpDetails) { 13874 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13875 } 13876 if (mi == null) { 13877 mi = new Debug.MemoryInfo(); 13878 } 13879 if (dumpDetails || (!brief && !oomOnly)) { 13880 Debug.getMemoryInfo(pid, mi); 13881 } else { 13882 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13883 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13884 } 13885 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13886 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13887 if (isCheckinRequest) { 13888 pw.println(); 13889 } 13890 } 13891 return; 13892 } 13893 } 13894 pw.println("No process found for: " + args[opti]); 13895 return; 13896 } 13897 13898 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13899 dumpDetails = true; 13900 } 13901 13902 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13903 13904 String[] innerArgs = new String[args.length-opti]; 13905 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13906 13907 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13908 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13909 long nativePss=0, dalvikPss=0, otherPss=0; 13910 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13911 13912 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13913 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13914 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13915 13916 long totalPss = 0; 13917 long cachedPss = 0; 13918 13919 Debug.MemoryInfo mi = null; 13920 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13921 final ProcessRecord r = procs.get(i); 13922 final IApplicationThread thread; 13923 final int pid; 13924 final int oomAdj; 13925 final boolean hasActivities; 13926 synchronized (this) { 13927 thread = r.thread; 13928 pid = r.pid; 13929 oomAdj = r.getSetAdjWithServices(); 13930 hasActivities = r.activities.size() > 0; 13931 } 13932 if (thread != null) { 13933 if (!isCheckinRequest && dumpDetails) { 13934 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13935 } 13936 if (mi == null) { 13937 mi = new Debug.MemoryInfo(); 13938 } 13939 if (dumpDetails || (!brief && !oomOnly)) { 13940 Debug.getMemoryInfo(pid, mi); 13941 } else { 13942 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13943 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13944 } 13945 if (dumpDetails) { 13946 if (localOnly) { 13947 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13948 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13949 if (isCheckinRequest) { 13950 pw.println(); 13951 } 13952 } else { 13953 try { 13954 pw.flush(); 13955 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13956 dumpDalvik, innerArgs); 13957 } catch (RemoteException e) { 13958 if (!isCheckinRequest) { 13959 pw.println("Got RemoteException!"); 13960 pw.flush(); 13961 } 13962 } 13963 } 13964 } 13965 13966 final long myTotalPss = mi.getTotalPss(); 13967 final long myTotalUss = mi.getTotalUss(); 13968 13969 synchronized (this) { 13970 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13971 // Record this for posterity if the process has been stable. 13972 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13973 } 13974 } 13975 13976 if (!isCheckinRequest && mi != null) { 13977 totalPss += myTotalPss; 13978 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13979 (hasActivities ? " / activities)" : ")"), 13980 r.processName, myTotalPss, pid, hasActivities); 13981 procMems.add(pssItem); 13982 procMemsMap.put(pid, pssItem); 13983 13984 nativePss += mi.nativePss; 13985 dalvikPss += mi.dalvikPss; 13986 otherPss += mi.otherPss; 13987 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13988 long mem = mi.getOtherPss(j); 13989 miscPss[j] += mem; 13990 otherPss -= mem; 13991 } 13992 13993 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13994 cachedPss += myTotalPss; 13995 } 13996 13997 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13998 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13999 || oomIndex == (oomPss.length-1)) { 14000 oomPss[oomIndex] += myTotalPss; 14001 if (oomProcs[oomIndex] == null) { 14002 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14003 } 14004 oomProcs[oomIndex].add(pssItem); 14005 break; 14006 } 14007 } 14008 } 14009 } 14010 } 14011 14012 long nativeProcTotalPss = 0; 14013 14014 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14015 // If we are showing aggregations, also look for native processes to 14016 // include so that our aggregations are more accurate. 14017 updateCpuStatsNow(); 14018 synchronized (mProcessCpuTracker) { 14019 final int N = mProcessCpuTracker.countStats(); 14020 for (int i=0; i<N; i++) { 14021 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14022 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14023 if (mi == null) { 14024 mi = new Debug.MemoryInfo(); 14025 } 14026 if (!brief && !oomOnly) { 14027 Debug.getMemoryInfo(st.pid, mi); 14028 } else { 14029 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14030 mi.nativePrivateDirty = (int)tmpLong[0]; 14031 } 14032 14033 final long myTotalPss = mi.getTotalPss(); 14034 totalPss += myTotalPss; 14035 nativeProcTotalPss += myTotalPss; 14036 14037 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14038 st.name, myTotalPss, st.pid, false); 14039 procMems.add(pssItem); 14040 14041 nativePss += mi.nativePss; 14042 dalvikPss += mi.dalvikPss; 14043 otherPss += mi.otherPss; 14044 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14045 long mem = mi.getOtherPss(j); 14046 miscPss[j] += mem; 14047 otherPss -= mem; 14048 } 14049 oomPss[0] += myTotalPss; 14050 if (oomProcs[0] == null) { 14051 oomProcs[0] = new ArrayList<MemItem>(); 14052 } 14053 oomProcs[0].add(pssItem); 14054 } 14055 } 14056 } 14057 14058 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14059 14060 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14061 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14062 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14063 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14064 String label = Debug.MemoryInfo.getOtherLabel(j); 14065 catMems.add(new MemItem(label, label, miscPss[j], j)); 14066 } 14067 14068 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14069 for (int j=0; j<oomPss.length; j++) { 14070 if (oomPss[j] != 0) { 14071 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14072 : DUMP_MEM_OOM_LABEL[j]; 14073 MemItem item = new MemItem(label, label, oomPss[j], 14074 DUMP_MEM_OOM_ADJ[j]); 14075 item.subitems = oomProcs[j]; 14076 oomMems.add(item); 14077 } 14078 } 14079 14080 if (!brief && !oomOnly && !isCompact) { 14081 pw.println(); 14082 pw.println("Total PSS by process:"); 14083 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14084 pw.println(); 14085 } 14086 if (!isCompact) { 14087 pw.println("Total PSS by OOM adjustment:"); 14088 } 14089 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14090 if (!brief && !oomOnly) { 14091 PrintWriter out = categoryPw != null ? categoryPw : pw; 14092 if (!isCompact) { 14093 out.println(); 14094 out.println("Total PSS by category:"); 14095 } 14096 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14097 } 14098 if (!isCompact) { 14099 pw.println(); 14100 } 14101 MemInfoReader memInfo = new MemInfoReader(); 14102 memInfo.readMemInfo(); 14103 if (nativeProcTotalPss > 0) { 14104 synchronized (this) { 14105 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14106 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14107 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14108 } 14109 } 14110 if (!brief) { 14111 if (!isCompact) { 14112 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14113 pw.print(" kB (status "); 14114 switch (mLastMemoryLevel) { 14115 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14116 pw.println("normal)"); 14117 break; 14118 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14119 pw.println("moderate)"); 14120 break; 14121 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14122 pw.println("low)"); 14123 break; 14124 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14125 pw.println("critical)"); 14126 break; 14127 default: 14128 pw.print(mLastMemoryLevel); 14129 pw.println(")"); 14130 break; 14131 } 14132 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14133 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14134 pw.print(cachedPss); pw.print(" cached pss + "); 14135 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14136 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14137 } else { 14138 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14139 pw.print(cachedPss + memInfo.getCachedSizeKb() 14140 + memInfo.getFreeSizeKb()); pw.print(","); 14141 pw.println(totalPss - cachedPss); 14142 } 14143 } 14144 if (!isCompact) { 14145 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14146 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14147 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14148 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14149 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14150 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14151 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14152 } 14153 if (!brief) { 14154 if (memInfo.getZramTotalSizeKb() != 0) { 14155 if (!isCompact) { 14156 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14157 pw.print(" kB physical used for "); 14158 pw.print(memInfo.getSwapTotalSizeKb() 14159 - memInfo.getSwapFreeSizeKb()); 14160 pw.print(" kB in swap ("); 14161 pw.print(memInfo.getSwapTotalSizeKb()); 14162 pw.println(" kB total swap)"); 14163 } else { 14164 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14165 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14166 pw.println(memInfo.getSwapFreeSizeKb()); 14167 } 14168 } 14169 final long[] ksm = getKsmInfo(); 14170 if (!isCompact) { 14171 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14172 || ksm[KSM_VOLATILE] != 0) { 14173 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14174 pw.print(" kB saved from shared "); 14175 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14176 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14177 pw.print(" kB unshared; "); 14178 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14179 } 14180 pw.print(" Tuning: "); 14181 pw.print(ActivityManager.staticGetMemoryClass()); 14182 pw.print(" (large "); 14183 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14184 pw.print("), oom "); 14185 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14186 pw.print(" kB"); 14187 pw.print(", restore limit "); 14188 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14189 pw.print(" kB"); 14190 if (ActivityManager.isLowRamDeviceStatic()) { 14191 pw.print(" (low-ram)"); 14192 } 14193 if (ActivityManager.isHighEndGfx()) { 14194 pw.print(" (high-end-gfx)"); 14195 } 14196 pw.println(); 14197 } else { 14198 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14199 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14200 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14201 pw.print("tuning,"); 14202 pw.print(ActivityManager.staticGetMemoryClass()); 14203 pw.print(','); 14204 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14205 pw.print(','); 14206 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14207 if (ActivityManager.isLowRamDeviceStatic()) { 14208 pw.print(",low-ram"); 14209 } 14210 if (ActivityManager.isHighEndGfx()) { 14211 pw.print(",high-end-gfx"); 14212 } 14213 pw.println(); 14214 } 14215 } 14216 } 14217 } 14218 14219 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14220 String name) { 14221 sb.append(" "); 14222 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14223 sb.append(' '); 14224 sb.append(ProcessList.makeProcStateString(procState)); 14225 sb.append(' '); 14226 ProcessList.appendRamKb(sb, pss); 14227 sb.append(" kB: "); 14228 sb.append(name); 14229 } 14230 14231 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14232 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14233 sb.append(" ("); 14234 sb.append(mi.pid); 14235 sb.append(") "); 14236 sb.append(mi.adjType); 14237 sb.append('\n'); 14238 if (mi.adjReason != null) { 14239 sb.append(" "); 14240 sb.append(mi.adjReason); 14241 sb.append('\n'); 14242 } 14243 } 14244 14245 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14246 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14247 for (int i=0, N=memInfos.size(); i<N; i++) { 14248 ProcessMemInfo mi = memInfos.get(i); 14249 infoMap.put(mi.pid, mi); 14250 } 14251 updateCpuStatsNow(); 14252 synchronized (mProcessCpuTracker) { 14253 final int N = mProcessCpuTracker.countStats(); 14254 for (int i=0; i<N; i++) { 14255 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14256 if (st.vsize > 0) { 14257 long pss = Debug.getPss(st.pid, null); 14258 if (pss > 0) { 14259 if (infoMap.indexOfKey(st.pid) < 0) { 14260 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14261 ProcessList.NATIVE_ADJ, -1, "native", null); 14262 mi.pss = pss; 14263 memInfos.add(mi); 14264 } 14265 } 14266 } 14267 } 14268 } 14269 14270 long totalPss = 0; 14271 for (int i=0, N=memInfos.size(); i<N; i++) { 14272 ProcessMemInfo mi = memInfos.get(i); 14273 if (mi.pss == 0) { 14274 mi.pss = Debug.getPss(mi.pid, null); 14275 } 14276 totalPss += mi.pss; 14277 } 14278 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14279 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14280 if (lhs.oomAdj != rhs.oomAdj) { 14281 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14282 } 14283 if (lhs.pss != rhs.pss) { 14284 return lhs.pss < rhs.pss ? 1 : -1; 14285 } 14286 return 0; 14287 } 14288 }); 14289 14290 StringBuilder tag = new StringBuilder(128); 14291 StringBuilder stack = new StringBuilder(128); 14292 tag.append("Low on memory -- "); 14293 appendMemBucket(tag, totalPss, "total", false); 14294 appendMemBucket(stack, totalPss, "total", true); 14295 14296 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14297 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14298 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14299 14300 boolean firstLine = true; 14301 int lastOomAdj = Integer.MIN_VALUE; 14302 long extraNativeRam = 0; 14303 long cachedPss = 0; 14304 for (int i=0, N=memInfos.size(); i<N; i++) { 14305 ProcessMemInfo mi = memInfos.get(i); 14306 14307 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14308 cachedPss += mi.pss; 14309 } 14310 14311 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14312 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14313 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14314 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14315 if (lastOomAdj != mi.oomAdj) { 14316 lastOomAdj = mi.oomAdj; 14317 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14318 tag.append(" / "); 14319 } 14320 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14321 if (firstLine) { 14322 stack.append(":"); 14323 firstLine = false; 14324 } 14325 stack.append("\n\t at "); 14326 } else { 14327 stack.append("$"); 14328 } 14329 } else { 14330 tag.append(" "); 14331 stack.append("$"); 14332 } 14333 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14334 appendMemBucket(tag, mi.pss, mi.name, false); 14335 } 14336 appendMemBucket(stack, mi.pss, mi.name, true); 14337 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14338 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14339 stack.append("("); 14340 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14341 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14342 stack.append(DUMP_MEM_OOM_LABEL[k]); 14343 stack.append(":"); 14344 stack.append(DUMP_MEM_OOM_ADJ[k]); 14345 } 14346 } 14347 stack.append(")"); 14348 } 14349 } 14350 14351 appendMemInfo(fullNativeBuilder, mi); 14352 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14353 // The short form only has native processes that are >= 1MB. 14354 if (mi.pss >= 1000) { 14355 appendMemInfo(shortNativeBuilder, mi); 14356 } else { 14357 extraNativeRam += mi.pss; 14358 } 14359 } else { 14360 // Short form has all other details, but if we have collected RAM 14361 // from smaller native processes let's dump a summary of that. 14362 if (extraNativeRam > 0) { 14363 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14364 -1, extraNativeRam, "(Other native)"); 14365 shortNativeBuilder.append('\n'); 14366 extraNativeRam = 0; 14367 } 14368 appendMemInfo(fullJavaBuilder, mi); 14369 } 14370 } 14371 14372 fullJavaBuilder.append(" "); 14373 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14374 fullJavaBuilder.append(" kB: TOTAL\n"); 14375 14376 MemInfoReader memInfo = new MemInfoReader(); 14377 memInfo.readMemInfo(); 14378 final long[] infos = memInfo.getRawInfo(); 14379 14380 StringBuilder memInfoBuilder = new StringBuilder(1024); 14381 Debug.getMemInfo(infos); 14382 memInfoBuilder.append(" MemInfo: "); 14383 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14384 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14385 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14386 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14387 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14388 memInfoBuilder.append(" "); 14389 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14390 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14391 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14392 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14393 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14394 memInfoBuilder.append(" ZRAM: "); 14395 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14396 memInfoBuilder.append(" kB RAM, "); 14397 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14398 memInfoBuilder.append(" kB swap total, "); 14399 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14400 memInfoBuilder.append(" kB swap free\n"); 14401 } 14402 final long[] ksm = getKsmInfo(); 14403 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14404 || ksm[KSM_VOLATILE] != 0) { 14405 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14406 memInfoBuilder.append(" kB saved from shared "); 14407 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14408 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14409 memInfoBuilder.append(" kB unshared; "); 14410 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14411 } 14412 memInfoBuilder.append(" Free RAM: "); 14413 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14414 + memInfo.getFreeSizeKb()); 14415 memInfoBuilder.append(" kB\n"); 14416 memInfoBuilder.append(" Used RAM: "); 14417 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14418 memInfoBuilder.append(" kB\n"); 14419 memInfoBuilder.append(" Lost RAM: "); 14420 memInfoBuilder.append(memInfo.getTotalSizeKb() 14421 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14422 - memInfo.getKernelUsedSizeKb()); 14423 memInfoBuilder.append(" kB\n"); 14424 Slog.i(TAG, "Low on memory:"); 14425 Slog.i(TAG, shortNativeBuilder.toString()); 14426 Slog.i(TAG, fullJavaBuilder.toString()); 14427 Slog.i(TAG, memInfoBuilder.toString()); 14428 14429 StringBuilder dropBuilder = new StringBuilder(1024); 14430 /* 14431 StringWriter oomSw = new StringWriter(); 14432 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14433 StringWriter catSw = new StringWriter(); 14434 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14435 String[] emptyArgs = new String[] { }; 14436 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14437 oomPw.flush(); 14438 String oomString = oomSw.toString(); 14439 */ 14440 dropBuilder.append("Low on memory:"); 14441 dropBuilder.append(stack); 14442 dropBuilder.append('\n'); 14443 dropBuilder.append(fullNativeBuilder); 14444 dropBuilder.append(fullJavaBuilder); 14445 dropBuilder.append('\n'); 14446 dropBuilder.append(memInfoBuilder); 14447 dropBuilder.append('\n'); 14448 /* 14449 dropBuilder.append(oomString); 14450 dropBuilder.append('\n'); 14451 */ 14452 StringWriter catSw = new StringWriter(); 14453 synchronized (ActivityManagerService.this) { 14454 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14455 String[] emptyArgs = new String[] { }; 14456 catPw.println(); 14457 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14458 catPw.println(); 14459 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14460 false, false, null); 14461 catPw.println(); 14462 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14463 catPw.flush(); 14464 } 14465 dropBuilder.append(catSw.toString()); 14466 addErrorToDropBox("lowmem", null, "system_server", null, 14467 null, tag.toString(), dropBuilder.toString(), null, null); 14468 //Slog.i(TAG, "Sent to dropbox:"); 14469 //Slog.i(TAG, dropBuilder.toString()); 14470 synchronized (ActivityManagerService.this) { 14471 long now = SystemClock.uptimeMillis(); 14472 if (mLastMemUsageReportTime < now) { 14473 mLastMemUsageReportTime = now; 14474 } 14475 } 14476 } 14477 14478 /** 14479 * Searches array of arguments for the specified string 14480 * @param args array of argument strings 14481 * @param value value to search for 14482 * @return true if the value is contained in the array 14483 */ 14484 private static boolean scanArgs(String[] args, String value) { 14485 if (args != null) { 14486 for (String arg : args) { 14487 if (value.equals(arg)) { 14488 return true; 14489 } 14490 } 14491 } 14492 return false; 14493 } 14494 14495 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14496 ContentProviderRecord cpr, boolean always) { 14497 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14498 14499 if (!inLaunching || always) { 14500 synchronized (cpr) { 14501 cpr.launchingApp = null; 14502 cpr.notifyAll(); 14503 } 14504 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14505 String names[] = cpr.info.authority.split(";"); 14506 for (int j = 0; j < names.length; j++) { 14507 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14508 } 14509 } 14510 14511 for (int i=0; i<cpr.connections.size(); i++) { 14512 ContentProviderConnection conn = cpr.connections.get(i); 14513 if (conn.waiting) { 14514 // If this connection is waiting for the provider, then we don't 14515 // need to mess with its process unless we are always removing 14516 // or for some reason the provider is not currently launching. 14517 if (inLaunching && !always) { 14518 continue; 14519 } 14520 } 14521 ProcessRecord capp = conn.client; 14522 conn.dead = true; 14523 if (conn.stableCount > 0) { 14524 if (!capp.persistent && capp.thread != null 14525 && capp.pid != 0 14526 && capp.pid != MY_PID) { 14527 capp.kill("depends on provider " 14528 + cpr.name.flattenToShortString() 14529 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14530 } 14531 } else if (capp.thread != null && conn.provider.provider != null) { 14532 try { 14533 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14534 } catch (RemoteException e) { 14535 } 14536 // In the protocol here, we don't expect the client to correctly 14537 // clean up this connection, we'll just remove it. 14538 cpr.connections.remove(i); 14539 conn.client.conProviders.remove(conn); 14540 } 14541 } 14542 14543 if (inLaunching && always) { 14544 mLaunchingProviders.remove(cpr); 14545 } 14546 return inLaunching; 14547 } 14548 14549 /** 14550 * Main code for cleaning up a process when it has gone away. This is 14551 * called both as a result of the process dying, or directly when stopping 14552 * a process when running in single process mode. 14553 * 14554 * @return Returns true if the given process has been restarted, so the 14555 * app that was passed in must remain on the process lists. 14556 */ 14557 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14558 boolean restarting, boolean allowRestart, int index) { 14559 if (index >= 0) { 14560 removeLruProcessLocked(app); 14561 ProcessList.remove(app.pid); 14562 } 14563 14564 mProcessesToGc.remove(app); 14565 mPendingPssProcesses.remove(app); 14566 14567 // Dismiss any open dialogs. 14568 if (app.crashDialog != null && !app.forceCrashReport) { 14569 app.crashDialog.dismiss(); 14570 app.crashDialog = null; 14571 } 14572 if (app.anrDialog != null) { 14573 app.anrDialog.dismiss(); 14574 app.anrDialog = null; 14575 } 14576 if (app.waitDialog != null) { 14577 app.waitDialog.dismiss(); 14578 app.waitDialog = null; 14579 } 14580 14581 app.crashing = false; 14582 app.notResponding = false; 14583 14584 app.resetPackageList(mProcessStats); 14585 app.unlinkDeathRecipient(); 14586 app.makeInactive(mProcessStats); 14587 app.waitingToKill = null; 14588 app.forcingToForeground = null; 14589 updateProcessForegroundLocked(app, false, false); 14590 app.foregroundActivities = false; 14591 app.hasShownUi = false; 14592 app.treatLikeActivity = false; 14593 app.hasAboveClient = false; 14594 app.hasClientActivities = false; 14595 14596 mServices.killServicesLocked(app, allowRestart); 14597 14598 boolean restart = false; 14599 14600 // Remove published content providers. 14601 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14602 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14603 final boolean always = app.bad || !allowRestart; 14604 if (removeDyingProviderLocked(app, cpr, always) || always) { 14605 // We left the provider in the launching list, need to 14606 // restart it. 14607 restart = true; 14608 } 14609 14610 cpr.provider = null; 14611 cpr.proc = null; 14612 } 14613 app.pubProviders.clear(); 14614 14615 // Take care of any launching providers waiting for this process. 14616 if (checkAppInLaunchingProvidersLocked(app, false)) { 14617 restart = true; 14618 } 14619 14620 // Unregister from connected content providers. 14621 if (!app.conProviders.isEmpty()) { 14622 for (int i=0; i<app.conProviders.size(); i++) { 14623 ContentProviderConnection conn = app.conProviders.get(i); 14624 conn.provider.connections.remove(conn); 14625 } 14626 app.conProviders.clear(); 14627 } 14628 14629 // At this point there may be remaining entries in mLaunchingProviders 14630 // where we were the only one waiting, so they are no longer of use. 14631 // Look for these and clean up if found. 14632 // XXX Commented out for now. Trying to figure out a way to reproduce 14633 // the actual situation to identify what is actually going on. 14634 if (false) { 14635 for (int i=0; i<mLaunchingProviders.size(); i++) { 14636 ContentProviderRecord cpr = (ContentProviderRecord) 14637 mLaunchingProviders.get(i); 14638 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14639 synchronized (cpr) { 14640 cpr.launchingApp = null; 14641 cpr.notifyAll(); 14642 } 14643 } 14644 } 14645 } 14646 14647 skipCurrentReceiverLocked(app); 14648 14649 // Unregister any receivers. 14650 for (int i=app.receivers.size()-1; i>=0; i--) { 14651 removeReceiverLocked(app.receivers.valueAt(i)); 14652 } 14653 app.receivers.clear(); 14654 14655 // If the app is undergoing backup, tell the backup manager about it 14656 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14657 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14658 + mBackupTarget.appInfo + " died during backup"); 14659 try { 14660 IBackupManager bm = IBackupManager.Stub.asInterface( 14661 ServiceManager.getService(Context.BACKUP_SERVICE)); 14662 bm.agentDisconnected(app.info.packageName); 14663 } catch (RemoteException e) { 14664 // can't happen; backup manager is local 14665 } 14666 } 14667 14668 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14669 ProcessChangeItem item = mPendingProcessChanges.get(i); 14670 if (item.pid == app.pid) { 14671 mPendingProcessChanges.remove(i); 14672 mAvailProcessChanges.add(item); 14673 } 14674 } 14675 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14676 14677 // If the caller is restarting this app, then leave it in its 14678 // current lists and let the caller take care of it. 14679 if (restarting) { 14680 return false; 14681 } 14682 14683 if (!app.persistent || app.isolated) { 14684 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14685 "Removing non-persistent process during cleanup: " + app); 14686 mProcessNames.remove(app.processName, app.uid); 14687 mIsolatedProcesses.remove(app.uid); 14688 if (mHeavyWeightProcess == app) { 14689 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14690 mHeavyWeightProcess.userId, 0)); 14691 mHeavyWeightProcess = null; 14692 } 14693 } else if (!app.removed) { 14694 // This app is persistent, so we need to keep its record around. 14695 // If it is not already on the pending app list, add it there 14696 // and start a new process for it. 14697 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14698 mPersistentStartingProcesses.add(app); 14699 restart = true; 14700 } 14701 } 14702 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14703 "Clean-up removing on hold: " + app); 14704 mProcessesOnHold.remove(app); 14705 14706 if (app == mHomeProcess) { 14707 mHomeProcess = null; 14708 } 14709 if (app == mPreviousProcess) { 14710 mPreviousProcess = null; 14711 } 14712 14713 if (restart && !app.isolated) { 14714 // We have components that still need to be running in the 14715 // process, so re-launch it. 14716 if (index < 0) { 14717 ProcessList.remove(app.pid); 14718 } 14719 mProcessNames.put(app.processName, app.uid, app); 14720 startProcessLocked(app, "restart", app.processName); 14721 return true; 14722 } else if (app.pid > 0 && app.pid != MY_PID) { 14723 // Goodbye! 14724 boolean removed; 14725 synchronized (mPidsSelfLocked) { 14726 mPidsSelfLocked.remove(app.pid); 14727 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14728 } 14729 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14730 if (app.isolated) { 14731 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14732 } 14733 app.setPid(0); 14734 } 14735 return false; 14736 } 14737 14738 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14739 // Look through the content providers we are waiting to have launched, 14740 // and if any run in this process then either schedule a restart of 14741 // the process or kill the client waiting for it if this process has 14742 // gone bad. 14743 int NL = mLaunchingProviders.size(); 14744 boolean restart = false; 14745 for (int i=0; i<NL; i++) { 14746 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14747 if (cpr.launchingApp == app) { 14748 if (!alwaysBad && !app.bad) { 14749 restart = true; 14750 } else { 14751 removeDyingProviderLocked(app, cpr, true); 14752 // cpr should have been removed from mLaunchingProviders 14753 NL = mLaunchingProviders.size(); 14754 i--; 14755 } 14756 } 14757 } 14758 return restart; 14759 } 14760 14761 // ========================================================= 14762 // SERVICES 14763 // ========================================================= 14764 14765 @Override 14766 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14767 int flags) { 14768 enforceNotIsolatedCaller("getServices"); 14769 synchronized (this) { 14770 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14771 } 14772 } 14773 14774 @Override 14775 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14776 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14777 synchronized (this) { 14778 return mServices.getRunningServiceControlPanelLocked(name); 14779 } 14780 } 14781 14782 @Override 14783 public ComponentName startService(IApplicationThread caller, Intent service, 14784 String resolvedType, int userId) { 14785 enforceNotIsolatedCaller("startService"); 14786 // Refuse possible leaked file descriptors 14787 if (service != null && service.hasFileDescriptors() == true) { 14788 throw new IllegalArgumentException("File descriptors passed in Intent"); 14789 } 14790 14791 if (DEBUG_SERVICE) 14792 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14793 synchronized(this) { 14794 final int callingPid = Binder.getCallingPid(); 14795 final int callingUid = Binder.getCallingUid(); 14796 final long origId = Binder.clearCallingIdentity(); 14797 ComponentName res = mServices.startServiceLocked(caller, service, 14798 resolvedType, callingPid, callingUid, userId); 14799 Binder.restoreCallingIdentity(origId); 14800 return res; 14801 } 14802 } 14803 14804 ComponentName startServiceInPackage(int uid, 14805 Intent service, String resolvedType, int userId) { 14806 synchronized(this) { 14807 if (DEBUG_SERVICE) 14808 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14809 final long origId = Binder.clearCallingIdentity(); 14810 ComponentName res = mServices.startServiceLocked(null, service, 14811 resolvedType, -1, uid, userId); 14812 Binder.restoreCallingIdentity(origId); 14813 return res; 14814 } 14815 } 14816 14817 @Override 14818 public int stopService(IApplicationThread caller, Intent service, 14819 String resolvedType, int userId) { 14820 enforceNotIsolatedCaller("stopService"); 14821 // Refuse possible leaked file descriptors 14822 if (service != null && service.hasFileDescriptors() == true) { 14823 throw new IllegalArgumentException("File descriptors passed in Intent"); 14824 } 14825 14826 synchronized(this) { 14827 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14828 } 14829 } 14830 14831 @Override 14832 public IBinder peekService(Intent service, String resolvedType) { 14833 enforceNotIsolatedCaller("peekService"); 14834 // Refuse possible leaked file descriptors 14835 if (service != null && service.hasFileDescriptors() == true) { 14836 throw new IllegalArgumentException("File descriptors passed in Intent"); 14837 } 14838 synchronized(this) { 14839 return mServices.peekServiceLocked(service, resolvedType); 14840 } 14841 } 14842 14843 @Override 14844 public boolean stopServiceToken(ComponentName className, IBinder token, 14845 int startId) { 14846 synchronized(this) { 14847 return mServices.stopServiceTokenLocked(className, token, startId); 14848 } 14849 } 14850 14851 @Override 14852 public void setServiceForeground(ComponentName className, IBinder token, 14853 int id, Notification notification, boolean removeNotification) { 14854 synchronized(this) { 14855 mServices.setServiceForegroundLocked(className, token, id, notification, 14856 removeNotification); 14857 } 14858 } 14859 14860 @Override 14861 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14862 boolean requireFull, String name, String callerPackage) { 14863 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14864 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14865 } 14866 14867 int unsafeConvertIncomingUser(int userId) { 14868 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14869 ? mCurrentUserId : userId; 14870 } 14871 14872 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14873 int allowMode, String name, String callerPackage) { 14874 final int callingUserId = UserHandle.getUserId(callingUid); 14875 if (callingUserId == userId) { 14876 return userId; 14877 } 14878 14879 // Note that we may be accessing mCurrentUserId outside of a lock... 14880 // shouldn't be a big deal, if this is being called outside 14881 // of a locked context there is intrinsically a race with 14882 // the value the caller will receive and someone else changing it. 14883 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14884 // we will switch to the calling user if access to the current user fails. 14885 int targetUserId = unsafeConvertIncomingUser(userId); 14886 14887 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14888 final boolean allow; 14889 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14890 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14891 // If the caller has this permission, they always pass go. And collect $200. 14892 allow = true; 14893 } else if (allowMode == ALLOW_FULL_ONLY) { 14894 // We require full access, sucks to be you. 14895 allow = false; 14896 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14897 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14898 // If the caller does not have either permission, they are always doomed. 14899 allow = false; 14900 } else if (allowMode == ALLOW_NON_FULL) { 14901 // We are blanket allowing non-full access, you lucky caller! 14902 allow = true; 14903 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14904 // We may or may not allow this depending on whether the two users are 14905 // in the same profile. 14906 synchronized (mUserProfileGroupIdsSelfLocked) { 14907 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14908 UserInfo.NO_PROFILE_GROUP_ID); 14909 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14910 UserInfo.NO_PROFILE_GROUP_ID); 14911 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14912 && callingProfile == targetProfile; 14913 } 14914 } else { 14915 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14916 } 14917 if (!allow) { 14918 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14919 // In this case, they would like to just execute as their 14920 // owner user instead of failing. 14921 targetUserId = callingUserId; 14922 } else { 14923 StringBuilder builder = new StringBuilder(128); 14924 builder.append("Permission Denial: "); 14925 builder.append(name); 14926 if (callerPackage != null) { 14927 builder.append(" from "); 14928 builder.append(callerPackage); 14929 } 14930 builder.append(" asks to run as user "); 14931 builder.append(userId); 14932 builder.append(" but is calling from user "); 14933 builder.append(UserHandle.getUserId(callingUid)); 14934 builder.append("; this requires "); 14935 builder.append(INTERACT_ACROSS_USERS_FULL); 14936 if (allowMode != ALLOW_FULL_ONLY) { 14937 builder.append(" or "); 14938 builder.append(INTERACT_ACROSS_USERS); 14939 } 14940 String msg = builder.toString(); 14941 Slog.w(TAG, msg); 14942 throw new SecurityException(msg); 14943 } 14944 } 14945 } 14946 if (!allowAll && targetUserId < 0) { 14947 throw new IllegalArgumentException( 14948 "Call does not support special user #" + targetUserId); 14949 } 14950 // Check shell permission 14951 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14952 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14953 targetUserId)) { 14954 throw new SecurityException("Shell does not have permission to access user " 14955 + targetUserId + "\n " + Debug.getCallers(3)); 14956 } 14957 } 14958 return targetUserId; 14959 } 14960 14961 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14962 String className, int flags) { 14963 boolean result = false; 14964 // For apps that don't have pre-defined UIDs, check for permission 14965 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14966 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14967 if (ActivityManager.checkUidPermission( 14968 INTERACT_ACROSS_USERS, 14969 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14970 ComponentName comp = new ComponentName(aInfo.packageName, className); 14971 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14972 + " requests FLAG_SINGLE_USER, but app does not hold " 14973 + INTERACT_ACROSS_USERS; 14974 Slog.w(TAG, msg); 14975 throw new SecurityException(msg); 14976 } 14977 // Permission passed 14978 result = true; 14979 } 14980 } else if ("system".equals(componentProcessName)) { 14981 result = true; 14982 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14983 // Phone app and persistent apps are allowed to export singleuser providers. 14984 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14985 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14986 } 14987 if (DEBUG_MU) { 14988 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14989 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14990 } 14991 return result; 14992 } 14993 14994 /** 14995 * Checks to see if the caller is in the same app as the singleton 14996 * component, or the component is in a special app. It allows special apps 14997 * to export singleton components but prevents exporting singleton 14998 * components for regular apps. 14999 */ 15000 boolean isValidSingletonCall(int callingUid, int componentUid) { 15001 int componentAppId = UserHandle.getAppId(componentUid); 15002 return UserHandle.isSameApp(callingUid, componentUid) 15003 || componentAppId == Process.SYSTEM_UID 15004 || componentAppId == Process.PHONE_UID 15005 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15006 == PackageManager.PERMISSION_GRANTED; 15007 } 15008 15009 public int bindService(IApplicationThread caller, IBinder token, 15010 Intent service, String resolvedType, 15011 IServiceConnection connection, int flags, int userId) { 15012 enforceNotIsolatedCaller("bindService"); 15013 15014 // Refuse possible leaked file descriptors 15015 if (service != null && service.hasFileDescriptors() == true) { 15016 throw new IllegalArgumentException("File descriptors passed in Intent"); 15017 } 15018 15019 synchronized(this) { 15020 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15021 connection, flags, userId); 15022 } 15023 } 15024 15025 public boolean unbindService(IServiceConnection connection) { 15026 synchronized (this) { 15027 return mServices.unbindServiceLocked(connection); 15028 } 15029 } 15030 15031 public void publishService(IBinder token, Intent intent, IBinder service) { 15032 // Refuse possible leaked file descriptors 15033 if (intent != null && intent.hasFileDescriptors() == true) { 15034 throw new IllegalArgumentException("File descriptors passed in Intent"); 15035 } 15036 15037 synchronized(this) { 15038 if (!(token instanceof ServiceRecord)) { 15039 throw new IllegalArgumentException("Invalid service token"); 15040 } 15041 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15042 } 15043 } 15044 15045 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15046 // Refuse possible leaked file descriptors 15047 if (intent != null && intent.hasFileDescriptors() == true) { 15048 throw new IllegalArgumentException("File descriptors passed in Intent"); 15049 } 15050 15051 synchronized(this) { 15052 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15053 } 15054 } 15055 15056 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15057 synchronized(this) { 15058 if (!(token instanceof ServiceRecord)) { 15059 throw new IllegalArgumentException("Invalid service token"); 15060 } 15061 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15062 } 15063 } 15064 15065 // ========================================================= 15066 // BACKUP AND RESTORE 15067 // ========================================================= 15068 15069 // Cause the target app to be launched if necessary and its backup agent 15070 // instantiated. The backup agent will invoke backupAgentCreated() on the 15071 // activity manager to announce its creation. 15072 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15073 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15074 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15075 15076 synchronized(this) { 15077 // !!! TODO: currently no check here that we're already bound 15078 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15079 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15080 synchronized (stats) { 15081 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15082 } 15083 15084 // Backup agent is now in use, its package can't be stopped. 15085 try { 15086 AppGlobals.getPackageManager().setPackageStoppedState( 15087 app.packageName, false, UserHandle.getUserId(app.uid)); 15088 } catch (RemoteException e) { 15089 } catch (IllegalArgumentException e) { 15090 Slog.w(TAG, "Failed trying to unstop package " 15091 + app.packageName + ": " + e); 15092 } 15093 15094 BackupRecord r = new BackupRecord(ss, app, backupMode); 15095 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15096 ? new ComponentName(app.packageName, app.backupAgentName) 15097 : new ComponentName("android", "FullBackupAgent"); 15098 // startProcessLocked() returns existing proc's record if it's already running 15099 ProcessRecord proc = startProcessLocked(app.processName, app, 15100 false, 0, "backup", hostingName, false, false, false); 15101 if (proc == null) { 15102 Slog.e(TAG, "Unable to start backup agent process " + r); 15103 return false; 15104 } 15105 15106 r.app = proc; 15107 mBackupTarget = r; 15108 mBackupAppName = app.packageName; 15109 15110 // Try not to kill the process during backup 15111 updateOomAdjLocked(proc); 15112 15113 // If the process is already attached, schedule the creation of the backup agent now. 15114 // If it is not yet live, this will be done when it attaches to the framework. 15115 if (proc.thread != null) { 15116 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15117 try { 15118 proc.thread.scheduleCreateBackupAgent(app, 15119 compatibilityInfoForPackageLocked(app), backupMode); 15120 } catch (RemoteException e) { 15121 // Will time out on the backup manager side 15122 } 15123 } else { 15124 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15125 } 15126 // Invariants: at this point, the target app process exists and the application 15127 // is either already running or in the process of coming up. mBackupTarget and 15128 // mBackupAppName describe the app, so that when it binds back to the AM we 15129 // know that it's scheduled for a backup-agent operation. 15130 } 15131 15132 return true; 15133 } 15134 15135 @Override 15136 public void clearPendingBackup() { 15137 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15138 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15139 15140 synchronized (this) { 15141 mBackupTarget = null; 15142 mBackupAppName = null; 15143 } 15144 } 15145 15146 // A backup agent has just come up 15147 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15148 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15149 + " = " + agent); 15150 15151 synchronized(this) { 15152 if (!agentPackageName.equals(mBackupAppName)) { 15153 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15154 return; 15155 } 15156 } 15157 15158 long oldIdent = Binder.clearCallingIdentity(); 15159 try { 15160 IBackupManager bm = IBackupManager.Stub.asInterface( 15161 ServiceManager.getService(Context.BACKUP_SERVICE)); 15162 bm.agentConnected(agentPackageName, agent); 15163 } catch (RemoteException e) { 15164 // can't happen; the backup manager service is local 15165 } catch (Exception e) { 15166 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15167 e.printStackTrace(); 15168 } finally { 15169 Binder.restoreCallingIdentity(oldIdent); 15170 } 15171 } 15172 15173 // done with this agent 15174 public void unbindBackupAgent(ApplicationInfo appInfo) { 15175 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15176 if (appInfo == null) { 15177 Slog.w(TAG, "unbind backup agent for null app"); 15178 return; 15179 } 15180 15181 synchronized(this) { 15182 try { 15183 if (mBackupAppName == null) { 15184 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15185 return; 15186 } 15187 15188 if (!mBackupAppName.equals(appInfo.packageName)) { 15189 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15190 return; 15191 } 15192 15193 // Not backing this app up any more; reset its OOM adjustment 15194 final ProcessRecord proc = mBackupTarget.app; 15195 updateOomAdjLocked(proc); 15196 15197 // If the app crashed during backup, 'thread' will be null here 15198 if (proc.thread != null) { 15199 try { 15200 proc.thread.scheduleDestroyBackupAgent(appInfo, 15201 compatibilityInfoForPackageLocked(appInfo)); 15202 } catch (Exception e) { 15203 Slog.e(TAG, "Exception when unbinding backup agent:"); 15204 e.printStackTrace(); 15205 } 15206 } 15207 } finally { 15208 mBackupTarget = null; 15209 mBackupAppName = null; 15210 } 15211 } 15212 } 15213 // ========================================================= 15214 // BROADCASTS 15215 // ========================================================= 15216 15217 private final List getStickiesLocked(String action, IntentFilter filter, 15218 List cur, int userId) { 15219 final ContentResolver resolver = mContext.getContentResolver(); 15220 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15221 if (stickies == null) { 15222 return cur; 15223 } 15224 final ArrayList<Intent> list = stickies.get(action); 15225 if (list == null) { 15226 return cur; 15227 } 15228 int N = list.size(); 15229 for (int i=0; i<N; i++) { 15230 Intent intent = list.get(i); 15231 if (filter.match(resolver, intent, true, TAG) >= 0) { 15232 if (cur == null) { 15233 cur = new ArrayList<Intent>(); 15234 } 15235 cur.add(intent); 15236 } 15237 } 15238 return cur; 15239 } 15240 15241 boolean isPendingBroadcastProcessLocked(int pid) { 15242 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15243 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15244 } 15245 15246 void skipPendingBroadcastLocked(int pid) { 15247 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15248 for (BroadcastQueue queue : mBroadcastQueues) { 15249 queue.skipPendingBroadcastLocked(pid); 15250 } 15251 } 15252 15253 // The app just attached; send any pending broadcasts that it should receive 15254 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15255 boolean didSomething = false; 15256 for (BroadcastQueue queue : mBroadcastQueues) { 15257 didSomething |= queue.sendPendingBroadcastsLocked(app); 15258 } 15259 return didSomething; 15260 } 15261 15262 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15263 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15264 enforceNotIsolatedCaller("registerReceiver"); 15265 int callingUid; 15266 int callingPid; 15267 synchronized(this) { 15268 ProcessRecord callerApp = null; 15269 if (caller != null) { 15270 callerApp = getRecordForAppLocked(caller); 15271 if (callerApp == null) { 15272 throw new SecurityException( 15273 "Unable to find app for caller " + caller 15274 + " (pid=" + Binder.getCallingPid() 15275 + ") when registering receiver " + receiver); 15276 } 15277 if (callerApp.info.uid != Process.SYSTEM_UID && 15278 !callerApp.pkgList.containsKey(callerPackage) && 15279 !"android".equals(callerPackage)) { 15280 throw new SecurityException("Given caller package " + callerPackage 15281 + " is not running in process " + callerApp); 15282 } 15283 callingUid = callerApp.info.uid; 15284 callingPid = callerApp.pid; 15285 } else { 15286 callerPackage = null; 15287 callingUid = Binder.getCallingUid(); 15288 callingPid = Binder.getCallingPid(); 15289 } 15290 15291 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15292 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15293 15294 List allSticky = null; 15295 15296 // Look for any matching sticky broadcasts... 15297 Iterator actions = filter.actionsIterator(); 15298 if (actions != null) { 15299 while (actions.hasNext()) { 15300 String action = (String)actions.next(); 15301 allSticky = getStickiesLocked(action, filter, allSticky, 15302 UserHandle.USER_ALL); 15303 allSticky = getStickiesLocked(action, filter, allSticky, 15304 UserHandle.getUserId(callingUid)); 15305 } 15306 } else { 15307 allSticky = getStickiesLocked(null, filter, allSticky, 15308 UserHandle.USER_ALL); 15309 allSticky = getStickiesLocked(null, filter, allSticky, 15310 UserHandle.getUserId(callingUid)); 15311 } 15312 15313 // The first sticky in the list is returned directly back to 15314 // the client. 15315 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15316 15317 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15318 + ": " + sticky); 15319 15320 if (receiver == null) { 15321 return sticky; 15322 } 15323 15324 ReceiverList rl 15325 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15326 if (rl == null) { 15327 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15328 userId, receiver); 15329 if (rl.app != null) { 15330 rl.app.receivers.add(rl); 15331 } else { 15332 try { 15333 receiver.asBinder().linkToDeath(rl, 0); 15334 } catch (RemoteException e) { 15335 return sticky; 15336 } 15337 rl.linkedToDeath = true; 15338 } 15339 mRegisteredReceivers.put(receiver.asBinder(), rl); 15340 } else if (rl.uid != callingUid) { 15341 throw new IllegalArgumentException( 15342 "Receiver requested to register for uid " + callingUid 15343 + " was previously registered for uid " + rl.uid); 15344 } else if (rl.pid != callingPid) { 15345 throw new IllegalArgumentException( 15346 "Receiver requested to register for pid " + callingPid 15347 + " was previously registered for pid " + rl.pid); 15348 } else if (rl.userId != userId) { 15349 throw new IllegalArgumentException( 15350 "Receiver requested to register for user " + userId 15351 + " was previously registered for user " + rl.userId); 15352 } 15353 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15354 permission, callingUid, userId); 15355 rl.add(bf); 15356 if (!bf.debugCheck()) { 15357 Slog.w(TAG, "==> For Dynamic broadast"); 15358 } 15359 mReceiverResolver.addFilter(bf); 15360 15361 // Enqueue broadcasts for all existing stickies that match 15362 // this filter. 15363 if (allSticky != null) { 15364 ArrayList receivers = new ArrayList(); 15365 receivers.add(bf); 15366 15367 int N = allSticky.size(); 15368 for (int i=0; i<N; i++) { 15369 Intent intent = (Intent)allSticky.get(i); 15370 BroadcastQueue queue = broadcastQueueForIntent(intent); 15371 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15372 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15373 null, null, false, true, true, -1); 15374 queue.enqueueParallelBroadcastLocked(r); 15375 queue.scheduleBroadcastsLocked(); 15376 } 15377 } 15378 15379 return sticky; 15380 } 15381 } 15382 15383 public void unregisterReceiver(IIntentReceiver receiver) { 15384 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15385 15386 final long origId = Binder.clearCallingIdentity(); 15387 try { 15388 boolean doTrim = false; 15389 15390 synchronized(this) { 15391 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15392 if (rl != null) { 15393 if (rl.curBroadcast != null) { 15394 BroadcastRecord r = rl.curBroadcast; 15395 final boolean doNext = finishReceiverLocked( 15396 receiver.asBinder(), r.resultCode, r.resultData, 15397 r.resultExtras, r.resultAbort); 15398 if (doNext) { 15399 doTrim = true; 15400 r.queue.processNextBroadcast(false); 15401 } 15402 } 15403 15404 if (rl.app != null) { 15405 rl.app.receivers.remove(rl); 15406 } 15407 removeReceiverLocked(rl); 15408 if (rl.linkedToDeath) { 15409 rl.linkedToDeath = false; 15410 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15411 } 15412 } 15413 } 15414 15415 // If we actually concluded any broadcasts, we might now be able 15416 // to trim the recipients' apps from our working set 15417 if (doTrim) { 15418 trimApplications(); 15419 return; 15420 } 15421 15422 } finally { 15423 Binder.restoreCallingIdentity(origId); 15424 } 15425 } 15426 15427 void removeReceiverLocked(ReceiverList rl) { 15428 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15429 int N = rl.size(); 15430 for (int i=0; i<N; i++) { 15431 mReceiverResolver.removeFilter(rl.get(i)); 15432 } 15433 } 15434 15435 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15437 ProcessRecord r = mLruProcesses.get(i); 15438 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15439 try { 15440 r.thread.dispatchPackageBroadcast(cmd, packages); 15441 } catch (RemoteException ex) { 15442 } 15443 } 15444 } 15445 } 15446 15447 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15448 int callingUid, int[] users) { 15449 List<ResolveInfo> receivers = null; 15450 try { 15451 HashSet<ComponentName> singleUserReceivers = null; 15452 boolean scannedFirstReceivers = false; 15453 for (int user : users) { 15454 // Skip users that have Shell restrictions 15455 if (callingUid == Process.SHELL_UID 15456 && getUserManagerLocked().hasUserRestriction( 15457 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15458 continue; 15459 } 15460 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15461 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15462 if (user != 0 && newReceivers != null) { 15463 // If this is not the primary user, we need to check for 15464 // any receivers that should be filtered out. 15465 for (int i=0; i<newReceivers.size(); i++) { 15466 ResolveInfo ri = newReceivers.get(i); 15467 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15468 newReceivers.remove(i); 15469 i--; 15470 } 15471 } 15472 } 15473 if (newReceivers != null && newReceivers.size() == 0) { 15474 newReceivers = null; 15475 } 15476 if (receivers == null) { 15477 receivers = newReceivers; 15478 } else if (newReceivers != null) { 15479 // We need to concatenate the additional receivers 15480 // found with what we have do far. This would be easy, 15481 // but we also need to de-dup any receivers that are 15482 // singleUser. 15483 if (!scannedFirstReceivers) { 15484 // Collect any single user receivers we had already retrieved. 15485 scannedFirstReceivers = true; 15486 for (int i=0; i<receivers.size(); i++) { 15487 ResolveInfo ri = receivers.get(i); 15488 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15489 ComponentName cn = new ComponentName( 15490 ri.activityInfo.packageName, ri.activityInfo.name); 15491 if (singleUserReceivers == null) { 15492 singleUserReceivers = new HashSet<ComponentName>(); 15493 } 15494 singleUserReceivers.add(cn); 15495 } 15496 } 15497 } 15498 // Add the new results to the existing results, tracking 15499 // and de-dupping single user receivers. 15500 for (int i=0; i<newReceivers.size(); i++) { 15501 ResolveInfo ri = newReceivers.get(i); 15502 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15503 ComponentName cn = new ComponentName( 15504 ri.activityInfo.packageName, ri.activityInfo.name); 15505 if (singleUserReceivers == null) { 15506 singleUserReceivers = new HashSet<ComponentName>(); 15507 } 15508 if (!singleUserReceivers.contains(cn)) { 15509 singleUserReceivers.add(cn); 15510 receivers.add(ri); 15511 } 15512 } else { 15513 receivers.add(ri); 15514 } 15515 } 15516 } 15517 } 15518 } catch (RemoteException ex) { 15519 // pm is in same process, this will never happen. 15520 } 15521 return receivers; 15522 } 15523 15524 private final int broadcastIntentLocked(ProcessRecord callerApp, 15525 String callerPackage, Intent intent, String resolvedType, 15526 IIntentReceiver resultTo, int resultCode, String resultData, 15527 Bundle map, String requiredPermission, int appOp, 15528 boolean ordered, boolean sticky, int callingPid, int callingUid, 15529 int userId) { 15530 intent = new Intent(intent); 15531 15532 // By default broadcasts do not go to stopped apps. 15533 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15534 15535 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15536 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15537 + " ordered=" + ordered + " userid=" + userId); 15538 if ((resultTo != null) && !ordered) { 15539 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15540 } 15541 15542 userId = handleIncomingUser(callingPid, callingUid, userId, 15543 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15544 15545 // Make sure that the user who is receiving this broadcast is started. 15546 // If not, we will just skip it. 15547 15548 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15549 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15550 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15551 Slog.w(TAG, "Skipping broadcast of " + intent 15552 + ": user " + userId + " is stopped"); 15553 return ActivityManager.BROADCAST_SUCCESS; 15554 } 15555 } 15556 15557 /* 15558 * Prevent non-system code (defined here to be non-persistent 15559 * processes) from sending protected broadcasts. 15560 */ 15561 int callingAppId = UserHandle.getAppId(callingUid); 15562 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15563 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15564 || callingAppId == Process.NFC_UID || callingUid == 0) { 15565 // Always okay. 15566 } else if (callerApp == null || !callerApp.persistent) { 15567 try { 15568 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15569 intent.getAction())) { 15570 String msg = "Permission Denial: not allowed to send broadcast " 15571 + intent.getAction() + " from pid=" 15572 + callingPid + ", uid=" + callingUid; 15573 Slog.w(TAG, msg); 15574 throw new SecurityException(msg); 15575 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15576 // Special case for compatibility: we don't want apps to send this, 15577 // but historically it has not been protected and apps may be using it 15578 // to poke their own app widget. So, instead of making it protected, 15579 // just limit it to the caller. 15580 if (callerApp == null) { 15581 String msg = "Permission Denial: not allowed to send broadcast " 15582 + intent.getAction() + " from unknown caller."; 15583 Slog.w(TAG, msg); 15584 throw new SecurityException(msg); 15585 } else if (intent.getComponent() != null) { 15586 // They are good enough to send to an explicit component... verify 15587 // it is being sent to the calling app. 15588 if (!intent.getComponent().getPackageName().equals( 15589 callerApp.info.packageName)) { 15590 String msg = "Permission Denial: not allowed to send broadcast " 15591 + intent.getAction() + " to " 15592 + intent.getComponent().getPackageName() + " from " 15593 + callerApp.info.packageName; 15594 Slog.w(TAG, msg); 15595 throw new SecurityException(msg); 15596 } 15597 } else { 15598 // Limit broadcast to their own package. 15599 intent.setPackage(callerApp.info.packageName); 15600 } 15601 } 15602 } catch (RemoteException e) { 15603 Slog.w(TAG, "Remote exception", e); 15604 return ActivityManager.BROADCAST_SUCCESS; 15605 } 15606 } 15607 15608 // Handle special intents: if this broadcast is from the package 15609 // manager about a package being removed, we need to remove all of 15610 // its activities from the history stack. 15611 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15612 intent.getAction()); 15613 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15614 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15615 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15616 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15617 || uidRemoved) { 15618 if (checkComponentPermission( 15619 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15620 callingPid, callingUid, -1, true) 15621 == PackageManager.PERMISSION_GRANTED) { 15622 if (uidRemoved) { 15623 final Bundle intentExtras = intent.getExtras(); 15624 final int uid = intentExtras != null 15625 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15626 if (uid >= 0) { 15627 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15628 synchronized (bs) { 15629 bs.removeUidStatsLocked(uid); 15630 } 15631 mAppOpsService.uidRemoved(uid); 15632 } 15633 } else { 15634 // If resources are unavailable just force stop all 15635 // those packages and flush the attribute cache as well. 15636 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15637 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15638 if (list != null && (list.length > 0)) { 15639 for (String pkg : list) { 15640 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15641 "storage unmount"); 15642 } 15643 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15644 sendPackageBroadcastLocked( 15645 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15646 } 15647 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15648 intent.getAction())) { 15649 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15650 } else { 15651 Uri data = intent.getData(); 15652 String ssp; 15653 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15654 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15655 intent.getAction()); 15656 boolean fullUninstall = removed && 15657 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15658 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15659 forceStopPackageLocked(ssp, UserHandle.getAppId( 15660 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15661 false, fullUninstall, userId, 15662 removed ? "pkg removed" : "pkg changed"); 15663 } 15664 if (removed) { 15665 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15666 new String[] {ssp}, userId); 15667 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15668 mAppOpsService.packageRemoved( 15669 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15670 15671 // Remove all permissions granted from/to this package 15672 removeUriPermissionsForPackageLocked(ssp, userId, true); 15673 } 15674 } 15675 } 15676 } 15677 } 15678 } else { 15679 String msg = "Permission Denial: " + intent.getAction() 15680 + " broadcast from " + callerPackage + " (pid=" + callingPid 15681 + ", uid=" + callingUid + ")" 15682 + " requires " 15683 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15684 Slog.w(TAG, msg); 15685 throw new SecurityException(msg); 15686 } 15687 15688 // Special case for adding a package: by default turn on compatibility 15689 // mode. 15690 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15691 Uri data = intent.getData(); 15692 String ssp; 15693 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15694 mCompatModePackages.handlePackageAddedLocked(ssp, 15695 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15696 } 15697 } 15698 15699 /* 15700 * If this is the time zone changed action, queue up a message that will reset the timezone 15701 * of all currently running processes. This message will get queued up before the broadcast 15702 * happens. 15703 */ 15704 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15705 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15706 } 15707 15708 /* 15709 * If the user set the time, let all running processes know. 15710 */ 15711 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15712 final int is24Hour = intent.getBooleanExtra( 15713 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15714 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15715 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15716 synchronized (stats) { 15717 stats.noteCurrentTimeChangedLocked(); 15718 } 15719 } 15720 15721 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15722 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15723 } 15724 15725 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15726 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15727 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15728 } 15729 15730 // Add to the sticky list if requested. 15731 if (sticky) { 15732 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15733 callingPid, callingUid) 15734 != PackageManager.PERMISSION_GRANTED) { 15735 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15736 + callingPid + ", uid=" + callingUid 15737 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15738 Slog.w(TAG, msg); 15739 throw new SecurityException(msg); 15740 } 15741 if (requiredPermission != null) { 15742 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15743 + " and enforce permission " + requiredPermission); 15744 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15745 } 15746 if (intent.getComponent() != null) { 15747 throw new SecurityException( 15748 "Sticky broadcasts can't target a specific component"); 15749 } 15750 // We use userId directly here, since the "all" target is maintained 15751 // as a separate set of sticky broadcasts. 15752 if (userId != UserHandle.USER_ALL) { 15753 // But first, if this is not a broadcast to all users, then 15754 // make sure it doesn't conflict with an existing broadcast to 15755 // all users. 15756 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15757 UserHandle.USER_ALL); 15758 if (stickies != null) { 15759 ArrayList<Intent> list = stickies.get(intent.getAction()); 15760 if (list != null) { 15761 int N = list.size(); 15762 int i; 15763 for (i=0; i<N; i++) { 15764 if (intent.filterEquals(list.get(i))) { 15765 throw new IllegalArgumentException( 15766 "Sticky broadcast " + intent + " for user " 15767 + userId + " conflicts with existing global broadcast"); 15768 } 15769 } 15770 } 15771 } 15772 } 15773 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15774 if (stickies == null) { 15775 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15776 mStickyBroadcasts.put(userId, stickies); 15777 } 15778 ArrayList<Intent> list = stickies.get(intent.getAction()); 15779 if (list == null) { 15780 list = new ArrayList<Intent>(); 15781 stickies.put(intent.getAction(), list); 15782 } 15783 int N = list.size(); 15784 int i; 15785 for (i=0; i<N; i++) { 15786 if (intent.filterEquals(list.get(i))) { 15787 // This sticky already exists, replace it. 15788 list.set(i, new Intent(intent)); 15789 break; 15790 } 15791 } 15792 if (i >= N) { 15793 list.add(new Intent(intent)); 15794 } 15795 } 15796 15797 int[] users; 15798 if (userId == UserHandle.USER_ALL) { 15799 // Caller wants broadcast to go to all started users. 15800 users = mStartedUserArray; 15801 } else { 15802 // Caller wants broadcast to go to one specific user. 15803 users = new int[] {userId}; 15804 } 15805 15806 // Figure out who all will receive this broadcast. 15807 List receivers = null; 15808 List<BroadcastFilter> registeredReceivers = null; 15809 // Need to resolve the intent to interested receivers... 15810 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15811 == 0) { 15812 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15813 } 15814 if (intent.getComponent() == null) { 15815 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15816 // Query one target user at a time, excluding shell-restricted users 15817 UserManagerService ums = getUserManagerLocked(); 15818 for (int i = 0; i < users.length; i++) { 15819 if (ums.hasUserRestriction( 15820 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15821 continue; 15822 } 15823 List<BroadcastFilter> registeredReceiversForUser = 15824 mReceiverResolver.queryIntent(intent, 15825 resolvedType, false, users[i]); 15826 if (registeredReceivers == null) { 15827 registeredReceivers = registeredReceiversForUser; 15828 } else if (registeredReceiversForUser != null) { 15829 registeredReceivers.addAll(registeredReceiversForUser); 15830 } 15831 } 15832 } else { 15833 registeredReceivers = mReceiverResolver.queryIntent(intent, 15834 resolvedType, false, userId); 15835 } 15836 } 15837 15838 final boolean replacePending = 15839 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15840 15841 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15842 + " replacePending=" + replacePending); 15843 15844 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15845 if (!ordered && NR > 0) { 15846 // If we are not serializing this broadcast, then send the 15847 // registered receivers separately so they don't wait for the 15848 // components to be launched. 15849 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15850 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15851 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15852 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15853 ordered, sticky, false, userId); 15854 if (DEBUG_BROADCAST) Slog.v( 15855 TAG, "Enqueueing parallel broadcast " + r); 15856 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15857 if (!replaced) { 15858 queue.enqueueParallelBroadcastLocked(r); 15859 queue.scheduleBroadcastsLocked(); 15860 } 15861 registeredReceivers = null; 15862 NR = 0; 15863 } 15864 15865 // Merge into one list. 15866 int ir = 0; 15867 if (receivers != null) { 15868 // A special case for PACKAGE_ADDED: do not allow the package 15869 // being added to see this broadcast. This prevents them from 15870 // using this as a back door to get run as soon as they are 15871 // installed. Maybe in the future we want to have a special install 15872 // broadcast or such for apps, but we'd like to deliberately make 15873 // this decision. 15874 String skipPackages[] = null; 15875 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15876 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15877 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15878 Uri data = intent.getData(); 15879 if (data != null) { 15880 String pkgName = data.getSchemeSpecificPart(); 15881 if (pkgName != null) { 15882 skipPackages = new String[] { pkgName }; 15883 } 15884 } 15885 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15886 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15887 } 15888 if (skipPackages != null && (skipPackages.length > 0)) { 15889 for (String skipPackage : skipPackages) { 15890 if (skipPackage != null) { 15891 int NT = receivers.size(); 15892 for (int it=0; it<NT; it++) { 15893 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15894 if (curt.activityInfo.packageName.equals(skipPackage)) { 15895 receivers.remove(it); 15896 it--; 15897 NT--; 15898 } 15899 } 15900 } 15901 } 15902 } 15903 15904 int NT = receivers != null ? receivers.size() : 0; 15905 int it = 0; 15906 ResolveInfo curt = null; 15907 BroadcastFilter curr = null; 15908 while (it < NT && ir < NR) { 15909 if (curt == null) { 15910 curt = (ResolveInfo)receivers.get(it); 15911 } 15912 if (curr == null) { 15913 curr = registeredReceivers.get(ir); 15914 } 15915 if (curr.getPriority() >= curt.priority) { 15916 // Insert this broadcast record into the final list. 15917 receivers.add(it, curr); 15918 ir++; 15919 curr = null; 15920 it++; 15921 NT++; 15922 } else { 15923 // Skip to the next ResolveInfo in the final list. 15924 it++; 15925 curt = null; 15926 } 15927 } 15928 } 15929 while (ir < NR) { 15930 if (receivers == null) { 15931 receivers = new ArrayList(); 15932 } 15933 receivers.add(registeredReceivers.get(ir)); 15934 ir++; 15935 } 15936 15937 if ((receivers != null && receivers.size() > 0) 15938 || resultTo != null) { 15939 BroadcastQueue queue = broadcastQueueForIntent(intent); 15940 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15941 callerPackage, callingPid, callingUid, resolvedType, 15942 requiredPermission, appOp, receivers, resultTo, resultCode, 15943 resultData, map, ordered, sticky, false, userId); 15944 if (DEBUG_BROADCAST) Slog.v( 15945 TAG, "Enqueueing ordered broadcast " + r 15946 + ": prev had " + queue.mOrderedBroadcasts.size()); 15947 if (DEBUG_BROADCAST) { 15948 int seq = r.intent.getIntExtra("seq", -1); 15949 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15950 } 15951 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15952 if (!replaced) { 15953 queue.enqueueOrderedBroadcastLocked(r); 15954 queue.scheduleBroadcastsLocked(); 15955 } 15956 } 15957 15958 return ActivityManager.BROADCAST_SUCCESS; 15959 } 15960 15961 final Intent verifyBroadcastLocked(Intent intent) { 15962 // Refuse possible leaked file descriptors 15963 if (intent != null && intent.hasFileDescriptors() == true) { 15964 throw new IllegalArgumentException("File descriptors passed in Intent"); 15965 } 15966 15967 int flags = intent.getFlags(); 15968 15969 if (!mProcessesReady) { 15970 // if the caller really truly claims to know what they're doing, go 15971 // ahead and allow the broadcast without launching any receivers 15972 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15973 intent = new Intent(intent); 15974 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15975 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15976 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15977 + " before boot completion"); 15978 throw new IllegalStateException("Cannot broadcast before boot completed"); 15979 } 15980 } 15981 15982 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15983 throw new IllegalArgumentException( 15984 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15985 } 15986 15987 return intent; 15988 } 15989 15990 public final int broadcastIntent(IApplicationThread caller, 15991 Intent intent, String resolvedType, IIntentReceiver resultTo, 15992 int resultCode, String resultData, Bundle map, 15993 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15994 enforceNotIsolatedCaller("broadcastIntent"); 15995 synchronized(this) { 15996 intent = verifyBroadcastLocked(intent); 15997 15998 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15999 final int callingPid = Binder.getCallingPid(); 16000 final int callingUid = Binder.getCallingUid(); 16001 final long origId = Binder.clearCallingIdentity(); 16002 int res = broadcastIntentLocked(callerApp, 16003 callerApp != null ? callerApp.info.packageName : null, 16004 intent, resolvedType, resultTo, 16005 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16006 callingPid, callingUid, userId); 16007 Binder.restoreCallingIdentity(origId); 16008 return res; 16009 } 16010 } 16011 16012 int broadcastIntentInPackage(String packageName, int uid, 16013 Intent intent, String resolvedType, IIntentReceiver resultTo, 16014 int resultCode, String resultData, Bundle map, 16015 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16016 synchronized(this) { 16017 intent = verifyBroadcastLocked(intent); 16018 16019 final long origId = Binder.clearCallingIdentity(); 16020 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16021 resultTo, resultCode, resultData, map, requiredPermission, 16022 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16023 Binder.restoreCallingIdentity(origId); 16024 return res; 16025 } 16026 } 16027 16028 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16029 // Refuse possible leaked file descriptors 16030 if (intent != null && intent.hasFileDescriptors() == true) { 16031 throw new IllegalArgumentException("File descriptors passed in Intent"); 16032 } 16033 16034 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16035 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16036 16037 synchronized(this) { 16038 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16039 != PackageManager.PERMISSION_GRANTED) { 16040 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16041 + Binder.getCallingPid() 16042 + ", uid=" + Binder.getCallingUid() 16043 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16044 Slog.w(TAG, msg); 16045 throw new SecurityException(msg); 16046 } 16047 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16048 if (stickies != null) { 16049 ArrayList<Intent> list = stickies.get(intent.getAction()); 16050 if (list != null) { 16051 int N = list.size(); 16052 int i; 16053 for (i=0; i<N; i++) { 16054 if (intent.filterEquals(list.get(i))) { 16055 list.remove(i); 16056 break; 16057 } 16058 } 16059 if (list.size() <= 0) { 16060 stickies.remove(intent.getAction()); 16061 } 16062 } 16063 if (stickies.size() <= 0) { 16064 mStickyBroadcasts.remove(userId); 16065 } 16066 } 16067 } 16068 } 16069 16070 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16071 String resultData, Bundle resultExtras, boolean resultAbort) { 16072 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16073 if (r == null) { 16074 Slog.w(TAG, "finishReceiver called but not found on queue"); 16075 return false; 16076 } 16077 16078 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16079 } 16080 16081 void backgroundServicesFinishedLocked(int userId) { 16082 for (BroadcastQueue queue : mBroadcastQueues) { 16083 queue.backgroundServicesFinishedLocked(userId); 16084 } 16085 } 16086 16087 public void finishReceiver(IBinder who, int resultCode, String resultData, 16088 Bundle resultExtras, boolean resultAbort) { 16089 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16090 16091 // Refuse possible leaked file descriptors 16092 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16093 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16094 } 16095 16096 final long origId = Binder.clearCallingIdentity(); 16097 try { 16098 boolean doNext = false; 16099 BroadcastRecord r; 16100 16101 synchronized(this) { 16102 r = broadcastRecordForReceiverLocked(who); 16103 if (r != null) { 16104 doNext = r.queue.finishReceiverLocked(r, resultCode, 16105 resultData, resultExtras, resultAbort, true); 16106 } 16107 } 16108 16109 if (doNext) { 16110 r.queue.processNextBroadcast(false); 16111 } 16112 trimApplications(); 16113 } finally { 16114 Binder.restoreCallingIdentity(origId); 16115 } 16116 } 16117 16118 // ========================================================= 16119 // INSTRUMENTATION 16120 // ========================================================= 16121 16122 public boolean startInstrumentation(ComponentName className, 16123 String profileFile, int flags, Bundle arguments, 16124 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16125 int userId, String abiOverride) { 16126 enforceNotIsolatedCaller("startInstrumentation"); 16127 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16128 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16129 // Refuse possible leaked file descriptors 16130 if (arguments != null && arguments.hasFileDescriptors()) { 16131 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16132 } 16133 16134 synchronized(this) { 16135 InstrumentationInfo ii = null; 16136 ApplicationInfo ai = null; 16137 try { 16138 ii = mContext.getPackageManager().getInstrumentationInfo( 16139 className, STOCK_PM_FLAGS); 16140 ai = AppGlobals.getPackageManager().getApplicationInfo( 16141 ii.targetPackage, STOCK_PM_FLAGS, userId); 16142 } catch (PackageManager.NameNotFoundException e) { 16143 } catch (RemoteException e) { 16144 } 16145 if (ii == null) { 16146 reportStartInstrumentationFailure(watcher, className, 16147 "Unable to find instrumentation info for: " + className); 16148 return false; 16149 } 16150 if (ai == null) { 16151 reportStartInstrumentationFailure(watcher, className, 16152 "Unable to find instrumentation target package: " + ii.targetPackage); 16153 return false; 16154 } 16155 16156 int match = mContext.getPackageManager().checkSignatures( 16157 ii.targetPackage, ii.packageName); 16158 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16159 String msg = "Permission Denial: starting instrumentation " 16160 + className + " from pid=" 16161 + Binder.getCallingPid() 16162 + ", uid=" + Binder.getCallingPid() 16163 + " not allowed because package " + ii.packageName 16164 + " does not have a signature matching the target " 16165 + ii.targetPackage; 16166 reportStartInstrumentationFailure(watcher, className, msg); 16167 throw new SecurityException(msg); 16168 } 16169 16170 final long origId = Binder.clearCallingIdentity(); 16171 // Instrumentation can kill and relaunch even persistent processes 16172 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16173 "start instr"); 16174 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16175 app.instrumentationClass = className; 16176 app.instrumentationInfo = ai; 16177 app.instrumentationProfileFile = profileFile; 16178 app.instrumentationArguments = arguments; 16179 app.instrumentationWatcher = watcher; 16180 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16181 app.instrumentationResultClass = className; 16182 Binder.restoreCallingIdentity(origId); 16183 } 16184 16185 return true; 16186 } 16187 16188 /** 16189 * Report errors that occur while attempting to start Instrumentation. Always writes the 16190 * error to the logs, but if somebody is watching, send the report there too. This enables 16191 * the "am" command to report errors with more information. 16192 * 16193 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16194 * @param cn The component name of the instrumentation. 16195 * @param report The error report. 16196 */ 16197 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16198 ComponentName cn, String report) { 16199 Slog.w(TAG, report); 16200 try { 16201 if (watcher != null) { 16202 Bundle results = new Bundle(); 16203 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16204 results.putString("Error", report); 16205 watcher.instrumentationStatus(cn, -1, results); 16206 } 16207 } catch (RemoteException e) { 16208 Slog.w(TAG, e); 16209 } 16210 } 16211 16212 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16213 if (app.instrumentationWatcher != null) { 16214 try { 16215 // NOTE: IInstrumentationWatcher *must* be oneway here 16216 app.instrumentationWatcher.instrumentationFinished( 16217 app.instrumentationClass, 16218 resultCode, 16219 results); 16220 } catch (RemoteException e) { 16221 } 16222 } 16223 if (app.instrumentationUiAutomationConnection != null) { 16224 try { 16225 app.instrumentationUiAutomationConnection.shutdown(); 16226 } catch (RemoteException re) { 16227 /* ignore */ 16228 } 16229 // Only a UiAutomation can set this flag and now that 16230 // it is finished we make sure it is reset to its default. 16231 mUserIsMonkey = false; 16232 } 16233 app.instrumentationWatcher = null; 16234 app.instrumentationUiAutomationConnection = null; 16235 app.instrumentationClass = null; 16236 app.instrumentationInfo = null; 16237 app.instrumentationProfileFile = null; 16238 app.instrumentationArguments = null; 16239 16240 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16241 "finished inst"); 16242 } 16243 16244 public void finishInstrumentation(IApplicationThread target, 16245 int resultCode, Bundle results) { 16246 int userId = UserHandle.getCallingUserId(); 16247 // Refuse possible leaked file descriptors 16248 if (results != null && results.hasFileDescriptors()) { 16249 throw new IllegalArgumentException("File descriptors passed in Intent"); 16250 } 16251 16252 synchronized(this) { 16253 ProcessRecord app = getRecordForAppLocked(target); 16254 if (app == null) { 16255 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16256 return; 16257 } 16258 final long origId = Binder.clearCallingIdentity(); 16259 finishInstrumentationLocked(app, resultCode, results); 16260 Binder.restoreCallingIdentity(origId); 16261 } 16262 } 16263 16264 // ========================================================= 16265 // CONFIGURATION 16266 // ========================================================= 16267 16268 public ConfigurationInfo getDeviceConfigurationInfo() { 16269 ConfigurationInfo config = new ConfigurationInfo(); 16270 synchronized (this) { 16271 config.reqTouchScreen = mConfiguration.touchscreen; 16272 config.reqKeyboardType = mConfiguration.keyboard; 16273 config.reqNavigation = mConfiguration.navigation; 16274 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16275 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16276 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16277 } 16278 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16279 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16280 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16281 } 16282 config.reqGlEsVersion = GL_ES_VERSION; 16283 } 16284 return config; 16285 } 16286 16287 ActivityStack getFocusedStack() { 16288 return mStackSupervisor.getFocusedStack(); 16289 } 16290 16291 public Configuration getConfiguration() { 16292 Configuration ci; 16293 synchronized(this) { 16294 ci = new Configuration(mConfiguration); 16295 } 16296 return ci; 16297 } 16298 16299 public void updatePersistentConfiguration(Configuration values) { 16300 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16301 "updateConfiguration()"); 16302 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16303 "updateConfiguration()"); 16304 if (values == null) { 16305 throw new NullPointerException("Configuration must not be null"); 16306 } 16307 16308 synchronized(this) { 16309 final long origId = Binder.clearCallingIdentity(); 16310 updateConfigurationLocked(values, null, true, false); 16311 Binder.restoreCallingIdentity(origId); 16312 } 16313 } 16314 16315 public void updateConfiguration(Configuration values) { 16316 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16317 "updateConfiguration()"); 16318 16319 synchronized(this) { 16320 if (values == null && mWindowManager != null) { 16321 // sentinel: fetch the current configuration from the window manager 16322 values = mWindowManager.computeNewConfiguration(); 16323 } 16324 16325 if (mWindowManager != null) { 16326 mProcessList.applyDisplaySize(mWindowManager); 16327 } 16328 16329 final long origId = Binder.clearCallingIdentity(); 16330 if (values != null) { 16331 Settings.System.clearConfiguration(values); 16332 } 16333 updateConfigurationLocked(values, null, false, false); 16334 Binder.restoreCallingIdentity(origId); 16335 } 16336 } 16337 16338 /** 16339 * Do either or both things: (1) change the current configuration, and (2) 16340 * make sure the given activity is running with the (now) current 16341 * configuration. Returns true if the activity has been left running, or 16342 * false if <var>starting</var> is being destroyed to match the new 16343 * configuration. 16344 * @param persistent TODO 16345 */ 16346 boolean updateConfigurationLocked(Configuration values, 16347 ActivityRecord starting, boolean persistent, boolean initLocale) { 16348 int changes = 0; 16349 16350 if (values != null) { 16351 Configuration newConfig = new Configuration(mConfiguration); 16352 changes = newConfig.updateFrom(values); 16353 if (changes != 0) { 16354 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16355 Slog.i(TAG, "Updating configuration to: " + values); 16356 } 16357 16358 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16359 16360 if (values.locale != null && !initLocale) { 16361 saveLocaleLocked(values.locale, 16362 !values.locale.equals(mConfiguration.locale), 16363 values.userSetLocale); 16364 } 16365 16366 mConfigurationSeq++; 16367 if (mConfigurationSeq <= 0) { 16368 mConfigurationSeq = 1; 16369 } 16370 newConfig.seq = mConfigurationSeq; 16371 mConfiguration = newConfig; 16372 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16373 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16374 //mUsageStatsService.noteStartConfig(newConfig); 16375 16376 final Configuration configCopy = new Configuration(mConfiguration); 16377 16378 // TODO: If our config changes, should we auto dismiss any currently 16379 // showing dialogs? 16380 mShowDialogs = shouldShowDialogs(newConfig); 16381 16382 AttributeCache ac = AttributeCache.instance(); 16383 if (ac != null) { 16384 ac.updateConfiguration(configCopy); 16385 } 16386 16387 // Make sure all resources in our process are updated 16388 // right now, so that anyone who is going to retrieve 16389 // resource values after we return will be sure to get 16390 // the new ones. This is especially important during 16391 // boot, where the first config change needs to guarantee 16392 // all resources have that config before following boot 16393 // code is executed. 16394 mSystemThread.applyConfigurationToResources(configCopy); 16395 16396 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16397 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16398 msg.obj = new Configuration(configCopy); 16399 mHandler.sendMessage(msg); 16400 } 16401 16402 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16403 ProcessRecord app = mLruProcesses.get(i); 16404 try { 16405 if (app.thread != null) { 16406 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16407 + app.processName + " new config " + mConfiguration); 16408 app.thread.scheduleConfigurationChanged(configCopy); 16409 } 16410 } catch (Exception e) { 16411 } 16412 } 16413 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16415 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16416 | Intent.FLAG_RECEIVER_FOREGROUND); 16417 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16418 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16419 Process.SYSTEM_UID, UserHandle.USER_ALL); 16420 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16421 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16422 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16423 broadcastIntentLocked(null, null, intent, 16424 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16425 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16426 } 16427 } 16428 } 16429 16430 boolean kept = true; 16431 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16432 // mainStack is null during startup. 16433 if (mainStack != null) { 16434 if (changes != 0 && starting == null) { 16435 // If the configuration changed, and the caller is not already 16436 // in the process of starting an activity, then find the top 16437 // activity to check if its configuration needs to change. 16438 starting = mainStack.topRunningActivityLocked(null); 16439 } 16440 16441 if (starting != null) { 16442 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16443 // And we need to make sure at this point that all other activities 16444 // are made visible with the correct configuration. 16445 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16446 } 16447 } 16448 16449 if (values != null && mWindowManager != null) { 16450 mWindowManager.setNewConfiguration(mConfiguration); 16451 } 16452 16453 return kept; 16454 } 16455 16456 /** 16457 * Decide based on the configuration whether we should shouw the ANR, 16458 * crash, etc dialogs. The idea is that if there is no affordnace to 16459 * press the on-screen buttons, we shouldn't show the dialog. 16460 * 16461 * A thought: SystemUI might also want to get told about this, the Power 16462 * dialog / global actions also might want different behaviors. 16463 */ 16464 private static final boolean shouldShowDialogs(Configuration config) { 16465 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16466 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16467 } 16468 16469 /** 16470 * Save the locale. You must be inside a synchronized (this) block. 16471 */ 16472 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16473 if(isDiff) { 16474 SystemProperties.set("user.language", l.getLanguage()); 16475 SystemProperties.set("user.region", l.getCountry()); 16476 } 16477 16478 if(isPersist) { 16479 SystemProperties.set("persist.sys.language", l.getLanguage()); 16480 SystemProperties.set("persist.sys.country", l.getCountry()); 16481 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16482 16483 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16484 } 16485 } 16486 16487 @Override 16488 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16489 synchronized (this) { 16490 ActivityRecord srec = ActivityRecord.forToken(token); 16491 if (srec.task != null && srec.task.stack != null) { 16492 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16493 } 16494 } 16495 return false; 16496 } 16497 16498 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16499 Intent resultData) { 16500 16501 synchronized (this) { 16502 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16503 if (stack != null) { 16504 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16505 } 16506 return false; 16507 } 16508 } 16509 16510 public int getLaunchedFromUid(IBinder activityToken) { 16511 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16512 if (srec == null) { 16513 return -1; 16514 } 16515 return srec.launchedFromUid; 16516 } 16517 16518 public String getLaunchedFromPackage(IBinder activityToken) { 16519 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16520 if (srec == null) { 16521 return null; 16522 } 16523 return srec.launchedFromPackage; 16524 } 16525 16526 // ========================================================= 16527 // LIFETIME MANAGEMENT 16528 // ========================================================= 16529 16530 // Returns which broadcast queue the app is the current [or imminent] receiver 16531 // on, or 'null' if the app is not an active broadcast recipient. 16532 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16533 BroadcastRecord r = app.curReceiver; 16534 if (r != null) { 16535 return r.queue; 16536 } 16537 16538 // It's not the current receiver, but it might be starting up to become one 16539 synchronized (this) { 16540 for (BroadcastQueue queue : mBroadcastQueues) { 16541 r = queue.mPendingBroadcast; 16542 if (r != null && r.curApp == app) { 16543 // found it; report which queue it's in 16544 return queue; 16545 } 16546 } 16547 } 16548 16549 return null; 16550 } 16551 16552 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16553 boolean doingAll, long now) { 16554 if (mAdjSeq == app.adjSeq) { 16555 // This adjustment has already been computed. 16556 return app.curRawAdj; 16557 } 16558 16559 if (app.thread == null) { 16560 app.adjSeq = mAdjSeq; 16561 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16562 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16563 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16564 } 16565 16566 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16567 app.adjSource = null; 16568 app.adjTarget = null; 16569 app.empty = false; 16570 app.cached = false; 16571 16572 final int activitiesSize = app.activities.size(); 16573 16574 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16575 // The max adjustment doesn't allow this app to be anything 16576 // below foreground, so it is not worth doing work for it. 16577 app.adjType = "fixed"; 16578 app.adjSeq = mAdjSeq; 16579 app.curRawAdj = app.maxAdj; 16580 app.foregroundActivities = false; 16581 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16582 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16583 // System processes can do UI, and when they do we want to have 16584 // them trim their memory after the user leaves the UI. To 16585 // facilitate this, here we need to determine whether or not it 16586 // is currently showing UI. 16587 app.systemNoUi = true; 16588 if (app == TOP_APP) { 16589 app.systemNoUi = false; 16590 } else if (activitiesSize > 0) { 16591 for (int j = 0; j < activitiesSize; j++) { 16592 final ActivityRecord r = app.activities.get(j); 16593 if (r.visible) { 16594 app.systemNoUi = false; 16595 } 16596 } 16597 } 16598 if (!app.systemNoUi) { 16599 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16600 } 16601 return (app.curAdj=app.maxAdj); 16602 } 16603 16604 app.systemNoUi = false; 16605 16606 // Determine the importance of the process, starting with most 16607 // important to least, and assign an appropriate OOM adjustment. 16608 int adj; 16609 int schedGroup; 16610 int procState; 16611 boolean foregroundActivities = false; 16612 BroadcastQueue queue; 16613 if (app == TOP_APP) { 16614 // The last app on the list is the foreground app. 16615 adj = ProcessList.FOREGROUND_APP_ADJ; 16616 schedGroup = Process.THREAD_GROUP_DEFAULT; 16617 app.adjType = "top-activity"; 16618 foregroundActivities = true; 16619 procState = ActivityManager.PROCESS_STATE_TOP; 16620 } else if (app.instrumentationClass != null) { 16621 // Don't want to kill running instrumentation. 16622 adj = ProcessList.FOREGROUND_APP_ADJ; 16623 schedGroup = Process.THREAD_GROUP_DEFAULT; 16624 app.adjType = "instrumentation"; 16625 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16626 } else if ((queue = isReceivingBroadcast(app)) != null) { 16627 // An app that is currently receiving a broadcast also 16628 // counts as being in the foreground for OOM killer purposes. 16629 // It's placed in a sched group based on the nature of the 16630 // broadcast as reflected by which queue it's active in. 16631 adj = ProcessList.FOREGROUND_APP_ADJ; 16632 schedGroup = (queue == mFgBroadcastQueue) 16633 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16634 app.adjType = "broadcast"; 16635 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16636 } else if (app.executingServices.size() > 0) { 16637 // An app that is currently executing a service callback also 16638 // counts as being in the foreground. 16639 adj = ProcessList.FOREGROUND_APP_ADJ; 16640 schedGroup = app.execServicesFg ? 16641 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16642 app.adjType = "exec-service"; 16643 procState = ActivityManager.PROCESS_STATE_SERVICE; 16644 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16645 } else { 16646 // As far as we know the process is empty. We may change our mind later. 16647 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16648 // At this point we don't actually know the adjustment. Use the cached adj 16649 // value that the caller wants us to. 16650 adj = cachedAdj; 16651 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16652 app.cached = true; 16653 app.empty = true; 16654 app.adjType = "cch-empty"; 16655 } 16656 16657 // Examine all activities if not already foreground. 16658 if (!foregroundActivities && activitiesSize > 0) { 16659 for (int j = 0; j < activitiesSize; j++) { 16660 final ActivityRecord r = app.activities.get(j); 16661 if (r.app != app) { 16662 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16663 + app + "?!?"); 16664 continue; 16665 } 16666 if (r.visible) { 16667 // App has a visible activity; only upgrade adjustment. 16668 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16669 adj = ProcessList.VISIBLE_APP_ADJ; 16670 app.adjType = "visible"; 16671 } 16672 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16673 procState = ActivityManager.PROCESS_STATE_TOP; 16674 } 16675 schedGroup = Process.THREAD_GROUP_DEFAULT; 16676 app.cached = false; 16677 app.empty = false; 16678 foregroundActivities = true; 16679 break; 16680 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16681 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16682 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16683 app.adjType = "pausing"; 16684 } 16685 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16686 procState = ActivityManager.PROCESS_STATE_TOP; 16687 } 16688 schedGroup = Process.THREAD_GROUP_DEFAULT; 16689 app.cached = false; 16690 app.empty = false; 16691 foregroundActivities = true; 16692 } else if (r.state == ActivityState.STOPPING) { 16693 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16694 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16695 app.adjType = "stopping"; 16696 } 16697 // For the process state, we will at this point consider the 16698 // process to be cached. It will be cached either as an activity 16699 // or empty depending on whether the activity is finishing. We do 16700 // this so that we can treat the process as cached for purposes of 16701 // memory trimming (determing current memory level, trim command to 16702 // send to process) since there can be an arbitrary number of stopping 16703 // processes and they should soon all go into the cached state. 16704 if (!r.finishing) { 16705 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16706 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16707 } 16708 } 16709 app.cached = false; 16710 app.empty = false; 16711 foregroundActivities = true; 16712 } else { 16713 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16714 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16715 app.adjType = "cch-act"; 16716 } 16717 } 16718 } 16719 } 16720 16721 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16722 if (app.foregroundServices) { 16723 // The user is aware of this app, so make it visible. 16724 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16725 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16726 app.cached = false; 16727 app.adjType = "fg-service"; 16728 schedGroup = Process.THREAD_GROUP_DEFAULT; 16729 } else if (app.forcingToForeground != null) { 16730 // The user is aware of this app, so make it visible. 16731 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16732 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16733 app.cached = false; 16734 app.adjType = "force-fg"; 16735 app.adjSource = app.forcingToForeground; 16736 schedGroup = Process.THREAD_GROUP_DEFAULT; 16737 } 16738 } 16739 16740 if (app == mHeavyWeightProcess) { 16741 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16742 // We don't want to kill the current heavy-weight process. 16743 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16744 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16745 app.cached = false; 16746 app.adjType = "heavy"; 16747 } 16748 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16749 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16750 } 16751 } 16752 16753 if (app == mHomeProcess) { 16754 if (adj > ProcessList.HOME_APP_ADJ) { 16755 // This process is hosting what we currently consider to be the 16756 // home app, so we don't want to let it go into the background. 16757 adj = ProcessList.HOME_APP_ADJ; 16758 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16759 app.cached = false; 16760 app.adjType = "home"; 16761 } 16762 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16763 procState = ActivityManager.PROCESS_STATE_HOME; 16764 } 16765 } 16766 16767 if (app == mPreviousProcess && app.activities.size() > 0) { 16768 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16769 // This was the previous process that showed UI to the user. 16770 // We want to try to keep it around more aggressively, to give 16771 // a good experience around switching between two apps. 16772 adj = ProcessList.PREVIOUS_APP_ADJ; 16773 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16774 app.cached = false; 16775 app.adjType = "previous"; 16776 } 16777 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16778 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16779 } 16780 } 16781 16782 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16783 + " reason=" + app.adjType); 16784 16785 // By default, we use the computed adjustment. It may be changed if 16786 // there are applications dependent on our services or providers, but 16787 // this gives us a baseline and makes sure we don't get into an 16788 // infinite recursion. 16789 app.adjSeq = mAdjSeq; 16790 app.curRawAdj = adj; 16791 app.hasStartedServices = false; 16792 16793 if (mBackupTarget != null && app == mBackupTarget.app) { 16794 // If possible we want to avoid killing apps while they're being backed up 16795 if (adj > ProcessList.BACKUP_APP_ADJ) { 16796 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16797 adj = ProcessList.BACKUP_APP_ADJ; 16798 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16799 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16800 } 16801 app.adjType = "backup"; 16802 app.cached = false; 16803 } 16804 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16805 procState = ActivityManager.PROCESS_STATE_BACKUP; 16806 } 16807 } 16808 16809 boolean mayBeTop = false; 16810 16811 for (int is = app.services.size()-1; 16812 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16813 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16814 || procState > ActivityManager.PROCESS_STATE_TOP); 16815 is--) { 16816 ServiceRecord s = app.services.valueAt(is); 16817 if (s.startRequested) { 16818 app.hasStartedServices = true; 16819 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16820 procState = ActivityManager.PROCESS_STATE_SERVICE; 16821 } 16822 if (app.hasShownUi && app != mHomeProcess) { 16823 // If this process has shown some UI, let it immediately 16824 // go to the LRU list because it may be pretty heavy with 16825 // UI stuff. We'll tag it with a label just to help 16826 // debug and understand what is going on. 16827 if (adj > ProcessList.SERVICE_ADJ) { 16828 app.adjType = "cch-started-ui-services"; 16829 } 16830 } else { 16831 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16832 // This service has seen some activity within 16833 // recent memory, so we will keep its process ahead 16834 // of the background processes. 16835 if (adj > ProcessList.SERVICE_ADJ) { 16836 adj = ProcessList.SERVICE_ADJ; 16837 app.adjType = "started-services"; 16838 app.cached = false; 16839 } 16840 } 16841 // If we have let the service slide into the background 16842 // state, still have some text describing what it is doing 16843 // even though the service no longer has an impact. 16844 if (adj > ProcessList.SERVICE_ADJ) { 16845 app.adjType = "cch-started-services"; 16846 } 16847 } 16848 } 16849 for (int conni = s.connections.size()-1; 16850 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16851 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16852 || procState > ActivityManager.PROCESS_STATE_TOP); 16853 conni--) { 16854 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16855 for (int i = 0; 16856 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16857 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16858 || procState > ActivityManager.PROCESS_STATE_TOP); 16859 i++) { 16860 // XXX should compute this based on the max of 16861 // all connected clients. 16862 ConnectionRecord cr = clist.get(i); 16863 if (cr.binding.client == app) { 16864 // Binding to ourself is not interesting. 16865 continue; 16866 } 16867 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16868 ProcessRecord client = cr.binding.client; 16869 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16870 TOP_APP, doingAll, now); 16871 int clientProcState = client.curProcState; 16872 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16873 // If the other app is cached for any reason, for purposes here 16874 // we are going to consider it empty. The specific cached state 16875 // doesn't propagate except under certain conditions. 16876 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16877 } 16878 String adjType = null; 16879 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16880 // Not doing bind OOM management, so treat 16881 // this guy more like a started service. 16882 if (app.hasShownUi && app != mHomeProcess) { 16883 // If this process has shown some UI, let it immediately 16884 // go to the LRU list because it may be pretty heavy with 16885 // UI stuff. We'll tag it with a label just to help 16886 // debug and understand what is going on. 16887 if (adj > clientAdj) { 16888 adjType = "cch-bound-ui-services"; 16889 } 16890 app.cached = false; 16891 clientAdj = adj; 16892 clientProcState = procState; 16893 } else { 16894 if (now >= (s.lastActivity 16895 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16896 // This service has not seen activity within 16897 // recent memory, so allow it to drop to the 16898 // LRU list if there is no other reason to keep 16899 // it around. We'll also tag it with a label just 16900 // to help debug and undertand what is going on. 16901 if (adj > clientAdj) { 16902 adjType = "cch-bound-services"; 16903 } 16904 clientAdj = adj; 16905 } 16906 } 16907 } 16908 if (adj > clientAdj) { 16909 // If this process has recently shown UI, and 16910 // the process that is binding to it is less 16911 // important than being visible, then we don't 16912 // care about the binding as much as we care 16913 // about letting this process get into the LRU 16914 // list to be killed and restarted if needed for 16915 // memory. 16916 if (app.hasShownUi && app != mHomeProcess 16917 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16918 adjType = "cch-bound-ui-services"; 16919 } else { 16920 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16921 |Context.BIND_IMPORTANT)) != 0) { 16922 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16923 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16924 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16925 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16926 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16927 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16928 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16929 adj = clientAdj; 16930 } else { 16931 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16932 adj = ProcessList.VISIBLE_APP_ADJ; 16933 } 16934 } 16935 if (!client.cached) { 16936 app.cached = false; 16937 } 16938 adjType = "service"; 16939 } 16940 } 16941 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16942 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16943 schedGroup = Process.THREAD_GROUP_DEFAULT; 16944 } 16945 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16946 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16947 // Special handling of clients who are in the top state. 16948 // We *may* want to consider this process to be in the 16949 // top state as well, but only if there is not another 16950 // reason for it to be running. Being on the top is a 16951 // special state, meaning you are specifically running 16952 // for the current top app. If the process is already 16953 // running in the background for some other reason, it 16954 // is more important to continue considering it to be 16955 // in the background state. 16956 mayBeTop = true; 16957 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16958 } else { 16959 // Special handling for above-top states (persistent 16960 // processes). These should not bring the current process 16961 // into the top state, since they are not on top. Instead 16962 // give them the best state after that. 16963 clientProcState = 16964 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16965 } 16966 } 16967 } else { 16968 if (clientProcState < 16969 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16970 clientProcState = 16971 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16972 } 16973 } 16974 if (procState > clientProcState) { 16975 procState = clientProcState; 16976 } 16977 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16978 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16979 app.pendingUiClean = true; 16980 } 16981 if (adjType != null) { 16982 app.adjType = adjType; 16983 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16984 .REASON_SERVICE_IN_USE; 16985 app.adjSource = cr.binding.client; 16986 app.adjSourceProcState = clientProcState; 16987 app.adjTarget = s.name; 16988 } 16989 } 16990 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16991 app.treatLikeActivity = true; 16992 } 16993 final ActivityRecord a = cr.activity; 16994 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16995 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16996 (a.visible || a.state == ActivityState.RESUMED 16997 || a.state == ActivityState.PAUSING)) { 16998 adj = ProcessList.FOREGROUND_APP_ADJ; 16999 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17000 schedGroup = Process.THREAD_GROUP_DEFAULT; 17001 } 17002 app.cached = false; 17003 app.adjType = "service"; 17004 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17005 .REASON_SERVICE_IN_USE; 17006 app.adjSource = a; 17007 app.adjSourceProcState = procState; 17008 app.adjTarget = s.name; 17009 } 17010 } 17011 } 17012 } 17013 } 17014 17015 for (int provi = app.pubProviders.size()-1; 17016 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17017 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17018 || procState > ActivityManager.PROCESS_STATE_TOP); 17019 provi--) { 17020 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17021 for (int i = cpr.connections.size()-1; 17022 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17023 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17024 || procState > ActivityManager.PROCESS_STATE_TOP); 17025 i--) { 17026 ContentProviderConnection conn = cpr.connections.get(i); 17027 ProcessRecord client = conn.client; 17028 if (client == app) { 17029 // Being our own client is not interesting. 17030 continue; 17031 } 17032 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17033 int clientProcState = client.curProcState; 17034 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17035 // If the other app is cached for any reason, for purposes here 17036 // we are going to consider it empty. 17037 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17038 } 17039 if (adj > clientAdj) { 17040 if (app.hasShownUi && app != mHomeProcess 17041 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17042 app.adjType = "cch-ui-provider"; 17043 } else { 17044 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17045 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17046 app.adjType = "provider"; 17047 } 17048 app.cached &= client.cached; 17049 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17050 .REASON_PROVIDER_IN_USE; 17051 app.adjSource = client; 17052 app.adjSourceProcState = clientProcState; 17053 app.adjTarget = cpr.name; 17054 } 17055 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17056 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17057 // Special handling of clients who are in the top state. 17058 // We *may* want to consider this process to be in the 17059 // top state as well, but only if there is not another 17060 // reason for it to be running. Being on the top is a 17061 // special state, meaning you are specifically running 17062 // for the current top app. If the process is already 17063 // running in the background for some other reason, it 17064 // is more important to continue considering it to be 17065 // in the background state. 17066 mayBeTop = true; 17067 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17068 } else { 17069 // Special handling for above-top states (persistent 17070 // processes). These should not bring the current process 17071 // into the top state, since they are not on top. Instead 17072 // give them the best state after that. 17073 clientProcState = 17074 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17075 } 17076 } 17077 if (procState > clientProcState) { 17078 procState = clientProcState; 17079 } 17080 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17081 schedGroup = Process.THREAD_GROUP_DEFAULT; 17082 } 17083 } 17084 // If the provider has external (non-framework) process 17085 // dependencies, ensure that its adjustment is at least 17086 // FOREGROUND_APP_ADJ. 17087 if (cpr.hasExternalProcessHandles()) { 17088 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17089 adj = ProcessList.FOREGROUND_APP_ADJ; 17090 schedGroup = Process.THREAD_GROUP_DEFAULT; 17091 app.cached = false; 17092 app.adjType = "provider"; 17093 app.adjTarget = cpr.name; 17094 } 17095 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17096 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17097 } 17098 } 17099 } 17100 17101 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17102 // A client of one of our services or providers is in the top state. We 17103 // *may* want to be in the top state, but not if we are already running in 17104 // the background for some other reason. For the decision here, we are going 17105 // to pick out a few specific states that we want to remain in when a client 17106 // is top (states that tend to be longer-term) and otherwise allow it to go 17107 // to the top state. 17108 switch (procState) { 17109 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17110 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17111 case ActivityManager.PROCESS_STATE_SERVICE: 17112 // These all are longer-term states, so pull them up to the top 17113 // of the background states, but not all the way to the top state. 17114 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17115 break; 17116 default: 17117 // Otherwise, top is a better choice, so take it. 17118 procState = ActivityManager.PROCESS_STATE_TOP; 17119 break; 17120 } 17121 } 17122 17123 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17124 if (app.hasClientActivities) { 17125 // This is a cached process, but with client activities. Mark it so. 17126 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17127 app.adjType = "cch-client-act"; 17128 } else if (app.treatLikeActivity) { 17129 // This is a cached process, but somebody wants us to treat it like it has 17130 // an activity, okay! 17131 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17132 app.adjType = "cch-as-act"; 17133 } 17134 } 17135 17136 if (adj == ProcessList.SERVICE_ADJ) { 17137 if (doingAll) { 17138 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17139 mNewNumServiceProcs++; 17140 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17141 if (!app.serviceb) { 17142 // This service isn't far enough down on the LRU list to 17143 // normally be a B service, but if we are low on RAM and it 17144 // is large we want to force it down since we would prefer to 17145 // keep launcher over it. 17146 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17147 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17148 app.serviceHighRam = true; 17149 app.serviceb = true; 17150 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17151 } else { 17152 mNewNumAServiceProcs++; 17153 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17154 } 17155 } else { 17156 app.serviceHighRam = false; 17157 } 17158 } 17159 if (app.serviceb) { 17160 adj = ProcessList.SERVICE_B_ADJ; 17161 } 17162 } 17163 17164 app.curRawAdj = adj; 17165 17166 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17167 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17168 if (adj > app.maxAdj) { 17169 adj = app.maxAdj; 17170 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17171 schedGroup = Process.THREAD_GROUP_DEFAULT; 17172 } 17173 } 17174 17175 // Do final modification to adj. Everything we do between here and applying 17176 // the final setAdj must be done in this function, because we will also use 17177 // it when computing the final cached adj later. Note that we don't need to 17178 // worry about this for max adj above, since max adj will always be used to 17179 // keep it out of the cached vaues. 17180 app.curAdj = app.modifyRawOomAdj(adj); 17181 app.curSchedGroup = schedGroup; 17182 app.curProcState = procState; 17183 app.foregroundActivities = foregroundActivities; 17184 17185 return app.curRawAdj; 17186 } 17187 17188 /** 17189 * Schedule PSS collection of a process. 17190 */ 17191 void requestPssLocked(ProcessRecord proc, int procState) { 17192 if (mPendingPssProcesses.contains(proc)) { 17193 return; 17194 } 17195 if (mPendingPssProcesses.size() == 0) { 17196 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17197 } 17198 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17199 proc.pssProcState = procState; 17200 mPendingPssProcesses.add(proc); 17201 } 17202 17203 /** 17204 * Schedule PSS collection of all processes. 17205 */ 17206 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17207 if (!always) { 17208 if (now < (mLastFullPssTime + 17209 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17210 return; 17211 } 17212 } 17213 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17214 mLastFullPssTime = now; 17215 mFullPssPending = true; 17216 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17217 mPendingPssProcesses.clear(); 17218 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17219 ProcessRecord app = mLruProcesses.get(i); 17220 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17221 app.pssProcState = app.setProcState; 17222 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17223 isSleeping(), now); 17224 mPendingPssProcesses.add(app); 17225 } 17226 } 17227 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17228 } 17229 17230 /** 17231 * Ask a given process to GC right now. 17232 */ 17233 final void performAppGcLocked(ProcessRecord app) { 17234 try { 17235 app.lastRequestedGc = SystemClock.uptimeMillis(); 17236 if (app.thread != null) { 17237 if (app.reportLowMemory) { 17238 app.reportLowMemory = false; 17239 app.thread.scheduleLowMemory(); 17240 } else { 17241 app.thread.processInBackground(); 17242 } 17243 } 17244 } catch (Exception e) { 17245 // whatever. 17246 } 17247 } 17248 17249 /** 17250 * Returns true if things are idle enough to perform GCs. 17251 */ 17252 private final boolean canGcNowLocked() { 17253 boolean processingBroadcasts = false; 17254 for (BroadcastQueue q : mBroadcastQueues) { 17255 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17256 processingBroadcasts = true; 17257 } 17258 } 17259 return !processingBroadcasts 17260 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17261 } 17262 17263 /** 17264 * Perform GCs on all processes that are waiting for it, but only 17265 * if things are idle. 17266 */ 17267 final void performAppGcsLocked() { 17268 final int N = mProcessesToGc.size(); 17269 if (N <= 0) { 17270 return; 17271 } 17272 if (canGcNowLocked()) { 17273 while (mProcessesToGc.size() > 0) { 17274 ProcessRecord proc = mProcessesToGc.remove(0); 17275 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17276 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17277 <= SystemClock.uptimeMillis()) { 17278 // To avoid spamming the system, we will GC processes one 17279 // at a time, waiting a few seconds between each. 17280 performAppGcLocked(proc); 17281 scheduleAppGcsLocked(); 17282 return; 17283 } else { 17284 // It hasn't been long enough since we last GCed this 17285 // process... put it in the list to wait for its time. 17286 addProcessToGcListLocked(proc); 17287 break; 17288 } 17289 } 17290 } 17291 17292 scheduleAppGcsLocked(); 17293 } 17294 } 17295 17296 /** 17297 * If all looks good, perform GCs on all processes waiting for them. 17298 */ 17299 final void performAppGcsIfAppropriateLocked() { 17300 if (canGcNowLocked()) { 17301 performAppGcsLocked(); 17302 return; 17303 } 17304 // Still not idle, wait some more. 17305 scheduleAppGcsLocked(); 17306 } 17307 17308 /** 17309 * Schedule the execution of all pending app GCs. 17310 */ 17311 final void scheduleAppGcsLocked() { 17312 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17313 17314 if (mProcessesToGc.size() > 0) { 17315 // Schedule a GC for the time to the next process. 17316 ProcessRecord proc = mProcessesToGc.get(0); 17317 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17318 17319 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17320 long now = SystemClock.uptimeMillis(); 17321 if (when < (now+GC_TIMEOUT)) { 17322 when = now + GC_TIMEOUT; 17323 } 17324 mHandler.sendMessageAtTime(msg, when); 17325 } 17326 } 17327 17328 /** 17329 * Add a process to the array of processes waiting to be GCed. Keeps the 17330 * list in sorted order by the last GC time. The process can't already be 17331 * on the list. 17332 */ 17333 final void addProcessToGcListLocked(ProcessRecord proc) { 17334 boolean added = false; 17335 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17336 if (mProcessesToGc.get(i).lastRequestedGc < 17337 proc.lastRequestedGc) { 17338 added = true; 17339 mProcessesToGc.add(i+1, proc); 17340 break; 17341 } 17342 } 17343 if (!added) { 17344 mProcessesToGc.add(0, proc); 17345 } 17346 } 17347 17348 /** 17349 * Set up to ask a process to GC itself. This will either do it 17350 * immediately, or put it on the list of processes to gc the next 17351 * time things are idle. 17352 */ 17353 final void scheduleAppGcLocked(ProcessRecord app) { 17354 long now = SystemClock.uptimeMillis(); 17355 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17356 return; 17357 } 17358 if (!mProcessesToGc.contains(app)) { 17359 addProcessToGcListLocked(app); 17360 scheduleAppGcsLocked(); 17361 } 17362 } 17363 17364 final void checkExcessivePowerUsageLocked(boolean doKills) { 17365 updateCpuStatsNow(); 17366 17367 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17368 boolean doWakeKills = doKills; 17369 boolean doCpuKills = doKills; 17370 if (mLastPowerCheckRealtime == 0) { 17371 doWakeKills = false; 17372 } 17373 if (mLastPowerCheckUptime == 0) { 17374 doCpuKills = false; 17375 } 17376 if (stats.isScreenOn()) { 17377 doWakeKills = false; 17378 } 17379 final long curRealtime = SystemClock.elapsedRealtime(); 17380 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17381 final long curUptime = SystemClock.uptimeMillis(); 17382 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17383 mLastPowerCheckRealtime = curRealtime; 17384 mLastPowerCheckUptime = curUptime; 17385 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17386 doWakeKills = false; 17387 } 17388 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17389 doCpuKills = false; 17390 } 17391 int i = mLruProcesses.size(); 17392 while (i > 0) { 17393 i--; 17394 ProcessRecord app = mLruProcesses.get(i); 17395 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17396 long wtime; 17397 synchronized (stats) { 17398 wtime = stats.getProcessWakeTime(app.info.uid, 17399 app.pid, curRealtime); 17400 } 17401 long wtimeUsed = wtime - app.lastWakeTime; 17402 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17403 if (DEBUG_POWER) { 17404 StringBuilder sb = new StringBuilder(128); 17405 sb.append("Wake for "); 17406 app.toShortString(sb); 17407 sb.append(": over "); 17408 TimeUtils.formatDuration(realtimeSince, sb); 17409 sb.append(" used "); 17410 TimeUtils.formatDuration(wtimeUsed, sb); 17411 sb.append(" ("); 17412 sb.append((wtimeUsed*100)/realtimeSince); 17413 sb.append("%)"); 17414 Slog.i(TAG, sb.toString()); 17415 sb.setLength(0); 17416 sb.append("CPU for "); 17417 app.toShortString(sb); 17418 sb.append(": over "); 17419 TimeUtils.formatDuration(uptimeSince, sb); 17420 sb.append(" used "); 17421 TimeUtils.formatDuration(cputimeUsed, sb); 17422 sb.append(" ("); 17423 sb.append((cputimeUsed*100)/uptimeSince); 17424 sb.append("%)"); 17425 Slog.i(TAG, sb.toString()); 17426 } 17427 // If a process has held a wake lock for more 17428 // than 50% of the time during this period, 17429 // that sounds bad. Kill! 17430 if (doWakeKills && realtimeSince > 0 17431 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17432 synchronized (stats) { 17433 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17434 realtimeSince, wtimeUsed); 17435 } 17436 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17437 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17438 } else if (doCpuKills && uptimeSince > 0 17439 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17440 synchronized (stats) { 17441 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17442 uptimeSince, cputimeUsed); 17443 } 17444 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17445 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17446 } else { 17447 app.lastWakeTime = wtime; 17448 app.lastCpuTime = app.curCpuTime; 17449 } 17450 } 17451 } 17452 } 17453 17454 private final boolean applyOomAdjLocked(ProcessRecord app, 17455 ProcessRecord TOP_APP, boolean doingAll, long now) { 17456 boolean success = true; 17457 17458 if (app.curRawAdj != app.setRawAdj) { 17459 app.setRawAdj = app.curRawAdj; 17460 } 17461 17462 int changes = 0; 17463 17464 if (app.curAdj != app.setAdj) { 17465 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17466 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17467 TAG, "Set " + app.pid + " " + app.processName + 17468 " adj " + app.curAdj + ": " + app.adjType); 17469 app.setAdj = app.curAdj; 17470 } 17471 17472 if (app.setSchedGroup != app.curSchedGroup) { 17473 app.setSchedGroup = app.curSchedGroup; 17474 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17475 "Setting process group of " + app.processName 17476 + " to " + app.curSchedGroup); 17477 if (app.waitingToKill != null && 17478 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17479 app.kill(app.waitingToKill, true); 17480 success = false; 17481 } else { 17482 if (true) { 17483 long oldId = Binder.clearCallingIdentity(); 17484 try { 17485 Process.setProcessGroup(app.pid, app.curSchedGroup); 17486 } catch (Exception e) { 17487 Slog.w(TAG, "Failed setting process group of " + app.pid 17488 + " to " + app.curSchedGroup); 17489 e.printStackTrace(); 17490 } finally { 17491 Binder.restoreCallingIdentity(oldId); 17492 } 17493 } else { 17494 if (app.thread != null) { 17495 try { 17496 app.thread.setSchedulingGroup(app.curSchedGroup); 17497 } catch (RemoteException e) { 17498 } 17499 } 17500 } 17501 Process.setSwappiness(app.pid, 17502 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17503 } 17504 } 17505 if (app.repForegroundActivities != app.foregroundActivities) { 17506 app.repForegroundActivities = app.foregroundActivities; 17507 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17508 } 17509 if (app.repProcState != app.curProcState) { 17510 app.repProcState = app.curProcState; 17511 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17512 if (app.thread != null) { 17513 try { 17514 if (false) { 17515 //RuntimeException h = new RuntimeException("here"); 17516 Slog.i(TAG, "Sending new process state " + app.repProcState 17517 + " to " + app /*, h*/); 17518 } 17519 app.thread.setProcessState(app.repProcState); 17520 } catch (RemoteException e) { 17521 } 17522 } 17523 } 17524 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17525 app.setProcState)) { 17526 app.lastStateTime = now; 17527 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17528 isSleeping(), now); 17529 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17530 + ProcessList.makeProcStateString(app.setProcState) + " to " 17531 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17532 + (app.nextPssTime-now) + ": " + app); 17533 } else { 17534 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17535 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17536 requestPssLocked(app, app.setProcState); 17537 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17538 isSleeping(), now); 17539 } else if (false && DEBUG_PSS) { 17540 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17541 } 17542 } 17543 if (app.setProcState != app.curProcState) { 17544 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17545 "Proc state change of " + app.processName 17546 + " to " + app.curProcState); 17547 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17548 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17549 if (setImportant && !curImportant) { 17550 // This app is no longer something we consider important enough to allow to 17551 // use arbitrary amounts of battery power. Note 17552 // its current wake lock time to later know to kill it if 17553 // it is not behaving well. 17554 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17555 synchronized (stats) { 17556 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17557 app.pid, SystemClock.elapsedRealtime()); 17558 } 17559 app.lastCpuTime = app.curCpuTime; 17560 17561 } 17562 app.setProcState = app.curProcState; 17563 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17564 app.notCachedSinceIdle = false; 17565 } 17566 if (!doingAll) { 17567 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17568 } else { 17569 app.procStateChanged = true; 17570 } 17571 } 17572 17573 if (changes != 0) { 17574 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17575 int i = mPendingProcessChanges.size()-1; 17576 ProcessChangeItem item = null; 17577 while (i >= 0) { 17578 item = mPendingProcessChanges.get(i); 17579 if (item.pid == app.pid) { 17580 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17581 break; 17582 } 17583 i--; 17584 } 17585 if (i < 0) { 17586 // No existing item in pending changes; need a new one. 17587 final int NA = mAvailProcessChanges.size(); 17588 if (NA > 0) { 17589 item = mAvailProcessChanges.remove(NA-1); 17590 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17591 } else { 17592 item = new ProcessChangeItem(); 17593 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17594 } 17595 item.changes = 0; 17596 item.pid = app.pid; 17597 item.uid = app.info.uid; 17598 if (mPendingProcessChanges.size() == 0) { 17599 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17600 "*** Enqueueing dispatch processes changed!"); 17601 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17602 } 17603 mPendingProcessChanges.add(item); 17604 } 17605 item.changes |= changes; 17606 item.processState = app.repProcState; 17607 item.foregroundActivities = app.repForegroundActivities; 17608 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17609 + Integer.toHexString(System.identityHashCode(item)) 17610 + " " + app.toShortString() + ": changes=" + item.changes 17611 + " procState=" + item.processState 17612 + " foreground=" + item.foregroundActivities 17613 + " type=" + app.adjType + " source=" + app.adjSource 17614 + " target=" + app.adjTarget); 17615 } 17616 17617 return success; 17618 } 17619 17620 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17621 if (proc.thread != null) { 17622 if (proc.baseProcessTracker != null) { 17623 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17624 } 17625 if (proc.repProcState >= 0) { 17626 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17627 proc.repProcState); 17628 } 17629 } 17630 } 17631 17632 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17633 ProcessRecord TOP_APP, boolean doingAll, long now) { 17634 if (app.thread == null) { 17635 return false; 17636 } 17637 17638 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17639 17640 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17641 } 17642 17643 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17644 boolean oomAdj) { 17645 if (isForeground != proc.foregroundServices) { 17646 proc.foregroundServices = isForeground; 17647 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17648 proc.info.uid); 17649 if (isForeground) { 17650 if (curProcs == null) { 17651 curProcs = new ArrayList<ProcessRecord>(); 17652 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17653 } 17654 if (!curProcs.contains(proc)) { 17655 curProcs.add(proc); 17656 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17657 proc.info.packageName, proc.info.uid); 17658 } 17659 } else { 17660 if (curProcs != null) { 17661 if (curProcs.remove(proc)) { 17662 mBatteryStatsService.noteEvent( 17663 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17664 proc.info.packageName, proc.info.uid); 17665 if (curProcs.size() <= 0) { 17666 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17667 } 17668 } 17669 } 17670 } 17671 if (oomAdj) { 17672 updateOomAdjLocked(); 17673 } 17674 } 17675 } 17676 17677 private final ActivityRecord resumedAppLocked() { 17678 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17679 String pkg; 17680 int uid; 17681 if (act != null) { 17682 pkg = act.packageName; 17683 uid = act.info.applicationInfo.uid; 17684 } else { 17685 pkg = null; 17686 uid = -1; 17687 } 17688 // Has the UID or resumed package name changed? 17689 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17690 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17691 if (mCurResumedPackage != null) { 17692 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17693 mCurResumedPackage, mCurResumedUid); 17694 } 17695 mCurResumedPackage = pkg; 17696 mCurResumedUid = uid; 17697 if (mCurResumedPackage != null) { 17698 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17699 mCurResumedPackage, mCurResumedUid); 17700 } 17701 } 17702 return act; 17703 } 17704 17705 final boolean updateOomAdjLocked(ProcessRecord app) { 17706 final ActivityRecord TOP_ACT = resumedAppLocked(); 17707 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17708 final boolean wasCached = app.cached; 17709 17710 mAdjSeq++; 17711 17712 // This is the desired cached adjusment we want to tell it to use. 17713 // If our app is currently cached, we know it, and that is it. Otherwise, 17714 // we don't know it yet, and it needs to now be cached we will then 17715 // need to do a complete oom adj. 17716 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17717 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17718 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17719 SystemClock.uptimeMillis()); 17720 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17721 // Changed to/from cached state, so apps after it in the LRU 17722 // list may also be changed. 17723 updateOomAdjLocked(); 17724 } 17725 return success; 17726 } 17727 17728 final void updateOomAdjLocked() { 17729 final ActivityRecord TOP_ACT = resumedAppLocked(); 17730 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17731 final long now = SystemClock.uptimeMillis(); 17732 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17733 final int N = mLruProcesses.size(); 17734 17735 if (false) { 17736 RuntimeException e = new RuntimeException(); 17737 e.fillInStackTrace(); 17738 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17739 } 17740 17741 mAdjSeq++; 17742 mNewNumServiceProcs = 0; 17743 mNewNumAServiceProcs = 0; 17744 17745 final int emptyProcessLimit; 17746 final int cachedProcessLimit; 17747 if (mProcessLimit <= 0) { 17748 emptyProcessLimit = cachedProcessLimit = 0; 17749 } else if (mProcessLimit == 1) { 17750 emptyProcessLimit = 1; 17751 cachedProcessLimit = 0; 17752 } else { 17753 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17754 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17755 } 17756 17757 // Let's determine how many processes we have running vs. 17758 // how many slots we have for background processes; we may want 17759 // to put multiple processes in a slot of there are enough of 17760 // them. 17761 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17762 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17763 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17764 if (numEmptyProcs > cachedProcessLimit) { 17765 // If there are more empty processes than our limit on cached 17766 // processes, then use the cached process limit for the factor. 17767 // This ensures that the really old empty processes get pushed 17768 // down to the bottom, so if we are running low on memory we will 17769 // have a better chance at keeping around more cached processes 17770 // instead of a gazillion empty processes. 17771 numEmptyProcs = cachedProcessLimit; 17772 } 17773 int emptyFactor = numEmptyProcs/numSlots; 17774 if (emptyFactor < 1) emptyFactor = 1; 17775 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17776 if (cachedFactor < 1) cachedFactor = 1; 17777 int stepCached = 0; 17778 int stepEmpty = 0; 17779 int numCached = 0; 17780 int numEmpty = 0; 17781 int numTrimming = 0; 17782 17783 mNumNonCachedProcs = 0; 17784 mNumCachedHiddenProcs = 0; 17785 17786 // First update the OOM adjustment for each of the 17787 // application processes based on their current state. 17788 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17789 int nextCachedAdj = curCachedAdj+1; 17790 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17791 int nextEmptyAdj = curEmptyAdj+2; 17792 for (int i=N-1; i>=0; i--) { 17793 ProcessRecord app = mLruProcesses.get(i); 17794 if (!app.killedByAm && app.thread != null) { 17795 app.procStateChanged = false; 17796 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17797 17798 // If we haven't yet assigned the final cached adj 17799 // to the process, do that now. 17800 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17801 switch (app.curProcState) { 17802 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17803 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17804 // This process is a cached process holding activities... 17805 // assign it the next cached value for that type, and then 17806 // step that cached level. 17807 app.curRawAdj = curCachedAdj; 17808 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17809 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17810 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17811 + ")"); 17812 if (curCachedAdj != nextCachedAdj) { 17813 stepCached++; 17814 if (stepCached >= cachedFactor) { 17815 stepCached = 0; 17816 curCachedAdj = nextCachedAdj; 17817 nextCachedAdj += 2; 17818 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17819 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17820 } 17821 } 17822 } 17823 break; 17824 default: 17825 // For everything else, assign next empty cached process 17826 // level and bump that up. Note that this means that 17827 // long-running services that have dropped down to the 17828 // cached level will be treated as empty (since their process 17829 // state is still as a service), which is what we want. 17830 app.curRawAdj = curEmptyAdj; 17831 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17832 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17833 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17834 + ")"); 17835 if (curEmptyAdj != nextEmptyAdj) { 17836 stepEmpty++; 17837 if (stepEmpty >= emptyFactor) { 17838 stepEmpty = 0; 17839 curEmptyAdj = nextEmptyAdj; 17840 nextEmptyAdj += 2; 17841 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17842 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17843 } 17844 } 17845 } 17846 break; 17847 } 17848 } 17849 17850 applyOomAdjLocked(app, TOP_APP, true, now); 17851 17852 // Count the number of process types. 17853 switch (app.curProcState) { 17854 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17855 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17856 mNumCachedHiddenProcs++; 17857 numCached++; 17858 if (numCached > cachedProcessLimit) { 17859 app.kill("cached #" + numCached, true); 17860 } 17861 break; 17862 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17863 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17864 && app.lastActivityTime < oldTime) { 17865 app.kill("empty for " 17866 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17867 / 1000) + "s", true); 17868 } else { 17869 numEmpty++; 17870 if (numEmpty > emptyProcessLimit) { 17871 app.kill("empty #" + numEmpty, true); 17872 } 17873 } 17874 break; 17875 default: 17876 mNumNonCachedProcs++; 17877 break; 17878 } 17879 17880 if (app.isolated && app.services.size() <= 0) { 17881 // If this is an isolated process, and there are no 17882 // services running in it, then the process is no longer 17883 // needed. We agressively kill these because we can by 17884 // definition not re-use the same process again, and it is 17885 // good to avoid having whatever code was running in them 17886 // left sitting around after no longer needed. 17887 app.kill("isolated not needed", true); 17888 } 17889 17890 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17891 && !app.killedByAm) { 17892 numTrimming++; 17893 } 17894 } 17895 } 17896 17897 mNumServiceProcs = mNewNumServiceProcs; 17898 17899 // Now determine the memory trimming level of background processes. 17900 // Unfortunately we need to start at the back of the list to do this 17901 // properly. We only do this if the number of background apps we 17902 // are managing to keep around is less than half the maximum we desire; 17903 // if we are keeping a good number around, we'll let them use whatever 17904 // memory they want. 17905 final int numCachedAndEmpty = numCached + numEmpty; 17906 int memFactor; 17907 if (numCached <= ProcessList.TRIM_CACHED_APPS 17908 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17909 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17910 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17911 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17912 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17913 } else { 17914 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17915 } 17916 } else { 17917 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17918 } 17919 // We always allow the memory level to go up (better). We only allow it to go 17920 // down if we are in a state where that is allowed, *and* the total number of processes 17921 // has gone down since last time. 17922 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17923 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17924 + " last=" + mLastNumProcesses); 17925 if (memFactor > mLastMemoryLevel) { 17926 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17927 memFactor = mLastMemoryLevel; 17928 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17929 } 17930 } 17931 mLastMemoryLevel = memFactor; 17932 mLastNumProcesses = mLruProcesses.size(); 17933 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17934 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17935 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17936 if (mLowRamStartTime == 0) { 17937 mLowRamStartTime = now; 17938 } 17939 int step = 0; 17940 int fgTrimLevel; 17941 switch (memFactor) { 17942 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17943 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17944 break; 17945 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17946 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17947 break; 17948 default: 17949 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17950 break; 17951 } 17952 int factor = numTrimming/3; 17953 int minFactor = 2; 17954 if (mHomeProcess != null) minFactor++; 17955 if (mPreviousProcess != null) minFactor++; 17956 if (factor < minFactor) factor = minFactor; 17957 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17958 for (int i=N-1; i>=0; i--) { 17959 ProcessRecord app = mLruProcesses.get(i); 17960 if (allChanged || app.procStateChanged) { 17961 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17962 app.procStateChanged = false; 17963 } 17964 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17965 && !app.killedByAm) { 17966 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17967 try { 17968 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17969 "Trimming memory of " + app.processName 17970 + " to " + curLevel); 17971 app.thread.scheduleTrimMemory(curLevel); 17972 } catch (RemoteException e) { 17973 } 17974 if (false) { 17975 // For now we won't do this; our memory trimming seems 17976 // to be good enough at this point that destroying 17977 // activities causes more harm than good. 17978 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17979 && app != mHomeProcess && app != mPreviousProcess) { 17980 // Need to do this on its own message because the stack may not 17981 // be in a consistent state at this point. 17982 // For these apps we will also finish their activities 17983 // to help them free memory. 17984 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17985 } 17986 } 17987 } 17988 app.trimMemoryLevel = curLevel; 17989 step++; 17990 if (step >= factor) { 17991 step = 0; 17992 switch (curLevel) { 17993 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17994 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17995 break; 17996 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17997 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17998 break; 17999 } 18000 } 18001 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18002 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18003 && app.thread != null) { 18004 try { 18005 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18006 "Trimming memory of heavy-weight " + app.processName 18007 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18008 app.thread.scheduleTrimMemory( 18009 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18010 } catch (RemoteException e) { 18011 } 18012 } 18013 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18014 } else { 18015 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18016 || app.systemNoUi) && app.pendingUiClean) { 18017 // If this application is now in the background and it 18018 // had done UI, then give it the special trim level to 18019 // have it free UI resources. 18020 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18021 if (app.trimMemoryLevel < level && app.thread != null) { 18022 try { 18023 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18024 "Trimming memory of bg-ui " + app.processName 18025 + " to " + level); 18026 app.thread.scheduleTrimMemory(level); 18027 } catch (RemoteException e) { 18028 } 18029 } 18030 app.pendingUiClean = false; 18031 } 18032 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18033 try { 18034 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18035 "Trimming memory of fg " + app.processName 18036 + " to " + fgTrimLevel); 18037 app.thread.scheduleTrimMemory(fgTrimLevel); 18038 } catch (RemoteException e) { 18039 } 18040 } 18041 app.trimMemoryLevel = fgTrimLevel; 18042 } 18043 } 18044 } else { 18045 if (mLowRamStartTime != 0) { 18046 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18047 mLowRamStartTime = 0; 18048 } 18049 for (int i=N-1; i>=0; i--) { 18050 ProcessRecord app = mLruProcesses.get(i); 18051 if (allChanged || app.procStateChanged) { 18052 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18053 app.procStateChanged = false; 18054 } 18055 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18056 || app.systemNoUi) && app.pendingUiClean) { 18057 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18058 && app.thread != null) { 18059 try { 18060 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18061 "Trimming memory of ui hidden " + app.processName 18062 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18063 app.thread.scheduleTrimMemory( 18064 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18065 } catch (RemoteException e) { 18066 } 18067 } 18068 app.pendingUiClean = false; 18069 } 18070 app.trimMemoryLevel = 0; 18071 } 18072 } 18073 18074 if (mAlwaysFinishActivities) { 18075 // Need to do this on its own message because the stack may not 18076 // be in a consistent state at this point. 18077 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18078 } 18079 18080 if (allChanged) { 18081 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18082 } 18083 18084 if (mProcessStats.shouldWriteNowLocked(now)) { 18085 mHandler.post(new Runnable() { 18086 @Override public void run() { 18087 synchronized (ActivityManagerService.this) { 18088 mProcessStats.writeStateAsyncLocked(); 18089 } 18090 } 18091 }); 18092 } 18093 18094 if (DEBUG_OOM_ADJ) { 18095 if (false) { 18096 RuntimeException here = new RuntimeException("here"); 18097 here.fillInStackTrace(); 18098 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18099 } else { 18100 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18101 } 18102 } 18103 } 18104 18105 final void trimApplications() { 18106 synchronized (this) { 18107 int i; 18108 18109 // First remove any unused application processes whose package 18110 // has been removed. 18111 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18112 final ProcessRecord app = mRemovedProcesses.get(i); 18113 if (app.activities.size() == 0 18114 && app.curReceiver == null && app.services.size() == 0) { 18115 Slog.i( 18116 TAG, "Exiting empty application process " 18117 + app.processName + " (" 18118 + (app.thread != null ? app.thread.asBinder() : null) 18119 + ")\n"); 18120 if (app.pid > 0 && app.pid != MY_PID) { 18121 app.kill("empty", false); 18122 } else { 18123 try { 18124 app.thread.scheduleExit(); 18125 } catch (Exception e) { 18126 // Ignore exceptions. 18127 } 18128 } 18129 cleanUpApplicationRecordLocked(app, false, true, -1); 18130 mRemovedProcesses.remove(i); 18131 18132 if (app.persistent) { 18133 addAppLocked(app.info, false, null /* ABI override */); 18134 } 18135 } 18136 } 18137 18138 // Now update the oom adj for all processes. 18139 updateOomAdjLocked(); 18140 } 18141 } 18142 18143 /** This method sends the specified signal to each of the persistent apps */ 18144 public void signalPersistentProcesses(int sig) throws RemoteException { 18145 if (sig != Process.SIGNAL_USR1) { 18146 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18147 } 18148 18149 synchronized (this) { 18150 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18151 != PackageManager.PERMISSION_GRANTED) { 18152 throw new SecurityException("Requires permission " 18153 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18154 } 18155 18156 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18157 ProcessRecord r = mLruProcesses.get(i); 18158 if (r.thread != null && r.persistent) { 18159 Process.sendSignal(r.pid, sig); 18160 } 18161 } 18162 } 18163 } 18164 18165 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18166 if (proc == null || proc == mProfileProc) { 18167 proc = mProfileProc; 18168 profileType = mProfileType; 18169 clearProfilerLocked(); 18170 } 18171 if (proc == null) { 18172 return; 18173 } 18174 try { 18175 proc.thread.profilerControl(false, null, profileType); 18176 } catch (RemoteException e) { 18177 throw new IllegalStateException("Process disappeared"); 18178 } 18179 } 18180 18181 private void clearProfilerLocked() { 18182 if (mProfileFd != null) { 18183 try { 18184 mProfileFd.close(); 18185 } catch (IOException e) { 18186 } 18187 } 18188 mProfileApp = null; 18189 mProfileProc = null; 18190 mProfileFile = null; 18191 mProfileType = 0; 18192 mAutoStopProfiler = false; 18193 mSamplingInterval = 0; 18194 } 18195 18196 public boolean profileControl(String process, int userId, boolean start, 18197 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18198 18199 try { 18200 synchronized (this) { 18201 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18202 // its own permission. 18203 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18204 != PackageManager.PERMISSION_GRANTED) { 18205 throw new SecurityException("Requires permission " 18206 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18207 } 18208 18209 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18210 throw new IllegalArgumentException("null profile info or fd"); 18211 } 18212 18213 ProcessRecord proc = null; 18214 if (process != null) { 18215 proc = findProcessLocked(process, userId, "profileControl"); 18216 } 18217 18218 if (start && (proc == null || proc.thread == null)) { 18219 throw new IllegalArgumentException("Unknown process: " + process); 18220 } 18221 18222 if (start) { 18223 stopProfilerLocked(null, 0); 18224 setProfileApp(proc.info, proc.processName, profilerInfo); 18225 mProfileProc = proc; 18226 mProfileType = profileType; 18227 ParcelFileDescriptor fd = profilerInfo.profileFd; 18228 try { 18229 fd = fd.dup(); 18230 } catch (IOException e) { 18231 fd = null; 18232 } 18233 profilerInfo.profileFd = fd; 18234 proc.thread.profilerControl(start, profilerInfo, profileType); 18235 fd = null; 18236 mProfileFd = null; 18237 } else { 18238 stopProfilerLocked(proc, profileType); 18239 if (profilerInfo != null && profilerInfo.profileFd != null) { 18240 try { 18241 profilerInfo.profileFd.close(); 18242 } catch (IOException e) { 18243 } 18244 } 18245 } 18246 18247 return true; 18248 } 18249 } catch (RemoteException e) { 18250 throw new IllegalStateException("Process disappeared"); 18251 } finally { 18252 if (profilerInfo != null && profilerInfo.profileFd != null) { 18253 try { 18254 profilerInfo.profileFd.close(); 18255 } catch (IOException e) { 18256 } 18257 } 18258 } 18259 } 18260 18261 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18262 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18263 userId, true, ALLOW_FULL_ONLY, callName, null); 18264 ProcessRecord proc = null; 18265 try { 18266 int pid = Integer.parseInt(process); 18267 synchronized (mPidsSelfLocked) { 18268 proc = mPidsSelfLocked.get(pid); 18269 } 18270 } catch (NumberFormatException e) { 18271 } 18272 18273 if (proc == null) { 18274 ArrayMap<String, SparseArray<ProcessRecord>> all 18275 = mProcessNames.getMap(); 18276 SparseArray<ProcessRecord> procs = all.get(process); 18277 if (procs != null && procs.size() > 0) { 18278 proc = procs.valueAt(0); 18279 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18280 for (int i=1; i<procs.size(); i++) { 18281 ProcessRecord thisProc = procs.valueAt(i); 18282 if (thisProc.userId == userId) { 18283 proc = thisProc; 18284 break; 18285 } 18286 } 18287 } 18288 } 18289 } 18290 18291 return proc; 18292 } 18293 18294 public boolean dumpHeap(String process, int userId, boolean managed, 18295 String path, ParcelFileDescriptor fd) throws RemoteException { 18296 18297 try { 18298 synchronized (this) { 18299 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18300 // its own permission (same as profileControl). 18301 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18302 != PackageManager.PERMISSION_GRANTED) { 18303 throw new SecurityException("Requires permission " 18304 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18305 } 18306 18307 if (fd == null) { 18308 throw new IllegalArgumentException("null fd"); 18309 } 18310 18311 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18312 if (proc == null || proc.thread == null) { 18313 throw new IllegalArgumentException("Unknown process: " + process); 18314 } 18315 18316 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18317 if (!isDebuggable) { 18318 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18319 throw new SecurityException("Process not debuggable: " + proc); 18320 } 18321 } 18322 18323 proc.thread.dumpHeap(managed, path, fd); 18324 fd = null; 18325 return true; 18326 } 18327 } catch (RemoteException e) { 18328 throw new IllegalStateException("Process disappeared"); 18329 } finally { 18330 if (fd != null) { 18331 try { 18332 fd.close(); 18333 } catch (IOException e) { 18334 } 18335 } 18336 } 18337 } 18338 18339 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18340 public void monitor() { 18341 synchronized (this) { } 18342 } 18343 18344 void onCoreSettingsChange(Bundle settings) { 18345 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18346 ProcessRecord processRecord = mLruProcesses.get(i); 18347 try { 18348 if (processRecord.thread != null) { 18349 processRecord.thread.setCoreSettings(settings); 18350 } 18351 } catch (RemoteException re) { 18352 /* ignore */ 18353 } 18354 } 18355 } 18356 18357 // Multi-user methods 18358 18359 /** 18360 * Start user, if its not already running, but don't bring it to foreground. 18361 */ 18362 @Override 18363 public boolean startUserInBackground(final int userId) { 18364 return startUser(userId, /* foreground */ false); 18365 } 18366 18367 /** 18368 * Start user, if its not already running, and bring it to foreground. 18369 */ 18370 boolean startUserInForeground(final int userId, Dialog dlg) { 18371 boolean result = startUser(userId, /* foreground */ true); 18372 dlg.dismiss(); 18373 return result; 18374 } 18375 18376 /** 18377 * Refreshes the list of users related to the current user when either a 18378 * user switch happens or when a new related user is started in the 18379 * background. 18380 */ 18381 private void updateCurrentProfileIdsLocked() { 18382 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18383 mCurrentUserId, false /* enabledOnly */); 18384 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18385 for (int i = 0; i < currentProfileIds.length; i++) { 18386 currentProfileIds[i] = profiles.get(i).id; 18387 } 18388 mCurrentProfileIds = currentProfileIds; 18389 18390 synchronized (mUserProfileGroupIdsSelfLocked) { 18391 mUserProfileGroupIdsSelfLocked.clear(); 18392 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18393 for (int i = 0; i < users.size(); i++) { 18394 UserInfo user = users.get(i); 18395 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18396 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18397 } 18398 } 18399 } 18400 } 18401 18402 private Set getProfileIdsLocked(int userId) { 18403 Set userIds = new HashSet<Integer>(); 18404 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18405 userId, false /* enabledOnly */); 18406 for (UserInfo user : profiles) { 18407 userIds.add(Integer.valueOf(user.id)); 18408 } 18409 return userIds; 18410 } 18411 18412 @Override 18413 public boolean switchUser(final int userId) { 18414 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18415 String userName; 18416 synchronized (this) { 18417 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18418 if (userInfo == null) { 18419 Slog.w(TAG, "No user info for user #" + userId); 18420 return false; 18421 } 18422 if (userInfo.isManagedProfile()) { 18423 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18424 return false; 18425 } 18426 userName = userInfo.name; 18427 mTargetUserId = userId; 18428 } 18429 mHandler.removeMessages(START_USER_SWITCH_MSG); 18430 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18431 return true; 18432 } 18433 18434 private void showUserSwitchDialog(int userId, String userName) { 18435 // The dialog will show and then initiate the user switch by calling startUserInForeground 18436 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18437 true /* above system */); 18438 d.show(); 18439 } 18440 18441 private boolean startUser(final int userId, final boolean foreground) { 18442 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18443 != PackageManager.PERMISSION_GRANTED) { 18444 String msg = "Permission Denial: switchUser() from pid=" 18445 + Binder.getCallingPid() 18446 + ", uid=" + Binder.getCallingUid() 18447 + " requires " + INTERACT_ACROSS_USERS_FULL; 18448 Slog.w(TAG, msg); 18449 throw new SecurityException(msg); 18450 } 18451 18452 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18453 18454 final long ident = Binder.clearCallingIdentity(); 18455 try { 18456 synchronized (this) { 18457 final int oldUserId = mCurrentUserId; 18458 if (oldUserId == userId) { 18459 return true; 18460 } 18461 18462 mStackSupervisor.setLockTaskModeLocked(null, false); 18463 18464 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18465 if (userInfo == null) { 18466 Slog.w(TAG, "No user info for user #" + userId); 18467 return false; 18468 } 18469 if (foreground && userInfo.isManagedProfile()) { 18470 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18471 return false; 18472 } 18473 18474 if (foreground) { 18475 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18476 R.anim.screen_user_enter); 18477 } 18478 18479 boolean needStart = false; 18480 18481 // If the user we are switching to is not currently started, then 18482 // we need to start it now. 18483 if (mStartedUsers.get(userId) == null) { 18484 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18485 updateStartedUserArrayLocked(); 18486 needStart = true; 18487 } 18488 18489 final Integer userIdInt = Integer.valueOf(userId); 18490 mUserLru.remove(userIdInt); 18491 mUserLru.add(userIdInt); 18492 18493 if (foreground) { 18494 mCurrentUserId = userId; 18495 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18496 updateCurrentProfileIdsLocked(); 18497 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18498 // Once the internal notion of the active user has switched, we lock the device 18499 // with the option to show the user switcher on the keyguard. 18500 mWindowManager.lockNow(null); 18501 } else { 18502 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18503 updateCurrentProfileIdsLocked(); 18504 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18505 mUserLru.remove(currentUserIdInt); 18506 mUserLru.add(currentUserIdInt); 18507 } 18508 18509 final UserStartedState uss = mStartedUsers.get(userId); 18510 18511 // Make sure user is in the started state. If it is currently 18512 // stopping, we need to knock that off. 18513 if (uss.mState == UserStartedState.STATE_STOPPING) { 18514 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18515 // so we can just fairly silently bring the user back from 18516 // the almost-dead. 18517 uss.mState = UserStartedState.STATE_RUNNING; 18518 updateStartedUserArrayLocked(); 18519 needStart = true; 18520 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18521 // This means ACTION_SHUTDOWN has been sent, so we will 18522 // need to treat this as a new boot of the user. 18523 uss.mState = UserStartedState.STATE_BOOTING; 18524 updateStartedUserArrayLocked(); 18525 needStart = true; 18526 } 18527 18528 if (uss.mState == UserStartedState.STATE_BOOTING) { 18529 // Booting up a new user, need to tell system services about it. 18530 // Note that this is on the same handler as scheduling of broadcasts, 18531 // which is important because it needs to go first. 18532 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18533 } 18534 18535 if (foreground) { 18536 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18537 oldUserId)); 18538 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18539 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18540 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18541 oldUserId, userId, uss)); 18542 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18543 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18544 } 18545 18546 if (needStart) { 18547 // Send USER_STARTED broadcast 18548 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18549 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18550 | Intent.FLAG_RECEIVER_FOREGROUND); 18551 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18552 broadcastIntentLocked(null, null, intent, 18553 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18554 false, false, MY_PID, Process.SYSTEM_UID, userId); 18555 } 18556 18557 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18558 if (userId != UserHandle.USER_OWNER) { 18559 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18560 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18561 broadcastIntentLocked(null, null, intent, null, 18562 new IIntentReceiver.Stub() { 18563 public void performReceive(Intent intent, int resultCode, 18564 String data, Bundle extras, boolean ordered, 18565 boolean sticky, int sendingUser) { 18566 onUserInitialized(uss, foreground, oldUserId, userId); 18567 } 18568 }, 0, null, null, null, AppOpsManager.OP_NONE, 18569 true, false, MY_PID, Process.SYSTEM_UID, 18570 userId); 18571 uss.initializing = true; 18572 } else { 18573 getUserManagerLocked().makeInitialized(userInfo.id); 18574 } 18575 } 18576 18577 if (foreground) { 18578 if (!uss.initializing) { 18579 moveUserToForeground(uss, oldUserId, userId); 18580 } 18581 } else { 18582 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18583 } 18584 18585 if (needStart) { 18586 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18587 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18588 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18589 broadcastIntentLocked(null, null, intent, 18590 null, new IIntentReceiver.Stub() { 18591 @Override 18592 public void performReceive(Intent intent, int resultCode, String data, 18593 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18594 throws RemoteException { 18595 } 18596 }, 0, null, null, 18597 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18598 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18599 } 18600 } 18601 } finally { 18602 Binder.restoreCallingIdentity(ident); 18603 } 18604 18605 return true; 18606 } 18607 18608 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18609 long ident = Binder.clearCallingIdentity(); 18610 try { 18611 Intent intent; 18612 if (oldUserId >= 0) { 18613 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18614 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18615 int count = profiles.size(); 18616 for (int i = 0; i < count; i++) { 18617 int profileUserId = profiles.get(i).id; 18618 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18619 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18620 | Intent.FLAG_RECEIVER_FOREGROUND); 18621 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18622 broadcastIntentLocked(null, null, intent, 18623 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18624 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18625 } 18626 } 18627 if (newUserId >= 0) { 18628 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18629 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18630 int count = profiles.size(); 18631 for (int i = 0; i < count; i++) { 18632 int profileUserId = profiles.get(i).id; 18633 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18634 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18635 | Intent.FLAG_RECEIVER_FOREGROUND); 18636 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18637 broadcastIntentLocked(null, null, intent, 18638 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18639 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18640 } 18641 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18642 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18643 | Intent.FLAG_RECEIVER_FOREGROUND); 18644 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18645 broadcastIntentLocked(null, null, intent, 18646 null, null, 0, null, null, 18647 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18648 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18649 } 18650 } finally { 18651 Binder.restoreCallingIdentity(ident); 18652 } 18653 } 18654 18655 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18656 final int newUserId) { 18657 final int N = mUserSwitchObservers.beginBroadcast(); 18658 if (N > 0) { 18659 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18660 int mCount = 0; 18661 @Override 18662 public void sendResult(Bundle data) throws RemoteException { 18663 synchronized (ActivityManagerService.this) { 18664 if (mCurUserSwitchCallback == this) { 18665 mCount++; 18666 if (mCount == N) { 18667 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18668 } 18669 } 18670 } 18671 } 18672 }; 18673 synchronized (this) { 18674 uss.switching = true; 18675 mCurUserSwitchCallback = callback; 18676 } 18677 for (int i=0; i<N; i++) { 18678 try { 18679 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18680 newUserId, callback); 18681 } catch (RemoteException e) { 18682 } 18683 } 18684 } else { 18685 synchronized (this) { 18686 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18687 } 18688 } 18689 mUserSwitchObservers.finishBroadcast(); 18690 } 18691 18692 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18693 synchronized (this) { 18694 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18695 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18696 } 18697 } 18698 18699 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18700 mCurUserSwitchCallback = null; 18701 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18702 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18703 oldUserId, newUserId, uss)); 18704 } 18705 18706 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18707 synchronized (this) { 18708 if (foreground) { 18709 moveUserToForeground(uss, oldUserId, newUserId); 18710 } 18711 } 18712 18713 completeSwitchAndInitalize(uss, newUserId, true, false); 18714 } 18715 18716 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18717 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18718 if (homeInFront) { 18719 startHomeActivityLocked(newUserId); 18720 } else { 18721 mStackSupervisor.resumeTopActivitiesLocked(); 18722 } 18723 EventLogTags.writeAmSwitchUser(newUserId); 18724 getUserManagerLocked().userForeground(newUserId); 18725 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18726 } 18727 18728 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18729 completeSwitchAndInitalize(uss, newUserId, false, true); 18730 } 18731 18732 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18733 boolean clearInitializing, boolean clearSwitching) { 18734 boolean unfrozen = false; 18735 synchronized (this) { 18736 if (clearInitializing) { 18737 uss.initializing = false; 18738 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18739 } 18740 if (clearSwitching) { 18741 uss.switching = false; 18742 } 18743 if (!uss.switching && !uss.initializing) { 18744 mWindowManager.stopFreezingScreen(); 18745 unfrozen = true; 18746 } 18747 } 18748 if (unfrozen) { 18749 final int N = mUserSwitchObservers.beginBroadcast(); 18750 for (int i=0; i<N; i++) { 18751 try { 18752 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18753 } catch (RemoteException e) { 18754 } 18755 } 18756 mUserSwitchObservers.finishBroadcast(); 18757 } 18758 } 18759 18760 void scheduleStartProfilesLocked() { 18761 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18762 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18763 DateUtils.SECOND_IN_MILLIS); 18764 } 18765 } 18766 18767 void startProfilesLocked() { 18768 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18769 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18770 mCurrentUserId, false /* enabledOnly */); 18771 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18772 for (UserInfo user : profiles) { 18773 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18774 && user.id != mCurrentUserId) { 18775 toStart.add(user); 18776 } 18777 } 18778 final int n = toStart.size(); 18779 int i = 0; 18780 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18781 startUserInBackground(toStart.get(i).id); 18782 } 18783 if (i < n) { 18784 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18785 } 18786 } 18787 18788 void finishUserBoot(UserStartedState uss) { 18789 synchronized (this) { 18790 if (uss.mState == UserStartedState.STATE_BOOTING 18791 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18792 uss.mState = UserStartedState.STATE_RUNNING; 18793 final int userId = uss.mHandle.getIdentifier(); 18794 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18795 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18796 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18797 broadcastIntentLocked(null, null, intent, 18798 null, null, 0, null, null, 18799 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18800 true, false, MY_PID, Process.SYSTEM_UID, userId); 18801 } 18802 } 18803 } 18804 18805 void finishUserSwitch(UserStartedState uss) { 18806 synchronized (this) { 18807 finishUserBoot(uss); 18808 18809 startProfilesLocked(); 18810 18811 int num = mUserLru.size(); 18812 int i = 0; 18813 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18814 Integer oldUserId = mUserLru.get(i); 18815 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18816 if (oldUss == null) { 18817 // Shouldn't happen, but be sane if it does. 18818 mUserLru.remove(i); 18819 num--; 18820 continue; 18821 } 18822 if (oldUss.mState == UserStartedState.STATE_STOPPING 18823 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18824 // This user is already stopping, doesn't count. 18825 num--; 18826 i++; 18827 continue; 18828 } 18829 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18830 // Owner and current can't be stopped, but count as running. 18831 i++; 18832 continue; 18833 } 18834 // This is a user to be stopped. 18835 stopUserLocked(oldUserId, null); 18836 num--; 18837 i++; 18838 } 18839 } 18840 } 18841 18842 @Override 18843 public int stopUser(final int userId, final IStopUserCallback callback) { 18844 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18845 != PackageManager.PERMISSION_GRANTED) { 18846 String msg = "Permission Denial: switchUser() from pid=" 18847 + Binder.getCallingPid() 18848 + ", uid=" + Binder.getCallingUid() 18849 + " requires " + INTERACT_ACROSS_USERS_FULL; 18850 Slog.w(TAG, msg); 18851 throw new SecurityException(msg); 18852 } 18853 if (userId <= 0) { 18854 throw new IllegalArgumentException("Can't stop primary user " + userId); 18855 } 18856 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18857 synchronized (this) { 18858 return stopUserLocked(userId, callback); 18859 } 18860 } 18861 18862 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18863 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18864 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18865 return ActivityManager.USER_OP_IS_CURRENT; 18866 } 18867 18868 final UserStartedState uss = mStartedUsers.get(userId); 18869 if (uss == null) { 18870 // User is not started, nothing to do... but we do need to 18871 // callback if requested. 18872 if (callback != null) { 18873 mHandler.post(new Runnable() { 18874 @Override 18875 public void run() { 18876 try { 18877 callback.userStopped(userId); 18878 } catch (RemoteException e) { 18879 } 18880 } 18881 }); 18882 } 18883 return ActivityManager.USER_OP_SUCCESS; 18884 } 18885 18886 if (callback != null) { 18887 uss.mStopCallbacks.add(callback); 18888 } 18889 18890 if (uss.mState != UserStartedState.STATE_STOPPING 18891 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18892 uss.mState = UserStartedState.STATE_STOPPING; 18893 updateStartedUserArrayLocked(); 18894 18895 long ident = Binder.clearCallingIdentity(); 18896 try { 18897 // We are going to broadcast ACTION_USER_STOPPING and then 18898 // once that is done send a final ACTION_SHUTDOWN and then 18899 // stop the user. 18900 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18901 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18902 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18903 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18904 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18905 // This is the result receiver for the final shutdown broadcast. 18906 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18907 @Override 18908 public void performReceive(Intent intent, int resultCode, String data, 18909 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18910 finishUserStop(uss); 18911 } 18912 }; 18913 // This is the result receiver for the initial stopping broadcast. 18914 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18915 @Override 18916 public void performReceive(Intent intent, int resultCode, String data, 18917 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18918 // On to the next. 18919 synchronized (ActivityManagerService.this) { 18920 if (uss.mState != UserStartedState.STATE_STOPPING) { 18921 // Whoops, we are being started back up. Abort, abort! 18922 return; 18923 } 18924 uss.mState = UserStartedState.STATE_SHUTDOWN; 18925 } 18926 mBatteryStatsService.noteEvent( 18927 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18928 Integer.toString(userId), userId); 18929 mSystemServiceManager.stopUser(userId); 18930 broadcastIntentLocked(null, null, shutdownIntent, 18931 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18932 true, false, MY_PID, Process.SYSTEM_UID, userId); 18933 } 18934 }; 18935 // Kick things off. 18936 broadcastIntentLocked(null, null, stoppingIntent, 18937 null, stoppingReceiver, 0, null, null, 18938 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18939 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18940 } finally { 18941 Binder.restoreCallingIdentity(ident); 18942 } 18943 } 18944 18945 return ActivityManager.USER_OP_SUCCESS; 18946 } 18947 18948 void finishUserStop(UserStartedState uss) { 18949 final int userId = uss.mHandle.getIdentifier(); 18950 boolean stopped; 18951 ArrayList<IStopUserCallback> callbacks; 18952 synchronized (this) { 18953 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18954 if (mStartedUsers.get(userId) != uss) { 18955 stopped = false; 18956 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18957 stopped = false; 18958 } else { 18959 stopped = true; 18960 // User can no longer run. 18961 mStartedUsers.remove(userId); 18962 mUserLru.remove(Integer.valueOf(userId)); 18963 updateStartedUserArrayLocked(); 18964 18965 // Clean up all state and processes associated with the user. 18966 // Kill all the processes for the user. 18967 forceStopUserLocked(userId, "finish user"); 18968 } 18969 18970 // Explicitly remove the old information in mRecentTasks. 18971 removeRecentTasksForUserLocked(userId); 18972 } 18973 18974 for (int i=0; i<callbacks.size(); i++) { 18975 try { 18976 if (stopped) callbacks.get(i).userStopped(userId); 18977 else callbacks.get(i).userStopAborted(userId); 18978 } catch (RemoteException e) { 18979 } 18980 } 18981 18982 if (stopped) { 18983 mSystemServiceManager.cleanupUser(userId); 18984 synchronized (this) { 18985 mStackSupervisor.removeUserLocked(userId); 18986 } 18987 } 18988 } 18989 18990 @Override 18991 public UserInfo getCurrentUser() { 18992 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18993 != PackageManager.PERMISSION_GRANTED) && ( 18994 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18995 != PackageManager.PERMISSION_GRANTED)) { 18996 String msg = "Permission Denial: getCurrentUser() from pid=" 18997 + Binder.getCallingPid() 18998 + ", uid=" + Binder.getCallingUid() 18999 + " requires " + INTERACT_ACROSS_USERS; 19000 Slog.w(TAG, msg); 19001 throw new SecurityException(msg); 19002 } 19003 synchronized (this) { 19004 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19005 return getUserManagerLocked().getUserInfo(userId); 19006 } 19007 } 19008 19009 int getCurrentUserIdLocked() { 19010 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19011 } 19012 19013 @Override 19014 public boolean isUserRunning(int userId, boolean orStopped) { 19015 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19016 != PackageManager.PERMISSION_GRANTED) { 19017 String msg = "Permission Denial: isUserRunning() from pid=" 19018 + Binder.getCallingPid() 19019 + ", uid=" + Binder.getCallingUid() 19020 + " requires " + INTERACT_ACROSS_USERS; 19021 Slog.w(TAG, msg); 19022 throw new SecurityException(msg); 19023 } 19024 synchronized (this) { 19025 return isUserRunningLocked(userId, orStopped); 19026 } 19027 } 19028 19029 boolean isUserRunningLocked(int userId, boolean orStopped) { 19030 UserStartedState state = mStartedUsers.get(userId); 19031 if (state == null) { 19032 return false; 19033 } 19034 if (orStopped) { 19035 return true; 19036 } 19037 return state.mState != UserStartedState.STATE_STOPPING 19038 && state.mState != UserStartedState.STATE_SHUTDOWN; 19039 } 19040 19041 @Override 19042 public int[] getRunningUserIds() { 19043 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19044 != PackageManager.PERMISSION_GRANTED) { 19045 String msg = "Permission Denial: isUserRunning() from pid=" 19046 + Binder.getCallingPid() 19047 + ", uid=" + Binder.getCallingUid() 19048 + " requires " + INTERACT_ACROSS_USERS; 19049 Slog.w(TAG, msg); 19050 throw new SecurityException(msg); 19051 } 19052 synchronized (this) { 19053 return mStartedUserArray; 19054 } 19055 } 19056 19057 private void updateStartedUserArrayLocked() { 19058 int num = 0; 19059 for (int i=0; i<mStartedUsers.size(); i++) { 19060 UserStartedState uss = mStartedUsers.valueAt(i); 19061 // This list does not include stopping users. 19062 if (uss.mState != UserStartedState.STATE_STOPPING 19063 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19064 num++; 19065 } 19066 } 19067 mStartedUserArray = new int[num]; 19068 num = 0; 19069 for (int i=0; i<mStartedUsers.size(); i++) { 19070 UserStartedState uss = mStartedUsers.valueAt(i); 19071 if (uss.mState != UserStartedState.STATE_STOPPING 19072 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19073 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19074 num++; 19075 } 19076 } 19077 } 19078 19079 @Override 19080 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19081 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19082 != PackageManager.PERMISSION_GRANTED) { 19083 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19084 + Binder.getCallingPid() 19085 + ", uid=" + Binder.getCallingUid() 19086 + " requires " + INTERACT_ACROSS_USERS_FULL; 19087 Slog.w(TAG, msg); 19088 throw new SecurityException(msg); 19089 } 19090 19091 mUserSwitchObservers.register(observer); 19092 } 19093 19094 @Override 19095 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19096 mUserSwitchObservers.unregister(observer); 19097 } 19098 19099 private boolean userExists(int userId) { 19100 if (userId == 0) { 19101 return true; 19102 } 19103 UserManagerService ums = getUserManagerLocked(); 19104 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19105 } 19106 19107 int[] getUsersLocked() { 19108 UserManagerService ums = getUserManagerLocked(); 19109 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19110 } 19111 19112 UserManagerService getUserManagerLocked() { 19113 if (mUserManager == null) { 19114 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19115 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19116 } 19117 return mUserManager; 19118 } 19119 19120 private int applyUserId(int uid, int userId) { 19121 return UserHandle.getUid(userId, uid); 19122 } 19123 19124 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19125 if (info == null) return null; 19126 ApplicationInfo newInfo = new ApplicationInfo(info); 19127 newInfo.uid = applyUserId(info.uid, userId); 19128 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19129 + info.packageName; 19130 return newInfo; 19131 } 19132 19133 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19134 if (aInfo == null 19135 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19136 return aInfo; 19137 } 19138 19139 ActivityInfo info = new ActivityInfo(aInfo); 19140 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19141 return info; 19142 } 19143 19144 private final class LocalService extends ActivityManagerInternal { 19145 @Override 19146 public void goingToSleep() { 19147 ActivityManagerService.this.goingToSleep(); 19148 } 19149 19150 @Override 19151 public void wakingUp() { 19152 ActivityManagerService.this.wakingUp(); 19153 } 19154 19155 @Override 19156 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19157 String processName, String abiOverride, int uid, Runnable crashHandler) { 19158 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19159 processName, abiOverride, uid, crashHandler); 19160 } 19161 } 19162 19163 /** 19164 * An implementation of IAppTask, that allows an app to manage its own tasks via 19165 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19166 * only the process that calls getAppTasks() can call the AppTask methods. 19167 */ 19168 class AppTaskImpl extends IAppTask.Stub { 19169 private int mTaskId; 19170 private int mCallingUid; 19171 19172 public AppTaskImpl(int taskId, int callingUid) { 19173 mTaskId = taskId; 19174 mCallingUid = callingUid; 19175 } 19176 19177 private void checkCaller() { 19178 if (mCallingUid != Binder.getCallingUid()) { 19179 throw new SecurityException("Caller " + mCallingUid 19180 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19181 } 19182 } 19183 19184 @Override 19185 public void finishAndRemoveTask() { 19186 checkCaller(); 19187 19188 synchronized (ActivityManagerService.this) { 19189 long origId = Binder.clearCallingIdentity(); 19190 try { 19191 if (!removeTaskByIdLocked(mTaskId, false)) { 19192 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19193 } 19194 } finally { 19195 Binder.restoreCallingIdentity(origId); 19196 } 19197 } 19198 } 19199 19200 @Override 19201 public ActivityManager.RecentTaskInfo getTaskInfo() { 19202 checkCaller(); 19203 19204 synchronized (ActivityManagerService.this) { 19205 long origId = Binder.clearCallingIdentity(); 19206 try { 19207 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19208 if (tr == null) { 19209 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19210 } 19211 return createRecentTaskInfoFromTaskRecord(tr); 19212 } finally { 19213 Binder.restoreCallingIdentity(origId); 19214 } 19215 } 19216 } 19217 19218 @Override 19219 public void moveToFront() { 19220 checkCaller(); 19221 19222 final TaskRecord tr; 19223 synchronized (ActivityManagerService.this) { 19224 tr = recentTaskForIdLocked(mTaskId); 19225 if (tr == null) { 19226 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19227 } 19228 if (tr.getRootActivity() != null) { 19229 moveTaskToFrontLocked(tr.taskId, 0, null); 19230 return; 19231 } 19232 } 19233 19234 startActivityFromRecentsInner(tr.taskId, null); 19235 } 19236 19237 @Override 19238 public int startActivity(IBinder whoThread, String callingPackage, 19239 Intent intent, String resolvedType, Bundle options) { 19240 checkCaller(); 19241 19242 int callingUser = UserHandle.getCallingUserId(); 19243 TaskRecord tr; 19244 IApplicationThread appThread; 19245 synchronized (ActivityManagerService.this) { 19246 tr = recentTaskForIdLocked(mTaskId); 19247 if (tr == null) { 19248 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19249 } 19250 appThread = ApplicationThreadNative.asInterface(whoThread); 19251 if (appThread == null) { 19252 throw new IllegalArgumentException("Bad app thread " + appThread); 19253 } 19254 } 19255 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19256 resolvedType, null, null, null, null, 0, 0, null, null, 19257 null, options, callingUser, null, tr); 19258 } 19259 19260 @Override 19261 public void setExcludeFromRecents(boolean exclude) { 19262 checkCaller(); 19263 19264 synchronized (ActivityManagerService.this) { 19265 long origId = Binder.clearCallingIdentity(); 19266 try { 19267 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19268 if (tr == null) { 19269 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19270 } 19271 Intent intent = tr.getBaseIntent(); 19272 if (exclude) { 19273 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19274 } else { 19275 intent.setFlags(intent.getFlags() 19276 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19277 } 19278 } finally { 19279 Binder.restoreCallingIdentity(origId); 19280 } 19281 } 19282 } 19283 } 19284} 19285