ActivityManagerService.java revision 044d52934e57a337665f707aa4be1d423ee3fb29
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 /** 956 * State of external call telling us if the lock screen is shown. 957 */ 958 private boolean mLockScreenShown = false; 959 960 /** 961 * Set if we are shutting down the system, similar to sleeping. 962 */ 963 boolean mShuttingDown = false; 964 965 /** 966 * Current sequence id for oom_adj computation traversal. 967 */ 968 int mAdjSeq = 0; 969 970 /** 971 * Current sequence id for process LRU updating. 972 */ 973 int mLruSeq = 0; 974 975 /** 976 * Keep track of the non-cached/empty process we last found, to help 977 * determine how to distribute cached/empty processes next time. 978 */ 979 int mNumNonCachedProcs = 0; 980 981 /** 982 * Keep track of the number of cached hidden procs, to balance oom adj 983 * distribution between those and empty procs. 984 */ 985 int mNumCachedHiddenProcs = 0; 986 987 /** 988 * Keep track of the number of service processes we last found, to 989 * determine on the next iteration which should be B services. 990 */ 991 int mNumServiceProcs = 0; 992 int mNewNumAServiceProcs = 0; 993 int mNewNumServiceProcs = 0; 994 995 /** 996 * Allow the current computed overall memory level of the system to go down? 997 * This is set to false when we are killing processes for reasons other than 998 * memory management, so that the now smaller process list will not be taken as 999 * an indication that memory is tighter. 1000 */ 1001 boolean mAllowLowerMemLevel = false; 1002 1003 /** 1004 * The last computed memory level, for holding when we are in a state that 1005 * processes are going away for other reasons. 1006 */ 1007 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1008 1009 /** 1010 * The last total number of process we have, to determine if changes actually look 1011 * like a shrinking number of process due to lower RAM. 1012 */ 1013 int mLastNumProcesses; 1014 1015 /** 1016 * The uptime of the last time we performed idle maintenance. 1017 */ 1018 long mLastIdleTime = SystemClock.uptimeMillis(); 1019 1020 /** 1021 * Total time spent with RAM that has been added in the past since the last idle time. 1022 */ 1023 long mLowRamTimeSinceLastIdle = 0; 1024 1025 /** 1026 * If RAM is currently low, when that horrible situation started. 1027 */ 1028 long mLowRamStartTime = 0; 1029 1030 /** 1031 * For reporting to battery stats the current top application. 1032 */ 1033 private String mCurResumedPackage = null; 1034 private int mCurResumedUid = -1; 1035 1036 /** 1037 * For reporting to battery stats the apps currently running foreground 1038 * service. The ProcessMap is package/uid tuples; each of these contain 1039 * an array of the currently foreground processes. 1040 */ 1041 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1042 = new ProcessMap<ArrayList<ProcessRecord>>(); 1043 1044 /** 1045 * This is set if we had to do a delayed dexopt of an app before launching 1046 * it, to increase the ANR timeouts in that case. 1047 */ 1048 boolean mDidDexOpt; 1049 1050 /** 1051 * Set if the systemServer made a call to enterSafeMode. 1052 */ 1053 boolean mSafeMode; 1054 1055 String mDebugApp = null; 1056 boolean mWaitForDebugger = false; 1057 boolean mDebugTransient = false; 1058 String mOrigDebugApp = null; 1059 boolean mOrigWaitForDebugger = false; 1060 boolean mAlwaysFinishActivities = false; 1061 IActivityController mController = null; 1062 String mProfileApp = null; 1063 ProcessRecord mProfileProc = null; 1064 String mProfileFile; 1065 ParcelFileDescriptor mProfileFd; 1066 int mSamplingInterval = 0; 1067 boolean mAutoStopProfiler = false; 1068 int mProfileType = 0; 1069 String mOpenGlTraceApp = null; 1070 1071 static class ProcessChangeItem { 1072 static final int CHANGE_ACTIVITIES = 1<<0; 1073 static final int CHANGE_PROCESS_STATE = 1<<1; 1074 int changes; 1075 int uid; 1076 int pid; 1077 int processState; 1078 boolean foregroundActivities; 1079 } 1080 1081 final RemoteCallbackList<IProcessObserver> mProcessObservers 1082 = new RemoteCallbackList<IProcessObserver>(); 1083 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1084 1085 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1086 = new ArrayList<ProcessChangeItem>(); 1087 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 1090 /** 1091 * Runtime CPU use collection thread. This object's lock is used to 1092 * perform synchronization with the thread (notifying it to run). 1093 */ 1094 final Thread mProcessCpuThread; 1095 1096 /** 1097 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1098 * Must acquire this object's lock when accessing it. 1099 * NOTE: this lock will be held while doing long operations (trawling 1100 * through all processes in /proc), so it should never be acquired by 1101 * any critical paths such as when holding the main activity manager lock. 1102 */ 1103 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1104 MONITOR_THREAD_CPU_USAGE); 1105 final AtomicLong mLastCpuTime = new AtomicLong(0); 1106 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1107 1108 long mLastWriteTime = 0; 1109 1110 /** 1111 * Used to retain an update lock when the foreground activity is in 1112 * immersive mode. 1113 */ 1114 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1115 1116 /** 1117 * Set to true after the system has finished booting. 1118 */ 1119 boolean mBooted = false; 1120 1121 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1122 int mProcessLimitOverride = -1; 1123 1124 WindowManagerService mWindowManager; 1125 1126 final ActivityThread mSystemThread; 1127 1128 // Holds the current foreground user's id 1129 int mCurrentUserId = 0; 1130 // Holds the target user's id during a user switch 1131 int mTargetUserId = UserHandle.USER_NULL; 1132 // If there are multiple profiles for the current user, their ids are here 1133 // Currently only the primary user can have managed profiles 1134 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1135 1136 /** 1137 * Mapping from each known user ID to the profile group ID it is associated with. 1138 */ 1139 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1140 1141 private UserManagerService mUserManager; 1142 1143 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1144 final ProcessRecord mApp; 1145 final int mPid; 1146 final IApplicationThread mAppThread; 1147 1148 AppDeathRecipient(ProcessRecord app, int pid, 1149 IApplicationThread thread) { 1150 if (localLOGV) Slog.v( 1151 TAG, "New death recipient " + this 1152 + " for thread " + thread.asBinder()); 1153 mApp = app; 1154 mPid = pid; 1155 mAppThread = thread; 1156 } 1157 1158 @Override 1159 public void binderDied() { 1160 if (localLOGV) Slog.v( 1161 TAG, "Death received in " + this 1162 + " for thread " + mAppThread.asBinder()); 1163 synchronized(ActivityManagerService.this) { 1164 appDiedLocked(mApp, mPid, mAppThread); 1165 } 1166 } 1167 } 1168 1169 static final int SHOW_ERROR_MSG = 1; 1170 static final int SHOW_NOT_RESPONDING_MSG = 2; 1171 static final int SHOW_FACTORY_ERROR_MSG = 3; 1172 static final int UPDATE_CONFIGURATION_MSG = 4; 1173 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1174 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1175 static final int SERVICE_TIMEOUT_MSG = 12; 1176 static final int UPDATE_TIME_ZONE = 13; 1177 static final int SHOW_UID_ERROR_MSG = 14; 1178 static final int IM_FEELING_LUCKY_MSG = 15; 1179 static final int PROC_START_TIMEOUT_MSG = 20; 1180 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1181 static final int KILL_APPLICATION_MSG = 22; 1182 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1183 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1184 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1185 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1186 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1187 static final int CLEAR_DNS_CACHE_MSG = 28; 1188 static final int UPDATE_HTTP_PROXY_MSG = 29; 1189 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1190 static final int DISPATCH_PROCESSES_CHANGED = 31; 1191 static final int DISPATCH_PROCESS_DIED = 32; 1192 static final int REPORT_MEM_USAGE_MSG = 33; 1193 static final int REPORT_USER_SWITCH_MSG = 34; 1194 static final int CONTINUE_USER_SWITCH_MSG = 35; 1195 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1196 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1197 static final int PERSIST_URI_GRANTS_MSG = 38; 1198 static final int REQUEST_ALL_PSS_MSG = 39; 1199 static final int START_PROFILES_MSG = 40; 1200 static final int UPDATE_TIME = 41; 1201 static final int SYSTEM_USER_START_MSG = 42; 1202 static final int SYSTEM_USER_CURRENT_MSG = 43; 1203 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1204 static final int FINISH_BOOTING_MSG = 45; 1205 static final int START_USER_SWITCH_MSG = 46; 1206 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1207 1208 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1209 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1210 static final int FIRST_COMPAT_MODE_MSG = 300; 1211 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1212 1213 AlertDialog mUidAlert; 1214 CompatModeDialog mCompatModeDialog; 1215 long mLastMemUsageReportTime = 0; 1216 1217 private LockToAppRequestDialog mLockToAppRequest; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 reportMemUsage(memInfos); 1610 } 1611 }; 1612 thread.start(); 1613 break; 1614 } 1615 case START_USER_SWITCH_MSG: { 1616 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1617 break; 1618 } 1619 case REPORT_USER_SWITCH_MSG: { 1620 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1621 break; 1622 } 1623 case CONTINUE_USER_SWITCH_MSG: { 1624 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1625 break; 1626 } 1627 case USER_SWITCH_TIMEOUT_MSG: { 1628 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1629 break; 1630 } 1631 case IMMERSIVE_MODE_LOCK_MSG: { 1632 final boolean nextState = (msg.arg1 != 0); 1633 if (mUpdateLock.isHeld() != nextState) { 1634 if (DEBUG_IMMERSIVE) { 1635 final ActivityRecord r = (ActivityRecord) msg.obj; 1636 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1637 } 1638 if (nextState) { 1639 mUpdateLock.acquire(); 1640 } else { 1641 mUpdateLock.release(); 1642 } 1643 } 1644 break; 1645 } 1646 case PERSIST_URI_GRANTS_MSG: { 1647 writeGrantedUriPermissions(); 1648 break; 1649 } 1650 case REQUEST_ALL_PSS_MSG: { 1651 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1652 break; 1653 } 1654 case START_PROFILES_MSG: { 1655 synchronized (ActivityManagerService.this) { 1656 startProfilesLocked(); 1657 } 1658 break; 1659 } 1660 case UPDATE_TIME: { 1661 synchronized (ActivityManagerService.this) { 1662 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1663 ProcessRecord r = mLruProcesses.get(i); 1664 if (r.thread != null) { 1665 try { 1666 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1667 } catch (RemoteException ex) { 1668 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1669 } 1670 } 1671 } 1672 } 1673 break; 1674 } 1675 case SYSTEM_USER_START_MSG: { 1676 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1677 Integer.toString(msg.arg1), msg.arg1); 1678 mSystemServiceManager.startUser(msg.arg1); 1679 break; 1680 } 1681 case SYSTEM_USER_CURRENT_MSG: { 1682 mBatteryStatsService.noteEvent( 1683 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1684 Integer.toString(msg.arg2), msg.arg2); 1685 mBatteryStatsService.noteEvent( 1686 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1687 Integer.toString(msg.arg1), msg.arg1); 1688 mSystemServiceManager.switchUser(msg.arg1); 1689 mLockToAppRequest.clearPrompt(); 1690 break; 1691 } 1692 case ENTER_ANIMATION_COMPLETE_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1695 if (r != null && r.app != null && r.app.thread != null) { 1696 try { 1697 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1698 } catch (RemoteException e) { 1699 } 1700 } 1701 } 1702 break; 1703 } 1704 case FINISH_BOOTING_MSG: { 1705 if (msg.arg1 != 0) { 1706 finishBooting(); 1707 } 1708 if (msg.arg2 != 0) { 1709 enableScreenAfterBoot(); 1710 } 1711 break; 1712 } 1713 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1714 try { 1715 Locale l = (Locale) msg.obj; 1716 IBinder service = ServiceManager.getService("mount"); 1717 IMountService mountService = IMountService.Stub.asInterface(service); 1718 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1719 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1720 } catch (RemoteException e) { 1721 Log.e(TAG, "Error storing locale for decryption UI", e); 1722 } 1723 break; 1724 } 1725 } 1726 } 1727 }; 1728 1729 static final int COLLECT_PSS_BG_MSG = 1; 1730 1731 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1732 @Override 1733 public void handleMessage(Message msg) { 1734 switch (msg.what) { 1735 case COLLECT_PSS_BG_MSG: { 1736 long start = SystemClock.uptimeMillis(); 1737 MemInfoReader memInfo = null; 1738 synchronized (ActivityManagerService.this) { 1739 if (mFullPssPending) { 1740 mFullPssPending = false; 1741 memInfo = new MemInfoReader(); 1742 } 1743 } 1744 if (memInfo != null) { 1745 updateCpuStatsNow(); 1746 long nativeTotalPss = 0; 1747 synchronized (mProcessCpuTracker) { 1748 final int N = mProcessCpuTracker.countStats(); 1749 for (int j=0; j<N; j++) { 1750 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1751 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1752 // This is definitely an application process; skip it. 1753 continue; 1754 } 1755 synchronized (mPidsSelfLocked) { 1756 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1757 // This is one of our own processes; skip it. 1758 continue; 1759 } 1760 } 1761 nativeTotalPss += Debug.getPss(st.pid, null); 1762 } 1763 } 1764 memInfo.readMemInfo(); 1765 synchronized (ActivityManagerService.this) { 1766 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1767 + (SystemClock.uptimeMillis()-start) + "ms"); 1768 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1769 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1770 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1771 } 1772 } 1773 1774 int i=0, num=0; 1775 long[] tmp = new long[1]; 1776 do { 1777 ProcessRecord proc; 1778 int procState; 1779 int pid; 1780 synchronized (ActivityManagerService.this) { 1781 if (i >= mPendingPssProcesses.size()) { 1782 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1783 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1784 mPendingPssProcesses.clear(); 1785 return; 1786 } 1787 proc = mPendingPssProcesses.get(i); 1788 procState = proc.pssProcState; 1789 if (proc.thread != null && procState == proc.setProcState) { 1790 pid = proc.pid; 1791 } else { 1792 proc = null; 1793 pid = 0; 1794 } 1795 i++; 1796 } 1797 if (proc != null) { 1798 long pss = Debug.getPss(pid, tmp); 1799 synchronized (ActivityManagerService.this) { 1800 if (proc.thread != null && proc.setProcState == procState 1801 && proc.pid == pid) { 1802 num++; 1803 proc.lastPssTime = SystemClock.uptimeMillis(); 1804 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1805 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1806 + ": " + pss + " lastPss=" + proc.lastPss 1807 + " state=" + ProcessList.makeProcStateString(procState)); 1808 if (proc.initialIdlePss == 0) { 1809 proc.initialIdlePss = pss; 1810 } 1811 proc.lastPss = pss; 1812 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1813 proc.lastCachedPss = pss; 1814 } 1815 } 1816 } 1817 } 1818 } while (true); 1819 } 1820 } 1821 } 1822 }; 1823 1824 /** 1825 * Monitor for package changes and update our internal state. 1826 */ 1827 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1828 @Override 1829 public void onPackageRemoved(String packageName, int uid) { 1830 // Remove all tasks with activities in the specified package from the list of recent tasks 1831 final int eventUserId = getChangingUserId(); 1832 synchronized (ActivityManagerService.this) { 1833 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1834 TaskRecord tr = mRecentTasks.get(i); 1835 if (tr.userId != eventUserId) continue; 1836 1837 ComponentName cn = tr.intent.getComponent(); 1838 if (cn != null && cn.getPackageName().equals(packageName)) { 1839 // If the package name matches, remove the task 1840 removeTaskByIdLocked(tr.taskId, true); 1841 } 1842 } 1843 } 1844 } 1845 1846 @Override 1847 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1848 onPackageModified(packageName); 1849 return true; 1850 } 1851 1852 @Override 1853 public void onPackageModified(String packageName) { 1854 final int eventUserId = getChangingUserId(); 1855 final IPackageManager pm = AppGlobals.getPackageManager(); 1856 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1857 new ArrayList<Pair<Intent, Integer>>(); 1858 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1859 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1860 // Copy the list of recent tasks so that we don't hold onto the lock on 1861 // ActivityManagerService for long periods while checking if components exist. 1862 synchronized (ActivityManagerService.this) { 1863 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1864 TaskRecord tr = mRecentTasks.get(i); 1865 if (tr.userId != eventUserId) continue; 1866 1867 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1868 } 1869 } 1870 // Check the recent tasks and filter out all tasks with components that no longer exist. 1871 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1872 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1873 ComponentName cn = p.first.getComponent(); 1874 if (cn != null && cn.getPackageName().equals(packageName)) { 1875 if (componentsKnownToExist.contains(cn)) { 1876 // If we know that the component still exists in the package, then skip 1877 continue; 1878 } 1879 try { 1880 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1881 if (info != null) { 1882 componentsKnownToExist.add(cn); 1883 } else { 1884 tasksToRemove.add(p.second); 1885 } 1886 } catch (RemoteException e) { 1887 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1888 } 1889 } 1890 } 1891 // Prune all the tasks with removed components from the list of recent tasks 1892 synchronized (ActivityManagerService.this) { 1893 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1894 removeTaskByIdLocked(tasksToRemove.get(i), false); 1895 } 1896 } 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1903 if (packages != null) { 1904 for (String pkg : packages) { 1905 synchronized (ActivityManagerService.this) { 1906 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1907 userId, "finished booting")) { 1908 return true; 1909 } 1910 } 1911 } 1912 } 1913 return false; 1914 } 1915 }; 1916 1917 public void setSystemProcess() { 1918 try { 1919 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1920 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1921 ServiceManager.addService("meminfo", new MemBinder(this)); 1922 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1923 ServiceManager.addService("dbinfo", new DbBinder(this)); 1924 if (MONITOR_CPU_USAGE) { 1925 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1926 } 1927 ServiceManager.addService("permission", new PermissionController(this)); 1928 1929 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1930 "android", STOCK_PM_FLAGS); 1931 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1932 1933 synchronized (this) { 1934 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1935 app.persistent = true; 1936 app.pid = MY_PID; 1937 app.maxAdj = ProcessList.SYSTEM_ADJ; 1938 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1939 mProcessNames.put(app.processName, app.uid, app); 1940 synchronized (mPidsSelfLocked) { 1941 mPidsSelfLocked.put(app.pid, app); 1942 } 1943 updateLruProcessLocked(app, false, null); 1944 updateOomAdjLocked(); 1945 } 1946 } catch (PackageManager.NameNotFoundException e) { 1947 throw new RuntimeException( 1948 "Unable to find android system package", e); 1949 } 1950 } 1951 1952 public void setWindowManager(WindowManagerService wm) { 1953 mWindowManager = wm; 1954 mStackSupervisor.setWindowManager(wm); 1955 } 1956 1957 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1958 mUsageStatsService = usageStatsManager; 1959 } 1960 1961 public void startObservingNativeCrashes() { 1962 final NativeCrashListener ncl = new NativeCrashListener(this); 1963 ncl.start(); 1964 } 1965 1966 public IAppOpsService getAppOpsService() { 1967 return mAppOpsService; 1968 } 1969 1970 static class MemBinder extends Binder { 1971 ActivityManagerService mActivityManagerService; 1972 MemBinder(ActivityManagerService activityManagerService) { 1973 mActivityManagerService = activityManagerService; 1974 } 1975 1976 @Override 1977 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1978 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1979 != PackageManager.PERMISSION_GRANTED) { 1980 pw.println("Permission Denial: can't dump meminfo from from pid=" 1981 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1982 + " without permission " + android.Manifest.permission.DUMP); 1983 return; 1984 } 1985 1986 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1987 } 1988 } 1989 1990 static class GraphicsBinder extends Binder { 1991 ActivityManagerService mActivityManagerService; 1992 GraphicsBinder(ActivityManagerService activityManagerService) { 1993 mActivityManagerService = activityManagerService; 1994 } 1995 1996 @Override 1997 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1998 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1999 != PackageManager.PERMISSION_GRANTED) { 2000 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2001 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2002 + " without permission " + android.Manifest.permission.DUMP); 2003 return; 2004 } 2005 2006 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2007 } 2008 } 2009 2010 static class DbBinder extends Binder { 2011 ActivityManagerService mActivityManagerService; 2012 DbBinder(ActivityManagerService activityManagerService) { 2013 mActivityManagerService = activityManagerService; 2014 } 2015 2016 @Override 2017 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2018 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2019 != PackageManager.PERMISSION_GRANTED) { 2020 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2021 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2022 + " without permission " + android.Manifest.permission.DUMP); 2023 return; 2024 } 2025 2026 mActivityManagerService.dumpDbInfo(fd, pw, args); 2027 } 2028 } 2029 2030 static class CpuBinder extends Binder { 2031 ActivityManagerService mActivityManagerService; 2032 CpuBinder(ActivityManagerService activityManagerService) { 2033 mActivityManagerService = activityManagerService; 2034 } 2035 2036 @Override 2037 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2038 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2039 != PackageManager.PERMISSION_GRANTED) { 2040 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2041 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2042 + " without permission " + android.Manifest.permission.DUMP); 2043 return; 2044 } 2045 2046 synchronized (mActivityManagerService.mProcessCpuTracker) { 2047 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2048 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2049 SystemClock.uptimeMillis())); 2050 } 2051 } 2052 } 2053 2054 public static final class Lifecycle extends SystemService { 2055 private final ActivityManagerService mService; 2056 2057 public Lifecycle(Context context) { 2058 super(context); 2059 mService = new ActivityManagerService(context); 2060 } 2061 2062 @Override 2063 public void onStart() { 2064 mService.start(); 2065 } 2066 2067 public ActivityManagerService getService() { 2068 return mService; 2069 } 2070 } 2071 2072 // Note: This method is invoked on the main thread but may need to attach various 2073 // handlers to other threads. So take care to be explicit about the looper. 2074 public ActivityManagerService(Context systemContext) { 2075 mContext = systemContext; 2076 mFactoryTest = FactoryTest.getMode(); 2077 mSystemThread = ActivityThread.currentActivityThread(); 2078 2079 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2080 2081 mHandlerThread = new ServiceThread(TAG, 2082 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2083 mHandlerThread.start(); 2084 mHandler = new MainHandler(mHandlerThread.getLooper()); 2085 2086 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2087 "foreground", BROADCAST_FG_TIMEOUT, false); 2088 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2089 "background", BROADCAST_BG_TIMEOUT, true); 2090 mBroadcastQueues[0] = mFgBroadcastQueue; 2091 mBroadcastQueues[1] = mBgBroadcastQueue; 2092 2093 mServices = new ActiveServices(this); 2094 mProviderMap = new ProviderMap(this); 2095 2096 // TODO: Move creation of battery stats service outside of activity manager service. 2097 File dataDir = Environment.getDataDirectory(); 2098 File systemDir = new File(dataDir, "system"); 2099 systemDir.mkdirs(); 2100 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2101 mBatteryStatsService.getActiveStatistics().readLocked(); 2102 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2103 mOnBattery = DEBUG_POWER ? true 2104 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2105 mBatteryStatsService.getActiveStatistics().setCallback(this); 2106 2107 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2108 2109 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2110 2111 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2112 2113 // User 0 is the first and only user that runs at boot. 2114 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2115 mUserLru.add(Integer.valueOf(0)); 2116 updateStartedUserArrayLocked(); 2117 2118 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2119 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2120 2121 mConfiguration.setToDefaults(); 2122 mConfiguration.setLocale(Locale.getDefault()); 2123 2124 mConfigurationSeq = mConfiguration.seq = 1; 2125 mProcessCpuTracker.init(); 2126 2127 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2128 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2129 mStackSupervisor = new ActivityStackSupervisor(this); 2130 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2131 2132 mProcessCpuThread = new Thread("CpuTracker") { 2133 @Override 2134 public void run() { 2135 while (true) { 2136 try { 2137 try { 2138 synchronized(this) { 2139 final long now = SystemClock.uptimeMillis(); 2140 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2141 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2142 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2143 // + ", write delay=" + nextWriteDelay); 2144 if (nextWriteDelay < nextCpuDelay) { 2145 nextCpuDelay = nextWriteDelay; 2146 } 2147 if (nextCpuDelay > 0) { 2148 mProcessCpuMutexFree.set(true); 2149 this.wait(nextCpuDelay); 2150 } 2151 } 2152 } catch (InterruptedException e) { 2153 } 2154 updateCpuStatsNow(); 2155 } catch (Exception e) { 2156 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2157 } 2158 } 2159 } 2160 }; 2161 2162 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2163 2164 Watchdog.getInstance().addMonitor(this); 2165 Watchdog.getInstance().addThread(mHandler); 2166 } 2167 2168 public void setSystemServiceManager(SystemServiceManager mgr) { 2169 mSystemServiceManager = mgr; 2170 } 2171 2172 private void start() { 2173 Process.removeAllProcessGroups(); 2174 mProcessCpuThread.start(); 2175 2176 mBatteryStatsService.publish(mContext); 2177 mAppOpsService.publish(mContext); 2178 Slog.d("AppOps", "AppOpsService published"); 2179 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2180 } 2181 2182 public void initPowerManagement() { 2183 mStackSupervisor.initPowerManagement(); 2184 mBatteryStatsService.initPowerManagement(); 2185 } 2186 2187 @Override 2188 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2189 throws RemoteException { 2190 if (code == SYSPROPS_TRANSACTION) { 2191 // We need to tell all apps about the system property change. 2192 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2193 synchronized(this) { 2194 final int NP = mProcessNames.getMap().size(); 2195 for (int ip=0; ip<NP; ip++) { 2196 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2197 final int NA = apps.size(); 2198 for (int ia=0; ia<NA; ia++) { 2199 ProcessRecord app = apps.valueAt(ia); 2200 if (app.thread != null) { 2201 procs.add(app.thread.asBinder()); 2202 } 2203 } 2204 } 2205 } 2206 2207 int N = procs.size(); 2208 for (int i=0; i<N; i++) { 2209 Parcel data2 = Parcel.obtain(); 2210 try { 2211 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2212 } catch (RemoteException e) { 2213 } 2214 data2.recycle(); 2215 } 2216 } 2217 try { 2218 return super.onTransact(code, data, reply, flags); 2219 } catch (RuntimeException e) { 2220 // The activity manager only throws security exceptions, so let's 2221 // log all others. 2222 if (!(e instanceof SecurityException)) { 2223 Slog.wtf(TAG, "Activity Manager Crash", e); 2224 } 2225 throw e; 2226 } 2227 } 2228 2229 void updateCpuStats() { 2230 final long now = SystemClock.uptimeMillis(); 2231 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2232 return; 2233 } 2234 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2235 synchronized (mProcessCpuThread) { 2236 mProcessCpuThread.notify(); 2237 } 2238 } 2239 } 2240 2241 void updateCpuStatsNow() { 2242 synchronized (mProcessCpuTracker) { 2243 mProcessCpuMutexFree.set(false); 2244 final long now = SystemClock.uptimeMillis(); 2245 boolean haveNewCpuStats = false; 2246 2247 if (MONITOR_CPU_USAGE && 2248 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2249 mLastCpuTime.set(now); 2250 haveNewCpuStats = true; 2251 mProcessCpuTracker.update(); 2252 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2253 //Slog.i(TAG, "Total CPU usage: " 2254 // + mProcessCpu.getTotalCpuPercent() + "%"); 2255 2256 // Slog the cpu usage if the property is set. 2257 if ("true".equals(SystemProperties.get("events.cpu"))) { 2258 int user = mProcessCpuTracker.getLastUserTime(); 2259 int system = mProcessCpuTracker.getLastSystemTime(); 2260 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2261 int irq = mProcessCpuTracker.getLastIrqTime(); 2262 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2263 int idle = mProcessCpuTracker.getLastIdleTime(); 2264 2265 int total = user + system + iowait + irq + softIrq + idle; 2266 if (total == 0) total = 1; 2267 2268 EventLog.writeEvent(EventLogTags.CPU, 2269 ((user+system+iowait+irq+softIrq) * 100) / total, 2270 (user * 100) / total, 2271 (system * 100) / total, 2272 (iowait * 100) / total, 2273 (irq * 100) / total, 2274 (softIrq * 100) / total); 2275 } 2276 } 2277 2278 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2279 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2280 synchronized(bstats) { 2281 synchronized(mPidsSelfLocked) { 2282 if (haveNewCpuStats) { 2283 if (mOnBattery) { 2284 int perc = bstats.startAddingCpuLocked(); 2285 int totalUTime = 0; 2286 int totalSTime = 0; 2287 final int N = mProcessCpuTracker.countStats(); 2288 for (int i=0; i<N; i++) { 2289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2290 if (!st.working) { 2291 continue; 2292 } 2293 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2294 int otherUTime = (st.rel_utime*perc)/100; 2295 int otherSTime = (st.rel_stime*perc)/100; 2296 totalUTime += otherUTime; 2297 totalSTime += otherSTime; 2298 if (pr != null) { 2299 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2300 if (ps == null || !ps.isActive()) { 2301 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2302 pr.info.uid, pr.processName); 2303 } 2304 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2305 st.rel_stime-otherSTime); 2306 ps.addSpeedStepTimes(cpuSpeedTimes); 2307 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2308 } else { 2309 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2310 if (ps == null || !ps.isActive()) { 2311 st.batteryStats = ps = bstats.getProcessStatsLocked( 2312 bstats.mapUid(st.uid), st.name); 2313 } 2314 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2315 st.rel_stime-otherSTime); 2316 ps.addSpeedStepTimes(cpuSpeedTimes); 2317 } 2318 } 2319 bstats.finishAddingCpuLocked(perc, totalUTime, 2320 totalSTime, cpuSpeedTimes); 2321 } 2322 } 2323 } 2324 2325 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2326 mLastWriteTime = now; 2327 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2328 } 2329 } 2330 } 2331 } 2332 2333 @Override 2334 public void batteryNeedsCpuUpdate() { 2335 updateCpuStatsNow(); 2336 } 2337 2338 @Override 2339 public void batteryPowerChanged(boolean onBattery) { 2340 // When plugging in, update the CPU stats first before changing 2341 // the plug state. 2342 updateCpuStatsNow(); 2343 synchronized (this) { 2344 synchronized(mPidsSelfLocked) { 2345 mOnBattery = DEBUG_POWER ? true : onBattery; 2346 } 2347 } 2348 } 2349 2350 /** 2351 * Initialize the application bind args. These are passed to each 2352 * process when the bindApplication() IPC is sent to the process. They're 2353 * lazily setup to make sure the services are running when they're asked for. 2354 */ 2355 private HashMap<String, IBinder> getCommonServicesLocked() { 2356 if (mAppBindArgs == null) { 2357 mAppBindArgs = new HashMap<String, IBinder>(); 2358 2359 // Setup the application init args 2360 mAppBindArgs.put("package", ServiceManager.getService("package")); 2361 mAppBindArgs.put("window", ServiceManager.getService("window")); 2362 mAppBindArgs.put(Context.ALARM_SERVICE, 2363 ServiceManager.getService(Context.ALARM_SERVICE)); 2364 } 2365 return mAppBindArgs; 2366 } 2367 2368 final void setFocusedActivityLocked(ActivityRecord r) { 2369 if (mFocusedActivity != r) { 2370 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2371 mFocusedActivity = r; 2372 if (r.task != null && r.task.voiceInteractor != null) { 2373 startRunningVoiceLocked(); 2374 } else { 2375 finishRunningVoiceLocked(); 2376 } 2377 mStackSupervisor.setFocusedStack(r); 2378 if (r != null) { 2379 mWindowManager.setFocusedApp(r.appToken, true); 2380 } 2381 applyUpdateLockStateLocked(r); 2382 } 2383 } 2384 2385 final void clearFocusedActivity(ActivityRecord r) { 2386 if (mFocusedActivity == r) { 2387 mFocusedActivity = null; 2388 } 2389 } 2390 2391 @Override 2392 public void setFocusedStack(int stackId) { 2393 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2394 synchronized (ActivityManagerService.this) { 2395 ActivityStack stack = mStackSupervisor.getStack(stackId); 2396 if (stack != null) { 2397 ActivityRecord r = stack.topRunningActivityLocked(null); 2398 if (r != null) { 2399 setFocusedActivityLocked(r); 2400 } 2401 } 2402 } 2403 } 2404 2405 @Override 2406 public void notifyActivityDrawn(IBinder token) { 2407 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2408 synchronized (this) { 2409 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2410 if (r != null) { 2411 r.task.stack.notifyActivityDrawnLocked(r); 2412 } 2413 } 2414 } 2415 2416 final void applyUpdateLockStateLocked(ActivityRecord r) { 2417 // Modifications to the UpdateLock state are done on our handler, outside 2418 // the activity manager's locks. The new state is determined based on the 2419 // state *now* of the relevant activity record. The object is passed to 2420 // the handler solely for logging detail, not to be consulted/modified. 2421 final boolean nextState = r != null && r.immersive; 2422 mHandler.sendMessage( 2423 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2424 } 2425 2426 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2427 Message msg = Message.obtain(); 2428 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2429 msg.obj = r.task.askedCompatMode ? null : r; 2430 mHandler.sendMessage(msg); 2431 } 2432 2433 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2434 String what, Object obj, ProcessRecord srcApp) { 2435 app.lastActivityTime = now; 2436 2437 if (app.activities.size() > 0) { 2438 // Don't want to touch dependent processes that are hosting activities. 2439 return index; 2440 } 2441 2442 int lrui = mLruProcesses.lastIndexOf(app); 2443 if (lrui < 0) { 2444 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2445 + what + " " + obj + " from " + srcApp); 2446 return index; 2447 } 2448 2449 if (lrui >= index) { 2450 // Don't want to cause this to move dependent processes *back* in the 2451 // list as if they were less frequently used. 2452 return index; 2453 } 2454 2455 if (lrui >= mLruProcessActivityStart) { 2456 // Don't want to touch dependent processes that are hosting activities. 2457 return index; 2458 } 2459 2460 mLruProcesses.remove(lrui); 2461 if (index > 0) { 2462 index--; 2463 } 2464 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2465 + " in LRU list: " + app); 2466 mLruProcesses.add(index, app); 2467 return index; 2468 } 2469 2470 final void removeLruProcessLocked(ProcessRecord app) { 2471 int lrui = mLruProcesses.lastIndexOf(app); 2472 if (lrui >= 0) { 2473 if (!app.killed) { 2474 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2475 Process.killProcessQuiet(app.pid); 2476 Process.killProcessGroup(app.info.uid, app.pid); 2477 } 2478 if (lrui <= mLruProcessActivityStart) { 2479 mLruProcessActivityStart--; 2480 } 2481 if (lrui <= mLruProcessServiceStart) { 2482 mLruProcessServiceStart--; 2483 } 2484 mLruProcesses.remove(lrui); 2485 } 2486 } 2487 2488 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2489 ProcessRecord client) { 2490 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2491 || app.treatLikeActivity; 2492 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2493 if (!activityChange && hasActivity) { 2494 // The process has activities, so we are only allowing activity-based adjustments 2495 // to move it. It should be kept in the front of the list with other 2496 // processes that have activities, and we don't want those to change their 2497 // order except due to activity operations. 2498 return; 2499 } 2500 2501 mLruSeq++; 2502 final long now = SystemClock.uptimeMillis(); 2503 app.lastActivityTime = now; 2504 2505 // First a quick reject: if the app is already at the position we will 2506 // put it, then there is nothing to do. 2507 if (hasActivity) { 2508 final int N = mLruProcesses.size(); 2509 if (N > 0 && mLruProcesses.get(N-1) == app) { 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2511 return; 2512 } 2513 } else { 2514 if (mLruProcessServiceStart > 0 2515 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2516 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2517 return; 2518 } 2519 } 2520 2521 int lrui = mLruProcesses.lastIndexOf(app); 2522 2523 if (app.persistent && lrui >= 0) { 2524 // We don't care about the position of persistent processes, as long as 2525 // they are in the list. 2526 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2527 return; 2528 } 2529 2530 /* In progress: compute new position first, so we can avoid doing work 2531 if the process is not actually going to move. Not yet working. 2532 int addIndex; 2533 int nextIndex; 2534 boolean inActivity = false, inService = false; 2535 if (hasActivity) { 2536 // Process has activities, put it at the very tipsy-top. 2537 addIndex = mLruProcesses.size(); 2538 nextIndex = mLruProcessServiceStart; 2539 inActivity = true; 2540 } else if (hasService) { 2541 // Process has services, put it at the top of the service list. 2542 addIndex = mLruProcessActivityStart; 2543 nextIndex = mLruProcessServiceStart; 2544 inActivity = true; 2545 inService = true; 2546 } else { 2547 // Process not otherwise of interest, it goes to the top of the non-service area. 2548 addIndex = mLruProcessServiceStart; 2549 if (client != null) { 2550 int clientIndex = mLruProcesses.lastIndexOf(client); 2551 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2552 + app); 2553 if (clientIndex >= 0 && addIndex > clientIndex) { 2554 addIndex = clientIndex; 2555 } 2556 } 2557 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2558 } 2559 2560 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2561 + mLruProcessActivityStart + "): " + app); 2562 */ 2563 2564 if (lrui >= 0) { 2565 if (lrui < mLruProcessActivityStart) { 2566 mLruProcessActivityStart--; 2567 } 2568 if (lrui < mLruProcessServiceStart) { 2569 mLruProcessServiceStart--; 2570 } 2571 /* 2572 if (addIndex > lrui) { 2573 addIndex--; 2574 } 2575 if (nextIndex > lrui) { 2576 nextIndex--; 2577 } 2578 */ 2579 mLruProcesses.remove(lrui); 2580 } 2581 2582 /* 2583 mLruProcesses.add(addIndex, app); 2584 if (inActivity) { 2585 mLruProcessActivityStart++; 2586 } 2587 if (inService) { 2588 mLruProcessActivityStart++; 2589 } 2590 */ 2591 2592 int nextIndex; 2593 if (hasActivity) { 2594 final int N = mLruProcesses.size(); 2595 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2596 // Process doesn't have activities, but has clients with 2597 // activities... move it up, but one below the top (the top 2598 // should always have a real activity). 2599 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2600 mLruProcesses.add(N-1, app); 2601 // To keep it from spamming the LRU list (by making a bunch of clients), 2602 // we will push down any other entries owned by the app. 2603 final int uid = app.info.uid; 2604 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2605 ProcessRecord subProc = mLruProcesses.get(i); 2606 if (subProc.info.uid == uid) { 2607 // We want to push this one down the list. If the process after 2608 // it is for the same uid, however, don't do so, because we don't 2609 // want them internally to be re-ordered. 2610 if (mLruProcesses.get(i-1).info.uid != uid) { 2611 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2612 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2613 ProcessRecord tmp = mLruProcesses.get(i); 2614 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2615 mLruProcesses.set(i-1, tmp); 2616 i--; 2617 } 2618 } else { 2619 // A gap, we can stop here. 2620 break; 2621 } 2622 } 2623 } else { 2624 // Process has activities, put it at the very tipsy-top. 2625 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2626 mLruProcesses.add(app); 2627 } 2628 nextIndex = mLruProcessServiceStart; 2629 } else if (hasService) { 2630 // Process has services, put it at the top of the service list. 2631 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2632 mLruProcesses.add(mLruProcessActivityStart, app); 2633 nextIndex = mLruProcessServiceStart; 2634 mLruProcessActivityStart++; 2635 } else { 2636 // Process not otherwise of interest, it goes to the top of the non-service area. 2637 int index = mLruProcessServiceStart; 2638 if (client != null) { 2639 // If there is a client, don't allow the process to be moved up higher 2640 // in the list than that client. 2641 int clientIndex = mLruProcesses.lastIndexOf(client); 2642 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2643 + " when updating " + app); 2644 if (clientIndex <= lrui) { 2645 // Don't allow the client index restriction to push it down farther in the 2646 // list than it already is. 2647 clientIndex = lrui; 2648 } 2649 if (clientIndex >= 0 && index > clientIndex) { 2650 index = clientIndex; 2651 } 2652 } 2653 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2654 mLruProcesses.add(index, app); 2655 nextIndex = index-1; 2656 mLruProcessActivityStart++; 2657 mLruProcessServiceStart++; 2658 } 2659 2660 // If the app is currently using a content provider or service, 2661 // bump those processes as well. 2662 for (int j=app.connections.size()-1; j>=0; j--) { 2663 ConnectionRecord cr = app.connections.valueAt(j); 2664 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2665 && cr.binding.service.app != null 2666 && cr.binding.service.app.lruSeq != mLruSeq 2667 && !cr.binding.service.app.persistent) { 2668 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2669 "service connection", cr, app); 2670 } 2671 } 2672 for (int j=app.conProviders.size()-1; j>=0; j--) { 2673 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2674 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2675 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2676 "provider reference", cpr, app); 2677 } 2678 } 2679 } 2680 2681 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2682 if (uid == Process.SYSTEM_UID) { 2683 // The system gets to run in any process. If there are multiple 2684 // processes with the same uid, just pick the first (this 2685 // should never happen). 2686 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2687 if (procs == null) return null; 2688 final int N = procs.size(); 2689 for (int i = 0; i < N; i++) { 2690 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2691 } 2692 } 2693 ProcessRecord proc = mProcessNames.get(processName, uid); 2694 if (false && proc != null && !keepIfLarge 2695 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2696 && proc.lastCachedPss >= 4000) { 2697 // Turn this condition on to cause killing to happen regularly, for testing. 2698 if (proc.baseProcessTracker != null) { 2699 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2700 } 2701 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2702 } else if (proc != null && !keepIfLarge 2703 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2704 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2705 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2706 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2707 if (proc.baseProcessTracker != null) { 2708 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2709 } 2710 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2711 } 2712 } 2713 return proc; 2714 } 2715 2716 void ensurePackageDexOpt(String packageName) { 2717 IPackageManager pm = AppGlobals.getPackageManager(); 2718 try { 2719 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2720 mDidDexOpt = true; 2721 } 2722 } catch (RemoteException e) { 2723 } 2724 } 2725 2726 boolean isNextTransitionForward() { 2727 int transit = mWindowManager.getPendingAppTransition(); 2728 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2729 || transit == AppTransition.TRANSIT_TASK_OPEN 2730 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2731 } 2732 2733 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2734 String processName, String abiOverride, int uid, Runnable crashHandler) { 2735 synchronized(this) { 2736 ApplicationInfo info = new ApplicationInfo(); 2737 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2738 // For isolated processes, the former contains the parent's uid and the latter the 2739 // actual uid of the isolated process. 2740 // In the special case introduced by this method (which is, starting an isolated 2741 // process directly from the SystemServer without an actual parent app process) the 2742 // closest thing to a parent's uid is SYSTEM_UID. 2743 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2744 // the |isolated| logic in the ProcessRecord constructor. 2745 info.uid = Process.SYSTEM_UID; 2746 info.processName = processName; 2747 info.className = entryPoint; 2748 info.packageName = "android"; 2749 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2750 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2751 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2752 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2753 crashHandler); 2754 return proc != null ? proc.pid : 0; 2755 } 2756 } 2757 2758 final ProcessRecord startProcessLocked(String processName, 2759 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2760 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2761 boolean isolated, boolean keepIfLarge) { 2762 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2763 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2764 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2765 null /* crashHandler */); 2766 } 2767 2768 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2769 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2770 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2771 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2772 long startTime = SystemClock.elapsedRealtime(); 2773 ProcessRecord app; 2774 if (!isolated) { 2775 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2776 checkTime(startTime, "startProcess: after getProcessRecord"); 2777 } else { 2778 // If this is an isolated process, it can't re-use an existing process. 2779 app = null; 2780 } 2781 // We don't have to do anything more if: 2782 // (1) There is an existing application record; and 2783 // (2) The caller doesn't think it is dead, OR there is no thread 2784 // object attached to it so we know it couldn't have crashed; and 2785 // (3) There is a pid assigned to it, so it is either starting or 2786 // already running. 2787 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2788 + " app=" + app + " knownToBeDead=" + knownToBeDead 2789 + " thread=" + (app != null ? app.thread : null) 2790 + " pid=" + (app != null ? app.pid : -1)); 2791 if (app != null && app.pid > 0) { 2792 if (!knownToBeDead || app.thread == null) { 2793 // We already have the app running, or are waiting for it to 2794 // come up (we have a pid but not yet its thread), so keep it. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2796 // If this is a new package in the process, add the package to the list 2797 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2798 checkTime(startTime, "startProcess: done, added package to proc"); 2799 return app; 2800 } 2801 2802 // An application record is attached to a previous process, 2803 // clean it up now. 2804 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2805 checkTime(startTime, "startProcess: bad proc running, killing"); 2806 Process.killProcessGroup(app.info.uid, app.pid); 2807 handleAppDiedLocked(app, true, true); 2808 checkTime(startTime, "startProcess: done killing old proc"); 2809 } 2810 2811 String hostingNameStr = hostingName != null 2812 ? hostingName.flattenToShortString() : null; 2813 2814 if (!isolated) { 2815 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2816 // If we are in the background, then check to see if this process 2817 // is bad. If so, we will just silently fail. 2818 if (mBadProcesses.get(info.processName, info.uid) != null) { 2819 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2820 + "/" + info.processName); 2821 return null; 2822 } 2823 } else { 2824 // When the user is explicitly starting a process, then clear its 2825 // crash count so that we won't make it bad until they see at 2826 // least one crash dialog again, and make the process good again 2827 // if it had been bad. 2828 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2829 + "/" + info.processName); 2830 mProcessCrashTimes.remove(info.processName, info.uid); 2831 if (mBadProcesses.get(info.processName, info.uid) != null) { 2832 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2833 UserHandle.getUserId(info.uid), info.uid, 2834 info.processName); 2835 mBadProcesses.remove(info.processName, info.uid); 2836 if (app != null) { 2837 app.bad = false; 2838 } 2839 } 2840 } 2841 } 2842 2843 if (app == null) { 2844 checkTime(startTime, "startProcess: creating new process record"); 2845 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2846 app.crashHandler = crashHandler; 2847 if (app == null) { 2848 Slog.w(TAG, "Failed making new process record for " 2849 + processName + "/" + info.uid + " isolated=" + isolated); 2850 return null; 2851 } 2852 mProcessNames.put(processName, app.uid, app); 2853 if (isolated) { 2854 mIsolatedProcesses.put(app.uid, app); 2855 } 2856 checkTime(startTime, "startProcess: done creating new process record"); 2857 } else { 2858 // If this is a new package in the process, add the package to the list 2859 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2860 checkTime(startTime, "startProcess: added package to existing proc"); 2861 } 2862 2863 // If the system is not ready yet, then hold off on starting this 2864 // process until it is. 2865 if (!mProcessesReady 2866 && !isAllowedWhileBooting(info) 2867 && !allowWhileBooting) { 2868 if (!mProcessesOnHold.contains(app)) { 2869 mProcessesOnHold.add(app); 2870 } 2871 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2872 checkTime(startTime, "startProcess: returning with proc on hold"); 2873 return app; 2874 } 2875 2876 checkTime(startTime, "startProcess: stepping in to startProcess"); 2877 startProcessLocked( 2878 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2879 checkTime(startTime, "startProcess: done starting proc!"); 2880 return (app.pid != 0) ? app : null; 2881 } 2882 2883 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2884 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2885 } 2886 2887 private final void startProcessLocked(ProcessRecord app, 2888 String hostingType, String hostingNameStr) { 2889 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2890 null /* entryPoint */, null /* entryPointArgs */); 2891 } 2892 2893 private final void startProcessLocked(ProcessRecord app, String hostingType, 2894 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2895 long startTime = SystemClock.elapsedRealtime(); 2896 if (app.pid > 0 && app.pid != MY_PID) { 2897 checkTime(startTime, "startProcess: removing from pids map"); 2898 synchronized (mPidsSelfLocked) { 2899 mPidsSelfLocked.remove(app.pid); 2900 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2901 } 2902 checkTime(startTime, "startProcess: done removing from pids map"); 2903 app.setPid(0); 2904 } 2905 2906 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2907 "startProcessLocked removing on hold: " + app); 2908 mProcessesOnHold.remove(app); 2909 2910 checkTime(startTime, "startProcess: starting to update cpu stats"); 2911 updateCpuStats(); 2912 checkTime(startTime, "startProcess: done updating cpu stats"); 2913 2914 try { 2915 int uid = app.uid; 2916 2917 int[] gids = null; 2918 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2919 if (!app.isolated) { 2920 int[] permGids = null; 2921 try { 2922 checkTime(startTime, "startProcess: getting gids from package manager"); 2923 final PackageManager pm = mContext.getPackageManager(); 2924 permGids = pm.getPackageGids(app.info.packageName); 2925 2926 if (Environment.isExternalStorageEmulated()) { 2927 checkTime(startTime, "startProcess: checking external storage perm"); 2928 if (pm.checkPermission( 2929 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2930 app.info.packageName) == PERMISSION_GRANTED) { 2931 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2932 } else { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2934 } 2935 } 2936 } catch (PackageManager.NameNotFoundException e) { 2937 Slog.w(TAG, "Unable to retrieve gids", e); 2938 } 2939 2940 /* 2941 * Add shared application and profile GIDs so applications can share some 2942 * resources like shared libraries and access user-wide resources 2943 */ 2944 if (permGids == null) { 2945 gids = new int[2]; 2946 } else { 2947 gids = new int[permGids.length + 2]; 2948 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2949 } 2950 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2951 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2952 } 2953 checkTime(startTime, "startProcess: building args"); 2954 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2955 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2956 && mTopComponent != null 2957 && app.processName.equals(mTopComponent.getPackageName())) { 2958 uid = 0; 2959 } 2960 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2961 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2962 uid = 0; 2963 } 2964 } 2965 int debugFlags = 0; 2966 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2967 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2968 // Also turn on CheckJNI for debuggable apps. It's quite 2969 // awkward to turn on otherwise. 2970 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2971 } 2972 // Run the app in safe mode if its manifest requests so or the 2973 // system is booted in safe mode. 2974 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2975 mSafeMode == true) { 2976 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2977 } 2978 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.assert"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2986 } 2987 2988 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2989 if (requiredAbi == null) { 2990 requiredAbi = Build.SUPPORTED_ABIS[0]; 2991 } 2992 2993 String instructionSet = null; 2994 if (app.info.primaryCpuAbi != null) { 2995 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2996 } 2997 2998 // Start the process. It will either succeed and return a result containing 2999 // the PID of the new process, or else throw a RuntimeException. 3000 boolean isActivityProcess = (entryPoint == null); 3001 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3002 checkTime(startTime, "startProcess: asking zygote to start proc"); 3003 Process.ProcessStartResult startResult = Process.start(entryPoint, 3004 app.processName, uid, uid, gids, debugFlags, mountExternal, 3005 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3006 app.info.dataDir, entryPointArgs); 3007 checkTime(startTime, "startProcess: returned from zygote!"); 3008 3009 if (app.isolated) { 3010 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3011 } 3012 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3013 checkTime(startTime, "startProcess: done updating battery stats"); 3014 3015 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3016 UserHandle.getUserId(uid), startResult.pid, uid, 3017 app.processName, hostingType, 3018 hostingNameStr != null ? hostingNameStr : ""); 3019 3020 if (app.persistent) { 3021 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3022 } 3023 3024 checkTime(startTime, "startProcess: building log message"); 3025 StringBuilder buf = mStringBuilder; 3026 buf.setLength(0); 3027 buf.append("Start proc "); 3028 buf.append(app.processName); 3029 if (!isActivityProcess) { 3030 buf.append(" ["); 3031 buf.append(entryPoint); 3032 buf.append("]"); 3033 } 3034 buf.append(" for "); 3035 buf.append(hostingType); 3036 if (hostingNameStr != null) { 3037 buf.append(" "); 3038 buf.append(hostingNameStr); 3039 } 3040 buf.append(": pid="); 3041 buf.append(startResult.pid); 3042 buf.append(" uid="); 3043 buf.append(uid); 3044 buf.append(" gids={"); 3045 if (gids != null) { 3046 for (int gi=0; gi<gids.length; gi++) { 3047 if (gi != 0) buf.append(", "); 3048 buf.append(gids[gi]); 3049 3050 } 3051 } 3052 buf.append("}"); 3053 if (requiredAbi != null) { 3054 buf.append(" abi="); 3055 buf.append(requiredAbi); 3056 } 3057 Slog.i(TAG, buf.toString()); 3058 app.setPid(startResult.pid); 3059 app.usingWrapper = startResult.usingWrapper; 3060 app.removed = false; 3061 app.killed = false; 3062 app.killedByAm = false; 3063 checkTime(startTime, "startProcess: starting to update pids map"); 3064 synchronized (mPidsSelfLocked) { 3065 this.mPidsSelfLocked.put(startResult.pid, app); 3066 if (isActivityProcess) { 3067 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3068 msg.obj = app; 3069 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3070 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3071 } 3072 } 3073 checkTime(startTime, "startProcess: done updating pids map"); 3074 } catch (RuntimeException e) { 3075 // XXX do better error recovery. 3076 app.setPid(0); 3077 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3078 if (app.isolated) { 3079 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3080 } 3081 Slog.e(TAG, "Failure starting process " + app.processName, e); 3082 } 3083 } 3084 3085 void updateUsageStats(ActivityRecord component, boolean resumed) { 3086 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3087 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3088 if (resumed) { 3089 if (mUsageStatsService != null) { 3090 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3091 UsageEvents.Event.MOVE_TO_FOREGROUND); 3092 } 3093 synchronized (stats) { 3094 stats.noteActivityResumedLocked(component.app.uid); 3095 } 3096 } else { 3097 if (mUsageStatsService != null) { 3098 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3099 UsageEvents.Event.MOVE_TO_BACKGROUND); 3100 } 3101 synchronized (stats) { 3102 stats.noteActivityPausedLocked(component.app.uid); 3103 } 3104 } 3105 } 3106 3107 Intent getHomeIntent() { 3108 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3109 intent.setComponent(mTopComponent); 3110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3111 intent.addCategory(Intent.CATEGORY_HOME); 3112 } 3113 return intent; 3114 } 3115 3116 boolean startHomeActivityLocked(int userId) { 3117 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3118 && mTopAction == null) { 3119 // We are running in factory test mode, but unable to find 3120 // the factory test app, so just sit around displaying the 3121 // error message and don't try to start anything. 3122 return false; 3123 } 3124 Intent intent = getHomeIntent(); 3125 ActivityInfo aInfo = 3126 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3127 if (aInfo != null) { 3128 intent.setComponent(new ComponentName( 3129 aInfo.applicationInfo.packageName, aInfo.name)); 3130 // Don't do this if the home app is currently being 3131 // instrumented. 3132 aInfo = new ActivityInfo(aInfo); 3133 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3134 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3135 aInfo.applicationInfo.uid, true); 3136 if (app == null || app.instrumentationClass == null) { 3137 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3138 mStackSupervisor.startHomeActivity(intent, aInfo); 3139 } 3140 } 3141 3142 return true; 3143 } 3144 3145 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3146 ActivityInfo ai = null; 3147 ComponentName comp = intent.getComponent(); 3148 try { 3149 if (comp != null) { 3150 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3151 } else { 3152 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3153 intent, 3154 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3155 flags, userId); 3156 3157 if (info != null) { 3158 ai = info.activityInfo; 3159 } 3160 } 3161 } catch (RemoteException e) { 3162 // ignore 3163 } 3164 3165 return ai; 3166 } 3167 3168 /** 3169 * Starts the "new version setup screen" if appropriate. 3170 */ 3171 void startSetupActivityLocked() { 3172 // Only do this once per boot. 3173 if (mCheckedForSetup) { 3174 return; 3175 } 3176 3177 // We will show this screen if the current one is a different 3178 // version than the last one shown, and we are not running in 3179 // low-level factory test mode. 3180 final ContentResolver resolver = mContext.getContentResolver(); 3181 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3182 Settings.Global.getInt(resolver, 3183 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3184 mCheckedForSetup = true; 3185 3186 // See if we should be showing the platform update setup UI. 3187 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3188 List<ResolveInfo> ris = mContext.getPackageManager() 3189 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3190 3191 // We don't allow third party apps to replace this. 3192 ResolveInfo ri = null; 3193 for (int i=0; ris != null && i<ris.size(); i++) { 3194 if ((ris.get(i).activityInfo.applicationInfo.flags 3195 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3196 ri = ris.get(i); 3197 break; 3198 } 3199 } 3200 3201 if (ri != null) { 3202 String vers = ri.activityInfo.metaData != null 3203 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3204 : null; 3205 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3206 vers = ri.activityInfo.applicationInfo.metaData.getString( 3207 Intent.METADATA_SETUP_VERSION); 3208 } 3209 String lastVers = Settings.Secure.getString( 3210 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3211 if (vers != null && !vers.equals(lastVers)) { 3212 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3213 intent.setComponent(new ComponentName( 3214 ri.activityInfo.packageName, ri.activityInfo.name)); 3215 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3216 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3217 null); 3218 } 3219 } 3220 } 3221 } 3222 3223 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3224 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3225 } 3226 3227 void enforceNotIsolatedCaller(String caller) { 3228 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3229 throw new SecurityException("Isolated process not allowed to call " + caller); 3230 } 3231 } 3232 3233 void enforceShellRestriction(String restriction, int userHandle) { 3234 if (Binder.getCallingUid() == Process.SHELL_UID) { 3235 if (userHandle < 0 3236 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3237 throw new SecurityException("Shell does not have permission to access user " 3238 + userHandle); 3239 } 3240 } 3241 } 3242 3243 @Override 3244 public int getFrontActivityScreenCompatMode() { 3245 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3246 synchronized (this) { 3247 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3248 } 3249 } 3250 3251 @Override 3252 public void setFrontActivityScreenCompatMode(int mode) { 3253 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3254 "setFrontActivityScreenCompatMode"); 3255 synchronized (this) { 3256 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3257 } 3258 } 3259 3260 @Override 3261 public int getPackageScreenCompatMode(String packageName) { 3262 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3263 synchronized (this) { 3264 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3265 } 3266 } 3267 3268 @Override 3269 public void setPackageScreenCompatMode(String packageName, int mode) { 3270 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3271 "setPackageScreenCompatMode"); 3272 synchronized (this) { 3273 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3274 } 3275 } 3276 3277 @Override 3278 public boolean getPackageAskScreenCompat(String packageName) { 3279 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3280 synchronized (this) { 3281 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3282 } 3283 } 3284 3285 @Override 3286 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3287 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3288 "setPackageAskScreenCompat"); 3289 synchronized (this) { 3290 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3291 } 3292 } 3293 3294 private void dispatchProcessesChanged() { 3295 int N; 3296 synchronized (this) { 3297 N = mPendingProcessChanges.size(); 3298 if (mActiveProcessChanges.length < N) { 3299 mActiveProcessChanges = new ProcessChangeItem[N]; 3300 } 3301 mPendingProcessChanges.toArray(mActiveProcessChanges); 3302 mAvailProcessChanges.addAll(mPendingProcessChanges); 3303 mPendingProcessChanges.clear(); 3304 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3305 } 3306 3307 int i = mProcessObservers.beginBroadcast(); 3308 while (i > 0) { 3309 i--; 3310 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3311 if (observer != null) { 3312 try { 3313 for (int j=0; j<N; j++) { 3314 ProcessChangeItem item = mActiveProcessChanges[j]; 3315 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3316 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3317 + item.pid + " uid=" + item.uid + ": " 3318 + item.foregroundActivities); 3319 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3320 item.foregroundActivities); 3321 } 3322 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3324 + item.pid + " uid=" + item.uid + ": " + item.processState); 3325 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3326 } 3327 } 3328 } catch (RemoteException e) { 3329 } 3330 } 3331 } 3332 mProcessObservers.finishBroadcast(); 3333 } 3334 3335 private void dispatchProcessDied(int pid, int uid) { 3336 int i = mProcessObservers.beginBroadcast(); 3337 while (i > 0) { 3338 i--; 3339 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3340 if (observer != null) { 3341 try { 3342 observer.onProcessDied(pid, uid); 3343 } catch (RemoteException e) { 3344 } 3345 } 3346 } 3347 mProcessObservers.finishBroadcast(); 3348 } 3349 3350 @Override 3351 public final int startActivity(IApplicationThread caller, String callingPackage, 3352 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3353 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3354 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3355 resultWho, requestCode, startFlags, profilerInfo, options, 3356 UserHandle.getCallingUserId()); 3357 } 3358 3359 @Override 3360 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3361 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3362 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3363 enforceNotIsolatedCaller("startActivity"); 3364 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3365 false, ALLOW_FULL_ONLY, "startActivity", null); 3366 // TODO: Switch to user app stacks here. 3367 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3368 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3369 profilerInfo, null, null, options, userId, null, null); 3370 } 3371 3372 @Override 3373 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3374 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3375 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3376 3377 // This is very dangerous -- it allows you to perform a start activity (including 3378 // permission grants) as any app that may launch one of your own activities. So 3379 // we will only allow this to be done from activities that are part of the core framework, 3380 // and then only when they are running as the system. 3381 final ActivityRecord sourceRecord; 3382 final int targetUid; 3383 final String targetPackage; 3384 synchronized (this) { 3385 if (resultTo == null) { 3386 throw new SecurityException("Must be called from an activity"); 3387 } 3388 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3389 if (sourceRecord == null) { 3390 throw new SecurityException("Called with bad activity token: " + resultTo); 3391 } 3392 if (!sourceRecord.info.packageName.equals("android")) { 3393 throw new SecurityException( 3394 "Must be called from an activity that is declared in the android package"); 3395 } 3396 if (sourceRecord.app == null) { 3397 throw new SecurityException("Called without a process attached to activity"); 3398 } 3399 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3400 // This is still okay, as long as this activity is running under the 3401 // uid of the original calling activity. 3402 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3403 throw new SecurityException( 3404 "Calling activity in uid " + sourceRecord.app.uid 3405 + " must be system uid or original calling uid " 3406 + sourceRecord.launchedFromUid); 3407 } 3408 } 3409 targetUid = sourceRecord.launchedFromUid; 3410 targetPackage = sourceRecord.launchedFromPackage; 3411 } 3412 3413 if (userId == UserHandle.USER_NULL) { 3414 userId = UserHandle.getUserId(sourceRecord.app.uid); 3415 } 3416 3417 // TODO: Switch to user app stacks here. 3418 try { 3419 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3420 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3421 null, null, options, userId, null, null); 3422 return ret; 3423 } catch (SecurityException e) { 3424 // XXX need to figure out how to propagate to original app. 3425 // A SecurityException here is generally actually a fault of the original 3426 // calling activity (such as a fairly granting permissions), so propagate it 3427 // back to them. 3428 /* 3429 StringBuilder msg = new StringBuilder(); 3430 msg.append("While launching"); 3431 msg.append(intent.toString()); 3432 msg.append(": "); 3433 msg.append(e.getMessage()); 3434 */ 3435 throw e; 3436 } 3437 } 3438 3439 @Override 3440 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3441 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3442 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3443 enforceNotIsolatedCaller("startActivityAndWait"); 3444 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3445 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3446 WaitResult res = new WaitResult(); 3447 // TODO: Switch to user app stacks here. 3448 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3449 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3450 options, userId, null, null); 3451 return res; 3452 } 3453 3454 @Override 3455 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3456 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3457 int startFlags, Configuration config, Bundle options, int userId) { 3458 enforceNotIsolatedCaller("startActivityWithConfig"); 3459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3460 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3461 // TODO: Switch to user app stacks here. 3462 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3463 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3464 null, null, config, options, userId, null, null); 3465 return ret; 3466 } 3467 3468 @Override 3469 public int startActivityIntentSender(IApplicationThread caller, 3470 IntentSender intent, Intent fillInIntent, String resolvedType, 3471 IBinder resultTo, String resultWho, int requestCode, 3472 int flagsMask, int flagsValues, Bundle options) { 3473 enforceNotIsolatedCaller("startActivityIntentSender"); 3474 // Refuse possible leaked file descriptors 3475 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3476 throw new IllegalArgumentException("File descriptors passed in Intent"); 3477 } 3478 3479 IIntentSender sender = intent.getTarget(); 3480 if (!(sender instanceof PendingIntentRecord)) { 3481 throw new IllegalArgumentException("Bad PendingIntent object"); 3482 } 3483 3484 PendingIntentRecord pir = (PendingIntentRecord)sender; 3485 3486 synchronized (this) { 3487 // If this is coming from the currently resumed activity, it is 3488 // effectively saying that app switches are allowed at this point. 3489 final ActivityStack stack = getFocusedStack(); 3490 if (stack.mResumedActivity != null && 3491 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3492 mAppSwitchesAllowedTime = 0; 3493 } 3494 } 3495 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3496 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3497 return ret; 3498 } 3499 3500 @Override 3501 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3502 Intent intent, String resolvedType, IVoiceInteractionSession session, 3503 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3504 Bundle options, int userId) { 3505 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3506 != PackageManager.PERMISSION_GRANTED) { 3507 String msg = "Permission Denial: startVoiceActivity() from pid=" 3508 + Binder.getCallingPid() 3509 + ", uid=" + Binder.getCallingUid() 3510 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3511 Slog.w(TAG, msg); 3512 throw new SecurityException(msg); 3513 } 3514 if (session == null || interactor == null) { 3515 throw new NullPointerException("null session or interactor"); 3516 } 3517 userId = handleIncomingUser(callingPid, callingUid, userId, 3518 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3519 // TODO: Switch to user app stacks here. 3520 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3521 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3522 null, options, userId, null, null); 3523 } 3524 3525 @Override 3526 public boolean startNextMatchingActivity(IBinder callingActivity, 3527 Intent intent, Bundle options) { 3528 // Refuse possible leaked file descriptors 3529 if (intent != null && intent.hasFileDescriptors() == true) { 3530 throw new IllegalArgumentException("File descriptors passed in Intent"); 3531 } 3532 3533 synchronized (this) { 3534 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3535 if (r == null) { 3536 ActivityOptions.abort(options); 3537 return false; 3538 } 3539 if (r.app == null || r.app.thread == null) { 3540 // The caller is not running... d'oh! 3541 ActivityOptions.abort(options); 3542 return false; 3543 } 3544 intent = new Intent(intent); 3545 // The caller is not allowed to change the data. 3546 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3547 // And we are resetting to find the next component... 3548 intent.setComponent(null); 3549 3550 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3551 3552 ActivityInfo aInfo = null; 3553 try { 3554 List<ResolveInfo> resolves = 3555 AppGlobals.getPackageManager().queryIntentActivities( 3556 intent, r.resolvedType, 3557 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3558 UserHandle.getCallingUserId()); 3559 3560 // Look for the original activity in the list... 3561 final int N = resolves != null ? resolves.size() : 0; 3562 for (int i=0; i<N; i++) { 3563 ResolveInfo rInfo = resolves.get(i); 3564 if (rInfo.activityInfo.packageName.equals(r.packageName) 3565 && rInfo.activityInfo.name.equals(r.info.name)) { 3566 // We found the current one... the next matching is 3567 // after it. 3568 i++; 3569 if (i<N) { 3570 aInfo = resolves.get(i).activityInfo; 3571 } 3572 if (debug) { 3573 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3574 + "/" + r.info.name); 3575 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3576 + "/" + aInfo.name); 3577 } 3578 break; 3579 } 3580 } 3581 } catch (RemoteException e) { 3582 } 3583 3584 if (aInfo == null) { 3585 // Nobody who is next! 3586 ActivityOptions.abort(options); 3587 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3588 return false; 3589 } 3590 3591 intent.setComponent(new ComponentName( 3592 aInfo.applicationInfo.packageName, aInfo.name)); 3593 intent.setFlags(intent.getFlags()&~( 3594 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3595 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3596 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3597 Intent.FLAG_ACTIVITY_NEW_TASK)); 3598 3599 // Okay now we need to start the new activity, replacing the 3600 // currently running activity. This is a little tricky because 3601 // we want to start the new one as if the current one is finished, 3602 // but not finish the current one first so that there is no flicker. 3603 // And thus... 3604 final boolean wasFinishing = r.finishing; 3605 r.finishing = true; 3606 3607 // Propagate reply information over to the new activity. 3608 final ActivityRecord resultTo = r.resultTo; 3609 final String resultWho = r.resultWho; 3610 final int requestCode = r.requestCode; 3611 r.resultTo = null; 3612 if (resultTo != null) { 3613 resultTo.removeResultsLocked(r, resultWho, requestCode); 3614 } 3615 3616 final long origId = Binder.clearCallingIdentity(); 3617 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3618 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3619 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3620 -1, r.launchedFromUid, 0, options, false, null, null, null); 3621 Binder.restoreCallingIdentity(origId); 3622 3623 r.finishing = wasFinishing; 3624 if (res != ActivityManager.START_SUCCESS) { 3625 return false; 3626 } 3627 return true; 3628 } 3629 } 3630 3631 @Override 3632 public final int startActivityFromRecents(int taskId, Bundle options) { 3633 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3634 String msg = "Permission Denial: startActivityFromRecents called without " + 3635 START_TASKS_FROM_RECENTS; 3636 Slog.w(TAG, msg); 3637 throw new SecurityException(msg); 3638 } 3639 return startActivityFromRecentsInner(taskId, options); 3640 } 3641 3642 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3643 final TaskRecord task; 3644 final int callingUid; 3645 final String callingPackage; 3646 final Intent intent; 3647 final int userId; 3648 synchronized (this) { 3649 task = recentTaskForIdLocked(taskId); 3650 if (task == null) { 3651 throw new IllegalArgumentException("Task " + taskId + " not found."); 3652 } 3653 callingUid = task.mCallingUid; 3654 callingPackage = task.mCallingPackage; 3655 intent = task.intent; 3656 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3657 userId = task.userId; 3658 } 3659 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3660 options, userId, null, task); 3661 } 3662 3663 final int startActivityInPackage(int uid, String callingPackage, 3664 Intent intent, String resolvedType, IBinder resultTo, 3665 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3666 IActivityContainer container, TaskRecord inTask) { 3667 3668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3669 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3670 3671 // TODO: Switch to user app stacks here. 3672 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3673 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3674 null, null, null, options, userId, container, inTask); 3675 return ret; 3676 } 3677 3678 @Override 3679 public final int startActivities(IApplicationThread caller, String callingPackage, 3680 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3681 int userId) { 3682 enforceNotIsolatedCaller("startActivities"); 3683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3684 false, ALLOW_FULL_ONLY, "startActivity", null); 3685 // TODO: Switch to user app stacks here. 3686 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3687 resolvedTypes, resultTo, options, userId); 3688 return ret; 3689 } 3690 3691 final int startActivitiesInPackage(int uid, String callingPackage, 3692 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3693 Bundle options, int userId) { 3694 3695 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3696 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3697 // TODO: Switch to user app stacks here. 3698 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3699 resultTo, options, userId); 3700 return ret; 3701 } 3702 3703 //explicitly remove thd old information in mRecentTasks when removing existing user. 3704 private void removeRecentTasksForUserLocked(int userId) { 3705 if(userId <= 0) { 3706 Slog.i(TAG, "Can't remove recent task on user " + userId); 3707 return; 3708 } 3709 3710 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3711 TaskRecord tr = mRecentTasks.get(i); 3712 if (tr.userId == userId) { 3713 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3714 + " when finishing user" + userId); 3715 mRecentTasks.remove(i); 3716 tr.removedFromRecents(mTaskPersister); 3717 } 3718 } 3719 3720 // Remove tasks from persistent storage. 3721 mTaskPersister.wakeup(null, true); 3722 } 3723 3724 // Sort by taskId 3725 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3726 @Override 3727 public int compare(TaskRecord lhs, TaskRecord rhs) { 3728 return rhs.taskId - lhs.taskId; 3729 } 3730 }; 3731 3732 // Extract the affiliates of the chain containing mRecentTasks[start]. 3733 private int processNextAffiliateChain(int start) { 3734 final TaskRecord startTask = mRecentTasks.get(start); 3735 final int affiliateId = startTask.mAffiliatedTaskId; 3736 3737 // Quick identification of isolated tasks. I.e. those not launched behind. 3738 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3739 startTask.mNextAffiliate == null) { 3740 // There is still a slim chance that there are other tasks that point to this task 3741 // and that the chain is so messed up that this task no longer points to them but 3742 // the gain of this optimization outweighs the risk. 3743 startTask.inRecents = true; 3744 return start + 1; 3745 } 3746 3747 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3748 mTmpRecents.clear(); 3749 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3750 final TaskRecord task = mRecentTasks.get(i); 3751 if (task.mAffiliatedTaskId == affiliateId) { 3752 mRecentTasks.remove(i); 3753 mTmpRecents.add(task); 3754 } 3755 } 3756 3757 // Sort them all by taskId. That is the order they were create in and that order will 3758 // always be correct. 3759 Collections.sort(mTmpRecents, mTaskRecordComparator); 3760 3761 // Go through and fix up the linked list. 3762 // The first one is the end of the chain and has no next. 3763 final TaskRecord first = mTmpRecents.get(0); 3764 first.inRecents = true; 3765 if (first.mNextAffiliate != null) { 3766 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3767 first.setNextAffiliate(null); 3768 mTaskPersister.wakeup(first, false); 3769 } 3770 // Everything in the middle is doubly linked from next to prev. 3771 final int tmpSize = mTmpRecents.size(); 3772 for (int i = 0; i < tmpSize - 1; ++i) { 3773 final TaskRecord next = mTmpRecents.get(i); 3774 final TaskRecord prev = mTmpRecents.get(i + 1); 3775 if (next.mPrevAffiliate != prev) { 3776 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3777 " setting prev=" + prev); 3778 next.setPrevAffiliate(prev); 3779 mTaskPersister.wakeup(next, false); 3780 } 3781 if (prev.mNextAffiliate != next) { 3782 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3783 " setting next=" + next); 3784 prev.setNextAffiliate(next); 3785 mTaskPersister.wakeup(prev, false); 3786 } 3787 prev.inRecents = true; 3788 } 3789 // The last one is the beginning of the list and has no prev. 3790 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3791 if (last.mPrevAffiliate != null) { 3792 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3793 last.setPrevAffiliate(null); 3794 mTaskPersister.wakeup(last, false); 3795 } 3796 3797 // Insert the group back into mRecentTasks at start. 3798 mRecentTasks.addAll(start, mTmpRecents); 3799 3800 // Let the caller know where we left off. 3801 return start + tmpSize; 3802 } 3803 3804 /** 3805 * Update the recent tasks lists: make sure tasks should still be here (their 3806 * applications / activities still exist), update their availability, fixup ordering 3807 * of affiliations. 3808 */ 3809 void cleanupRecentTasksLocked(int userId) { 3810 if (mRecentTasks == null) { 3811 // Happens when called from the packagemanager broadcast before boot. 3812 return; 3813 } 3814 3815 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3816 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3817 final IPackageManager pm = AppGlobals.getPackageManager(); 3818 final ActivityInfo dummyAct = new ActivityInfo(); 3819 final ApplicationInfo dummyApp = new ApplicationInfo(); 3820 3821 int N = mRecentTasks.size(); 3822 3823 int[] users = userId == UserHandle.USER_ALL 3824 ? getUsersLocked() : new int[] { userId }; 3825 for (int user : users) { 3826 for (int i = 0; i < N; i++) { 3827 TaskRecord task = mRecentTasks.get(i); 3828 if (task.userId != user) { 3829 // Only look at tasks for the user ID of interest. 3830 continue; 3831 } 3832 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3833 // This situation is broken, and we should just get rid of it now. 3834 mRecentTasks.remove(i); 3835 task.removedFromRecents(mTaskPersister); 3836 i--; 3837 N--; 3838 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3839 continue; 3840 } 3841 // Check whether this activity is currently available. 3842 if (task.realActivity != null) { 3843 ActivityInfo ai = availActCache.get(task.realActivity); 3844 if (ai == null) { 3845 try { 3846 ai = pm.getActivityInfo(task.realActivity, 3847 PackageManager.GET_UNINSTALLED_PACKAGES 3848 | PackageManager.GET_DISABLED_COMPONENTS, user); 3849 } catch (RemoteException e) { 3850 // Will never happen. 3851 continue; 3852 } 3853 if (ai == null) { 3854 ai = dummyAct; 3855 } 3856 availActCache.put(task.realActivity, ai); 3857 } 3858 if (ai == dummyAct) { 3859 // This could be either because the activity no longer exists, or the 3860 // app is temporarily gone. For the former we want to remove the recents 3861 // entry; for the latter we want to mark it as unavailable. 3862 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3863 if (app == null) { 3864 try { 3865 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3866 PackageManager.GET_UNINSTALLED_PACKAGES 3867 | PackageManager.GET_DISABLED_COMPONENTS, user); 3868 } catch (RemoteException e) { 3869 // Will never happen. 3870 continue; 3871 } 3872 if (app == null) { 3873 app = dummyApp; 3874 } 3875 availAppCache.put(task.realActivity.getPackageName(), app); 3876 } 3877 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3878 // Doesn't exist any more! Good-bye. 3879 mRecentTasks.remove(i); 3880 task.removedFromRecents(mTaskPersister); 3881 i--; 3882 N--; 3883 Slog.w(TAG, "Removing no longer valid recent: " + task); 3884 continue; 3885 } else { 3886 // Otherwise just not available for now. 3887 if (task.isAvailable) { 3888 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3889 + task); 3890 } 3891 task.isAvailable = false; 3892 } 3893 } else { 3894 if (!ai.enabled || !ai.applicationInfo.enabled 3895 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3896 if (task.isAvailable) { 3897 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3898 + task + " (enabled=" + ai.enabled + "/" 3899 + ai.applicationInfo.enabled + " flags=" 3900 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3901 } 3902 task.isAvailable = false; 3903 } else { 3904 if (!task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3906 + task); 3907 } 3908 task.isAvailable = true; 3909 } 3910 } 3911 } 3912 } 3913 } 3914 3915 // Verify the affiliate chain for each task. 3916 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3917 } 3918 3919 mTmpRecents.clear(); 3920 // mRecentTasks is now in sorted, affiliated order. 3921 } 3922 3923 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3924 int N = mRecentTasks.size(); 3925 TaskRecord top = task; 3926 int topIndex = taskIndex; 3927 while (top.mNextAffiliate != null && topIndex > 0) { 3928 top = top.mNextAffiliate; 3929 topIndex--; 3930 } 3931 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3932 + topIndex + " from intial " + taskIndex); 3933 // Find the end of the chain, doing a sanity check along the way. 3934 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3935 int endIndex = topIndex; 3936 TaskRecord prev = top; 3937 while (endIndex < N) { 3938 TaskRecord cur = mRecentTasks.get(endIndex); 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3940 + endIndex + " " + cur); 3941 if (cur == top) { 3942 // Verify start of the chain. 3943 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": first task has next affiliate: " + prev); 3946 sane = false; 3947 break; 3948 } 3949 } else { 3950 // Verify middle of the chain's next points back to the one before. 3951 if (cur.mNextAffiliate != prev 3952 || cur.mNextAffiliateTaskId != prev.taskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": middle task " + cur + " @" + endIndex 3955 + " has bad next affiliate " 3956 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3957 + ", expected " + prev); 3958 sane = false; 3959 break; 3960 } 3961 } 3962 if (cur.mPrevAffiliateTaskId == -1) { 3963 // Chain ends here. 3964 if (cur.mPrevAffiliate != null) { 3965 Slog.wtf(TAG, "Bad chain @" + endIndex 3966 + ": last task " + cur + " has previous affiliate " 3967 + cur.mPrevAffiliate); 3968 sane = false; 3969 } 3970 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3971 break; 3972 } else { 3973 // Verify middle of the chain's prev points to a valid item. 3974 if (cur.mPrevAffiliate == null) { 3975 Slog.wtf(TAG, "Bad chain @" + endIndex 3976 + ": task " + cur + " has previous affiliate " 3977 + cur.mPrevAffiliate + " but should be id " 3978 + cur.mPrevAffiliate); 3979 sane = false; 3980 break; 3981 } 3982 } 3983 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3984 Slog.wtf(TAG, "Bad chain @" + endIndex 3985 + ": task " + cur + " has affiliated id " 3986 + cur.mAffiliatedTaskId + " but should be " 3987 + task.mAffiliatedTaskId); 3988 sane = false; 3989 break; 3990 } 3991 prev = cur; 3992 endIndex++; 3993 if (endIndex >= N) { 3994 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3995 + ": last task " + prev); 3996 sane = false; 3997 break; 3998 } 3999 } 4000 if (sane) { 4001 if (endIndex < taskIndex) { 4002 Slog.wtf(TAG, "Bad chain @" + endIndex 4003 + ": did not extend to task " + task + " @" + taskIndex); 4004 sane = false; 4005 } 4006 } 4007 if (sane) { 4008 // All looks good, we can just move all of the affiliated tasks 4009 // to the top. 4010 for (int i=topIndex; i<=endIndex; i++) { 4011 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4012 + " from " + i + " to " + (i-topIndex)); 4013 TaskRecord cur = mRecentTasks.remove(i); 4014 mRecentTasks.add(i-topIndex, cur); 4015 } 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4017 + " to " + endIndex); 4018 return true; 4019 } 4020 4021 // Whoops, couldn't do it. 4022 return false; 4023 } 4024 4025 final void addRecentTaskLocked(TaskRecord task) { 4026 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4027 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4028 4029 int N = mRecentTasks.size(); 4030 // Quick case: check if the top-most recent task is the same. 4031 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4032 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4033 return; 4034 } 4035 // Another quick case: check if this is part of a set of affiliated 4036 // tasks that are at the top. 4037 if (isAffiliated && N > 0 && task.inRecents 4038 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4040 + " at top when adding " + task); 4041 return; 4042 } 4043 // Another quick case: never add voice sessions. 4044 if (task.voiceSession != null) { 4045 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4046 return; 4047 } 4048 4049 boolean needAffiliationFix = false; 4050 4051 // Slightly less quick case: the task is already in recents, so all we need 4052 // to do is move it. 4053 if (task.inRecents) { 4054 int taskIndex = mRecentTasks.indexOf(task); 4055 if (taskIndex >= 0) { 4056 if (!isAffiliated) { 4057 // Simple case: this is not an affiliated task, so we just move it to the front. 4058 mRecentTasks.remove(taskIndex); 4059 mRecentTasks.add(0, task); 4060 notifyTaskPersisterLocked(task, false); 4061 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4062 + " from " + taskIndex); 4063 return; 4064 } else { 4065 // More complicated: need to keep all affiliated tasks together. 4066 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4067 // All went well. 4068 return; 4069 } 4070 4071 // Uh oh... something bad in the affiliation chain, try to rebuild 4072 // everything and then go through our general path of adding a new task. 4073 needAffiliationFix = true; 4074 } 4075 } else { 4076 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4077 needAffiliationFix = true; 4078 } 4079 } 4080 4081 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4082 trimRecentsForTask(task, true); 4083 4084 N = mRecentTasks.size(); 4085 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4086 final TaskRecord tr = mRecentTasks.remove(N - 1); 4087 tr.removedFromRecents(mTaskPersister); 4088 N--; 4089 } 4090 task.inRecents = true; 4091 if (!isAffiliated || needAffiliationFix) { 4092 // If this is a simple non-affiliated task, or we had some failure trying to 4093 // handle it as part of an affilated task, then just place it at the top. 4094 mRecentTasks.add(0, task); 4095 } else if (isAffiliated) { 4096 // If this is a new affiliated task, then move all of the affiliated tasks 4097 // to the front and insert this new one. 4098 TaskRecord other = task.mNextAffiliate; 4099 if (other == null) { 4100 other = task.mPrevAffiliate; 4101 } 4102 if (other != null) { 4103 int otherIndex = mRecentTasks.indexOf(other); 4104 if (otherIndex >= 0) { 4105 // Insert new task at appropriate location. 4106 int taskIndex; 4107 if (other == task.mNextAffiliate) { 4108 // We found the index of our next affiliation, which is who is 4109 // before us in the list, so add after that point. 4110 taskIndex = otherIndex+1; 4111 } else { 4112 // We found the index of our previous affiliation, which is who is 4113 // after us in the list, so add at their position. 4114 taskIndex = otherIndex; 4115 } 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4117 + taskIndex + ": " + task); 4118 mRecentTasks.add(taskIndex, task); 4119 4120 // Now move everything to the front. 4121 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4122 // All went well. 4123 return; 4124 } 4125 4126 // Uh oh... something bad in the affiliation chain, try to rebuild 4127 // everything and then go through our general path of adding a new task. 4128 needAffiliationFix = true; 4129 } else { 4130 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4131 + other); 4132 needAffiliationFix = true; 4133 } 4134 } else { 4135 if (DEBUG_RECENTS) Slog.d(TAG, 4136 "addRecent: adding affiliated task without next/prev:" + task); 4137 needAffiliationFix = true; 4138 } 4139 } 4140 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4141 4142 if (needAffiliationFix) { 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4144 cleanupRecentTasksLocked(task.userId); 4145 } 4146 } 4147 4148 /** 4149 * If needed, remove oldest existing entries in recents that are for the same kind 4150 * of task as the given one. 4151 */ 4152 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4153 int N = mRecentTasks.size(); 4154 final Intent intent = task.intent; 4155 final boolean document = intent != null && intent.isDocument(); 4156 4157 int maxRecents = task.maxRecents - 1; 4158 for (int i=0; i<N; i++) { 4159 final TaskRecord tr = mRecentTasks.get(i); 4160 if (task != tr) { 4161 if (task.userId != tr.userId) { 4162 continue; 4163 } 4164 if (i > MAX_RECENT_BITMAPS) { 4165 tr.freeLastThumbnail(); 4166 } 4167 final Intent trIntent = tr.intent; 4168 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4169 (intent == null || !intent.filterEquals(trIntent))) { 4170 continue; 4171 } 4172 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4173 if (document && trIsDocument) { 4174 // These are the same document activity (not necessarily the same doc). 4175 if (maxRecents > 0) { 4176 --maxRecents; 4177 continue; 4178 } 4179 // Hit the maximum number of documents for this task. Fall through 4180 // and remove this document from recents. 4181 } else if (document || trIsDocument) { 4182 // Only one of these is a document. Not the droid we're looking for. 4183 continue; 4184 } 4185 } 4186 4187 if (!doTrim) { 4188 // If the caller is not actually asking for a trim, just tell them we reached 4189 // a point where the trim would happen. 4190 return i; 4191 } 4192 4193 // Either task and tr are the same or, their affinities match or their intents match 4194 // and neither of them is a document, or they are documents using the same activity 4195 // and their maxRecents has been reached. 4196 tr.disposeThumbnail(); 4197 mRecentTasks.remove(i); 4198 if (task != tr) { 4199 tr.removedFromRecents(mTaskPersister); 4200 } 4201 i--; 4202 N--; 4203 if (task.intent == null) { 4204 // If the new recent task we are adding is not fully 4205 // specified, then replace it with the existing recent task. 4206 task = tr; 4207 } 4208 notifyTaskPersisterLocked(tr, false); 4209 } 4210 4211 return -1; 4212 } 4213 4214 @Override 4215 public void reportActivityFullyDrawn(IBinder token) { 4216 synchronized (this) { 4217 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4218 if (r == null) { 4219 return; 4220 } 4221 r.reportFullyDrawnLocked(); 4222 } 4223 } 4224 4225 @Override 4226 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4227 synchronized (this) { 4228 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4229 if (r == null) { 4230 return; 4231 } 4232 final long origId = Binder.clearCallingIdentity(); 4233 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4234 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4235 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4236 if (config != null) { 4237 r.frozenBeforeDestroy = true; 4238 if (!updateConfigurationLocked(config, r, false, false)) { 4239 mStackSupervisor.resumeTopActivitiesLocked(); 4240 } 4241 } 4242 Binder.restoreCallingIdentity(origId); 4243 } 4244 } 4245 4246 @Override 4247 public int getRequestedOrientation(IBinder token) { 4248 synchronized (this) { 4249 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4250 if (r == null) { 4251 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4252 } 4253 return mWindowManager.getAppOrientation(r.appToken); 4254 } 4255 } 4256 4257 /** 4258 * This is the internal entry point for handling Activity.finish(). 4259 * 4260 * @param token The Binder token referencing the Activity we want to finish. 4261 * @param resultCode Result code, if any, from this Activity. 4262 * @param resultData Result data (Intent), if any, from this Activity. 4263 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4264 * the root Activity in the task. 4265 * 4266 * @return Returns true if the activity successfully finished, or false if it is still running. 4267 */ 4268 @Override 4269 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4270 boolean finishTask) { 4271 // Refuse possible leaked file descriptors 4272 if (resultData != null && resultData.hasFileDescriptors() == true) { 4273 throw new IllegalArgumentException("File descriptors passed in Intent"); 4274 } 4275 4276 synchronized(this) { 4277 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4278 if (r == null) { 4279 return true; 4280 } 4281 // Keep track of the root activity of the task before we finish it 4282 TaskRecord tr = r.task; 4283 ActivityRecord rootR = tr.getRootActivity(); 4284 // Do not allow task to finish in Lock Task mode. 4285 if (tr == mStackSupervisor.mLockTaskModeTask) { 4286 if (rootR == r) { 4287 mStackSupervisor.showLockTaskToast(); 4288 return false; 4289 } 4290 } 4291 if (mController != null) { 4292 // Find the first activity that is not finishing. 4293 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4294 if (next != null) { 4295 // ask watcher if this is allowed 4296 boolean resumeOK = true; 4297 try { 4298 resumeOK = mController.activityResuming(next.packageName); 4299 } catch (RemoteException e) { 4300 mController = null; 4301 Watchdog.getInstance().setActivityController(null); 4302 } 4303 4304 if (!resumeOK) { 4305 return false; 4306 } 4307 } 4308 } 4309 final long origId = Binder.clearCallingIdentity(); 4310 try { 4311 boolean res; 4312 if (finishTask && r == rootR) { 4313 // If requested, remove the task that is associated to this activity only if it 4314 // was the root activity in the task. The result code and data is ignored 4315 // because we don't support returning them across task boundaries. 4316 res = removeTaskByIdLocked(tr.taskId, false); 4317 } else { 4318 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4319 resultData, "app-request", true); 4320 } 4321 return res; 4322 } finally { 4323 Binder.restoreCallingIdentity(origId); 4324 } 4325 } 4326 } 4327 4328 @Override 4329 public final void finishHeavyWeightApp() { 4330 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4331 != PackageManager.PERMISSION_GRANTED) { 4332 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4333 + Binder.getCallingPid() 4334 + ", uid=" + Binder.getCallingUid() 4335 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4336 Slog.w(TAG, msg); 4337 throw new SecurityException(msg); 4338 } 4339 4340 synchronized(this) { 4341 if (mHeavyWeightProcess == null) { 4342 return; 4343 } 4344 4345 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4346 mHeavyWeightProcess.activities); 4347 for (int i=0; i<activities.size(); i++) { 4348 ActivityRecord r = activities.get(i); 4349 if (!r.finishing) { 4350 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4351 null, "finish-heavy", true); 4352 } 4353 } 4354 4355 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4356 mHeavyWeightProcess.userId, 0)); 4357 mHeavyWeightProcess = null; 4358 } 4359 } 4360 4361 @Override 4362 public void crashApplication(int uid, int initialPid, String packageName, 4363 String message) { 4364 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4365 != PackageManager.PERMISSION_GRANTED) { 4366 String msg = "Permission Denial: crashApplication() from pid=" 4367 + Binder.getCallingPid() 4368 + ", uid=" + Binder.getCallingUid() 4369 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4370 Slog.w(TAG, msg); 4371 throw new SecurityException(msg); 4372 } 4373 4374 synchronized(this) { 4375 ProcessRecord proc = null; 4376 4377 // Figure out which process to kill. We don't trust that initialPid 4378 // still has any relation to current pids, so must scan through the 4379 // list. 4380 synchronized (mPidsSelfLocked) { 4381 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4382 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4383 if (p.uid != uid) { 4384 continue; 4385 } 4386 if (p.pid == initialPid) { 4387 proc = p; 4388 break; 4389 } 4390 if (p.pkgList.containsKey(packageName)) { 4391 proc = p; 4392 } 4393 } 4394 } 4395 4396 if (proc == null) { 4397 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4398 + " initialPid=" + initialPid 4399 + " packageName=" + packageName); 4400 return; 4401 } 4402 4403 if (proc.thread != null) { 4404 if (proc.pid == Process.myPid()) { 4405 Log.w(TAG, "crashApplication: trying to crash self!"); 4406 return; 4407 } 4408 long ident = Binder.clearCallingIdentity(); 4409 try { 4410 proc.thread.scheduleCrash(message); 4411 } catch (RemoteException e) { 4412 } 4413 Binder.restoreCallingIdentity(ident); 4414 } 4415 } 4416 } 4417 4418 @Override 4419 public final void finishSubActivity(IBinder token, String resultWho, 4420 int requestCode) { 4421 synchronized(this) { 4422 final long origId = Binder.clearCallingIdentity(); 4423 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4424 if (r != null) { 4425 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4426 } 4427 Binder.restoreCallingIdentity(origId); 4428 } 4429 } 4430 4431 @Override 4432 public boolean finishActivityAffinity(IBinder token) { 4433 synchronized(this) { 4434 final long origId = Binder.clearCallingIdentity(); 4435 try { 4436 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4437 4438 ActivityRecord rootR = r.task.getRootActivity(); 4439 // Do not allow task to finish in Lock Task mode. 4440 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4441 if (rootR == r) { 4442 mStackSupervisor.showLockTaskToast(); 4443 return false; 4444 } 4445 } 4446 boolean res = false; 4447 if (r != null) { 4448 res = r.task.stack.finishActivityAffinityLocked(r); 4449 } 4450 return res; 4451 } finally { 4452 Binder.restoreCallingIdentity(origId); 4453 } 4454 } 4455 } 4456 4457 @Override 4458 public void finishVoiceTask(IVoiceInteractionSession session) { 4459 synchronized(this) { 4460 final long origId = Binder.clearCallingIdentity(); 4461 try { 4462 mStackSupervisor.finishVoiceTask(session); 4463 } finally { 4464 Binder.restoreCallingIdentity(origId); 4465 } 4466 } 4467 4468 } 4469 4470 @Override 4471 public boolean releaseActivityInstance(IBinder token) { 4472 synchronized(this) { 4473 final long origId = Binder.clearCallingIdentity(); 4474 try { 4475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4476 if (r.task == null || r.task.stack == null) { 4477 return false; 4478 } 4479 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4480 } finally { 4481 Binder.restoreCallingIdentity(origId); 4482 } 4483 } 4484 } 4485 4486 @Override 4487 public void releaseSomeActivities(IApplicationThread appInt) { 4488 synchronized(this) { 4489 final long origId = Binder.clearCallingIdentity(); 4490 try { 4491 ProcessRecord app = getRecordForAppLocked(appInt); 4492 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4493 } finally { 4494 Binder.restoreCallingIdentity(origId); 4495 } 4496 } 4497 } 4498 4499 @Override 4500 public boolean willActivityBeVisible(IBinder token) { 4501 synchronized(this) { 4502 ActivityStack stack = ActivityRecord.getStackLocked(token); 4503 if (stack != null) { 4504 return stack.willActivityBeVisibleLocked(token); 4505 } 4506 return false; 4507 } 4508 } 4509 4510 @Override 4511 public void overridePendingTransition(IBinder token, String packageName, 4512 int enterAnim, int exitAnim) { 4513 synchronized(this) { 4514 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4515 if (self == null) { 4516 return; 4517 } 4518 4519 final long origId = Binder.clearCallingIdentity(); 4520 4521 if (self.state == ActivityState.RESUMED 4522 || self.state == ActivityState.PAUSING) { 4523 mWindowManager.overridePendingAppTransition(packageName, 4524 enterAnim, exitAnim, null); 4525 } 4526 4527 Binder.restoreCallingIdentity(origId); 4528 } 4529 } 4530 4531 /** 4532 * Main function for removing an existing process from the activity manager 4533 * as a result of that process going away. Clears out all connections 4534 * to the process. 4535 */ 4536 private final void handleAppDiedLocked(ProcessRecord app, 4537 boolean restarting, boolean allowRestart) { 4538 int pid = app.pid; 4539 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4540 if (!kept && !restarting) { 4541 removeLruProcessLocked(app); 4542 if (pid > 0) { 4543 ProcessList.remove(pid); 4544 } 4545 } 4546 4547 if (mProfileProc == app) { 4548 clearProfilerLocked(); 4549 } 4550 4551 // Remove this application's activities from active lists. 4552 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4553 4554 app.activities.clear(); 4555 4556 if (app.instrumentationClass != null) { 4557 Slog.w(TAG, "Crash of app " + app.processName 4558 + " running instrumentation " + app.instrumentationClass); 4559 Bundle info = new Bundle(); 4560 info.putString("shortMsg", "Process crashed."); 4561 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4562 } 4563 4564 if (!restarting) { 4565 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4566 // If there was nothing to resume, and we are not already 4567 // restarting this process, but there is a visible activity that 4568 // is hosted by the process... then make sure all visible 4569 // activities are running, taking care of restarting this 4570 // process. 4571 if (hasVisibleActivities) { 4572 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4573 } 4574 } 4575 } 4576 } 4577 4578 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4579 IBinder threadBinder = thread.asBinder(); 4580 // Find the application record. 4581 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4582 ProcessRecord rec = mLruProcesses.get(i); 4583 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4584 return i; 4585 } 4586 } 4587 return -1; 4588 } 4589 4590 final ProcessRecord getRecordForAppLocked( 4591 IApplicationThread thread) { 4592 if (thread == null) { 4593 return null; 4594 } 4595 4596 int appIndex = getLRURecordIndexForAppLocked(thread); 4597 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4598 } 4599 4600 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4601 // If there are no longer any background processes running, 4602 // and the app that died was not running instrumentation, 4603 // then tell everyone we are now low on memory. 4604 boolean haveBg = false; 4605 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4606 ProcessRecord rec = mLruProcesses.get(i); 4607 if (rec.thread != null 4608 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4609 haveBg = true; 4610 break; 4611 } 4612 } 4613 4614 if (!haveBg) { 4615 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4616 if (doReport) { 4617 long now = SystemClock.uptimeMillis(); 4618 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4619 doReport = false; 4620 } else { 4621 mLastMemUsageReportTime = now; 4622 } 4623 } 4624 final ArrayList<ProcessMemInfo> memInfos 4625 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4626 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4627 long now = SystemClock.uptimeMillis(); 4628 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4629 ProcessRecord rec = mLruProcesses.get(i); 4630 if (rec == dyingProc || rec.thread == null) { 4631 continue; 4632 } 4633 if (doReport) { 4634 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4635 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4636 } 4637 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4638 // The low memory report is overriding any current 4639 // state for a GC request. Make sure to do 4640 // heavy/important/visible/foreground processes first. 4641 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4642 rec.lastRequestedGc = 0; 4643 } else { 4644 rec.lastRequestedGc = rec.lastLowMemory; 4645 } 4646 rec.reportLowMemory = true; 4647 rec.lastLowMemory = now; 4648 mProcessesToGc.remove(rec); 4649 addProcessToGcListLocked(rec); 4650 } 4651 } 4652 if (doReport) { 4653 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4654 mHandler.sendMessage(msg); 4655 } 4656 scheduleAppGcsLocked(); 4657 } 4658 } 4659 4660 final void appDiedLocked(ProcessRecord app) { 4661 appDiedLocked(app, app.pid, app.thread); 4662 } 4663 4664 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4665 // First check if this ProcessRecord is actually active for the pid. 4666 synchronized (mPidsSelfLocked) { 4667 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4668 if (curProc != app) { 4669 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4670 return; 4671 } 4672 } 4673 4674 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4675 synchronized (stats) { 4676 stats.noteProcessDiedLocked(app.info.uid, pid); 4677 } 4678 4679 Process.killProcessQuiet(pid); 4680 Process.killProcessGroup(app.info.uid, pid); 4681 app.killed = true; 4682 4683 // Clean up already done if the process has been re-started. 4684 if (app.pid == pid && app.thread != null && 4685 app.thread.asBinder() == thread.asBinder()) { 4686 boolean doLowMem = app.instrumentationClass == null; 4687 boolean doOomAdj = doLowMem; 4688 if (!app.killedByAm) { 4689 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4690 + ") has died"); 4691 mAllowLowerMemLevel = true; 4692 } else { 4693 // Note that we always want to do oom adj to update our state with the 4694 // new number of procs. 4695 mAllowLowerMemLevel = false; 4696 doLowMem = false; 4697 } 4698 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4699 if (DEBUG_CLEANUP) Slog.v( 4700 TAG, "Dying app: " + app + ", pid: " + pid 4701 + ", thread: " + thread.asBinder()); 4702 handleAppDiedLocked(app, false, true); 4703 4704 if (doOomAdj) { 4705 updateOomAdjLocked(); 4706 } 4707 if (doLowMem) { 4708 doLowMemReportIfNeededLocked(app); 4709 } 4710 } else if (app.pid != pid) { 4711 // A new process has already been started. 4712 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4713 + ") has died and restarted (pid " + app.pid + ")."); 4714 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4715 } else if (DEBUG_PROCESSES) { 4716 Slog.d(TAG, "Received spurious death notification for thread " 4717 + thread.asBinder()); 4718 } 4719 } 4720 4721 /** 4722 * If a stack trace dump file is configured, dump process stack traces. 4723 * @param clearTraces causes the dump file to be erased prior to the new 4724 * traces being written, if true; when false, the new traces will be 4725 * appended to any existing file content. 4726 * @param firstPids of dalvik VM processes to dump stack traces for first 4727 * @param lastPids of dalvik VM processes to dump stack traces for last 4728 * @param nativeProcs optional list of native process names to dump stack crawls 4729 * @return file containing stack traces, or null if no dump file is configured 4730 */ 4731 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4732 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4733 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4734 if (tracesPath == null || tracesPath.length() == 0) { 4735 return null; 4736 } 4737 4738 File tracesFile = new File(tracesPath); 4739 try { 4740 File tracesDir = tracesFile.getParentFile(); 4741 if (!tracesDir.exists()) { 4742 tracesDir.mkdirs(); 4743 if (!SELinux.restorecon(tracesDir)) { 4744 return null; 4745 } 4746 } 4747 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4748 4749 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4750 tracesFile.createNewFile(); 4751 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4752 } catch (IOException e) { 4753 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4754 return null; 4755 } 4756 4757 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4758 return tracesFile; 4759 } 4760 4761 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4762 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4763 // Use a FileObserver to detect when traces finish writing. 4764 // The order of traces is considered important to maintain for legibility. 4765 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4766 @Override 4767 public synchronized void onEvent(int event, String path) { notify(); } 4768 }; 4769 4770 try { 4771 observer.startWatching(); 4772 4773 // First collect all of the stacks of the most important pids. 4774 if (firstPids != null) { 4775 try { 4776 int num = firstPids.size(); 4777 for (int i = 0; i < num; i++) { 4778 synchronized (observer) { 4779 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4780 observer.wait(200); // Wait for write-close, give up after 200msec 4781 } 4782 } 4783 } catch (InterruptedException e) { 4784 Slog.wtf(TAG, e); 4785 } 4786 } 4787 4788 // Next collect the stacks of the native pids 4789 if (nativeProcs != null) { 4790 int[] pids = Process.getPidsForCommands(nativeProcs); 4791 if (pids != null) { 4792 for (int pid : pids) { 4793 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4794 } 4795 } 4796 } 4797 4798 // Lastly, measure CPU usage. 4799 if (processCpuTracker != null) { 4800 processCpuTracker.init(); 4801 System.gc(); 4802 processCpuTracker.update(); 4803 try { 4804 synchronized (processCpuTracker) { 4805 processCpuTracker.wait(500); // measure over 1/2 second. 4806 } 4807 } catch (InterruptedException e) { 4808 } 4809 processCpuTracker.update(); 4810 4811 // We'll take the stack crawls of just the top apps using CPU. 4812 final int N = processCpuTracker.countWorkingStats(); 4813 int numProcs = 0; 4814 for (int i=0; i<N && numProcs<5; i++) { 4815 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4816 if (lastPids.indexOfKey(stats.pid) >= 0) { 4817 numProcs++; 4818 try { 4819 synchronized (observer) { 4820 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4821 observer.wait(200); // Wait for write-close, give up after 200msec 4822 } 4823 } catch (InterruptedException e) { 4824 Slog.wtf(TAG, e); 4825 } 4826 4827 } 4828 } 4829 } 4830 } finally { 4831 observer.stopWatching(); 4832 } 4833 } 4834 4835 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4836 if (true || IS_USER_BUILD) { 4837 return; 4838 } 4839 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4840 if (tracesPath == null || tracesPath.length() == 0) { 4841 return; 4842 } 4843 4844 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4845 StrictMode.allowThreadDiskWrites(); 4846 try { 4847 final File tracesFile = new File(tracesPath); 4848 final File tracesDir = tracesFile.getParentFile(); 4849 final File tracesTmp = new File(tracesDir, "__tmp__"); 4850 try { 4851 if (!tracesDir.exists()) { 4852 tracesDir.mkdirs(); 4853 if (!SELinux.restorecon(tracesDir.getPath())) { 4854 return; 4855 } 4856 } 4857 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4858 4859 if (tracesFile.exists()) { 4860 tracesTmp.delete(); 4861 tracesFile.renameTo(tracesTmp); 4862 } 4863 StringBuilder sb = new StringBuilder(); 4864 Time tobj = new Time(); 4865 tobj.set(System.currentTimeMillis()); 4866 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4867 sb.append(": "); 4868 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4869 sb.append(" since "); 4870 sb.append(msg); 4871 FileOutputStream fos = new FileOutputStream(tracesFile); 4872 fos.write(sb.toString().getBytes()); 4873 if (app == null) { 4874 fos.write("\n*** No application process!".getBytes()); 4875 } 4876 fos.close(); 4877 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4878 } catch (IOException e) { 4879 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4880 return; 4881 } 4882 4883 if (app != null) { 4884 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4885 firstPids.add(app.pid); 4886 dumpStackTraces(tracesPath, firstPids, null, null, null); 4887 } 4888 4889 File lastTracesFile = null; 4890 File curTracesFile = null; 4891 for (int i=9; i>=0; i--) { 4892 String name = String.format(Locale.US, "slow%02d.txt", i); 4893 curTracesFile = new File(tracesDir, name); 4894 if (curTracesFile.exists()) { 4895 if (lastTracesFile != null) { 4896 curTracesFile.renameTo(lastTracesFile); 4897 } else { 4898 curTracesFile.delete(); 4899 } 4900 } 4901 lastTracesFile = curTracesFile; 4902 } 4903 tracesFile.renameTo(curTracesFile); 4904 if (tracesTmp.exists()) { 4905 tracesTmp.renameTo(tracesFile); 4906 } 4907 } finally { 4908 StrictMode.setThreadPolicy(oldPolicy); 4909 } 4910 } 4911 4912 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4913 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4914 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4915 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4916 4917 if (mController != null) { 4918 try { 4919 // 0 == continue, -1 = kill process immediately 4920 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4921 if (res < 0 && app.pid != MY_PID) { 4922 app.kill("anr", true); 4923 } 4924 } catch (RemoteException e) { 4925 mController = null; 4926 Watchdog.getInstance().setActivityController(null); 4927 } 4928 } 4929 4930 long anrTime = SystemClock.uptimeMillis(); 4931 if (MONITOR_CPU_USAGE) { 4932 updateCpuStatsNow(); 4933 } 4934 4935 synchronized (this) { 4936 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4937 if (mShuttingDown) { 4938 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4939 return; 4940 } else if (app.notResponding) { 4941 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4942 return; 4943 } else if (app.crashing) { 4944 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4945 return; 4946 } 4947 4948 // In case we come through here for the same app before completing 4949 // this one, mark as anring now so we will bail out. 4950 app.notResponding = true; 4951 4952 // Log the ANR to the event log. 4953 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4954 app.processName, app.info.flags, annotation); 4955 4956 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4957 firstPids.add(app.pid); 4958 4959 int parentPid = app.pid; 4960 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4961 if (parentPid != app.pid) firstPids.add(parentPid); 4962 4963 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4964 4965 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4966 ProcessRecord r = mLruProcesses.get(i); 4967 if (r != null && r.thread != null) { 4968 int pid = r.pid; 4969 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4970 if (r.persistent) { 4971 firstPids.add(pid); 4972 } else { 4973 lastPids.put(pid, Boolean.TRUE); 4974 } 4975 } 4976 } 4977 } 4978 } 4979 4980 // Log the ANR to the main log. 4981 StringBuilder info = new StringBuilder(); 4982 info.setLength(0); 4983 info.append("ANR in ").append(app.processName); 4984 if (activity != null && activity.shortComponentName != null) { 4985 info.append(" (").append(activity.shortComponentName).append(")"); 4986 } 4987 info.append("\n"); 4988 info.append("PID: ").append(app.pid).append("\n"); 4989 if (annotation != null) { 4990 info.append("Reason: ").append(annotation).append("\n"); 4991 } 4992 if (parent != null && parent != activity) { 4993 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4994 } 4995 4996 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4997 4998 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4999 NATIVE_STACKS_OF_INTEREST); 5000 5001 String cpuInfo = null; 5002 if (MONITOR_CPU_USAGE) { 5003 updateCpuStatsNow(); 5004 synchronized (mProcessCpuTracker) { 5005 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5006 } 5007 info.append(processCpuTracker.printCurrentLoad()); 5008 info.append(cpuInfo); 5009 } 5010 5011 info.append(processCpuTracker.printCurrentState(anrTime)); 5012 5013 Slog.e(TAG, info.toString()); 5014 if (tracesFile == null) { 5015 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5016 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5017 } 5018 5019 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5020 cpuInfo, tracesFile, null); 5021 5022 if (mController != null) { 5023 try { 5024 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5025 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5026 if (res != 0) { 5027 if (res < 0 && app.pid != MY_PID) { 5028 app.kill("anr", true); 5029 } else { 5030 synchronized (this) { 5031 mServices.scheduleServiceTimeoutLocked(app); 5032 } 5033 } 5034 return; 5035 } 5036 } catch (RemoteException e) { 5037 mController = null; 5038 Watchdog.getInstance().setActivityController(null); 5039 } 5040 } 5041 5042 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5043 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5044 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5045 5046 synchronized (this) { 5047 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5048 app.kill("bg anr", true); 5049 return; 5050 } 5051 5052 // Set the app's notResponding state, and look up the errorReportReceiver 5053 makeAppNotRespondingLocked(app, 5054 activity != null ? activity.shortComponentName : null, 5055 annotation != null ? "ANR " + annotation : "ANR", 5056 info.toString()); 5057 5058 // Bring up the infamous App Not Responding dialog 5059 Message msg = Message.obtain(); 5060 HashMap<String, Object> map = new HashMap<String, Object>(); 5061 msg.what = SHOW_NOT_RESPONDING_MSG; 5062 msg.obj = map; 5063 msg.arg1 = aboveSystem ? 1 : 0; 5064 map.put("app", app); 5065 if (activity != null) { 5066 map.put("activity", activity); 5067 } 5068 5069 mHandler.sendMessage(msg); 5070 } 5071 } 5072 5073 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5074 if (!mLaunchWarningShown) { 5075 mLaunchWarningShown = true; 5076 mHandler.post(new Runnable() { 5077 @Override 5078 public void run() { 5079 synchronized (ActivityManagerService.this) { 5080 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5081 d.show(); 5082 mHandler.postDelayed(new Runnable() { 5083 @Override 5084 public void run() { 5085 synchronized (ActivityManagerService.this) { 5086 d.dismiss(); 5087 mLaunchWarningShown = false; 5088 } 5089 } 5090 }, 4000); 5091 } 5092 } 5093 }); 5094 } 5095 } 5096 5097 @Override 5098 public boolean clearApplicationUserData(final String packageName, 5099 final IPackageDataObserver observer, int userId) { 5100 enforceNotIsolatedCaller("clearApplicationUserData"); 5101 int uid = Binder.getCallingUid(); 5102 int pid = Binder.getCallingPid(); 5103 userId = handleIncomingUser(pid, uid, 5104 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5105 long callingId = Binder.clearCallingIdentity(); 5106 try { 5107 IPackageManager pm = AppGlobals.getPackageManager(); 5108 int pkgUid = -1; 5109 synchronized(this) { 5110 try { 5111 pkgUid = pm.getPackageUid(packageName, userId); 5112 } catch (RemoteException e) { 5113 } 5114 if (pkgUid == -1) { 5115 Slog.w(TAG, "Invalid packageName: " + packageName); 5116 if (observer != null) { 5117 try { 5118 observer.onRemoveCompleted(packageName, false); 5119 } catch (RemoteException e) { 5120 Slog.i(TAG, "Observer no longer exists."); 5121 } 5122 } 5123 return false; 5124 } 5125 if (uid == pkgUid || checkComponentPermission( 5126 android.Manifest.permission.CLEAR_APP_USER_DATA, 5127 pid, uid, -1, true) 5128 == PackageManager.PERMISSION_GRANTED) { 5129 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5130 } else { 5131 throw new SecurityException("PID " + pid + " does not have permission " 5132 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5133 + " of package " + packageName); 5134 } 5135 5136 // Remove all tasks match the cleared application package and user 5137 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5138 final TaskRecord tr = mRecentTasks.get(i); 5139 final String taskPackageName = 5140 tr.getBaseIntent().getComponent().getPackageName(); 5141 if (tr.userId != userId) continue; 5142 if (!taskPackageName.equals(packageName)) continue; 5143 removeTaskByIdLocked(tr.taskId, false); 5144 } 5145 } 5146 5147 try { 5148 // Clear application user data 5149 pm.clearApplicationUserData(packageName, observer, userId); 5150 5151 synchronized(this) { 5152 // Remove all permissions granted from/to this package 5153 removeUriPermissionsForPackageLocked(packageName, userId, true); 5154 } 5155 5156 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5157 Uri.fromParts("package", packageName, null)); 5158 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5159 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5160 null, null, 0, null, null, null, false, false, userId); 5161 } catch (RemoteException e) { 5162 } 5163 } finally { 5164 Binder.restoreCallingIdentity(callingId); 5165 } 5166 return true; 5167 } 5168 5169 @Override 5170 public void killBackgroundProcesses(final String packageName, int userId) { 5171 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5172 != PackageManager.PERMISSION_GRANTED && 5173 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5174 != PackageManager.PERMISSION_GRANTED) { 5175 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5176 + Binder.getCallingPid() 5177 + ", uid=" + Binder.getCallingUid() 5178 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5179 Slog.w(TAG, msg); 5180 throw new SecurityException(msg); 5181 } 5182 5183 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5184 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5185 long callingId = Binder.clearCallingIdentity(); 5186 try { 5187 IPackageManager pm = AppGlobals.getPackageManager(); 5188 synchronized(this) { 5189 int appId = -1; 5190 try { 5191 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5192 } catch (RemoteException e) { 5193 } 5194 if (appId == -1) { 5195 Slog.w(TAG, "Invalid packageName: " + packageName); 5196 return; 5197 } 5198 killPackageProcessesLocked(packageName, appId, userId, 5199 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5200 } 5201 } finally { 5202 Binder.restoreCallingIdentity(callingId); 5203 } 5204 } 5205 5206 @Override 5207 public void killAllBackgroundProcesses() { 5208 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5209 != PackageManager.PERMISSION_GRANTED) { 5210 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5211 + Binder.getCallingPid() 5212 + ", uid=" + Binder.getCallingUid() 5213 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5214 Slog.w(TAG, msg); 5215 throw new SecurityException(msg); 5216 } 5217 5218 long callingId = Binder.clearCallingIdentity(); 5219 try { 5220 synchronized(this) { 5221 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5222 final int NP = mProcessNames.getMap().size(); 5223 for (int ip=0; ip<NP; ip++) { 5224 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5225 final int NA = apps.size(); 5226 for (int ia=0; ia<NA; ia++) { 5227 ProcessRecord app = apps.valueAt(ia); 5228 if (app.persistent) { 5229 // we don't kill persistent processes 5230 continue; 5231 } 5232 if (app.removed) { 5233 procs.add(app); 5234 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5235 app.removed = true; 5236 procs.add(app); 5237 } 5238 } 5239 } 5240 5241 int N = procs.size(); 5242 for (int i=0; i<N; i++) { 5243 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5244 } 5245 mAllowLowerMemLevel = true; 5246 updateOomAdjLocked(); 5247 doLowMemReportIfNeededLocked(null); 5248 } 5249 } finally { 5250 Binder.restoreCallingIdentity(callingId); 5251 } 5252 } 5253 5254 @Override 5255 public void forceStopPackage(final String packageName, int userId) { 5256 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5257 != PackageManager.PERMISSION_GRANTED) { 5258 String msg = "Permission Denial: forceStopPackage() from pid=" 5259 + Binder.getCallingPid() 5260 + ", uid=" + Binder.getCallingUid() 5261 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5262 Slog.w(TAG, msg); 5263 throw new SecurityException(msg); 5264 } 5265 final int callingPid = Binder.getCallingPid(); 5266 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5267 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5268 long callingId = Binder.clearCallingIdentity(); 5269 try { 5270 IPackageManager pm = AppGlobals.getPackageManager(); 5271 synchronized(this) { 5272 int[] users = userId == UserHandle.USER_ALL 5273 ? getUsersLocked() : new int[] { userId }; 5274 for (int user : users) { 5275 int pkgUid = -1; 5276 try { 5277 pkgUid = pm.getPackageUid(packageName, user); 5278 } catch (RemoteException e) { 5279 } 5280 if (pkgUid == -1) { 5281 Slog.w(TAG, "Invalid packageName: " + packageName); 5282 continue; 5283 } 5284 try { 5285 pm.setPackageStoppedState(packageName, true, user); 5286 } catch (RemoteException e) { 5287 } catch (IllegalArgumentException e) { 5288 Slog.w(TAG, "Failed trying to unstop package " 5289 + packageName + ": " + e); 5290 } 5291 if (isUserRunningLocked(user, false)) { 5292 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5293 } 5294 } 5295 } 5296 } finally { 5297 Binder.restoreCallingIdentity(callingId); 5298 } 5299 } 5300 5301 @Override 5302 public void addPackageDependency(String packageName) { 5303 synchronized (this) { 5304 int callingPid = Binder.getCallingPid(); 5305 if (callingPid == Process.myPid()) { 5306 // Yeah, um, no. 5307 Slog.w(TAG, "Can't addPackageDependency on system process"); 5308 return; 5309 } 5310 ProcessRecord proc; 5311 synchronized (mPidsSelfLocked) { 5312 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5313 } 5314 if (proc != null) { 5315 if (proc.pkgDeps == null) { 5316 proc.pkgDeps = new ArraySet<String>(1); 5317 } 5318 proc.pkgDeps.add(packageName); 5319 } 5320 } 5321 } 5322 5323 /* 5324 * The pkg name and app id have to be specified. 5325 */ 5326 @Override 5327 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5328 if (pkg == null) { 5329 return; 5330 } 5331 // Make sure the uid is valid. 5332 if (appid < 0) { 5333 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5334 return; 5335 } 5336 int callerUid = Binder.getCallingUid(); 5337 // Only the system server can kill an application 5338 if (callerUid == Process.SYSTEM_UID) { 5339 // Post an aysnc message to kill the application 5340 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5341 msg.arg1 = appid; 5342 msg.arg2 = 0; 5343 Bundle bundle = new Bundle(); 5344 bundle.putString("pkg", pkg); 5345 bundle.putString("reason", reason); 5346 msg.obj = bundle; 5347 mHandler.sendMessage(msg); 5348 } else { 5349 throw new SecurityException(callerUid + " cannot kill pkg: " + 5350 pkg); 5351 } 5352 } 5353 5354 @Override 5355 public void closeSystemDialogs(String reason) { 5356 enforceNotIsolatedCaller("closeSystemDialogs"); 5357 5358 final int pid = Binder.getCallingPid(); 5359 final int uid = Binder.getCallingUid(); 5360 final long origId = Binder.clearCallingIdentity(); 5361 try { 5362 synchronized (this) { 5363 // Only allow this from foreground processes, so that background 5364 // applications can't abuse it to prevent system UI from being shown. 5365 if (uid >= Process.FIRST_APPLICATION_UID) { 5366 ProcessRecord proc; 5367 synchronized (mPidsSelfLocked) { 5368 proc = mPidsSelfLocked.get(pid); 5369 } 5370 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5371 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5372 + " from background process " + proc); 5373 return; 5374 } 5375 } 5376 closeSystemDialogsLocked(reason); 5377 } 5378 } finally { 5379 Binder.restoreCallingIdentity(origId); 5380 } 5381 } 5382 5383 void closeSystemDialogsLocked(String reason) { 5384 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5385 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5386 | Intent.FLAG_RECEIVER_FOREGROUND); 5387 if (reason != null) { 5388 intent.putExtra("reason", reason); 5389 } 5390 mWindowManager.closeSystemDialogs(reason); 5391 5392 mStackSupervisor.closeSystemDialogsLocked(); 5393 5394 broadcastIntentLocked(null, null, intent, null, 5395 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5396 Process.SYSTEM_UID, UserHandle.USER_ALL); 5397 } 5398 5399 @Override 5400 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5401 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5402 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5403 for (int i=pids.length-1; i>=0; i--) { 5404 ProcessRecord proc; 5405 int oomAdj; 5406 synchronized (this) { 5407 synchronized (mPidsSelfLocked) { 5408 proc = mPidsSelfLocked.get(pids[i]); 5409 oomAdj = proc != null ? proc.setAdj : 0; 5410 } 5411 } 5412 infos[i] = new Debug.MemoryInfo(); 5413 Debug.getMemoryInfo(pids[i], infos[i]); 5414 if (proc != null) { 5415 synchronized (this) { 5416 if (proc.thread != null && proc.setAdj == oomAdj) { 5417 // Record this for posterity if the process has been stable. 5418 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5419 infos[i].getTotalUss(), false, proc.pkgList); 5420 } 5421 } 5422 } 5423 } 5424 return infos; 5425 } 5426 5427 @Override 5428 public long[] getProcessPss(int[] pids) { 5429 enforceNotIsolatedCaller("getProcessPss"); 5430 long[] pss = new long[pids.length]; 5431 for (int i=pids.length-1; i>=0; i--) { 5432 ProcessRecord proc; 5433 int oomAdj; 5434 synchronized (this) { 5435 synchronized (mPidsSelfLocked) { 5436 proc = mPidsSelfLocked.get(pids[i]); 5437 oomAdj = proc != null ? proc.setAdj : 0; 5438 } 5439 } 5440 long[] tmpUss = new long[1]; 5441 pss[i] = Debug.getPss(pids[i], tmpUss); 5442 if (proc != null) { 5443 synchronized (this) { 5444 if (proc.thread != null && proc.setAdj == oomAdj) { 5445 // Record this for posterity if the process has been stable. 5446 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5447 } 5448 } 5449 } 5450 } 5451 return pss; 5452 } 5453 5454 @Override 5455 public void killApplicationProcess(String processName, int uid) { 5456 if (processName == null) { 5457 return; 5458 } 5459 5460 int callerUid = Binder.getCallingUid(); 5461 // Only the system server can kill an application 5462 if (callerUid == Process.SYSTEM_UID) { 5463 synchronized (this) { 5464 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5465 if (app != null && app.thread != null) { 5466 try { 5467 app.thread.scheduleSuicide(); 5468 } catch (RemoteException e) { 5469 // If the other end already died, then our work here is done. 5470 } 5471 } else { 5472 Slog.w(TAG, "Process/uid not found attempting kill of " 5473 + processName + " / " + uid); 5474 } 5475 } 5476 } else { 5477 throw new SecurityException(callerUid + " cannot kill app process: " + 5478 processName); 5479 } 5480 } 5481 5482 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5483 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5484 false, true, false, false, UserHandle.getUserId(uid), reason); 5485 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5486 Uri.fromParts("package", packageName, null)); 5487 if (!mProcessesReady) { 5488 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5489 | Intent.FLAG_RECEIVER_FOREGROUND); 5490 } 5491 intent.putExtra(Intent.EXTRA_UID, uid); 5492 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5493 broadcastIntentLocked(null, null, intent, 5494 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5495 false, false, 5496 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5497 } 5498 5499 private void forceStopUserLocked(int userId, String reason) { 5500 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5501 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5502 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5503 | Intent.FLAG_RECEIVER_FOREGROUND); 5504 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5505 broadcastIntentLocked(null, null, intent, 5506 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5507 false, false, 5508 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5509 } 5510 5511 private final boolean killPackageProcessesLocked(String packageName, int appId, 5512 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5513 boolean doit, boolean evenPersistent, String reason) { 5514 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5515 5516 // Remove all processes this package may have touched: all with the 5517 // same UID (except for the system or root user), and all whose name 5518 // matches the package name. 5519 final int NP = mProcessNames.getMap().size(); 5520 for (int ip=0; ip<NP; ip++) { 5521 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5522 final int NA = apps.size(); 5523 for (int ia=0; ia<NA; ia++) { 5524 ProcessRecord app = apps.valueAt(ia); 5525 if (app.persistent && !evenPersistent) { 5526 // we don't kill persistent processes 5527 continue; 5528 } 5529 if (app.removed) { 5530 if (doit) { 5531 procs.add(app); 5532 } 5533 continue; 5534 } 5535 5536 // Skip process if it doesn't meet our oom adj requirement. 5537 if (app.setAdj < minOomAdj) { 5538 continue; 5539 } 5540 5541 // If no package is specified, we call all processes under the 5542 // give user id. 5543 if (packageName == null) { 5544 if (app.userId != userId) { 5545 continue; 5546 } 5547 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5548 continue; 5549 } 5550 // Package has been specified, we want to hit all processes 5551 // that match it. We need to qualify this by the processes 5552 // that are running under the specified app and user ID. 5553 } else { 5554 final boolean isDep = app.pkgDeps != null 5555 && app.pkgDeps.contains(packageName); 5556 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5557 continue; 5558 } 5559 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5560 continue; 5561 } 5562 if (!app.pkgList.containsKey(packageName) && !isDep) { 5563 continue; 5564 } 5565 } 5566 5567 // Process has passed all conditions, kill it! 5568 if (!doit) { 5569 return true; 5570 } 5571 app.removed = true; 5572 procs.add(app); 5573 } 5574 } 5575 5576 int N = procs.size(); 5577 for (int i=0; i<N; i++) { 5578 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5579 } 5580 updateOomAdjLocked(); 5581 return N > 0; 5582 } 5583 5584 private final boolean forceStopPackageLocked(String name, int appId, 5585 boolean callerWillRestart, boolean purgeCache, boolean doit, 5586 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5587 int i; 5588 int N; 5589 5590 if (userId == UserHandle.USER_ALL && name == null) { 5591 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5592 } 5593 5594 if (appId < 0 && name != null) { 5595 try { 5596 appId = UserHandle.getAppId( 5597 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5598 } catch (RemoteException e) { 5599 } 5600 } 5601 5602 if (doit) { 5603 if (name != null) { 5604 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5605 + " user=" + userId + ": " + reason); 5606 } else { 5607 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5608 } 5609 5610 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5611 for (int ip=pmap.size()-1; ip>=0; ip--) { 5612 SparseArray<Long> ba = pmap.valueAt(ip); 5613 for (i=ba.size()-1; i>=0; i--) { 5614 boolean remove = false; 5615 final int entUid = ba.keyAt(i); 5616 if (name != null) { 5617 if (userId == UserHandle.USER_ALL) { 5618 if (UserHandle.getAppId(entUid) == appId) { 5619 remove = true; 5620 } 5621 } else { 5622 if (entUid == UserHandle.getUid(userId, appId)) { 5623 remove = true; 5624 } 5625 } 5626 } else if (UserHandle.getUserId(entUid) == userId) { 5627 remove = true; 5628 } 5629 if (remove) { 5630 ba.removeAt(i); 5631 } 5632 } 5633 if (ba.size() == 0) { 5634 pmap.removeAt(ip); 5635 } 5636 } 5637 } 5638 5639 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5640 -100, callerWillRestart, true, doit, evenPersistent, 5641 name == null ? ("stop user " + userId) : ("stop " + name)); 5642 5643 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5644 if (!doit) { 5645 return true; 5646 } 5647 didSomething = true; 5648 } 5649 5650 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5651 if (!doit) { 5652 return true; 5653 } 5654 didSomething = true; 5655 } 5656 5657 if (name == null) { 5658 // Remove all sticky broadcasts from this user. 5659 mStickyBroadcasts.remove(userId); 5660 } 5661 5662 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5663 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5664 userId, providers)) { 5665 if (!doit) { 5666 return true; 5667 } 5668 didSomething = true; 5669 } 5670 N = providers.size(); 5671 for (i=0; i<N; i++) { 5672 removeDyingProviderLocked(null, providers.get(i), true); 5673 } 5674 5675 // Remove transient permissions granted from/to this package/user 5676 removeUriPermissionsForPackageLocked(name, userId, false); 5677 5678 if (name == null || uninstalling) { 5679 // Remove pending intents. For now we only do this when force 5680 // stopping users, because we have some problems when doing this 5681 // for packages -- app widgets are not currently cleaned up for 5682 // such packages, so they can be left with bad pending intents. 5683 if (mIntentSenderRecords.size() > 0) { 5684 Iterator<WeakReference<PendingIntentRecord>> it 5685 = mIntentSenderRecords.values().iterator(); 5686 while (it.hasNext()) { 5687 WeakReference<PendingIntentRecord> wpir = it.next(); 5688 if (wpir == null) { 5689 it.remove(); 5690 continue; 5691 } 5692 PendingIntentRecord pir = wpir.get(); 5693 if (pir == null) { 5694 it.remove(); 5695 continue; 5696 } 5697 if (name == null) { 5698 // Stopping user, remove all objects for the user. 5699 if (pir.key.userId != userId) { 5700 // Not the same user, skip it. 5701 continue; 5702 } 5703 } else { 5704 if (UserHandle.getAppId(pir.uid) != appId) { 5705 // Different app id, skip it. 5706 continue; 5707 } 5708 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5709 // Different user, skip it. 5710 continue; 5711 } 5712 if (!pir.key.packageName.equals(name)) { 5713 // Different package, skip it. 5714 continue; 5715 } 5716 } 5717 if (!doit) { 5718 return true; 5719 } 5720 didSomething = true; 5721 it.remove(); 5722 pir.canceled = true; 5723 if (pir.key.activity != null) { 5724 pir.key.activity.pendingResults.remove(pir.ref); 5725 } 5726 } 5727 } 5728 } 5729 5730 if (doit) { 5731 if (purgeCache && name != null) { 5732 AttributeCache ac = AttributeCache.instance(); 5733 if (ac != null) { 5734 ac.removePackage(name); 5735 } 5736 } 5737 if (mBooted) { 5738 mStackSupervisor.resumeTopActivitiesLocked(); 5739 mStackSupervisor.scheduleIdleLocked(); 5740 } 5741 } 5742 5743 return didSomething; 5744 } 5745 5746 private final boolean removeProcessLocked(ProcessRecord app, 5747 boolean callerWillRestart, boolean allowRestart, String reason) { 5748 final String name = app.processName; 5749 final int uid = app.uid; 5750 if (DEBUG_PROCESSES) Slog.d( 5751 TAG, "Force removing proc " + app.toShortString() + " (" + name 5752 + "/" + uid + ")"); 5753 5754 mProcessNames.remove(name, uid); 5755 mIsolatedProcesses.remove(app.uid); 5756 if (mHeavyWeightProcess == app) { 5757 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5758 mHeavyWeightProcess.userId, 0)); 5759 mHeavyWeightProcess = null; 5760 } 5761 boolean needRestart = false; 5762 if (app.pid > 0 && app.pid != MY_PID) { 5763 int pid = app.pid; 5764 synchronized (mPidsSelfLocked) { 5765 mPidsSelfLocked.remove(pid); 5766 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5767 } 5768 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5769 if (app.isolated) { 5770 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5771 } 5772 app.kill(reason, true); 5773 handleAppDiedLocked(app, true, allowRestart); 5774 removeLruProcessLocked(app); 5775 5776 if (app.persistent && !app.isolated) { 5777 if (!callerWillRestart) { 5778 addAppLocked(app.info, false, null /* ABI override */); 5779 } else { 5780 needRestart = true; 5781 } 5782 } 5783 } else { 5784 mRemovedProcesses.add(app); 5785 } 5786 5787 return needRestart; 5788 } 5789 5790 private final void processStartTimedOutLocked(ProcessRecord app) { 5791 final int pid = app.pid; 5792 boolean gone = false; 5793 synchronized (mPidsSelfLocked) { 5794 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5795 if (knownApp != null && knownApp.thread == null) { 5796 mPidsSelfLocked.remove(pid); 5797 gone = true; 5798 } 5799 } 5800 5801 if (gone) { 5802 Slog.w(TAG, "Process " + app + " failed to attach"); 5803 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5804 pid, app.uid, app.processName); 5805 mProcessNames.remove(app.processName, app.uid); 5806 mIsolatedProcesses.remove(app.uid); 5807 if (mHeavyWeightProcess == app) { 5808 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5809 mHeavyWeightProcess.userId, 0)); 5810 mHeavyWeightProcess = null; 5811 } 5812 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5813 if (app.isolated) { 5814 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5815 } 5816 // Take care of any launching providers waiting for this process. 5817 checkAppInLaunchingProvidersLocked(app, true); 5818 // Take care of any services that are waiting for the process. 5819 mServices.processStartTimedOutLocked(app); 5820 app.kill("start timeout", true); 5821 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5822 Slog.w(TAG, "Unattached app died before backup, skipping"); 5823 try { 5824 IBackupManager bm = IBackupManager.Stub.asInterface( 5825 ServiceManager.getService(Context.BACKUP_SERVICE)); 5826 bm.agentDisconnected(app.info.packageName); 5827 } catch (RemoteException e) { 5828 // Can't happen; the backup manager is local 5829 } 5830 } 5831 if (isPendingBroadcastProcessLocked(pid)) { 5832 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5833 skipPendingBroadcastLocked(pid); 5834 } 5835 } else { 5836 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5837 } 5838 } 5839 5840 private final boolean attachApplicationLocked(IApplicationThread thread, 5841 int pid) { 5842 5843 // Find the application record that is being attached... either via 5844 // the pid if we are running in multiple processes, or just pull the 5845 // next app record if we are emulating process with anonymous threads. 5846 ProcessRecord app; 5847 if (pid != MY_PID && pid >= 0) { 5848 synchronized (mPidsSelfLocked) { 5849 app = mPidsSelfLocked.get(pid); 5850 } 5851 } else { 5852 app = null; 5853 } 5854 5855 if (app == null) { 5856 Slog.w(TAG, "No pending application record for pid " + pid 5857 + " (IApplicationThread " + thread + "); dropping process"); 5858 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5859 if (pid > 0 && pid != MY_PID) { 5860 Process.killProcessQuiet(pid); 5861 //TODO: Process.killProcessGroup(app.info.uid, pid); 5862 } else { 5863 try { 5864 thread.scheduleExit(); 5865 } catch (Exception e) { 5866 // Ignore exceptions. 5867 } 5868 } 5869 return false; 5870 } 5871 5872 // If this application record is still attached to a previous 5873 // process, clean it up now. 5874 if (app.thread != null) { 5875 handleAppDiedLocked(app, true, true); 5876 } 5877 5878 // Tell the process all about itself. 5879 5880 if (localLOGV) Slog.v( 5881 TAG, "Binding process pid " + pid + " to record " + app); 5882 5883 final String processName = app.processName; 5884 try { 5885 AppDeathRecipient adr = new AppDeathRecipient( 5886 app, pid, thread); 5887 thread.asBinder().linkToDeath(adr, 0); 5888 app.deathRecipient = adr; 5889 } catch (RemoteException e) { 5890 app.resetPackageList(mProcessStats); 5891 startProcessLocked(app, "link fail", processName); 5892 return false; 5893 } 5894 5895 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5896 5897 app.makeActive(thread, mProcessStats); 5898 app.curAdj = app.setAdj = -100; 5899 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5900 app.forcingToForeground = null; 5901 updateProcessForegroundLocked(app, false, false); 5902 app.hasShownUi = false; 5903 app.debugging = false; 5904 app.cached = false; 5905 5906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5907 5908 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5909 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5910 5911 if (!normalMode) { 5912 Slog.i(TAG, "Launching preboot mode app: " + app); 5913 } 5914 5915 if (localLOGV) Slog.v( 5916 TAG, "New app record " + app 5917 + " thread=" + thread.asBinder() + " pid=" + pid); 5918 try { 5919 int testMode = IApplicationThread.DEBUG_OFF; 5920 if (mDebugApp != null && mDebugApp.equals(processName)) { 5921 testMode = mWaitForDebugger 5922 ? IApplicationThread.DEBUG_WAIT 5923 : IApplicationThread.DEBUG_ON; 5924 app.debugging = true; 5925 if (mDebugTransient) { 5926 mDebugApp = mOrigDebugApp; 5927 mWaitForDebugger = mOrigWaitForDebugger; 5928 } 5929 } 5930 String profileFile = app.instrumentationProfileFile; 5931 ParcelFileDescriptor profileFd = null; 5932 int samplingInterval = 0; 5933 boolean profileAutoStop = false; 5934 if (mProfileApp != null && mProfileApp.equals(processName)) { 5935 mProfileProc = app; 5936 profileFile = mProfileFile; 5937 profileFd = mProfileFd; 5938 samplingInterval = mSamplingInterval; 5939 profileAutoStop = mAutoStopProfiler; 5940 } 5941 boolean enableOpenGlTrace = false; 5942 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5943 enableOpenGlTrace = true; 5944 mOpenGlTraceApp = null; 5945 } 5946 5947 // If the app is being launched for restore or full backup, set it up specially 5948 boolean isRestrictedBackupMode = false; 5949 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5950 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5951 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5952 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5953 } 5954 5955 ensurePackageDexOpt(app.instrumentationInfo != null 5956 ? app.instrumentationInfo.packageName 5957 : app.info.packageName); 5958 if (app.instrumentationClass != null) { 5959 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5960 } 5961 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5962 + processName + " with config " + mConfiguration); 5963 ApplicationInfo appInfo = app.instrumentationInfo != null 5964 ? app.instrumentationInfo : app.info; 5965 app.compat = compatibilityInfoForPackageLocked(appInfo); 5966 if (profileFd != null) { 5967 profileFd = profileFd.dup(); 5968 } 5969 ProfilerInfo profilerInfo = profileFile == null ? null 5970 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5971 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5972 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5973 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5974 isRestrictedBackupMode || !normalMode, app.persistent, 5975 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5976 mCoreSettingsObserver.getCoreSettingsLocked()); 5977 updateLruProcessLocked(app, false, null); 5978 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5979 } catch (Exception e) { 5980 // todo: Yikes! What should we do? For now we will try to 5981 // start another process, but that could easily get us in 5982 // an infinite loop of restarting processes... 5983 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5984 5985 app.resetPackageList(mProcessStats); 5986 app.unlinkDeathRecipient(); 5987 startProcessLocked(app, "bind fail", processName); 5988 return false; 5989 } 5990 5991 // Remove this record from the list of starting applications. 5992 mPersistentStartingProcesses.remove(app); 5993 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5994 "Attach application locked removing on hold: " + app); 5995 mProcessesOnHold.remove(app); 5996 5997 boolean badApp = false; 5998 boolean didSomething = false; 5999 6000 // See if the top visible activity is waiting to run in this process... 6001 if (normalMode) { 6002 try { 6003 if (mStackSupervisor.attachApplicationLocked(app)) { 6004 didSomething = true; 6005 } 6006 } catch (Exception e) { 6007 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6008 badApp = true; 6009 } 6010 } 6011 6012 // Find any services that should be running in this process... 6013 if (!badApp) { 6014 try { 6015 didSomething |= mServices.attachApplicationLocked(app, processName); 6016 } catch (Exception e) { 6017 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6018 badApp = true; 6019 } 6020 } 6021 6022 // Check if a next-broadcast receiver is in this process... 6023 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6024 try { 6025 didSomething |= sendPendingBroadcastsLocked(app); 6026 } catch (Exception e) { 6027 // If the app died trying to launch the receiver we declare it 'bad' 6028 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6029 badApp = true; 6030 } 6031 } 6032 6033 // Check whether the next backup agent is in this process... 6034 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6035 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6036 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6037 try { 6038 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6039 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6040 mBackupTarget.backupMode); 6041 } catch (Exception e) { 6042 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6043 badApp = true; 6044 } 6045 } 6046 6047 if (badApp) { 6048 app.kill("error during init", true); 6049 handleAppDiedLocked(app, false, true); 6050 return false; 6051 } 6052 6053 if (!didSomething) { 6054 updateOomAdjLocked(); 6055 } 6056 6057 return true; 6058 } 6059 6060 @Override 6061 public final void attachApplication(IApplicationThread thread) { 6062 synchronized (this) { 6063 int callingPid = Binder.getCallingPid(); 6064 final long origId = Binder.clearCallingIdentity(); 6065 attachApplicationLocked(thread, callingPid); 6066 Binder.restoreCallingIdentity(origId); 6067 } 6068 } 6069 6070 @Override 6071 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6072 final long origId = Binder.clearCallingIdentity(); 6073 synchronized (this) { 6074 ActivityStack stack = ActivityRecord.getStackLocked(token); 6075 if (stack != null) { 6076 ActivityRecord r = 6077 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6078 if (stopProfiling) { 6079 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6080 try { 6081 mProfileFd.close(); 6082 } catch (IOException e) { 6083 } 6084 clearProfilerLocked(); 6085 } 6086 } 6087 } 6088 } 6089 Binder.restoreCallingIdentity(origId); 6090 } 6091 6092 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6093 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6094 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6095 } 6096 6097 void enableScreenAfterBoot() { 6098 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6099 SystemClock.uptimeMillis()); 6100 mWindowManager.enableScreenAfterBoot(); 6101 6102 synchronized (this) { 6103 updateEventDispatchingLocked(); 6104 } 6105 } 6106 6107 @Override 6108 public void showBootMessage(final CharSequence msg, final boolean always) { 6109 enforceNotIsolatedCaller("showBootMessage"); 6110 mWindowManager.showBootMessage(msg, always); 6111 } 6112 6113 @Override 6114 public void keyguardWaitingForActivityDrawn() { 6115 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6116 final long token = Binder.clearCallingIdentity(); 6117 try { 6118 synchronized (this) { 6119 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6120 mWindowManager.keyguardWaitingForActivityDrawn(); 6121 if (mLockScreenShown) { 6122 mLockScreenShown = false; 6123 comeOutOfSleepIfNeededLocked(); 6124 } 6125 } 6126 } finally { 6127 Binder.restoreCallingIdentity(token); 6128 } 6129 } 6130 6131 final void finishBooting() { 6132 synchronized (this) { 6133 if (!mBootAnimationComplete) { 6134 mCallFinishBooting = true; 6135 return; 6136 } 6137 mCallFinishBooting = false; 6138 } 6139 6140 // Register receivers to handle package update events 6141 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6142 6143 // Let system services know. 6144 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6145 6146 synchronized (this) { 6147 // Ensure that any processes we had put on hold are now started 6148 // up. 6149 final int NP = mProcessesOnHold.size(); 6150 if (NP > 0) { 6151 ArrayList<ProcessRecord> procs = 6152 new ArrayList<ProcessRecord>(mProcessesOnHold); 6153 for (int ip=0; ip<NP; ip++) { 6154 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6155 + procs.get(ip)); 6156 startProcessLocked(procs.get(ip), "on-hold", null); 6157 } 6158 } 6159 6160 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6161 // Start looking for apps that are abusing wake locks. 6162 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6163 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6164 // Tell anyone interested that we are done booting! 6165 SystemProperties.set("sys.boot_completed", "1"); 6166 6167 // And trigger dev.bootcomplete if we are not showing encryption progress 6168 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6169 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6170 SystemProperties.set("dev.bootcomplete", "1"); 6171 } 6172 for (int i=0; i<mStartedUsers.size(); i++) { 6173 UserStartedState uss = mStartedUsers.valueAt(i); 6174 if (uss.mState == UserStartedState.STATE_BOOTING) { 6175 uss.mState = UserStartedState.STATE_RUNNING; 6176 final int userId = mStartedUsers.keyAt(i); 6177 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6178 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6179 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6180 broadcastIntentLocked(null, null, intent, null, 6181 new IIntentReceiver.Stub() { 6182 @Override 6183 public void performReceive(Intent intent, int resultCode, 6184 String data, Bundle extras, boolean ordered, 6185 boolean sticky, int sendingUser) { 6186 synchronized (ActivityManagerService.this) { 6187 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6188 true, false); 6189 } 6190 } 6191 }, 6192 0, null, null, 6193 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6194 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6195 userId); 6196 } 6197 } 6198 scheduleStartProfilesLocked(); 6199 } 6200 } 6201 } 6202 6203 @Override 6204 public void bootAnimationComplete() { 6205 final boolean callFinishBooting; 6206 synchronized (this) { 6207 callFinishBooting = mCallFinishBooting; 6208 mBootAnimationComplete = true; 6209 } 6210 if (callFinishBooting) { 6211 finishBooting(); 6212 } 6213 } 6214 6215 final void ensureBootCompleted() { 6216 boolean booting; 6217 boolean enableScreen; 6218 synchronized (this) { 6219 booting = mBooting; 6220 mBooting = false; 6221 enableScreen = !mBooted; 6222 mBooted = true; 6223 } 6224 6225 if (booting) { 6226 finishBooting(); 6227 } 6228 6229 if (enableScreen) { 6230 enableScreenAfterBoot(); 6231 } 6232 } 6233 6234 @Override 6235 public final void activityResumed(IBinder token) { 6236 final long origId = Binder.clearCallingIdentity(); 6237 synchronized(this) { 6238 ActivityStack stack = ActivityRecord.getStackLocked(token); 6239 if (stack != null) { 6240 ActivityRecord.activityResumedLocked(token); 6241 } 6242 } 6243 Binder.restoreCallingIdentity(origId); 6244 } 6245 6246 @Override 6247 public final void activityPaused(IBinder token) { 6248 final long origId = Binder.clearCallingIdentity(); 6249 synchronized(this) { 6250 ActivityStack stack = ActivityRecord.getStackLocked(token); 6251 if (stack != null) { 6252 stack.activityPausedLocked(token, false); 6253 } 6254 } 6255 Binder.restoreCallingIdentity(origId); 6256 } 6257 6258 @Override 6259 public final void activityStopped(IBinder token, Bundle icicle, 6260 PersistableBundle persistentState, CharSequence description) { 6261 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6262 6263 // Refuse possible leaked file descriptors 6264 if (icicle != null && icicle.hasFileDescriptors()) { 6265 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6266 } 6267 6268 final long origId = Binder.clearCallingIdentity(); 6269 6270 synchronized (this) { 6271 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6272 if (r != null) { 6273 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6274 } 6275 } 6276 6277 trimApplications(); 6278 6279 Binder.restoreCallingIdentity(origId); 6280 } 6281 6282 @Override 6283 public final void activityDestroyed(IBinder token) { 6284 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6285 synchronized (this) { 6286 ActivityStack stack = ActivityRecord.getStackLocked(token); 6287 if (stack != null) { 6288 stack.activityDestroyedLocked(token); 6289 } 6290 } 6291 } 6292 6293 @Override 6294 public final void backgroundResourcesReleased(IBinder token) { 6295 final long origId = Binder.clearCallingIdentity(); 6296 try { 6297 synchronized (this) { 6298 ActivityStack stack = ActivityRecord.getStackLocked(token); 6299 if (stack != null) { 6300 stack.backgroundResourcesReleased(token); 6301 } 6302 } 6303 } finally { 6304 Binder.restoreCallingIdentity(origId); 6305 } 6306 } 6307 6308 @Override 6309 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6310 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6311 } 6312 6313 @Override 6314 public final void notifyEnterAnimationComplete(IBinder token) { 6315 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6316 } 6317 6318 @Override 6319 public String getCallingPackage(IBinder token) { 6320 synchronized (this) { 6321 ActivityRecord r = getCallingRecordLocked(token); 6322 return r != null ? r.info.packageName : null; 6323 } 6324 } 6325 6326 @Override 6327 public ComponentName getCallingActivity(IBinder token) { 6328 synchronized (this) { 6329 ActivityRecord r = getCallingRecordLocked(token); 6330 return r != null ? r.intent.getComponent() : null; 6331 } 6332 } 6333 6334 private ActivityRecord getCallingRecordLocked(IBinder token) { 6335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6336 if (r == null) { 6337 return null; 6338 } 6339 return r.resultTo; 6340 } 6341 6342 @Override 6343 public ComponentName getActivityClassForToken(IBinder token) { 6344 synchronized(this) { 6345 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6346 if (r == null) { 6347 return null; 6348 } 6349 return r.intent.getComponent(); 6350 } 6351 } 6352 6353 @Override 6354 public String getPackageForToken(IBinder token) { 6355 synchronized(this) { 6356 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6357 if (r == null) { 6358 return null; 6359 } 6360 return r.packageName; 6361 } 6362 } 6363 6364 @Override 6365 public IIntentSender getIntentSender(int type, 6366 String packageName, IBinder token, String resultWho, 6367 int requestCode, Intent[] intents, String[] resolvedTypes, 6368 int flags, Bundle options, int userId) { 6369 enforceNotIsolatedCaller("getIntentSender"); 6370 // Refuse possible leaked file descriptors 6371 if (intents != null) { 6372 if (intents.length < 1) { 6373 throw new IllegalArgumentException("Intents array length must be >= 1"); 6374 } 6375 for (int i=0; i<intents.length; i++) { 6376 Intent intent = intents[i]; 6377 if (intent != null) { 6378 if (intent.hasFileDescriptors()) { 6379 throw new IllegalArgumentException("File descriptors passed in Intent"); 6380 } 6381 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6382 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6383 throw new IllegalArgumentException( 6384 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6385 } 6386 intents[i] = new Intent(intent); 6387 } 6388 } 6389 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6390 throw new IllegalArgumentException( 6391 "Intent array length does not match resolvedTypes length"); 6392 } 6393 } 6394 if (options != null) { 6395 if (options.hasFileDescriptors()) { 6396 throw new IllegalArgumentException("File descriptors passed in options"); 6397 } 6398 } 6399 6400 synchronized(this) { 6401 int callingUid = Binder.getCallingUid(); 6402 int origUserId = userId; 6403 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6404 type == ActivityManager.INTENT_SENDER_BROADCAST, 6405 ALLOW_NON_FULL, "getIntentSender", null); 6406 if (origUserId == UserHandle.USER_CURRENT) { 6407 // We don't want to evaluate this until the pending intent is 6408 // actually executed. However, we do want to always do the 6409 // security checking for it above. 6410 userId = UserHandle.USER_CURRENT; 6411 } 6412 try { 6413 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6414 int uid = AppGlobals.getPackageManager() 6415 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6416 if (!UserHandle.isSameApp(callingUid, uid)) { 6417 String msg = "Permission Denial: getIntentSender() from pid=" 6418 + Binder.getCallingPid() 6419 + ", uid=" + Binder.getCallingUid() 6420 + ", (need uid=" + uid + ")" 6421 + " is not allowed to send as package " + packageName; 6422 Slog.w(TAG, msg); 6423 throw new SecurityException(msg); 6424 } 6425 } 6426 6427 return getIntentSenderLocked(type, packageName, callingUid, userId, 6428 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6429 6430 } catch (RemoteException e) { 6431 throw new SecurityException(e); 6432 } 6433 } 6434 } 6435 6436 IIntentSender getIntentSenderLocked(int type, String packageName, 6437 int callingUid, int userId, IBinder token, String resultWho, 6438 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6439 Bundle options) { 6440 if (DEBUG_MU) 6441 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6442 ActivityRecord activity = null; 6443 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6444 activity = ActivityRecord.isInStackLocked(token); 6445 if (activity == null) { 6446 return null; 6447 } 6448 if (activity.finishing) { 6449 return null; 6450 } 6451 } 6452 6453 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6454 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6455 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6456 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6457 |PendingIntent.FLAG_UPDATE_CURRENT); 6458 6459 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6460 type, packageName, activity, resultWho, 6461 requestCode, intents, resolvedTypes, flags, options, userId); 6462 WeakReference<PendingIntentRecord> ref; 6463 ref = mIntentSenderRecords.get(key); 6464 PendingIntentRecord rec = ref != null ? ref.get() : null; 6465 if (rec != null) { 6466 if (!cancelCurrent) { 6467 if (updateCurrent) { 6468 if (rec.key.requestIntent != null) { 6469 rec.key.requestIntent.replaceExtras(intents != null ? 6470 intents[intents.length - 1] : null); 6471 } 6472 if (intents != null) { 6473 intents[intents.length-1] = rec.key.requestIntent; 6474 rec.key.allIntents = intents; 6475 rec.key.allResolvedTypes = resolvedTypes; 6476 } else { 6477 rec.key.allIntents = null; 6478 rec.key.allResolvedTypes = null; 6479 } 6480 } 6481 return rec; 6482 } 6483 rec.canceled = true; 6484 mIntentSenderRecords.remove(key); 6485 } 6486 if (noCreate) { 6487 return rec; 6488 } 6489 rec = new PendingIntentRecord(this, key, callingUid); 6490 mIntentSenderRecords.put(key, rec.ref); 6491 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6492 if (activity.pendingResults == null) { 6493 activity.pendingResults 6494 = new HashSet<WeakReference<PendingIntentRecord>>(); 6495 } 6496 activity.pendingResults.add(rec.ref); 6497 } 6498 return rec; 6499 } 6500 6501 @Override 6502 public void cancelIntentSender(IIntentSender sender) { 6503 if (!(sender instanceof PendingIntentRecord)) { 6504 return; 6505 } 6506 synchronized(this) { 6507 PendingIntentRecord rec = (PendingIntentRecord)sender; 6508 try { 6509 int uid = AppGlobals.getPackageManager() 6510 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6511 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6512 String msg = "Permission Denial: cancelIntentSender() from pid=" 6513 + Binder.getCallingPid() 6514 + ", uid=" + Binder.getCallingUid() 6515 + " is not allowed to cancel packges " 6516 + rec.key.packageName; 6517 Slog.w(TAG, msg); 6518 throw new SecurityException(msg); 6519 } 6520 } catch (RemoteException e) { 6521 throw new SecurityException(e); 6522 } 6523 cancelIntentSenderLocked(rec, true); 6524 } 6525 } 6526 6527 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6528 rec.canceled = true; 6529 mIntentSenderRecords.remove(rec.key); 6530 if (cleanActivity && rec.key.activity != null) { 6531 rec.key.activity.pendingResults.remove(rec.ref); 6532 } 6533 } 6534 6535 @Override 6536 public String getPackageForIntentSender(IIntentSender pendingResult) { 6537 if (!(pendingResult instanceof PendingIntentRecord)) { 6538 return null; 6539 } 6540 try { 6541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6542 return res.key.packageName; 6543 } catch (ClassCastException e) { 6544 } 6545 return null; 6546 } 6547 6548 @Override 6549 public int getUidForIntentSender(IIntentSender sender) { 6550 if (sender instanceof PendingIntentRecord) { 6551 try { 6552 PendingIntentRecord res = (PendingIntentRecord)sender; 6553 return res.uid; 6554 } catch (ClassCastException e) { 6555 } 6556 } 6557 return -1; 6558 } 6559 6560 @Override 6561 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6562 if (!(pendingResult instanceof PendingIntentRecord)) { 6563 return false; 6564 } 6565 try { 6566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6567 if (res.key.allIntents == null) { 6568 return false; 6569 } 6570 for (int i=0; i<res.key.allIntents.length; i++) { 6571 Intent intent = res.key.allIntents[i]; 6572 if (intent.getPackage() != null && intent.getComponent() != null) { 6573 return false; 6574 } 6575 } 6576 return true; 6577 } catch (ClassCastException e) { 6578 } 6579 return false; 6580 } 6581 6582 @Override 6583 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6584 if (!(pendingResult instanceof PendingIntentRecord)) { 6585 return false; 6586 } 6587 try { 6588 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6589 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6590 return true; 6591 } 6592 return false; 6593 } catch (ClassCastException e) { 6594 } 6595 return false; 6596 } 6597 6598 @Override 6599 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6600 if (!(pendingResult instanceof PendingIntentRecord)) { 6601 return null; 6602 } 6603 try { 6604 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6605 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6606 } catch (ClassCastException e) { 6607 } 6608 return null; 6609 } 6610 6611 @Override 6612 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6613 if (!(pendingResult instanceof PendingIntentRecord)) { 6614 return null; 6615 } 6616 try { 6617 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6618 Intent intent = res.key.requestIntent; 6619 if (intent != null) { 6620 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6621 || res.lastTagPrefix.equals(prefix))) { 6622 return res.lastTag; 6623 } 6624 res.lastTagPrefix = prefix; 6625 StringBuilder sb = new StringBuilder(128); 6626 if (prefix != null) { 6627 sb.append(prefix); 6628 } 6629 if (intent.getAction() != null) { 6630 sb.append(intent.getAction()); 6631 } else if (intent.getComponent() != null) { 6632 intent.getComponent().appendShortString(sb); 6633 } else { 6634 sb.append("?"); 6635 } 6636 return res.lastTag = sb.toString(); 6637 } 6638 } catch (ClassCastException e) { 6639 } 6640 return null; 6641 } 6642 6643 @Override 6644 public void setProcessLimit(int max) { 6645 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6646 "setProcessLimit()"); 6647 synchronized (this) { 6648 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6649 mProcessLimitOverride = max; 6650 } 6651 trimApplications(); 6652 } 6653 6654 @Override 6655 public int getProcessLimit() { 6656 synchronized (this) { 6657 return mProcessLimitOverride; 6658 } 6659 } 6660 6661 void foregroundTokenDied(ForegroundToken token) { 6662 synchronized (ActivityManagerService.this) { 6663 synchronized (mPidsSelfLocked) { 6664 ForegroundToken cur 6665 = mForegroundProcesses.get(token.pid); 6666 if (cur != token) { 6667 return; 6668 } 6669 mForegroundProcesses.remove(token.pid); 6670 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6671 if (pr == null) { 6672 return; 6673 } 6674 pr.forcingToForeground = null; 6675 updateProcessForegroundLocked(pr, false, false); 6676 } 6677 updateOomAdjLocked(); 6678 } 6679 } 6680 6681 @Override 6682 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6683 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6684 "setProcessForeground()"); 6685 synchronized(this) { 6686 boolean changed = false; 6687 6688 synchronized (mPidsSelfLocked) { 6689 ProcessRecord pr = mPidsSelfLocked.get(pid); 6690 if (pr == null && isForeground) { 6691 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6692 return; 6693 } 6694 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6695 if (oldToken != null) { 6696 oldToken.token.unlinkToDeath(oldToken, 0); 6697 mForegroundProcesses.remove(pid); 6698 if (pr != null) { 6699 pr.forcingToForeground = null; 6700 } 6701 changed = true; 6702 } 6703 if (isForeground && token != null) { 6704 ForegroundToken newToken = new ForegroundToken() { 6705 @Override 6706 public void binderDied() { 6707 foregroundTokenDied(this); 6708 } 6709 }; 6710 newToken.pid = pid; 6711 newToken.token = token; 6712 try { 6713 token.linkToDeath(newToken, 0); 6714 mForegroundProcesses.put(pid, newToken); 6715 pr.forcingToForeground = token; 6716 changed = true; 6717 } catch (RemoteException e) { 6718 // If the process died while doing this, we will later 6719 // do the cleanup with the process death link. 6720 } 6721 } 6722 } 6723 6724 if (changed) { 6725 updateOomAdjLocked(); 6726 } 6727 } 6728 } 6729 6730 // ========================================================= 6731 // PERMISSIONS 6732 // ========================================================= 6733 6734 static class PermissionController extends IPermissionController.Stub { 6735 ActivityManagerService mActivityManagerService; 6736 PermissionController(ActivityManagerService activityManagerService) { 6737 mActivityManagerService = activityManagerService; 6738 } 6739 6740 @Override 6741 public boolean checkPermission(String permission, int pid, int uid) { 6742 return mActivityManagerService.checkPermission(permission, pid, 6743 uid) == PackageManager.PERMISSION_GRANTED; 6744 } 6745 } 6746 6747 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6748 @Override 6749 public int checkComponentPermission(String permission, int pid, int uid, 6750 int owningUid, boolean exported) { 6751 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6752 owningUid, exported); 6753 } 6754 6755 @Override 6756 public Object getAMSLock() { 6757 return ActivityManagerService.this; 6758 } 6759 } 6760 6761 /** 6762 * This can be called with or without the global lock held. 6763 */ 6764 int checkComponentPermission(String permission, int pid, int uid, 6765 int owningUid, boolean exported) { 6766 // We might be performing an operation on behalf of an indirect binder 6767 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6768 // client identity accordingly before proceeding. 6769 Identity tlsIdentity = sCallerIdentity.get(); 6770 if (tlsIdentity != null) { 6771 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6772 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6773 uid = tlsIdentity.uid; 6774 pid = tlsIdentity.pid; 6775 } 6776 6777 if (pid == MY_PID) { 6778 return PackageManager.PERMISSION_GRANTED; 6779 } 6780 6781 return ActivityManager.checkComponentPermission(permission, uid, 6782 owningUid, exported); 6783 } 6784 6785 /** 6786 * As the only public entry point for permissions checking, this method 6787 * can enforce the semantic that requesting a check on a null global 6788 * permission is automatically denied. (Internally a null permission 6789 * string is used when calling {@link #checkComponentPermission} in cases 6790 * when only uid-based security is needed.) 6791 * 6792 * This can be called with or without the global lock held. 6793 */ 6794 @Override 6795 public int checkPermission(String permission, int pid, int uid) { 6796 if (permission == null) { 6797 return PackageManager.PERMISSION_DENIED; 6798 } 6799 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6800 } 6801 6802 /** 6803 * Binder IPC calls go through the public entry point. 6804 * This can be called with or without the global lock held. 6805 */ 6806 int checkCallingPermission(String permission) { 6807 return checkPermission(permission, 6808 Binder.getCallingPid(), 6809 UserHandle.getAppId(Binder.getCallingUid())); 6810 } 6811 6812 /** 6813 * This can be called with or without the global lock held. 6814 */ 6815 void enforceCallingPermission(String permission, String func) { 6816 if (checkCallingPermission(permission) 6817 == PackageManager.PERMISSION_GRANTED) { 6818 return; 6819 } 6820 6821 String msg = "Permission Denial: " + func + " from pid=" 6822 + Binder.getCallingPid() 6823 + ", uid=" + Binder.getCallingUid() 6824 + " requires " + permission; 6825 Slog.w(TAG, msg); 6826 throw new SecurityException(msg); 6827 } 6828 6829 /** 6830 * Determine if UID is holding permissions required to access {@link Uri} in 6831 * the given {@link ProviderInfo}. Final permission checking is always done 6832 * in {@link ContentProvider}. 6833 */ 6834 private final boolean checkHoldingPermissionsLocked( 6835 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6836 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6837 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6838 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6839 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6840 != PERMISSION_GRANTED) { 6841 return false; 6842 } 6843 } 6844 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6845 } 6846 6847 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6848 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6849 if (pi.applicationInfo.uid == uid) { 6850 return true; 6851 } else if (!pi.exported) { 6852 return false; 6853 } 6854 6855 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6856 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6857 try { 6858 // check if target holds top-level <provider> permissions 6859 if (!readMet && pi.readPermission != null && considerUidPermissions 6860 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6861 readMet = true; 6862 } 6863 if (!writeMet && pi.writePermission != null && considerUidPermissions 6864 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6865 writeMet = true; 6866 } 6867 6868 // track if unprotected read/write is allowed; any denied 6869 // <path-permission> below removes this ability 6870 boolean allowDefaultRead = pi.readPermission == null; 6871 boolean allowDefaultWrite = pi.writePermission == null; 6872 6873 // check if target holds any <path-permission> that match uri 6874 final PathPermission[] pps = pi.pathPermissions; 6875 if (pps != null) { 6876 final String path = grantUri.uri.getPath(); 6877 int i = pps.length; 6878 while (i > 0 && (!readMet || !writeMet)) { 6879 i--; 6880 PathPermission pp = pps[i]; 6881 if (pp.match(path)) { 6882 if (!readMet) { 6883 final String pprperm = pp.getReadPermission(); 6884 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6885 + pprperm + " for " + pp.getPath() 6886 + ": match=" + pp.match(path) 6887 + " check=" + pm.checkUidPermission(pprperm, uid)); 6888 if (pprperm != null) { 6889 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6890 == PERMISSION_GRANTED) { 6891 readMet = true; 6892 } else { 6893 allowDefaultRead = false; 6894 } 6895 } 6896 } 6897 if (!writeMet) { 6898 final String ppwperm = pp.getWritePermission(); 6899 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6900 + ppwperm + " for " + pp.getPath() 6901 + ": match=" + pp.match(path) 6902 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6903 if (ppwperm != null) { 6904 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6905 == PERMISSION_GRANTED) { 6906 writeMet = true; 6907 } else { 6908 allowDefaultWrite = false; 6909 } 6910 } 6911 } 6912 } 6913 } 6914 } 6915 6916 // grant unprotected <provider> read/write, if not blocked by 6917 // <path-permission> above 6918 if (allowDefaultRead) readMet = true; 6919 if (allowDefaultWrite) writeMet = true; 6920 6921 } catch (RemoteException e) { 6922 return false; 6923 } 6924 6925 return readMet && writeMet; 6926 } 6927 6928 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6929 ProviderInfo pi = null; 6930 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6931 if (cpr != null) { 6932 pi = cpr.info; 6933 } else { 6934 try { 6935 pi = AppGlobals.getPackageManager().resolveContentProvider( 6936 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6937 } catch (RemoteException ex) { 6938 } 6939 } 6940 return pi; 6941 } 6942 6943 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6944 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6945 if (targetUris != null) { 6946 return targetUris.get(grantUri); 6947 } 6948 return null; 6949 } 6950 6951 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6952 String targetPkg, int targetUid, GrantUri grantUri) { 6953 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6954 if (targetUris == null) { 6955 targetUris = Maps.newArrayMap(); 6956 mGrantedUriPermissions.put(targetUid, targetUris); 6957 } 6958 6959 UriPermission perm = targetUris.get(grantUri); 6960 if (perm == null) { 6961 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6962 targetUris.put(grantUri, perm); 6963 } 6964 6965 return perm; 6966 } 6967 6968 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6969 final int modeFlags) { 6970 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6971 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6972 : UriPermission.STRENGTH_OWNED; 6973 6974 // Root gets to do everything. 6975 if (uid == 0) { 6976 return true; 6977 } 6978 6979 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6980 if (perms == null) return false; 6981 6982 // First look for exact match 6983 final UriPermission exactPerm = perms.get(grantUri); 6984 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6985 return true; 6986 } 6987 6988 // No exact match, look for prefixes 6989 final int N = perms.size(); 6990 for (int i = 0; i < N; i++) { 6991 final UriPermission perm = perms.valueAt(i); 6992 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6993 && perm.getStrength(modeFlags) >= minStrength) { 6994 return true; 6995 } 6996 } 6997 6998 return false; 6999 } 7000 7001 /** 7002 * @param uri This uri must NOT contain an embedded userId. 7003 * @param userId The userId in which the uri is to be resolved. 7004 */ 7005 @Override 7006 public int checkUriPermission(Uri uri, int pid, int uid, 7007 final int modeFlags, int userId) { 7008 enforceNotIsolatedCaller("checkUriPermission"); 7009 7010 // Another redirected-binder-call permissions check as in 7011 // {@link checkComponentPermission}. 7012 Identity tlsIdentity = sCallerIdentity.get(); 7013 if (tlsIdentity != null) { 7014 uid = tlsIdentity.uid; 7015 pid = tlsIdentity.pid; 7016 } 7017 7018 // Our own process gets to do everything. 7019 if (pid == MY_PID) { 7020 return PackageManager.PERMISSION_GRANTED; 7021 } 7022 synchronized (this) { 7023 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7024 ? PackageManager.PERMISSION_GRANTED 7025 : PackageManager.PERMISSION_DENIED; 7026 } 7027 } 7028 7029 /** 7030 * Check if the targetPkg can be granted permission to access uri by 7031 * the callingUid using the given modeFlags. Throws a security exception 7032 * if callingUid is not allowed to do this. Returns the uid of the target 7033 * if the URI permission grant should be performed; returns -1 if it is not 7034 * needed (for example targetPkg already has permission to access the URI). 7035 * If you already know the uid of the target, you can supply it in 7036 * lastTargetUid else set that to -1. 7037 */ 7038 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7039 final int modeFlags, int lastTargetUid) { 7040 if (!Intent.isAccessUriMode(modeFlags)) { 7041 return -1; 7042 } 7043 7044 if (targetPkg != null) { 7045 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7046 "Checking grant " + targetPkg + " permission to " + grantUri); 7047 } 7048 7049 final IPackageManager pm = AppGlobals.getPackageManager(); 7050 7051 // If this is not a content: uri, we can't do anything with it. 7052 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7054 "Can't grant URI permission for non-content URI: " + grantUri); 7055 return -1; 7056 } 7057 7058 final String authority = grantUri.uri.getAuthority(); 7059 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7060 if (pi == null) { 7061 Slog.w(TAG, "No content provider found for permission check: " + 7062 grantUri.uri.toSafeString()); 7063 return -1; 7064 } 7065 7066 int targetUid = lastTargetUid; 7067 if (targetUid < 0 && targetPkg != null) { 7068 try { 7069 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7070 if (targetUid < 0) { 7071 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7072 "Can't grant URI permission no uid for: " + targetPkg); 7073 return -1; 7074 } 7075 } catch (RemoteException ex) { 7076 return -1; 7077 } 7078 } 7079 7080 if (targetUid >= 0) { 7081 // First... does the target actually need this permission? 7082 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7083 // No need to grant the target this permission. 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7085 "Target " + targetPkg + " already has full permission to " + grantUri); 7086 return -1; 7087 } 7088 } else { 7089 // First... there is no target package, so can anyone access it? 7090 boolean allowed = pi.exported; 7091 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7092 if (pi.readPermission != null) { 7093 allowed = false; 7094 } 7095 } 7096 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7097 if (pi.writePermission != null) { 7098 allowed = false; 7099 } 7100 } 7101 if (allowed) { 7102 return -1; 7103 } 7104 } 7105 7106 /* There is a special cross user grant if: 7107 * - The target is on another user. 7108 * - Apps on the current user can access the uri without any uid permissions. 7109 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7110 * grant uri permissions. 7111 */ 7112 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7113 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7114 modeFlags, false /*without considering the uid permissions*/); 7115 7116 // Second... is the provider allowing granting of URI permissions? 7117 if (!specialCrossUserGrant) { 7118 if (!pi.grantUriPermissions) { 7119 throw new SecurityException("Provider " + pi.packageName 7120 + "/" + pi.name 7121 + " does not allow granting of Uri permissions (uri " 7122 + grantUri + ")"); 7123 } 7124 if (pi.uriPermissionPatterns != null) { 7125 final int N = pi.uriPermissionPatterns.length; 7126 boolean allowed = false; 7127 for (int i=0; i<N; i++) { 7128 if (pi.uriPermissionPatterns[i] != null 7129 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7130 allowed = true; 7131 break; 7132 } 7133 } 7134 if (!allowed) { 7135 throw new SecurityException("Provider " + pi.packageName 7136 + "/" + pi.name 7137 + " does not allow granting of permission to path of Uri " 7138 + grantUri); 7139 } 7140 } 7141 } 7142 7143 // Third... does the caller itself have permission to access 7144 // this uri? 7145 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7146 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7147 // Require they hold a strong enough Uri permission 7148 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7149 throw new SecurityException("Uid " + callingUid 7150 + " does not have permission to uri " + grantUri); 7151 } 7152 } 7153 } 7154 return targetUid; 7155 } 7156 7157 /** 7158 * @param uri This uri must NOT contain an embedded userId. 7159 * @param userId The userId in which the uri is to be resolved. 7160 */ 7161 @Override 7162 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7163 final int modeFlags, int userId) { 7164 enforceNotIsolatedCaller("checkGrantUriPermission"); 7165 synchronized(this) { 7166 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7167 new GrantUri(userId, uri, false), modeFlags, -1); 7168 } 7169 } 7170 7171 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7172 final int modeFlags, UriPermissionOwner owner) { 7173 if (!Intent.isAccessUriMode(modeFlags)) { 7174 return; 7175 } 7176 7177 // So here we are: the caller has the assumed permission 7178 // to the uri, and the target doesn't. Let's now give this to 7179 // the target. 7180 7181 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7182 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7183 7184 final String authority = grantUri.uri.getAuthority(); 7185 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7186 if (pi == null) { 7187 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7188 return; 7189 } 7190 7191 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7192 grantUri.prefix = true; 7193 } 7194 final UriPermission perm = findOrCreateUriPermissionLocked( 7195 pi.packageName, targetPkg, targetUid, grantUri); 7196 perm.grantModes(modeFlags, owner); 7197 } 7198 7199 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7200 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7201 if (targetPkg == null) { 7202 throw new NullPointerException("targetPkg"); 7203 } 7204 int targetUid; 7205 final IPackageManager pm = AppGlobals.getPackageManager(); 7206 try { 7207 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7208 } catch (RemoteException ex) { 7209 return; 7210 } 7211 7212 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7213 targetUid); 7214 if (targetUid < 0) { 7215 return; 7216 } 7217 7218 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7219 owner); 7220 } 7221 7222 static class NeededUriGrants extends ArrayList<GrantUri> { 7223 final String targetPkg; 7224 final int targetUid; 7225 final int flags; 7226 7227 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7228 this.targetPkg = targetPkg; 7229 this.targetUid = targetUid; 7230 this.flags = flags; 7231 } 7232 } 7233 7234 /** 7235 * Like checkGrantUriPermissionLocked, but takes an Intent. 7236 */ 7237 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7238 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7239 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7240 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7241 + " clip=" + (intent != null ? intent.getClipData() : null) 7242 + " from " + intent + "; flags=0x" 7243 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7244 7245 if (targetPkg == null) { 7246 throw new NullPointerException("targetPkg"); 7247 } 7248 7249 if (intent == null) { 7250 return null; 7251 } 7252 Uri data = intent.getData(); 7253 ClipData clip = intent.getClipData(); 7254 if (data == null && clip == null) { 7255 return null; 7256 } 7257 // Default userId for uris in the intent (if they don't specify it themselves) 7258 int contentUserHint = intent.getContentUserHint(); 7259 if (contentUserHint == UserHandle.USER_CURRENT) { 7260 contentUserHint = UserHandle.getUserId(callingUid); 7261 } 7262 final IPackageManager pm = AppGlobals.getPackageManager(); 7263 int targetUid; 7264 if (needed != null) { 7265 targetUid = needed.targetUid; 7266 } else { 7267 try { 7268 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7269 } catch (RemoteException ex) { 7270 return null; 7271 } 7272 if (targetUid < 0) { 7273 if (DEBUG_URI_PERMISSION) { 7274 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7275 + " on user " + targetUserId); 7276 } 7277 return null; 7278 } 7279 } 7280 if (data != null) { 7281 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7282 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7283 targetUid); 7284 if (targetUid > 0) { 7285 if (needed == null) { 7286 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7287 } 7288 needed.add(grantUri); 7289 } 7290 } 7291 if (clip != null) { 7292 for (int i=0; i<clip.getItemCount(); i++) { 7293 Uri uri = clip.getItemAt(i).getUri(); 7294 if (uri != null) { 7295 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7296 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7297 targetUid); 7298 if (targetUid > 0) { 7299 if (needed == null) { 7300 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7301 } 7302 needed.add(grantUri); 7303 } 7304 } else { 7305 Intent clipIntent = clip.getItemAt(i).getIntent(); 7306 if (clipIntent != null) { 7307 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7308 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7309 if (newNeeded != null) { 7310 needed = newNeeded; 7311 } 7312 } 7313 } 7314 } 7315 } 7316 7317 return needed; 7318 } 7319 7320 /** 7321 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7322 */ 7323 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7324 UriPermissionOwner owner) { 7325 if (needed != null) { 7326 for (int i=0; i<needed.size(); i++) { 7327 GrantUri grantUri = needed.get(i); 7328 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7329 grantUri, needed.flags, owner); 7330 } 7331 } 7332 } 7333 7334 void grantUriPermissionFromIntentLocked(int callingUid, 7335 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7336 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7337 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7338 if (needed == null) { 7339 return; 7340 } 7341 7342 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7343 } 7344 7345 /** 7346 * @param uri This uri must NOT contain an embedded userId. 7347 * @param userId The userId in which the uri is to be resolved. 7348 */ 7349 @Override 7350 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7351 final int modeFlags, int userId) { 7352 enforceNotIsolatedCaller("grantUriPermission"); 7353 GrantUri grantUri = new GrantUri(userId, uri, false); 7354 synchronized(this) { 7355 final ProcessRecord r = getRecordForAppLocked(caller); 7356 if (r == null) { 7357 throw new SecurityException("Unable to find app for caller " 7358 + caller 7359 + " when granting permission to uri " + grantUri); 7360 } 7361 if (targetPkg == null) { 7362 throw new IllegalArgumentException("null target"); 7363 } 7364 if (grantUri == null) { 7365 throw new IllegalArgumentException("null uri"); 7366 } 7367 7368 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7369 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7370 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7371 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7372 7373 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7374 UserHandle.getUserId(r.uid)); 7375 } 7376 } 7377 7378 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7379 if (perm.modeFlags == 0) { 7380 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7381 perm.targetUid); 7382 if (perms != null) { 7383 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7384 "Removing " + perm.targetUid + " permission to " + perm.uri); 7385 7386 perms.remove(perm.uri); 7387 if (perms.isEmpty()) { 7388 mGrantedUriPermissions.remove(perm.targetUid); 7389 } 7390 } 7391 } 7392 } 7393 7394 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7395 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7396 7397 final IPackageManager pm = AppGlobals.getPackageManager(); 7398 final String authority = grantUri.uri.getAuthority(); 7399 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7400 if (pi == null) { 7401 Slog.w(TAG, "No content provider found for permission revoke: " 7402 + grantUri.toSafeString()); 7403 return; 7404 } 7405 7406 // Does the caller have this permission on the URI? 7407 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7408 // If they don't have direct access to the URI, then revoke any 7409 // ownerless URI permissions that have been granted to them. 7410 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7411 if (perms != null) { 7412 boolean persistChanged = false; 7413 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7414 final UriPermission perm = it.next(); 7415 if (perm.uri.sourceUserId == grantUri.sourceUserId 7416 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7417 if (DEBUG_URI_PERMISSION) 7418 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7419 " permission to " + perm.uri); 7420 persistChanged |= perm.revokeModes( 7421 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7422 if (perm.modeFlags == 0) { 7423 it.remove(); 7424 } 7425 } 7426 } 7427 if (perms.isEmpty()) { 7428 mGrantedUriPermissions.remove(callingUid); 7429 } 7430 if (persistChanged) { 7431 schedulePersistUriGrants(); 7432 } 7433 } 7434 return; 7435 } 7436 7437 boolean persistChanged = false; 7438 7439 // Go through all of the permissions and remove any that match. 7440 int N = mGrantedUriPermissions.size(); 7441 for (int i = 0; i < N; i++) { 7442 final int targetUid = mGrantedUriPermissions.keyAt(i); 7443 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7444 7445 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7446 final UriPermission perm = it.next(); 7447 if (perm.uri.sourceUserId == grantUri.sourceUserId 7448 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7449 if (DEBUG_URI_PERMISSION) 7450 Slog.v(TAG, 7451 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7452 persistChanged |= perm.revokeModes( 7453 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7454 if (perm.modeFlags == 0) { 7455 it.remove(); 7456 } 7457 } 7458 } 7459 7460 if (perms.isEmpty()) { 7461 mGrantedUriPermissions.remove(targetUid); 7462 N--; 7463 i--; 7464 } 7465 } 7466 7467 if (persistChanged) { 7468 schedulePersistUriGrants(); 7469 } 7470 } 7471 7472 /** 7473 * @param uri This uri must NOT contain an embedded userId. 7474 * @param userId The userId in which the uri is to be resolved. 7475 */ 7476 @Override 7477 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7478 int userId) { 7479 enforceNotIsolatedCaller("revokeUriPermission"); 7480 synchronized(this) { 7481 final ProcessRecord r = getRecordForAppLocked(caller); 7482 if (r == null) { 7483 throw new SecurityException("Unable to find app for caller " 7484 + caller 7485 + " when revoking permission to uri " + uri); 7486 } 7487 if (uri == null) { 7488 Slog.w(TAG, "revokeUriPermission: null uri"); 7489 return; 7490 } 7491 7492 if (!Intent.isAccessUriMode(modeFlags)) { 7493 return; 7494 } 7495 7496 final IPackageManager pm = AppGlobals.getPackageManager(); 7497 final String authority = uri.getAuthority(); 7498 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7499 if (pi == null) { 7500 Slog.w(TAG, "No content provider found for permission revoke: " 7501 + uri.toSafeString()); 7502 return; 7503 } 7504 7505 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7506 } 7507 } 7508 7509 /** 7510 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7511 * given package. 7512 * 7513 * @param packageName Package name to match, or {@code null} to apply to all 7514 * packages. 7515 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7516 * to all users. 7517 * @param persistable If persistable grants should be removed. 7518 */ 7519 private void removeUriPermissionsForPackageLocked( 7520 String packageName, int userHandle, boolean persistable) { 7521 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7522 throw new IllegalArgumentException("Must narrow by either package or user"); 7523 } 7524 7525 boolean persistChanged = false; 7526 7527 int N = mGrantedUriPermissions.size(); 7528 for (int i = 0; i < N; i++) { 7529 final int targetUid = mGrantedUriPermissions.keyAt(i); 7530 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7531 7532 // Only inspect grants matching user 7533 if (userHandle == UserHandle.USER_ALL 7534 || userHandle == UserHandle.getUserId(targetUid)) { 7535 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7536 final UriPermission perm = it.next(); 7537 7538 // Only inspect grants matching package 7539 if (packageName == null || perm.sourcePkg.equals(packageName) 7540 || perm.targetPkg.equals(packageName)) { 7541 persistChanged |= perm.revokeModes(persistable 7542 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7543 7544 // Only remove when no modes remain; any persisted grants 7545 // will keep this alive. 7546 if (perm.modeFlags == 0) { 7547 it.remove(); 7548 } 7549 } 7550 } 7551 7552 if (perms.isEmpty()) { 7553 mGrantedUriPermissions.remove(targetUid); 7554 N--; 7555 i--; 7556 } 7557 } 7558 } 7559 7560 if (persistChanged) { 7561 schedulePersistUriGrants(); 7562 } 7563 } 7564 7565 @Override 7566 public IBinder newUriPermissionOwner(String name) { 7567 enforceNotIsolatedCaller("newUriPermissionOwner"); 7568 synchronized(this) { 7569 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7570 return owner.getExternalTokenLocked(); 7571 } 7572 } 7573 7574 /** 7575 * @param uri This uri must NOT contain an embedded userId. 7576 * @param sourceUserId The userId in which the uri is to be resolved. 7577 * @param targetUserId The userId of the app that receives the grant. 7578 */ 7579 @Override 7580 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7581 final int modeFlags, int sourceUserId, int targetUserId) { 7582 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7583 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7584 synchronized(this) { 7585 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7586 if (owner == null) { 7587 throw new IllegalArgumentException("Unknown owner: " + token); 7588 } 7589 if (fromUid != Binder.getCallingUid()) { 7590 if (Binder.getCallingUid() != Process.myUid()) { 7591 // Only system code can grant URI permissions on behalf 7592 // of other users. 7593 throw new SecurityException("nice try"); 7594 } 7595 } 7596 if (targetPkg == null) { 7597 throw new IllegalArgumentException("null target"); 7598 } 7599 if (uri == null) { 7600 throw new IllegalArgumentException("null uri"); 7601 } 7602 7603 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7604 modeFlags, owner, targetUserId); 7605 } 7606 } 7607 7608 /** 7609 * @param uri This uri must NOT contain an embedded userId. 7610 * @param userId The userId in which the uri is to be resolved. 7611 */ 7612 @Override 7613 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7614 synchronized(this) { 7615 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7616 if (owner == null) { 7617 throw new IllegalArgumentException("Unknown owner: " + token); 7618 } 7619 7620 if (uri == null) { 7621 owner.removeUriPermissionsLocked(mode); 7622 } else { 7623 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7624 } 7625 } 7626 } 7627 7628 private void schedulePersistUriGrants() { 7629 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7630 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7631 10 * DateUtils.SECOND_IN_MILLIS); 7632 } 7633 } 7634 7635 private void writeGrantedUriPermissions() { 7636 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7637 7638 // Snapshot permissions so we can persist without lock 7639 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7640 synchronized (this) { 7641 final int size = mGrantedUriPermissions.size(); 7642 for (int i = 0; i < size; i++) { 7643 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7644 for (UriPermission perm : perms.values()) { 7645 if (perm.persistedModeFlags != 0) { 7646 persist.add(perm.snapshot()); 7647 } 7648 } 7649 } 7650 } 7651 7652 FileOutputStream fos = null; 7653 try { 7654 fos = mGrantFile.startWrite(); 7655 7656 XmlSerializer out = new FastXmlSerializer(); 7657 out.setOutput(fos, "utf-8"); 7658 out.startDocument(null, true); 7659 out.startTag(null, TAG_URI_GRANTS); 7660 for (UriPermission.Snapshot perm : persist) { 7661 out.startTag(null, TAG_URI_GRANT); 7662 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7663 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7664 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7665 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7666 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7667 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7668 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7669 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7670 out.endTag(null, TAG_URI_GRANT); 7671 } 7672 out.endTag(null, TAG_URI_GRANTS); 7673 out.endDocument(); 7674 7675 mGrantFile.finishWrite(fos); 7676 } catch (IOException e) { 7677 if (fos != null) { 7678 mGrantFile.failWrite(fos); 7679 } 7680 } 7681 } 7682 7683 private void readGrantedUriPermissionsLocked() { 7684 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7685 7686 final long now = System.currentTimeMillis(); 7687 7688 FileInputStream fis = null; 7689 try { 7690 fis = mGrantFile.openRead(); 7691 final XmlPullParser in = Xml.newPullParser(); 7692 in.setInput(fis, null); 7693 7694 int type; 7695 while ((type = in.next()) != END_DOCUMENT) { 7696 final String tag = in.getName(); 7697 if (type == START_TAG) { 7698 if (TAG_URI_GRANT.equals(tag)) { 7699 final int sourceUserId; 7700 final int targetUserId; 7701 final int userHandle = readIntAttribute(in, 7702 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7703 if (userHandle != UserHandle.USER_NULL) { 7704 // For backwards compatibility. 7705 sourceUserId = userHandle; 7706 targetUserId = userHandle; 7707 } else { 7708 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7709 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7710 } 7711 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7712 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7713 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7714 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7715 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7716 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7717 7718 // Sanity check that provider still belongs to source package 7719 final ProviderInfo pi = getProviderInfoLocked( 7720 uri.getAuthority(), sourceUserId); 7721 if (pi != null && sourcePkg.equals(pi.packageName)) { 7722 int targetUid = -1; 7723 try { 7724 targetUid = AppGlobals.getPackageManager() 7725 .getPackageUid(targetPkg, targetUserId); 7726 } catch (RemoteException e) { 7727 } 7728 if (targetUid != -1) { 7729 final UriPermission perm = findOrCreateUriPermissionLocked( 7730 sourcePkg, targetPkg, targetUid, 7731 new GrantUri(sourceUserId, uri, prefix)); 7732 perm.initPersistedModes(modeFlags, createdTime); 7733 } 7734 } else { 7735 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7736 + " but instead found " + pi); 7737 } 7738 } 7739 } 7740 } 7741 } catch (FileNotFoundException e) { 7742 // Missing grants is okay 7743 } catch (IOException e) { 7744 Slog.wtf(TAG, "Failed reading Uri grants", e); 7745 } catch (XmlPullParserException e) { 7746 Slog.wtf(TAG, "Failed reading Uri grants", e); 7747 } finally { 7748 IoUtils.closeQuietly(fis); 7749 } 7750 } 7751 7752 /** 7753 * @param uri This uri must NOT contain an embedded userId. 7754 * @param userId The userId in which the uri is to be resolved. 7755 */ 7756 @Override 7757 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7758 enforceNotIsolatedCaller("takePersistableUriPermission"); 7759 7760 Preconditions.checkFlagsArgument(modeFlags, 7761 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7762 7763 synchronized (this) { 7764 final int callingUid = Binder.getCallingUid(); 7765 boolean persistChanged = false; 7766 GrantUri grantUri = new GrantUri(userId, uri, false); 7767 7768 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7769 new GrantUri(userId, uri, false)); 7770 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7771 new GrantUri(userId, uri, true)); 7772 7773 final boolean exactValid = (exactPerm != null) 7774 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7775 final boolean prefixValid = (prefixPerm != null) 7776 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7777 7778 if (!(exactValid || prefixValid)) { 7779 throw new SecurityException("No persistable permission grants found for UID " 7780 + callingUid + " and Uri " + grantUri.toSafeString()); 7781 } 7782 7783 if (exactValid) { 7784 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7785 } 7786 if (prefixValid) { 7787 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7788 } 7789 7790 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7791 7792 if (persistChanged) { 7793 schedulePersistUriGrants(); 7794 } 7795 } 7796 } 7797 7798 /** 7799 * @param uri This uri must NOT contain an embedded userId. 7800 * @param userId The userId in which the uri is to be resolved. 7801 */ 7802 @Override 7803 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7804 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7805 7806 Preconditions.checkFlagsArgument(modeFlags, 7807 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7808 7809 synchronized (this) { 7810 final int callingUid = Binder.getCallingUid(); 7811 boolean persistChanged = false; 7812 7813 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7814 new GrantUri(userId, uri, false)); 7815 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7816 new GrantUri(userId, uri, true)); 7817 if (exactPerm == null && prefixPerm == null) { 7818 throw new SecurityException("No permission grants found for UID " + callingUid 7819 + " and Uri " + uri.toSafeString()); 7820 } 7821 7822 if (exactPerm != null) { 7823 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7824 removeUriPermissionIfNeededLocked(exactPerm); 7825 } 7826 if (prefixPerm != null) { 7827 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7828 removeUriPermissionIfNeededLocked(prefixPerm); 7829 } 7830 7831 if (persistChanged) { 7832 schedulePersistUriGrants(); 7833 } 7834 } 7835 } 7836 7837 /** 7838 * Prune any older {@link UriPermission} for the given UID until outstanding 7839 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7840 * 7841 * @return if any mutations occured that require persisting. 7842 */ 7843 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7844 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7845 if (perms == null) return false; 7846 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7847 7848 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7849 for (UriPermission perm : perms.values()) { 7850 if (perm.persistedModeFlags != 0) { 7851 persisted.add(perm); 7852 } 7853 } 7854 7855 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7856 if (trimCount <= 0) return false; 7857 7858 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7859 for (int i = 0; i < trimCount; i++) { 7860 final UriPermission perm = persisted.get(i); 7861 7862 if (DEBUG_URI_PERMISSION) { 7863 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7864 } 7865 7866 perm.releasePersistableModes(~0); 7867 removeUriPermissionIfNeededLocked(perm); 7868 } 7869 7870 return true; 7871 } 7872 7873 @Override 7874 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7875 String packageName, boolean incoming) { 7876 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7877 Preconditions.checkNotNull(packageName, "packageName"); 7878 7879 final int callingUid = Binder.getCallingUid(); 7880 final IPackageManager pm = AppGlobals.getPackageManager(); 7881 try { 7882 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7883 if (packageUid != callingUid) { 7884 throw new SecurityException( 7885 "Package " + packageName + " does not belong to calling UID " + callingUid); 7886 } 7887 } catch (RemoteException e) { 7888 throw new SecurityException("Failed to verify package name ownership"); 7889 } 7890 7891 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7892 synchronized (this) { 7893 if (incoming) { 7894 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7895 callingUid); 7896 if (perms == null) { 7897 Slog.w(TAG, "No permission grants found for " + packageName); 7898 } else { 7899 for (UriPermission perm : perms.values()) { 7900 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7901 result.add(perm.buildPersistedPublicApiObject()); 7902 } 7903 } 7904 } 7905 } else { 7906 final int size = mGrantedUriPermissions.size(); 7907 for (int i = 0; i < size; i++) { 7908 final ArrayMap<GrantUri, UriPermission> perms = 7909 mGrantedUriPermissions.valueAt(i); 7910 for (UriPermission perm : perms.values()) { 7911 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7912 result.add(perm.buildPersistedPublicApiObject()); 7913 } 7914 } 7915 } 7916 } 7917 } 7918 return new ParceledListSlice<android.content.UriPermission>(result); 7919 } 7920 7921 @Override 7922 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7923 synchronized (this) { 7924 ProcessRecord app = 7925 who != null ? getRecordForAppLocked(who) : null; 7926 if (app == null) return; 7927 7928 Message msg = Message.obtain(); 7929 msg.what = WAIT_FOR_DEBUGGER_MSG; 7930 msg.obj = app; 7931 msg.arg1 = waiting ? 1 : 0; 7932 mHandler.sendMessage(msg); 7933 } 7934 } 7935 7936 @Override 7937 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7938 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7939 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7940 outInfo.availMem = Process.getFreeMemory(); 7941 outInfo.totalMem = Process.getTotalMemory(); 7942 outInfo.threshold = homeAppMem; 7943 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7944 outInfo.hiddenAppThreshold = cachedAppMem; 7945 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7946 ProcessList.SERVICE_ADJ); 7947 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7948 ProcessList.VISIBLE_APP_ADJ); 7949 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7950 ProcessList.FOREGROUND_APP_ADJ); 7951 } 7952 7953 // ========================================================= 7954 // TASK MANAGEMENT 7955 // ========================================================= 7956 7957 @Override 7958 public List<IAppTask> getAppTasks(String callingPackage) { 7959 int callingUid = Binder.getCallingUid(); 7960 long ident = Binder.clearCallingIdentity(); 7961 7962 synchronized(this) { 7963 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7964 try { 7965 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7966 7967 final int N = mRecentTasks.size(); 7968 for (int i = 0; i < N; i++) { 7969 TaskRecord tr = mRecentTasks.get(i); 7970 // Skip tasks that do not match the caller. We don't need to verify 7971 // callingPackage, because we are also limiting to callingUid and know 7972 // that will limit to the correct security sandbox. 7973 if (tr.effectiveUid != callingUid) { 7974 continue; 7975 } 7976 Intent intent = tr.getBaseIntent(); 7977 if (intent == null || 7978 !callingPackage.equals(intent.getComponent().getPackageName())) { 7979 continue; 7980 } 7981 ActivityManager.RecentTaskInfo taskInfo = 7982 createRecentTaskInfoFromTaskRecord(tr); 7983 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7984 list.add(taskImpl); 7985 } 7986 } finally { 7987 Binder.restoreCallingIdentity(ident); 7988 } 7989 return list; 7990 } 7991 } 7992 7993 @Override 7994 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7995 final int callingUid = Binder.getCallingUid(); 7996 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7997 7998 synchronized(this) { 7999 if (localLOGV) Slog.v( 8000 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8001 8002 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8003 callingUid); 8004 8005 // TODO: Improve with MRU list from all ActivityStacks. 8006 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8007 } 8008 8009 return list; 8010 } 8011 8012 TaskRecord getMostRecentTask() { 8013 return mRecentTasks.get(0); 8014 } 8015 8016 /** 8017 * Creates a new RecentTaskInfo from a TaskRecord. 8018 */ 8019 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8020 // Update the task description to reflect any changes in the task stack 8021 tr.updateTaskDescription(); 8022 8023 // Compose the recent task info 8024 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8025 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8026 rti.persistentId = tr.taskId; 8027 rti.baseIntent = new Intent(tr.getBaseIntent()); 8028 rti.origActivity = tr.origActivity; 8029 rti.description = tr.lastDescription; 8030 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8031 rti.userId = tr.userId; 8032 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8033 rti.firstActiveTime = tr.firstActiveTime; 8034 rti.lastActiveTime = tr.lastActiveTime; 8035 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8036 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8037 return rti; 8038 } 8039 8040 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8041 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8042 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8043 if (!allowed) { 8044 if (checkPermission(android.Manifest.permission.GET_TASKS, 8045 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8046 // Temporary compatibility: some existing apps on the system image may 8047 // still be requesting the old permission and not switched to the new 8048 // one; if so, we'll still allow them full access. This means we need 8049 // to see if they are holding the old permission and are a system app. 8050 try { 8051 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8052 allowed = true; 8053 Slog.w(TAG, caller + ": caller " + callingUid 8054 + " is using old GET_TASKS but privileged; allowing"); 8055 } 8056 } catch (RemoteException e) { 8057 } 8058 } 8059 } 8060 if (!allowed) { 8061 Slog.w(TAG, caller + ": caller " + callingUid 8062 + " does not hold GET_TASKS; limiting output"); 8063 } 8064 return allowed; 8065 } 8066 8067 @Override 8068 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8069 final int callingUid = Binder.getCallingUid(); 8070 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8071 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8072 8073 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8074 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8075 synchronized (this) { 8076 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8077 callingUid); 8078 final boolean detailed = checkCallingPermission( 8079 android.Manifest.permission.GET_DETAILED_TASKS) 8080 == PackageManager.PERMISSION_GRANTED; 8081 8082 final int N = mRecentTasks.size(); 8083 ArrayList<ActivityManager.RecentTaskInfo> res 8084 = new ArrayList<ActivityManager.RecentTaskInfo>( 8085 maxNum < N ? maxNum : N); 8086 8087 final Set<Integer> includedUsers; 8088 if (includeProfiles) { 8089 includedUsers = getProfileIdsLocked(userId); 8090 } else { 8091 includedUsers = new HashSet<Integer>(); 8092 } 8093 includedUsers.add(Integer.valueOf(userId)); 8094 8095 for (int i=0; i<N && maxNum > 0; i++) { 8096 TaskRecord tr = mRecentTasks.get(i); 8097 // Only add calling user or related users recent tasks 8098 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8099 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8100 continue; 8101 } 8102 8103 // Return the entry if desired by the caller. We always return 8104 // the first entry, because callers always expect this to be the 8105 // foreground app. We may filter others if the caller has 8106 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8107 // we should exclude the entry. 8108 8109 if (i == 0 8110 || withExcluded 8111 || (tr.intent == null) 8112 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8113 == 0)) { 8114 if (!allowed) { 8115 // If the caller doesn't have the GET_TASKS permission, then only 8116 // allow them to see a small subset of tasks -- their own and home. 8117 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8118 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8119 continue; 8120 } 8121 } 8122 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8123 if (tr.stack != null && tr.stack.isHomeStack()) { 8124 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8125 continue; 8126 } 8127 } 8128 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8129 // Don't include auto remove tasks that are finished or finishing. 8130 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8131 + tr); 8132 continue; 8133 } 8134 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8135 && !tr.isAvailable) { 8136 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8137 continue; 8138 } 8139 8140 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8141 if (!detailed) { 8142 rti.baseIntent.replaceExtras((Bundle)null); 8143 } 8144 8145 res.add(rti); 8146 maxNum--; 8147 } 8148 } 8149 return res; 8150 } 8151 } 8152 8153 private TaskRecord recentTaskForIdLocked(int id) { 8154 final int N = mRecentTasks.size(); 8155 for (int i=0; i<N; i++) { 8156 TaskRecord tr = mRecentTasks.get(i); 8157 if (tr.taskId == id) { 8158 return tr; 8159 } 8160 } 8161 return null; 8162 } 8163 8164 @Override 8165 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8166 synchronized (this) { 8167 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8168 "getTaskThumbnail()"); 8169 TaskRecord tr = recentTaskForIdLocked(id); 8170 if (tr != null) { 8171 return tr.getTaskThumbnailLocked(); 8172 } 8173 } 8174 return null; 8175 } 8176 8177 @Override 8178 public int addAppTask(IBinder activityToken, Intent intent, 8179 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8180 final int callingUid = Binder.getCallingUid(); 8181 final long callingIdent = Binder.clearCallingIdentity(); 8182 8183 try { 8184 synchronized (this) { 8185 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8186 if (r == null) { 8187 throw new IllegalArgumentException("Activity does not exist; token=" 8188 + activityToken); 8189 } 8190 ComponentName comp = intent.getComponent(); 8191 if (comp == null) { 8192 throw new IllegalArgumentException("Intent " + intent 8193 + " must specify explicit component"); 8194 } 8195 if (thumbnail.getWidth() != mThumbnailWidth 8196 || thumbnail.getHeight() != mThumbnailHeight) { 8197 throw new IllegalArgumentException("Bad thumbnail size: got " 8198 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8199 + mThumbnailWidth + "x" + mThumbnailHeight); 8200 } 8201 if (intent.getSelector() != null) { 8202 intent.setSelector(null); 8203 } 8204 if (intent.getSourceBounds() != null) { 8205 intent.setSourceBounds(null); 8206 } 8207 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8208 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8209 // The caller has added this as an auto-remove task... that makes no 8210 // sense, so turn off auto-remove. 8211 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8212 } 8213 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8214 // Must be a new task. 8215 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8216 } 8217 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8218 mLastAddedTaskActivity = null; 8219 } 8220 ActivityInfo ainfo = mLastAddedTaskActivity; 8221 if (ainfo == null) { 8222 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8223 comp, 0, UserHandle.getUserId(callingUid)); 8224 if (ainfo.applicationInfo.uid != callingUid) { 8225 throw new SecurityException( 8226 "Can't add task for another application: target uid=" 8227 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8228 } 8229 } 8230 8231 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8232 intent, description); 8233 8234 int trimIdx = trimRecentsForTask(task, false); 8235 if (trimIdx >= 0) { 8236 // If this would have caused a trim, then we'll abort because that 8237 // means it would be added at the end of the list but then just removed. 8238 return -1; 8239 } 8240 8241 final int N = mRecentTasks.size(); 8242 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8243 final TaskRecord tr = mRecentTasks.remove(N - 1); 8244 tr.removedFromRecents(mTaskPersister); 8245 } 8246 8247 task.inRecents = true; 8248 mRecentTasks.add(task); 8249 r.task.stack.addTask(task, false, false); 8250 8251 task.setLastThumbnail(thumbnail); 8252 task.freeLastThumbnail(); 8253 8254 return task.taskId; 8255 } 8256 } finally { 8257 Binder.restoreCallingIdentity(callingIdent); 8258 } 8259 } 8260 8261 @Override 8262 public Point getAppTaskThumbnailSize() { 8263 synchronized (this) { 8264 return new Point(mThumbnailWidth, mThumbnailHeight); 8265 } 8266 } 8267 8268 @Override 8269 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8270 synchronized (this) { 8271 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8272 if (r != null) { 8273 r.setTaskDescription(td); 8274 r.task.updateTaskDescription(); 8275 } 8276 } 8277 } 8278 8279 @Override 8280 public Bitmap getTaskDescriptionIcon(String filename) { 8281 if (!FileUtils.isValidExtFilename(filename) 8282 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8283 throw new IllegalArgumentException("Bad filename: " + filename); 8284 } 8285 return mTaskPersister.getTaskDescriptionIcon(filename); 8286 } 8287 8288 @Override 8289 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8290 throws RemoteException { 8291 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8292 opts.getCustomInPlaceResId() == 0) { 8293 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8294 "with valid animation"); 8295 } 8296 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8297 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8298 opts.getCustomInPlaceResId()); 8299 mWindowManager.executeAppTransition(); 8300 } 8301 8302 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8303 mRecentTasks.remove(tr); 8304 tr.removedFromRecents(mTaskPersister); 8305 ComponentName component = tr.getBaseIntent().getComponent(); 8306 if (component == null) { 8307 Slog.w(TAG, "No component for base intent of task: " + tr); 8308 return; 8309 } 8310 8311 if (!killProcess) { 8312 return; 8313 } 8314 8315 // Determine if the process(es) for this task should be killed. 8316 final String pkg = component.getPackageName(); 8317 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8318 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8319 for (int i = 0; i < pmap.size(); i++) { 8320 8321 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8322 for (int j = 0; j < uids.size(); j++) { 8323 ProcessRecord proc = uids.valueAt(j); 8324 if (proc.userId != tr.userId) { 8325 // Don't kill process for a different user. 8326 continue; 8327 } 8328 if (proc == mHomeProcess) { 8329 // Don't kill the home process along with tasks from the same package. 8330 continue; 8331 } 8332 if (!proc.pkgList.containsKey(pkg)) { 8333 // Don't kill process that is not associated with this task. 8334 continue; 8335 } 8336 8337 for (int k = 0; k < proc.activities.size(); k++) { 8338 TaskRecord otherTask = proc.activities.get(k).task; 8339 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8340 // Don't kill process(es) that has an activity in a different task that is 8341 // also in recents. 8342 return; 8343 } 8344 } 8345 8346 // Add process to kill list. 8347 procsToKill.add(proc); 8348 } 8349 } 8350 8351 // Find any running services associated with this app and stop if needed. 8352 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8353 8354 // Kill the running processes. 8355 for (int i = 0; i < procsToKill.size(); i++) { 8356 ProcessRecord pr = procsToKill.get(i); 8357 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8358 pr.kill("remove task", true); 8359 } else { 8360 pr.waitingToKill = "remove task"; 8361 } 8362 } 8363 } 8364 8365 /** 8366 * Removes the task with the specified task id. 8367 * 8368 * @param taskId Identifier of the task to be removed. 8369 * @param killProcess Kill any process associated with the task if possible. 8370 * @return Returns true if the given task was found and removed. 8371 */ 8372 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8373 TaskRecord tr = recentTaskForIdLocked(taskId); 8374 if (tr != null) { 8375 tr.removeTaskActivitiesLocked(); 8376 cleanUpRemovedTaskLocked(tr, killProcess); 8377 if (tr.isPersistable) { 8378 notifyTaskPersisterLocked(null, true); 8379 } 8380 return true; 8381 } 8382 return false; 8383 } 8384 8385 @Override 8386 public boolean removeTask(int taskId) { 8387 synchronized (this) { 8388 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8389 "removeTask()"); 8390 long ident = Binder.clearCallingIdentity(); 8391 try { 8392 return removeTaskByIdLocked(taskId, true); 8393 } finally { 8394 Binder.restoreCallingIdentity(ident); 8395 } 8396 } 8397 } 8398 8399 /** 8400 * TODO: Add mController hook 8401 */ 8402 @Override 8403 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8404 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8405 "moveTaskToFront()"); 8406 8407 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8408 synchronized(this) { 8409 moveTaskToFrontLocked(taskId, flags, options); 8410 } 8411 } 8412 8413 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8414 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8415 Binder.getCallingUid(), -1, -1, "Task to front")) { 8416 ActivityOptions.abort(options); 8417 return; 8418 } 8419 final long origId = Binder.clearCallingIdentity(); 8420 try { 8421 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8422 if (task == null) { 8423 return; 8424 } 8425 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8426 mStackSupervisor.showLockTaskToast(); 8427 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8428 return; 8429 } 8430 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8431 if (prev != null && prev.isRecentsActivity()) { 8432 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8433 } 8434 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8435 } finally { 8436 Binder.restoreCallingIdentity(origId); 8437 } 8438 ActivityOptions.abort(options); 8439 } 8440 8441 @Override 8442 public void moveTaskToBack(int taskId) { 8443 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8444 "moveTaskToBack()"); 8445 8446 synchronized(this) { 8447 TaskRecord tr = recentTaskForIdLocked(taskId); 8448 if (tr != null) { 8449 if (tr == mStackSupervisor.mLockTaskModeTask) { 8450 mStackSupervisor.showLockTaskToast(); 8451 return; 8452 } 8453 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8454 ActivityStack stack = tr.stack; 8455 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8456 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8457 Binder.getCallingUid(), -1, -1, "Task to back")) { 8458 return; 8459 } 8460 } 8461 final long origId = Binder.clearCallingIdentity(); 8462 try { 8463 stack.moveTaskToBackLocked(taskId, null); 8464 } finally { 8465 Binder.restoreCallingIdentity(origId); 8466 } 8467 } 8468 } 8469 } 8470 8471 /** 8472 * Moves an activity, and all of the other activities within the same task, to the bottom 8473 * of the history stack. The activity's order within the task is unchanged. 8474 * 8475 * @param token A reference to the activity we wish to move 8476 * @param nonRoot If false then this only works if the activity is the root 8477 * of a task; if true it will work for any activity in a task. 8478 * @return Returns true if the move completed, false if not. 8479 */ 8480 @Override 8481 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8482 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8483 synchronized(this) { 8484 final long origId = Binder.clearCallingIdentity(); 8485 try { 8486 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8487 if (taskId >= 0) { 8488 if ((mStackSupervisor.mLockTaskModeTask != null) 8489 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8490 mStackSupervisor.showLockTaskToast(); 8491 return false; 8492 } 8493 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8494 } 8495 } finally { 8496 Binder.restoreCallingIdentity(origId); 8497 } 8498 } 8499 return false; 8500 } 8501 8502 @Override 8503 public void moveTaskBackwards(int task) { 8504 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8505 "moveTaskBackwards()"); 8506 8507 synchronized(this) { 8508 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8509 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8510 return; 8511 } 8512 final long origId = Binder.clearCallingIdentity(); 8513 moveTaskBackwardsLocked(task); 8514 Binder.restoreCallingIdentity(origId); 8515 } 8516 } 8517 8518 private final void moveTaskBackwardsLocked(int task) { 8519 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8520 } 8521 8522 @Override 8523 public IBinder getHomeActivityToken() throws RemoteException { 8524 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8525 "getHomeActivityToken()"); 8526 synchronized (this) { 8527 return mStackSupervisor.getHomeActivityToken(); 8528 } 8529 } 8530 8531 @Override 8532 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8533 IActivityContainerCallback callback) throws RemoteException { 8534 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8535 "createActivityContainer()"); 8536 synchronized (this) { 8537 if (parentActivityToken == null) { 8538 throw new IllegalArgumentException("parent token must not be null"); 8539 } 8540 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8541 if (r == null) { 8542 return null; 8543 } 8544 if (callback == null) { 8545 throw new IllegalArgumentException("callback must not be null"); 8546 } 8547 return mStackSupervisor.createActivityContainer(r, callback); 8548 } 8549 } 8550 8551 @Override 8552 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8553 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8554 "deleteActivityContainer()"); 8555 synchronized (this) { 8556 mStackSupervisor.deleteActivityContainer(container); 8557 } 8558 } 8559 8560 @Override 8561 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8562 throws RemoteException { 8563 synchronized (this) { 8564 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8565 if (stack != null) { 8566 return stack.mActivityContainer; 8567 } 8568 return null; 8569 } 8570 } 8571 8572 @Override 8573 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8574 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8575 "moveTaskToStack()"); 8576 if (stackId == HOME_STACK_ID) { 8577 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8578 new RuntimeException("here").fillInStackTrace()); 8579 } 8580 synchronized (this) { 8581 long ident = Binder.clearCallingIdentity(); 8582 try { 8583 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8584 + stackId + " toTop=" + toTop); 8585 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8586 } finally { 8587 Binder.restoreCallingIdentity(ident); 8588 } 8589 } 8590 } 8591 8592 @Override 8593 public void resizeStack(int stackBoxId, Rect bounds) { 8594 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8595 "resizeStackBox()"); 8596 long ident = Binder.clearCallingIdentity(); 8597 try { 8598 mWindowManager.resizeStack(stackBoxId, bounds); 8599 } finally { 8600 Binder.restoreCallingIdentity(ident); 8601 } 8602 } 8603 8604 @Override 8605 public List<StackInfo> getAllStackInfos() { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getAllStackInfos()"); 8608 long ident = Binder.clearCallingIdentity(); 8609 try { 8610 synchronized (this) { 8611 return mStackSupervisor.getAllStackInfosLocked(); 8612 } 8613 } finally { 8614 Binder.restoreCallingIdentity(ident); 8615 } 8616 } 8617 8618 @Override 8619 public StackInfo getStackInfo(int stackId) { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "getStackInfo()"); 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 return mStackSupervisor.getStackInfoLocked(stackId); 8626 } 8627 } finally { 8628 Binder.restoreCallingIdentity(ident); 8629 } 8630 } 8631 8632 @Override 8633 public boolean isInHomeStack(int taskId) { 8634 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8635 "getStackInfo()"); 8636 long ident = Binder.clearCallingIdentity(); 8637 try { 8638 synchronized (this) { 8639 TaskRecord tr = recentTaskForIdLocked(taskId); 8640 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8641 } 8642 } finally { 8643 Binder.restoreCallingIdentity(ident); 8644 } 8645 } 8646 8647 @Override 8648 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8649 synchronized(this) { 8650 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8651 } 8652 } 8653 8654 private boolean isLockTaskAuthorized(String pkg) { 8655 final DevicePolicyManager dpm = (DevicePolicyManager) 8656 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8657 try { 8658 int uid = mContext.getPackageManager().getPackageUid(pkg, 8659 Binder.getCallingUserHandle().getIdentifier()); 8660 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8661 } catch (NameNotFoundException e) { 8662 return false; 8663 } 8664 } 8665 8666 void startLockTaskMode(TaskRecord task) { 8667 final String pkg; 8668 synchronized (this) { 8669 pkg = task.intent.getComponent().getPackageName(); 8670 } 8671 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8672 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8673 final TaskRecord taskRecord = task; 8674 mHandler.post(new Runnable() { 8675 @Override 8676 public void run() { 8677 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8678 } 8679 }); 8680 return; 8681 } 8682 long ident = Binder.clearCallingIdentity(); 8683 try { 8684 synchronized (this) { 8685 // Since we lost lock on task, make sure it is still there. 8686 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8687 if (task != null) { 8688 if (!isSystemInitiated 8689 && ((mStackSupervisor.getFocusedStack() == null) 8690 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8691 throw new IllegalArgumentException("Invalid task, not in foreground"); 8692 } 8693 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8694 } 8695 } 8696 } finally { 8697 Binder.restoreCallingIdentity(ident); 8698 } 8699 } 8700 8701 @Override 8702 public void startLockTaskMode(int taskId) { 8703 final TaskRecord task; 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 if (task != null) { 8713 startLockTaskMode(task); 8714 } 8715 } 8716 8717 @Override 8718 public void startLockTaskMode(IBinder token) { 8719 final TaskRecord task; 8720 long ident = Binder.clearCallingIdentity(); 8721 try { 8722 synchronized (this) { 8723 final ActivityRecord r = ActivityRecord.forToken(token); 8724 if (r == null) { 8725 return; 8726 } 8727 task = r.task; 8728 } 8729 } finally { 8730 Binder.restoreCallingIdentity(ident); 8731 } 8732 if (task != null) { 8733 startLockTaskMode(task); 8734 } 8735 } 8736 8737 @Override 8738 public void startLockTaskModeOnCurrent() throws RemoteException { 8739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8740 "startLockTaskModeOnCurrent"); 8741 ActivityRecord r = null; 8742 synchronized (this) { 8743 r = mStackSupervisor.topRunningActivityLocked(); 8744 } 8745 startLockTaskMode(r.task); 8746 } 8747 8748 @Override 8749 public void stopLockTaskMode() { 8750 // Verify that the user matches the package of the intent for the TaskRecord 8751 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8752 // and stopLockTaskMode. 8753 final int callingUid = Binder.getCallingUid(); 8754 if (callingUid != Process.SYSTEM_UID) { 8755 try { 8756 String pkg = 8757 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8758 int uid = mContext.getPackageManager().getPackageUid(pkg, 8759 Binder.getCallingUserHandle().getIdentifier()); 8760 if (uid != callingUid) { 8761 throw new SecurityException("Invalid uid, expected " + uid); 8762 } 8763 } catch (NameNotFoundException e) { 8764 Log.d(TAG, "stopLockTaskMode " + e); 8765 return; 8766 } 8767 } 8768 long ident = Binder.clearCallingIdentity(); 8769 try { 8770 Log.d(TAG, "stopLockTaskMode"); 8771 // Stop lock task 8772 synchronized (this) { 8773 mStackSupervisor.setLockTaskModeLocked(null, false); 8774 } 8775 } finally { 8776 Binder.restoreCallingIdentity(ident); 8777 } 8778 } 8779 8780 @Override 8781 public void stopLockTaskModeOnCurrent() throws RemoteException { 8782 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8783 "stopLockTaskModeOnCurrent"); 8784 long ident = Binder.clearCallingIdentity(); 8785 try { 8786 stopLockTaskMode(); 8787 } finally { 8788 Binder.restoreCallingIdentity(ident); 8789 } 8790 } 8791 8792 @Override 8793 public boolean isInLockTaskMode() { 8794 synchronized (this) { 8795 return mStackSupervisor.isInLockTaskMode(); 8796 } 8797 } 8798 8799 // ========================================================= 8800 // CONTENT PROVIDERS 8801 // ========================================================= 8802 8803 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8804 List<ProviderInfo> providers = null; 8805 try { 8806 providers = AppGlobals.getPackageManager(). 8807 queryContentProviders(app.processName, app.uid, 8808 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8809 } catch (RemoteException ex) { 8810 } 8811 if (DEBUG_MU) 8812 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8813 int userId = app.userId; 8814 if (providers != null) { 8815 int N = providers.size(); 8816 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8817 for (int i=0; i<N; i++) { 8818 ProviderInfo cpi = 8819 (ProviderInfo)providers.get(i); 8820 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8821 cpi.name, cpi.flags); 8822 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8823 // This is a singleton provider, but a user besides the 8824 // default user is asking to initialize a process it runs 8825 // in... well, no, it doesn't actually run in this process, 8826 // it runs in the process of the default user. Get rid of it. 8827 providers.remove(i); 8828 N--; 8829 i--; 8830 continue; 8831 } 8832 8833 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8834 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8835 if (cpr == null) { 8836 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8837 mProviderMap.putProviderByClass(comp, cpr); 8838 } 8839 if (DEBUG_MU) 8840 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8841 app.pubProviders.put(cpi.name, cpr); 8842 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8843 // Don't add this if it is a platform component that is marked 8844 // to run in multiple processes, because this is actually 8845 // part of the framework so doesn't make sense to track as a 8846 // separate apk in the process. 8847 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8848 mProcessStats); 8849 } 8850 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8851 } 8852 } 8853 return providers; 8854 } 8855 8856 /** 8857 * Check if {@link ProcessRecord} has a possible chance at accessing the 8858 * given {@link ProviderInfo}. Final permission checking is always done 8859 * in {@link ContentProvider}. 8860 */ 8861 private final String checkContentProviderPermissionLocked( 8862 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8863 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8864 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8865 boolean checkedGrants = false; 8866 if (checkUser) { 8867 // Looking for cross-user grants before enforcing the typical cross-users permissions 8868 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8869 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8870 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8871 return null; 8872 } 8873 checkedGrants = true; 8874 } 8875 userId = handleIncomingUser(callingPid, callingUid, userId, 8876 false, ALLOW_NON_FULL, 8877 "checkContentProviderPermissionLocked " + cpi.authority, null); 8878 if (userId != tmpTargetUserId) { 8879 // When we actually went to determine the final targer user ID, this ended 8880 // up different than our initial check for the authority. This is because 8881 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8882 // SELF. So we need to re-check the grants again. 8883 checkedGrants = false; 8884 } 8885 } 8886 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8887 cpi.applicationInfo.uid, cpi.exported) 8888 == PackageManager.PERMISSION_GRANTED) { 8889 return null; 8890 } 8891 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8892 cpi.applicationInfo.uid, cpi.exported) 8893 == PackageManager.PERMISSION_GRANTED) { 8894 return null; 8895 } 8896 8897 PathPermission[] pps = cpi.pathPermissions; 8898 if (pps != null) { 8899 int i = pps.length; 8900 while (i > 0) { 8901 i--; 8902 PathPermission pp = pps[i]; 8903 String pprperm = pp.getReadPermission(); 8904 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8905 cpi.applicationInfo.uid, cpi.exported) 8906 == PackageManager.PERMISSION_GRANTED) { 8907 return null; 8908 } 8909 String ppwperm = pp.getWritePermission(); 8910 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8911 cpi.applicationInfo.uid, cpi.exported) 8912 == PackageManager.PERMISSION_GRANTED) { 8913 return null; 8914 } 8915 } 8916 } 8917 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8918 return null; 8919 } 8920 8921 String msg; 8922 if (!cpi.exported) { 8923 msg = "Permission Denial: opening provider " + cpi.name 8924 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8925 + ", uid=" + callingUid + ") that is not exported from uid " 8926 + cpi.applicationInfo.uid; 8927 } else { 8928 msg = "Permission Denial: opening provider " + cpi.name 8929 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8930 + ", uid=" + callingUid + ") requires " 8931 + cpi.readPermission + " or " + cpi.writePermission; 8932 } 8933 Slog.w(TAG, msg); 8934 return msg; 8935 } 8936 8937 /** 8938 * Returns if the ContentProvider has granted a uri to callingUid 8939 */ 8940 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8941 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8942 if (perms != null) { 8943 for (int i=perms.size()-1; i>=0; i--) { 8944 GrantUri grantUri = perms.keyAt(i); 8945 if (grantUri.sourceUserId == userId || !checkUser) { 8946 if (matchesProvider(grantUri.uri, cpi)) { 8947 return true; 8948 } 8949 } 8950 } 8951 } 8952 return false; 8953 } 8954 8955 /** 8956 * Returns true if the uri authority is one of the authorities specified in the provider. 8957 */ 8958 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8959 String uriAuth = uri.getAuthority(); 8960 String cpiAuth = cpi.authority; 8961 if (cpiAuth.indexOf(';') == -1) { 8962 return cpiAuth.equals(uriAuth); 8963 } 8964 String[] cpiAuths = cpiAuth.split(";"); 8965 int length = cpiAuths.length; 8966 for (int i = 0; i < length; i++) { 8967 if (cpiAuths[i].equals(uriAuth)) return true; 8968 } 8969 return false; 8970 } 8971 8972 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8973 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8974 if (r != null) { 8975 for (int i=0; i<r.conProviders.size(); i++) { 8976 ContentProviderConnection conn = r.conProviders.get(i); 8977 if (conn.provider == cpr) { 8978 if (DEBUG_PROVIDER) Slog.v(TAG, 8979 "Adding provider requested by " 8980 + r.processName + " from process " 8981 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8982 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8983 if (stable) { 8984 conn.stableCount++; 8985 conn.numStableIncs++; 8986 } else { 8987 conn.unstableCount++; 8988 conn.numUnstableIncs++; 8989 } 8990 return conn; 8991 } 8992 } 8993 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8994 if (stable) { 8995 conn.stableCount = 1; 8996 conn.numStableIncs = 1; 8997 } else { 8998 conn.unstableCount = 1; 8999 conn.numUnstableIncs = 1; 9000 } 9001 cpr.connections.add(conn); 9002 r.conProviders.add(conn); 9003 return conn; 9004 } 9005 cpr.addExternalProcessHandleLocked(externalProcessToken); 9006 return null; 9007 } 9008 9009 boolean decProviderCountLocked(ContentProviderConnection conn, 9010 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9011 if (conn != null) { 9012 cpr = conn.provider; 9013 if (DEBUG_PROVIDER) Slog.v(TAG, 9014 "Removing provider requested by " 9015 + conn.client.processName + " from process " 9016 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9017 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9018 if (stable) { 9019 conn.stableCount--; 9020 } else { 9021 conn.unstableCount--; 9022 } 9023 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9024 cpr.connections.remove(conn); 9025 conn.client.conProviders.remove(conn); 9026 return true; 9027 } 9028 return false; 9029 } 9030 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9031 return false; 9032 } 9033 9034 private void checkTime(long startTime, String where) { 9035 long now = SystemClock.elapsedRealtime(); 9036 if ((now-startTime) > 1000) { 9037 // If we are taking more than a second, log about it. 9038 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9039 } 9040 } 9041 9042 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9043 String name, IBinder token, boolean stable, int userId) { 9044 ContentProviderRecord cpr; 9045 ContentProviderConnection conn = null; 9046 ProviderInfo cpi = null; 9047 9048 synchronized(this) { 9049 long startTime = SystemClock.elapsedRealtime(); 9050 9051 ProcessRecord r = null; 9052 if (caller != null) { 9053 r = getRecordForAppLocked(caller); 9054 if (r == null) { 9055 throw new SecurityException( 9056 "Unable to find app for caller " + caller 9057 + " (pid=" + Binder.getCallingPid() 9058 + ") when getting content provider " + name); 9059 } 9060 } 9061 9062 boolean checkCrossUser = true; 9063 9064 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9065 9066 // First check if this content provider has been published... 9067 cpr = mProviderMap.getProviderByName(name, userId); 9068 // If that didn't work, check if it exists for user 0 and then 9069 // verify that it's a singleton provider before using it. 9070 if (cpr == null && userId != UserHandle.USER_OWNER) { 9071 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9072 if (cpr != null) { 9073 cpi = cpr.info; 9074 if (isSingleton(cpi.processName, cpi.applicationInfo, 9075 cpi.name, cpi.flags) 9076 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9077 userId = UserHandle.USER_OWNER; 9078 checkCrossUser = false; 9079 } else { 9080 cpr = null; 9081 cpi = null; 9082 } 9083 } 9084 } 9085 9086 boolean providerRunning = cpr != null; 9087 if (providerRunning) { 9088 cpi = cpr.info; 9089 String msg; 9090 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9091 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9092 != null) { 9093 throw new SecurityException(msg); 9094 } 9095 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9096 9097 if (r != null && cpr.canRunHere(r)) { 9098 // This provider has been published or is in the process 9099 // of being published... but it is also allowed to run 9100 // in the caller's process, so don't make a connection 9101 // and just let the caller instantiate its own instance. 9102 ContentProviderHolder holder = cpr.newHolder(null); 9103 // don't give caller the provider object, it needs 9104 // to make its own. 9105 holder.provider = null; 9106 return holder; 9107 } 9108 9109 final long origId = Binder.clearCallingIdentity(); 9110 9111 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9112 9113 // In this case the provider instance already exists, so we can 9114 // return it right away. 9115 conn = incProviderCountLocked(r, cpr, token, stable); 9116 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9117 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9118 // If this is a perceptible app accessing the provider, 9119 // make sure to count it as being accessed and thus 9120 // back up on the LRU list. This is good because 9121 // content providers are often expensive to start. 9122 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9123 updateLruProcessLocked(cpr.proc, false, null); 9124 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9125 } 9126 } 9127 9128 if (cpr.proc != null) { 9129 if (false) { 9130 if (cpr.name.flattenToShortString().equals( 9131 "com.android.providers.calendar/.CalendarProvider2")) { 9132 Slog.v(TAG, "****************** KILLING " 9133 + cpr.name.flattenToShortString()); 9134 Process.killProcess(cpr.proc.pid); 9135 } 9136 } 9137 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9138 boolean success = updateOomAdjLocked(cpr.proc); 9139 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9140 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9141 // NOTE: there is still a race here where a signal could be 9142 // pending on the process even though we managed to update its 9143 // adj level. Not sure what to do about this, but at least 9144 // the race is now smaller. 9145 if (!success) { 9146 // Uh oh... it looks like the provider's process 9147 // has been killed on us. We need to wait for a new 9148 // process to be started, and make sure its death 9149 // doesn't kill our process. 9150 Slog.i(TAG, 9151 "Existing provider " + cpr.name.flattenToShortString() 9152 + " is crashing; detaching " + r); 9153 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9154 checkTime(startTime, "getContentProviderImpl: before appDied"); 9155 appDiedLocked(cpr.proc); 9156 checkTime(startTime, "getContentProviderImpl: after appDied"); 9157 if (!lastRef) { 9158 // This wasn't the last ref our process had on 9159 // the provider... we have now been killed, bail. 9160 return null; 9161 } 9162 providerRunning = false; 9163 conn = null; 9164 } 9165 } 9166 9167 Binder.restoreCallingIdentity(origId); 9168 } 9169 9170 boolean singleton; 9171 if (!providerRunning) { 9172 try { 9173 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9174 cpi = AppGlobals.getPackageManager(). 9175 resolveContentProvider(name, 9176 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9177 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9178 } catch (RemoteException ex) { 9179 } 9180 if (cpi == null) { 9181 return null; 9182 } 9183 // If the provider is a singleton AND 9184 // (it's a call within the same user || the provider is a 9185 // privileged app) 9186 // Then allow connecting to the singleton provider 9187 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9188 cpi.name, cpi.flags) 9189 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9190 if (singleton) { 9191 userId = UserHandle.USER_OWNER; 9192 } 9193 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9194 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9195 9196 String msg; 9197 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9198 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9199 != null) { 9200 throw new SecurityException(msg); 9201 } 9202 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9203 9204 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9205 && !cpi.processName.equals("system")) { 9206 // If this content provider does not run in the system 9207 // process, and the system is not yet ready to run other 9208 // processes, then fail fast instead of hanging. 9209 throw new IllegalArgumentException( 9210 "Attempt to launch content provider before system ready"); 9211 } 9212 9213 // Make sure that the user who owns this provider is started. If not, 9214 // we don't want to allow it to run. 9215 if (mStartedUsers.get(userId) == null) { 9216 Slog.w(TAG, "Unable to launch app " 9217 + cpi.applicationInfo.packageName + "/" 9218 + cpi.applicationInfo.uid + " for provider " 9219 + name + ": user " + userId + " is stopped"); 9220 return null; 9221 } 9222 9223 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9224 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9225 cpr = mProviderMap.getProviderByClass(comp, userId); 9226 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9227 final boolean firstClass = cpr == null; 9228 if (firstClass) { 9229 final long ident = Binder.clearCallingIdentity(); 9230 try { 9231 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9232 ApplicationInfo ai = 9233 AppGlobals.getPackageManager(). 9234 getApplicationInfo( 9235 cpi.applicationInfo.packageName, 9236 STOCK_PM_FLAGS, userId); 9237 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9238 if (ai == null) { 9239 Slog.w(TAG, "No package info for content provider " 9240 + cpi.name); 9241 return null; 9242 } 9243 ai = getAppInfoForUser(ai, userId); 9244 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9245 } catch (RemoteException ex) { 9246 // pm is in same process, this will never happen. 9247 } finally { 9248 Binder.restoreCallingIdentity(ident); 9249 } 9250 } 9251 9252 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9253 9254 if (r != null && cpr.canRunHere(r)) { 9255 // If this is a multiprocess provider, then just return its 9256 // info and allow the caller to instantiate it. Only do 9257 // this if the provider is the same user as the caller's 9258 // process, or can run as root (so can be in any process). 9259 return cpr.newHolder(null); 9260 } 9261 9262 if (DEBUG_PROVIDER) { 9263 RuntimeException e = new RuntimeException("here"); 9264 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9265 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9266 } 9267 9268 // This is single process, and our app is now connecting to it. 9269 // See if we are already in the process of launching this 9270 // provider. 9271 final int N = mLaunchingProviders.size(); 9272 int i; 9273 for (i=0; i<N; i++) { 9274 if (mLaunchingProviders.get(i) == cpr) { 9275 break; 9276 } 9277 } 9278 9279 // If the provider is not already being launched, then get it 9280 // started. 9281 if (i >= N) { 9282 final long origId = Binder.clearCallingIdentity(); 9283 9284 try { 9285 // Content provider is now in use, its package can't be stopped. 9286 try { 9287 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9288 AppGlobals.getPackageManager().setPackageStoppedState( 9289 cpr.appInfo.packageName, false, userId); 9290 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9291 } catch (RemoteException e) { 9292 } catch (IllegalArgumentException e) { 9293 Slog.w(TAG, "Failed trying to unstop package " 9294 + cpr.appInfo.packageName + ": " + e); 9295 } 9296 9297 // Use existing process if already started 9298 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9299 ProcessRecord proc = getProcessRecordLocked( 9300 cpi.processName, cpr.appInfo.uid, false); 9301 if (proc != null && proc.thread != null) { 9302 if (DEBUG_PROVIDER) { 9303 Slog.d(TAG, "Installing in existing process " + proc); 9304 } 9305 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9306 proc.pubProviders.put(cpi.name, cpr); 9307 try { 9308 proc.thread.scheduleInstallProvider(cpi); 9309 } catch (RemoteException e) { 9310 } 9311 } else { 9312 checkTime(startTime, "getContentProviderImpl: before start process"); 9313 proc = startProcessLocked(cpi.processName, 9314 cpr.appInfo, false, 0, "content provider", 9315 new ComponentName(cpi.applicationInfo.packageName, 9316 cpi.name), false, false, false); 9317 checkTime(startTime, "getContentProviderImpl: after start process"); 9318 if (proc == null) { 9319 Slog.w(TAG, "Unable to launch app " 9320 + cpi.applicationInfo.packageName + "/" 9321 + cpi.applicationInfo.uid + " for provider " 9322 + name + ": process is bad"); 9323 return null; 9324 } 9325 } 9326 cpr.launchingApp = proc; 9327 mLaunchingProviders.add(cpr); 9328 } finally { 9329 Binder.restoreCallingIdentity(origId); 9330 } 9331 } 9332 9333 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9334 9335 // Make sure the provider is published (the same provider class 9336 // may be published under multiple names). 9337 if (firstClass) { 9338 mProviderMap.putProviderByClass(comp, cpr); 9339 } 9340 9341 mProviderMap.putProviderByName(name, cpr); 9342 conn = incProviderCountLocked(r, cpr, token, stable); 9343 if (conn != null) { 9344 conn.waiting = true; 9345 } 9346 } 9347 checkTime(startTime, "getContentProviderImpl: done!"); 9348 } 9349 9350 // Wait for the provider to be published... 9351 synchronized (cpr) { 9352 while (cpr.provider == null) { 9353 if (cpr.launchingApp == null) { 9354 Slog.w(TAG, "Unable to launch app " 9355 + cpi.applicationInfo.packageName + "/" 9356 + cpi.applicationInfo.uid + " for provider " 9357 + name + ": launching app became null"); 9358 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9359 UserHandle.getUserId(cpi.applicationInfo.uid), 9360 cpi.applicationInfo.packageName, 9361 cpi.applicationInfo.uid, name); 9362 return null; 9363 } 9364 try { 9365 if (DEBUG_MU) { 9366 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9367 + cpr.launchingApp); 9368 } 9369 if (conn != null) { 9370 conn.waiting = true; 9371 } 9372 cpr.wait(); 9373 } catch (InterruptedException ex) { 9374 } finally { 9375 if (conn != null) { 9376 conn.waiting = false; 9377 } 9378 } 9379 } 9380 } 9381 return cpr != null ? cpr.newHolder(conn) : null; 9382 } 9383 9384 @Override 9385 public final ContentProviderHolder getContentProvider( 9386 IApplicationThread caller, String name, int userId, boolean stable) { 9387 enforceNotIsolatedCaller("getContentProvider"); 9388 if (caller == null) { 9389 String msg = "null IApplicationThread when getting content provider " 9390 + name; 9391 Slog.w(TAG, msg); 9392 throw new SecurityException(msg); 9393 } 9394 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9395 // with cross-user grant. 9396 return getContentProviderImpl(caller, name, null, stable, userId); 9397 } 9398 9399 public ContentProviderHolder getContentProviderExternal( 9400 String name, int userId, IBinder token) { 9401 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9402 "Do not have permission in call getContentProviderExternal()"); 9403 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9404 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9405 return getContentProviderExternalUnchecked(name, token, userId); 9406 } 9407 9408 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9409 IBinder token, int userId) { 9410 return getContentProviderImpl(null, name, token, true, userId); 9411 } 9412 9413 /** 9414 * Drop a content provider from a ProcessRecord's bookkeeping 9415 */ 9416 public void removeContentProvider(IBinder connection, boolean stable) { 9417 enforceNotIsolatedCaller("removeContentProvider"); 9418 long ident = Binder.clearCallingIdentity(); 9419 try { 9420 synchronized (this) { 9421 ContentProviderConnection conn; 9422 try { 9423 conn = (ContentProviderConnection)connection; 9424 } catch (ClassCastException e) { 9425 String msg ="removeContentProvider: " + connection 9426 + " not a ContentProviderConnection"; 9427 Slog.w(TAG, msg); 9428 throw new IllegalArgumentException(msg); 9429 } 9430 if (conn == null) { 9431 throw new NullPointerException("connection is null"); 9432 } 9433 if (decProviderCountLocked(conn, null, null, stable)) { 9434 updateOomAdjLocked(); 9435 } 9436 } 9437 } finally { 9438 Binder.restoreCallingIdentity(ident); 9439 } 9440 } 9441 9442 public void removeContentProviderExternal(String name, IBinder token) { 9443 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9444 "Do not have permission in call removeContentProviderExternal()"); 9445 int userId = UserHandle.getCallingUserId(); 9446 long ident = Binder.clearCallingIdentity(); 9447 try { 9448 removeContentProviderExternalUnchecked(name, token, userId); 9449 } finally { 9450 Binder.restoreCallingIdentity(ident); 9451 } 9452 } 9453 9454 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9455 synchronized (this) { 9456 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9457 if(cpr == null) { 9458 //remove from mProvidersByClass 9459 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9460 return; 9461 } 9462 9463 //update content provider record entry info 9464 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9465 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9466 if (localCpr.hasExternalProcessHandles()) { 9467 if (localCpr.removeExternalProcessHandleLocked(token)) { 9468 updateOomAdjLocked(); 9469 } else { 9470 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9471 + " with no external reference for token: " 9472 + token + "."); 9473 } 9474 } else { 9475 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9476 + " with no external references."); 9477 } 9478 } 9479 } 9480 9481 public final void publishContentProviders(IApplicationThread caller, 9482 List<ContentProviderHolder> providers) { 9483 if (providers == null) { 9484 return; 9485 } 9486 9487 enforceNotIsolatedCaller("publishContentProviders"); 9488 synchronized (this) { 9489 final ProcessRecord r = getRecordForAppLocked(caller); 9490 if (DEBUG_MU) 9491 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9492 if (r == null) { 9493 throw new SecurityException( 9494 "Unable to find app for caller " + caller 9495 + " (pid=" + Binder.getCallingPid() 9496 + ") when publishing content providers"); 9497 } 9498 9499 final long origId = Binder.clearCallingIdentity(); 9500 9501 final int N = providers.size(); 9502 for (int i=0; i<N; i++) { 9503 ContentProviderHolder src = providers.get(i); 9504 if (src == null || src.info == null || src.provider == null) { 9505 continue; 9506 } 9507 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9508 if (DEBUG_MU) 9509 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9510 if (dst != null) { 9511 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9512 mProviderMap.putProviderByClass(comp, dst); 9513 String names[] = dst.info.authority.split(";"); 9514 for (int j = 0; j < names.length; j++) { 9515 mProviderMap.putProviderByName(names[j], dst); 9516 } 9517 9518 int NL = mLaunchingProviders.size(); 9519 int j; 9520 for (j=0; j<NL; j++) { 9521 if (mLaunchingProviders.get(j) == dst) { 9522 mLaunchingProviders.remove(j); 9523 j--; 9524 NL--; 9525 } 9526 } 9527 synchronized (dst) { 9528 dst.provider = src.provider; 9529 dst.proc = r; 9530 dst.notifyAll(); 9531 } 9532 updateOomAdjLocked(r); 9533 } 9534 } 9535 9536 Binder.restoreCallingIdentity(origId); 9537 } 9538 } 9539 9540 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9541 ContentProviderConnection conn; 9542 try { 9543 conn = (ContentProviderConnection)connection; 9544 } catch (ClassCastException e) { 9545 String msg ="refContentProvider: " + connection 9546 + " not a ContentProviderConnection"; 9547 Slog.w(TAG, msg); 9548 throw new IllegalArgumentException(msg); 9549 } 9550 if (conn == null) { 9551 throw new NullPointerException("connection is null"); 9552 } 9553 9554 synchronized (this) { 9555 if (stable > 0) { 9556 conn.numStableIncs += stable; 9557 } 9558 stable = conn.stableCount + stable; 9559 if (stable < 0) { 9560 throw new IllegalStateException("stableCount < 0: " + stable); 9561 } 9562 9563 if (unstable > 0) { 9564 conn.numUnstableIncs += unstable; 9565 } 9566 unstable = conn.unstableCount + unstable; 9567 if (unstable < 0) { 9568 throw new IllegalStateException("unstableCount < 0: " + unstable); 9569 } 9570 9571 if ((stable+unstable) <= 0) { 9572 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9573 + stable + " unstable=" + unstable); 9574 } 9575 conn.stableCount = stable; 9576 conn.unstableCount = unstable; 9577 return !conn.dead; 9578 } 9579 } 9580 9581 public void unstableProviderDied(IBinder connection) { 9582 ContentProviderConnection conn; 9583 try { 9584 conn = (ContentProviderConnection)connection; 9585 } catch (ClassCastException e) { 9586 String msg ="refContentProvider: " + connection 9587 + " not a ContentProviderConnection"; 9588 Slog.w(TAG, msg); 9589 throw new IllegalArgumentException(msg); 9590 } 9591 if (conn == null) { 9592 throw new NullPointerException("connection is null"); 9593 } 9594 9595 // Safely retrieve the content provider associated with the connection. 9596 IContentProvider provider; 9597 synchronized (this) { 9598 provider = conn.provider.provider; 9599 } 9600 9601 if (provider == null) { 9602 // Um, yeah, we're way ahead of you. 9603 return; 9604 } 9605 9606 // Make sure the caller is being honest with us. 9607 if (provider.asBinder().pingBinder()) { 9608 // Er, no, still looks good to us. 9609 synchronized (this) { 9610 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9611 + " says " + conn + " died, but we don't agree"); 9612 return; 9613 } 9614 } 9615 9616 // Well look at that! It's dead! 9617 synchronized (this) { 9618 if (conn.provider.provider != provider) { 9619 // But something changed... good enough. 9620 return; 9621 } 9622 9623 ProcessRecord proc = conn.provider.proc; 9624 if (proc == null || proc.thread == null) { 9625 // Seems like the process is already cleaned up. 9626 return; 9627 } 9628 9629 // As far as we're concerned, this is just like receiving a 9630 // death notification... just a bit prematurely. 9631 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9632 + ") early provider death"); 9633 final long ident = Binder.clearCallingIdentity(); 9634 try { 9635 appDiedLocked(proc); 9636 } finally { 9637 Binder.restoreCallingIdentity(ident); 9638 } 9639 } 9640 } 9641 9642 @Override 9643 public void appNotRespondingViaProvider(IBinder connection) { 9644 enforceCallingPermission( 9645 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9646 9647 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9648 if (conn == null) { 9649 Slog.w(TAG, "ContentProviderConnection is null"); 9650 return; 9651 } 9652 9653 final ProcessRecord host = conn.provider.proc; 9654 if (host == null) { 9655 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9656 return; 9657 } 9658 9659 final long token = Binder.clearCallingIdentity(); 9660 try { 9661 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9662 } finally { 9663 Binder.restoreCallingIdentity(token); 9664 } 9665 } 9666 9667 public final void installSystemProviders() { 9668 List<ProviderInfo> providers; 9669 synchronized (this) { 9670 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9671 providers = generateApplicationProvidersLocked(app); 9672 if (providers != null) { 9673 for (int i=providers.size()-1; i>=0; i--) { 9674 ProviderInfo pi = (ProviderInfo)providers.get(i); 9675 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9676 Slog.w(TAG, "Not installing system proc provider " + pi.name 9677 + ": not system .apk"); 9678 providers.remove(i); 9679 } 9680 } 9681 } 9682 } 9683 if (providers != null) { 9684 mSystemThread.installSystemProviders(providers); 9685 } 9686 9687 mCoreSettingsObserver = new CoreSettingsObserver(this); 9688 9689 //mUsageStatsService.monitorPackages(); 9690 } 9691 9692 /** 9693 * Allows apps to retrieve the MIME type of a URI. 9694 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9695 * users, then it does not need permission to access the ContentProvider. 9696 * Either, it needs cross-user uri grants. 9697 * 9698 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9699 * 9700 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9701 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9702 */ 9703 public String getProviderMimeType(Uri uri, int userId) { 9704 enforceNotIsolatedCaller("getProviderMimeType"); 9705 final String name = uri.getAuthority(); 9706 int callingUid = Binder.getCallingUid(); 9707 int callingPid = Binder.getCallingPid(); 9708 long ident = 0; 9709 boolean clearedIdentity = false; 9710 userId = unsafeConvertIncomingUser(userId); 9711 if (canClearIdentity(callingPid, callingUid, userId)) { 9712 clearedIdentity = true; 9713 ident = Binder.clearCallingIdentity(); 9714 } 9715 ContentProviderHolder holder = null; 9716 try { 9717 holder = getContentProviderExternalUnchecked(name, null, userId); 9718 if (holder != null) { 9719 return holder.provider.getType(uri); 9720 } 9721 } catch (RemoteException e) { 9722 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9723 return null; 9724 } finally { 9725 // We need to clear the identity to call removeContentProviderExternalUnchecked 9726 if (!clearedIdentity) { 9727 ident = Binder.clearCallingIdentity(); 9728 } 9729 try { 9730 if (holder != null) { 9731 removeContentProviderExternalUnchecked(name, null, userId); 9732 } 9733 } finally { 9734 Binder.restoreCallingIdentity(ident); 9735 } 9736 } 9737 9738 return null; 9739 } 9740 9741 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9742 if (UserHandle.getUserId(callingUid) == userId) { 9743 return true; 9744 } 9745 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9746 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9747 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9748 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9749 return true; 9750 } 9751 return false; 9752 } 9753 9754 // ========================================================= 9755 // GLOBAL MANAGEMENT 9756 // ========================================================= 9757 9758 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9759 boolean isolated, int isolatedUid) { 9760 String proc = customProcess != null ? customProcess : info.processName; 9761 BatteryStatsImpl.Uid.Proc ps = null; 9762 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9763 int uid = info.uid; 9764 if (isolated) { 9765 if (isolatedUid == 0) { 9766 int userId = UserHandle.getUserId(uid); 9767 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9768 while (true) { 9769 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9770 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9771 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9772 } 9773 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9774 mNextIsolatedProcessUid++; 9775 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9776 // No process for this uid, use it. 9777 break; 9778 } 9779 stepsLeft--; 9780 if (stepsLeft <= 0) { 9781 return null; 9782 } 9783 } 9784 } else { 9785 // Special case for startIsolatedProcess (internal only), where 9786 // the uid of the isolated process is specified by the caller. 9787 uid = isolatedUid; 9788 } 9789 } 9790 return new ProcessRecord(stats, info, proc, uid); 9791 } 9792 9793 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9794 String abiOverride) { 9795 ProcessRecord app; 9796 if (!isolated) { 9797 app = getProcessRecordLocked(info.processName, info.uid, true); 9798 } else { 9799 app = null; 9800 } 9801 9802 if (app == null) { 9803 app = newProcessRecordLocked(info, null, isolated, 0); 9804 mProcessNames.put(info.processName, app.uid, app); 9805 if (isolated) { 9806 mIsolatedProcesses.put(app.uid, app); 9807 } 9808 updateLruProcessLocked(app, false, null); 9809 updateOomAdjLocked(); 9810 } 9811 9812 // This package really, really can not be stopped. 9813 try { 9814 AppGlobals.getPackageManager().setPackageStoppedState( 9815 info.packageName, false, UserHandle.getUserId(app.uid)); 9816 } catch (RemoteException e) { 9817 } catch (IllegalArgumentException e) { 9818 Slog.w(TAG, "Failed trying to unstop package " 9819 + info.packageName + ": " + e); 9820 } 9821 9822 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9823 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9824 app.persistent = true; 9825 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9826 } 9827 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9828 mPersistentStartingProcesses.add(app); 9829 startProcessLocked(app, "added application", app.processName, abiOverride, 9830 null /* entryPoint */, null /* entryPointArgs */); 9831 } 9832 9833 return app; 9834 } 9835 9836 public void unhandledBack() { 9837 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9838 "unhandledBack()"); 9839 9840 synchronized(this) { 9841 final long origId = Binder.clearCallingIdentity(); 9842 try { 9843 getFocusedStack().unhandledBackLocked(); 9844 } finally { 9845 Binder.restoreCallingIdentity(origId); 9846 } 9847 } 9848 } 9849 9850 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9851 enforceNotIsolatedCaller("openContentUri"); 9852 final int userId = UserHandle.getCallingUserId(); 9853 String name = uri.getAuthority(); 9854 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9855 ParcelFileDescriptor pfd = null; 9856 if (cph != null) { 9857 // We record the binder invoker's uid in thread-local storage before 9858 // going to the content provider to open the file. Later, in the code 9859 // that handles all permissions checks, we look for this uid and use 9860 // that rather than the Activity Manager's own uid. The effect is that 9861 // we do the check against the caller's permissions even though it looks 9862 // to the content provider like the Activity Manager itself is making 9863 // the request. 9864 sCallerIdentity.set(new Identity( 9865 Binder.getCallingPid(), Binder.getCallingUid())); 9866 try { 9867 pfd = cph.provider.openFile(null, uri, "r", null); 9868 } catch (FileNotFoundException e) { 9869 // do nothing; pfd will be returned null 9870 } finally { 9871 // Ensure that whatever happens, we clean up the identity state 9872 sCallerIdentity.remove(); 9873 } 9874 9875 // We've got the fd now, so we're done with the provider. 9876 removeContentProviderExternalUnchecked(name, null, userId); 9877 } else { 9878 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9879 } 9880 return pfd; 9881 } 9882 9883 // Actually is sleeping or shutting down or whatever else in the future 9884 // is an inactive state. 9885 public boolean isSleepingOrShuttingDown() { 9886 return isSleeping() || mShuttingDown; 9887 } 9888 9889 public boolean isSleeping() { 9890 return mSleeping; 9891 } 9892 9893 void goingToSleep() { 9894 synchronized(this) { 9895 mWentToSleep = true; 9896 goToSleepIfNeededLocked(); 9897 } 9898 } 9899 9900 void finishRunningVoiceLocked() { 9901 if (mRunningVoice) { 9902 mRunningVoice = false; 9903 goToSleepIfNeededLocked(); 9904 } 9905 } 9906 9907 void goToSleepIfNeededLocked() { 9908 if (mWentToSleep && !mRunningVoice) { 9909 if (!mSleeping) { 9910 mSleeping = true; 9911 mStackSupervisor.goingToSleepLocked(); 9912 9913 // Initialize the wake times of all processes. 9914 checkExcessivePowerUsageLocked(false); 9915 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9916 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9917 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9918 } 9919 } 9920 } 9921 9922 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9923 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9924 // Never persist the home stack. 9925 return; 9926 } 9927 mTaskPersister.wakeup(task, flush); 9928 } 9929 9930 @Override 9931 public boolean shutdown(int timeout) { 9932 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9933 != PackageManager.PERMISSION_GRANTED) { 9934 throw new SecurityException("Requires permission " 9935 + android.Manifest.permission.SHUTDOWN); 9936 } 9937 9938 boolean timedout = false; 9939 9940 synchronized(this) { 9941 mShuttingDown = true; 9942 updateEventDispatchingLocked(); 9943 timedout = mStackSupervisor.shutdownLocked(timeout); 9944 } 9945 9946 mAppOpsService.shutdown(); 9947 if (mUsageStatsService != null) { 9948 mUsageStatsService.prepareShutdown(); 9949 } 9950 mBatteryStatsService.shutdown(); 9951 synchronized (this) { 9952 mProcessStats.shutdownLocked(); 9953 } 9954 notifyTaskPersisterLocked(null, true); 9955 9956 return timedout; 9957 } 9958 9959 public final void activitySlept(IBinder token) { 9960 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9961 9962 final long origId = Binder.clearCallingIdentity(); 9963 9964 synchronized (this) { 9965 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9966 if (r != null) { 9967 mStackSupervisor.activitySleptLocked(r); 9968 } 9969 } 9970 9971 Binder.restoreCallingIdentity(origId); 9972 } 9973 9974 void logLockScreen(String msg) { 9975 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9976 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9977 mWentToSleep + " mSleeping=" + mSleeping); 9978 } 9979 9980 private void comeOutOfSleepIfNeededLocked() { 9981 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9982 if (mSleeping) { 9983 mSleeping = false; 9984 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9985 } 9986 } 9987 } 9988 9989 void wakingUp() { 9990 synchronized(this) { 9991 mWentToSleep = false; 9992 comeOutOfSleepIfNeededLocked(); 9993 } 9994 } 9995 9996 void startRunningVoiceLocked() { 9997 if (!mRunningVoice) { 9998 mRunningVoice = true; 9999 comeOutOfSleepIfNeededLocked(); 10000 } 10001 } 10002 10003 private void updateEventDispatchingLocked() { 10004 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10005 } 10006 10007 public void setLockScreenShown(boolean shown) { 10008 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10009 != PackageManager.PERMISSION_GRANTED) { 10010 throw new SecurityException("Requires permission " 10011 + android.Manifest.permission.DEVICE_POWER); 10012 } 10013 10014 synchronized(this) { 10015 long ident = Binder.clearCallingIdentity(); 10016 try { 10017 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10018 mLockScreenShown = shown; 10019 comeOutOfSleepIfNeededLocked(); 10020 } finally { 10021 Binder.restoreCallingIdentity(ident); 10022 } 10023 } 10024 } 10025 10026 @Override 10027 public void stopAppSwitches() { 10028 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10029 != PackageManager.PERMISSION_GRANTED) { 10030 throw new SecurityException("Requires permission " 10031 + android.Manifest.permission.STOP_APP_SWITCHES); 10032 } 10033 10034 synchronized(this) { 10035 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10036 + APP_SWITCH_DELAY_TIME; 10037 mDidAppSwitch = false; 10038 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10039 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10040 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10041 } 10042 } 10043 10044 public void resumeAppSwitches() { 10045 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10046 != PackageManager.PERMISSION_GRANTED) { 10047 throw new SecurityException("Requires permission " 10048 + android.Manifest.permission.STOP_APP_SWITCHES); 10049 } 10050 10051 synchronized(this) { 10052 // Note that we don't execute any pending app switches... we will 10053 // let those wait until either the timeout, or the next start 10054 // activity request. 10055 mAppSwitchesAllowedTime = 0; 10056 } 10057 } 10058 10059 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10060 int callingPid, int callingUid, String name) { 10061 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10062 return true; 10063 } 10064 10065 int perm = checkComponentPermission( 10066 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10067 sourceUid, -1, true); 10068 if (perm == PackageManager.PERMISSION_GRANTED) { 10069 return true; 10070 } 10071 10072 // If the actual IPC caller is different from the logical source, then 10073 // also see if they are allowed to control app switches. 10074 if (callingUid != -1 && callingUid != sourceUid) { 10075 perm = checkComponentPermission( 10076 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10077 callingUid, -1, true); 10078 if (perm == PackageManager.PERMISSION_GRANTED) { 10079 return true; 10080 } 10081 } 10082 10083 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10084 return false; 10085 } 10086 10087 public void setDebugApp(String packageName, boolean waitForDebugger, 10088 boolean persistent) { 10089 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10090 "setDebugApp()"); 10091 10092 long ident = Binder.clearCallingIdentity(); 10093 try { 10094 // Note that this is not really thread safe if there are multiple 10095 // callers into it at the same time, but that's not a situation we 10096 // care about. 10097 if (persistent) { 10098 final ContentResolver resolver = mContext.getContentResolver(); 10099 Settings.Global.putString( 10100 resolver, Settings.Global.DEBUG_APP, 10101 packageName); 10102 Settings.Global.putInt( 10103 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10104 waitForDebugger ? 1 : 0); 10105 } 10106 10107 synchronized (this) { 10108 if (!persistent) { 10109 mOrigDebugApp = mDebugApp; 10110 mOrigWaitForDebugger = mWaitForDebugger; 10111 } 10112 mDebugApp = packageName; 10113 mWaitForDebugger = waitForDebugger; 10114 mDebugTransient = !persistent; 10115 if (packageName != null) { 10116 forceStopPackageLocked(packageName, -1, false, false, true, true, 10117 false, UserHandle.USER_ALL, "set debug app"); 10118 } 10119 } 10120 } finally { 10121 Binder.restoreCallingIdentity(ident); 10122 } 10123 } 10124 10125 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10126 synchronized (this) { 10127 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10128 if (!isDebuggable) { 10129 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10130 throw new SecurityException("Process not debuggable: " + app.packageName); 10131 } 10132 } 10133 10134 mOpenGlTraceApp = processName; 10135 } 10136 } 10137 10138 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10139 synchronized (this) { 10140 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10141 if (!isDebuggable) { 10142 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10143 throw new SecurityException("Process not debuggable: " + app.packageName); 10144 } 10145 } 10146 mProfileApp = processName; 10147 mProfileFile = profilerInfo.profileFile; 10148 if (mProfileFd != null) { 10149 try { 10150 mProfileFd.close(); 10151 } catch (IOException e) { 10152 } 10153 mProfileFd = null; 10154 } 10155 mProfileFd = profilerInfo.profileFd; 10156 mSamplingInterval = profilerInfo.samplingInterval; 10157 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10158 mProfileType = 0; 10159 } 10160 } 10161 10162 @Override 10163 public void setAlwaysFinish(boolean enabled) { 10164 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10165 "setAlwaysFinish()"); 10166 10167 Settings.Global.putInt( 10168 mContext.getContentResolver(), 10169 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10170 10171 synchronized (this) { 10172 mAlwaysFinishActivities = enabled; 10173 } 10174 } 10175 10176 @Override 10177 public void setActivityController(IActivityController controller) { 10178 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10179 "setActivityController()"); 10180 synchronized (this) { 10181 mController = controller; 10182 Watchdog.getInstance().setActivityController(controller); 10183 } 10184 } 10185 10186 @Override 10187 public void setUserIsMonkey(boolean userIsMonkey) { 10188 synchronized (this) { 10189 synchronized (mPidsSelfLocked) { 10190 final int callingPid = Binder.getCallingPid(); 10191 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10192 if (precessRecord == null) { 10193 throw new SecurityException("Unknown process: " + callingPid); 10194 } 10195 if (precessRecord.instrumentationUiAutomationConnection == null) { 10196 throw new SecurityException("Only an instrumentation process " 10197 + "with a UiAutomation can call setUserIsMonkey"); 10198 } 10199 } 10200 mUserIsMonkey = userIsMonkey; 10201 } 10202 } 10203 10204 @Override 10205 public boolean isUserAMonkey() { 10206 synchronized (this) { 10207 // If there is a controller also implies the user is a monkey. 10208 return (mUserIsMonkey || mController != null); 10209 } 10210 } 10211 10212 public void requestBugReport() { 10213 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10214 SystemProperties.set("ctl.start", "bugreport"); 10215 } 10216 10217 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10218 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10219 } 10220 10221 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10222 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10223 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10224 } 10225 return KEY_DISPATCHING_TIMEOUT; 10226 } 10227 10228 @Override 10229 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10230 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10231 != PackageManager.PERMISSION_GRANTED) { 10232 throw new SecurityException("Requires permission " 10233 + android.Manifest.permission.FILTER_EVENTS); 10234 } 10235 ProcessRecord proc; 10236 long timeout; 10237 synchronized (this) { 10238 synchronized (mPidsSelfLocked) { 10239 proc = mPidsSelfLocked.get(pid); 10240 } 10241 timeout = getInputDispatchingTimeoutLocked(proc); 10242 } 10243 10244 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10245 return -1; 10246 } 10247 10248 return timeout; 10249 } 10250 10251 /** 10252 * Handle input dispatching timeouts. 10253 * Returns whether input dispatching should be aborted or not. 10254 */ 10255 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10256 final ActivityRecord activity, final ActivityRecord parent, 10257 final boolean aboveSystem, String reason) { 10258 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10259 != PackageManager.PERMISSION_GRANTED) { 10260 throw new SecurityException("Requires permission " 10261 + android.Manifest.permission.FILTER_EVENTS); 10262 } 10263 10264 final String annotation; 10265 if (reason == null) { 10266 annotation = "Input dispatching timed out"; 10267 } else { 10268 annotation = "Input dispatching timed out (" + reason + ")"; 10269 } 10270 10271 if (proc != null) { 10272 synchronized (this) { 10273 if (proc.debugging) { 10274 return false; 10275 } 10276 10277 if (mDidDexOpt) { 10278 // Give more time since we were dexopting. 10279 mDidDexOpt = false; 10280 return false; 10281 } 10282 10283 if (proc.instrumentationClass != null) { 10284 Bundle info = new Bundle(); 10285 info.putString("shortMsg", "keyDispatchingTimedOut"); 10286 info.putString("longMsg", annotation); 10287 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10288 return true; 10289 } 10290 } 10291 mHandler.post(new Runnable() { 10292 @Override 10293 public void run() { 10294 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10295 } 10296 }); 10297 } 10298 10299 return true; 10300 } 10301 10302 public Bundle getAssistContextExtras(int requestType) { 10303 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10304 UserHandle.getCallingUserId()); 10305 if (pae == null) { 10306 return null; 10307 } 10308 synchronized (pae) { 10309 while (!pae.haveResult) { 10310 try { 10311 pae.wait(); 10312 } catch (InterruptedException e) { 10313 } 10314 } 10315 if (pae.result != null) { 10316 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10317 } 10318 } 10319 synchronized (this) { 10320 mPendingAssistExtras.remove(pae); 10321 mHandler.removeCallbacks(pae); 10322 } 10323 return pae.extras; 10324 } 10325 10326 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10327 int userHandle) { 10328 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10329 "getAssistContextExtras()"); 10330 PendingAssistExtras pae; 10331 Bundle extras = new Bundle(); 10332 synchronized (this) { 10333 ActivityRecord activity = getFocusedStack().mResumedActivity; 10334 if (activity == null) { 10335 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10336 return null; 10337 } 10338 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10339 if (activity.app == null || activity.app.thread == null) { 10340 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10341 return null; 10342 } 10343 if (activity.app.pid == Binder.getCallingPid()) { 10344 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10345 return null; 10346 } 10347 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10348 try { 10349 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10350 requestType); 10351 mPendingAssistExtras.add(pae); 10352 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10353 } catch (RemoteException e) { 10354 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10355 return null; 10356 } 10357 return pae; 10358 } 10359 } 10360 10361 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10362 PendingAssistExtras pae = (PendingAssistExtras)token; 10363 synchronized (pae) { 10364 pae.result = extras; 10365 pae.haveResult = true; 10366 pae.notifyAll(); 10367 if (pae.intent == null) { 10368 // Caller is just waiting for the result. 10369 return; 10370 } 10371 } 10372 10373 // We are now ready to launch the assist activity. 10374 synchronized (this) { 10375 boolean exists = mPendingAssistExtras.remove(pae); 10376 mHandler.removeCallbacks(pae); 10377 if (!exists) { 10378 // Timed out. 10379 return; 10380 } 10381 } 10382 pae.intent.replaceExtras(extras); 10383 if (pae.hint != null) { 10384 pae.intent.putExtra(pae.hint, true); 10385 } 10386 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10387 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10388 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10389 closeSystemDialogs("assist"); 10390 try { 10391 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10392 } catch (ActivityNotFoundException e) { 10393 Slog.w(TAG, "No activity to handle assist action.", e); 10394 } 10395 } 10396 10397 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10398 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10399 } 10400 10401 public void registerProcessObserver(IProcessObserver observer) { 10402 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10403 "registerProcessObserver()"); 10404 synchronized (this) { 10405 mProcessObservers.register(observer); 10406 } 10407 } 10408 10409 @Override 10410 public void unregisterProcessObserver(IProcessObserver observer) { 10411 synchronized (this) { 10412 mProcessObservers.unregister(observer); 10413 } 10414 } 10415 10416 @Override 10417 public boolean convertFromTranslucent(IBinder token) { 10418 final long origId = Binder.clearCallingIdentity(); 10419 try { 10420 synchronized (this) { 10421 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10422 if (r == null) { 10423 return false; 10424 } 10425 final boolean translucentChanged = r.changeWindowTranslucency(true); 10426 if (translucentChanged) { 10427 r.task.stack.releaseBackgroundResources(); 10428 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10429 } 10430 mWindowManager.setAppFullscreen(token, true); 10431 return translucentChanged; 10432 } 10433 } finally { 10434 Binder.restoreCallingIdentity(origId); 10435 } 10436 } 10437 10438 @Override 10439 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10440 final long origId = Binder.clearCallingIdentity(); 10441 try { 10442 synchronized (this) { 10443 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10444 if (r == null) { 10445 return false; 10446 } 10447 int index = r.task.mActivities.lastIndexOf(r); 10448 if (index > 0) { 10449 ActivityRecord under = r.task.mActivities.get(index - 1); 10450 under.returningOptions = options; 10451 } 10452 final boolean translucentChanged = r.changeWindowTranslucency(false); 10453 if (translucentChanged) { 10454 r.task.stack.convertToTranslucent(r); 10455 } 10456 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10457 mWindowManager.setAppFullscreen(token, false); 10458 return translucentChanged; 10459 } 10460 } finally { 10461 Binder.restoreCallingIdentity(origId); 10462 } 10463 } 10464 10465 @Override 10466 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10467 final long origId = Binder.clearCallingIdentity(); 10468 try { 10469 synchronized (this) { 10470 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10471 if (r != null) { 10472 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10473 } 10474 } 10475 return false; 10476 } finally { 10477 Binder.restoreCallingIdentity(origId); 10478 } 10479 } 10480 10481 @Override 10482 public boolean isBackgroundVisibleBehind(IBinder token) { 10483 final long origId = Binder.clearCallingIdentity(); 10484 try { 10485 synchronized (this) { 10486 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10487 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10488 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10489 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10490 return visible; 10491 } 10492 } finally { 10493 Binder.restoreCallingIdentity(origId); 10494 } 10495 } 10496 10497 @Override 10498 public ActivityOptions getActivityOptions(IBinder token) { 10499 final long origId = Binder.clearCallingIdentity(); 10500 try { 10501 synchronized (this) { 10502 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10503 if (r != null) { 10504 final ActivityOptions activityOptions = r.pendingOptions; 10505 r.pendingOptions = null; 10506 return activityOptions; 10507 } 10508 return null; 10509 } 10510 } finally { 10511 Binder.restoreCallingIdentity(origId); 10512 } 10513 } 10514 10515 @Override 10516 public void setImmersive(IBinder token, boolean immersive) { 10517 synchronized(this) { 10518 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10519 if (r == null) { 10520 throw new IllegalArgumentException(); 10521 } 10522 r.immersive = immersive; 10523 10524 // update associated state if we're frontmost 10525 if (r == mFocusedActivity) { 10526 if (DEBUG_IMMERSIVE) { 10527 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10528 } 10529 applyUpdateLockStateLocked(r); 10530 } 10531 } 10532 } 10533 10534 @Override 10535 public boolean isImmersive(IBinder token) { 10536 synchronized (this) { 10537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10538 if (r == null) { 10539 throw new IllegalArgumentException(); 10540 } 10541 return r.immersive; 10542 } 10543 } 10544 10545 public boolean isTopActivityImmersive() { 10546 enforceNotIsolatedCaller("startActivity"); 10547 synchronized (this) { 10548 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10549 return (r != null) ? r.immersive : false; 10550 } 10551 } 10552 10553 @Override 10554 public boolean isTopOfTask(IBinder token) { 10555 synchronized (this) { 10556 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10557 if (r == null) { 10558 throw new IllegalArgumentException(); 10559 } 10560 return r.task.getTopActivity() == r; 10561 } 10562 } 10563 10564 public final void enterSafeMode() { 10565 synchronized(this) { 10566 // It only makes sense to do this before the system is ready 10567 // and started launching other packages. 10568 if (!mSystemReady) { 10569 try { 10570 AppGlobals.getPackageManager().enterSafeMode(); 10571 } catch (RemoteException e) { 10572 } 10573 } 10574 10575 mSafeMode = true; 10576 } 10577 } 10578 10579 public final void showSafeModeOverlay() { 10580 View v = LayoutInflater.from(mContext).inflate( 10581 com.android.internal.R.layout.safe_mode, null); 10582 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10583 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10584 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10585 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10586 lp.gravity = Gravity.BOTTOM | Gravity.START; 10587 lp.format = v.getBackground().getOpacity(); 10588 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10589 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10590 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10591 ((WindowManager)mContext.getSystemService( 10592 Context.WINDOW_SERVICE)).addView(v, lp); 10593 } 10594 10595 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10596 if (!(sender instanceof PendingIntentRecord)) { 10597 return; 10598 } 10599 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10600 synchronized (stats) { 10601 if (mBatteryStatsService.isOnBattery()) { 10602 mBatteryStatsService.enforceCallingPermission(); 10603 PendingIntentRecord rec = (PendingIntentRecord)sender; 10604 int MY_UID = Binder.getCallingUid(); 10605 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10606 BatteryStatsImpl.Uid.Pkg pkg = 10607 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10608 sourcePkg != null ? sourcePkg : rec.key.packageName); 10609 pkg.incWakeupsLocked(); 10610 } 10611 } 10612 } 10613 10614 public boolean killPids(int[] pids, String pReason, boolean secure) { 10615 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10616 throw new SecurityException("killPids only available to the system"); 10617 } 10618 String reason = (pReason == null) ? "Unknown" : pReason; 10619 // XXX Note: don't acquire main activity lock here, because the window 10620 // manager calls in with its locks held. 10621 10622 boolean killed = false; 10623 synchronized (mPidsSelfLocked) { 10624 int[] types = new int[pids.length]; 10625 int worstType = 0; 10626 for (int i=0; i<pids.length; i++) { 10627 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10628 if (proc != null) { 10629 int type = proc.setAdj; 10630 types[i] = type; 10631 if (type > worstType) { 10632 worstType = type; 10633 } 10634 } 10635 } 10636 10637 // If the worst oom_adj is somewhere in the cached proc LRU range, 10638 // then constrain it so we will kill all cached procs. 10639 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10640 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10641 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10642 } 10643 10644 // If this is not a secure call, don't let it kill processes that 10645 // are important. 10646 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10647 worstType = ProcessList.SERVICE_ADJ; 10648 } 10649 10650 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10651 for (int i=0; i<pids.length; i++) { 10652 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10653 if (proc == null) { 10654 continue; 10655 } 10656 int adj = proc.setAdj; 10657 if (adj >= worstType && !proc.killedByAm) { 10658 proc.kill(reason, true); 10659 killed = true; 10660 } 10661 } 10662 } 10663 return killed; 10664 } 10665 10666 @Override 10667 public void killUid(int uid, String reason) { 10668 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10669 throw new SecurityException("killUid only available to the system"); 10670 } 10671 synchronized (this) { 10672 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10673 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10674 reason != null ? reason : "kill uid"); 10675 } 10676 } 10677 10678 @Override 10679 public boolean killProcessesBelowForeground(String reason) { 10680 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10681 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10682 } 10683 10684 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10685 } 10686 10687 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10688 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10689 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10690 } 10691 10692 boolean killed = false; 10693 synchronized (mPidsSelfLocked) { 10694 final int size = mPidsSelfLocked.size(); 10695 for (int i = 0; i < size; i++) { 10696 final int pid = mPidsSelfLocked.keyAt(i); 10697 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10698 if (proc == null) continue; 10699 10700 final int adj = proc.setAdj; 10701 if (adj > belowAdj && !proc.killedByAm) { 10702 proc.kill(reason, true); 10703 killed = true; 10704 } 10705 } 10706 } 10707 return killed; 10708 } 10709 10710 @Override 10711 public void hang(final IBinder who, boolean allowRestart) { 10712 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10713 != PackageManager.PERMISSION_GRANTED) { 10714 throw new SecurityException("Requires permission " 10715 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10716 } 10717 10718 final IBinder.DeathRecipient death = new DeathRecipient() { 10719 @Override 10720 public void binderDied() { 10721 synchronized (this) { 10722 notifyAll(); 10723 } 10724 } 10725 }; 10726 10727 try { 10728 who.linkToDeath(death, 0); 10729 } catch (RemoteException e) { 10730 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10731 return; 10732 } 10733 10734 synchronized (this) { 10735 Watchdog.getInstance().setAllowRestart(allowRestart); 10736 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10737 synchronized (death) { 10738 while (who.isBinderAlive()) { 10739 try { 10740 death.wait(); 10741 } catch (InterruptedException e) { 10742 } 10743 } 10744 } 10745 Watchdog.getInstance().setAllowRestart(true); 10746 } 10747 } 10748 10749 @Override 10750 public void restart() { 10751 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10752 != PackageManager.PERMISSION_GRANTED) { 10753 throw new SecurityException("Requires permission " 10754 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10755 } 10756 10757 Log.i(TAG, "Sending shutdown broadcast..."); 10758 10759 BroadcastReceiver br = new BroadcastReceiver() { 10760 @Override public void onReceive(Context context, Intent intent) { 10761 // Now the broadcast is done, finish up the low-level shutdown. 10762 Log.i(TAG, "Shutting down activity manager..."); 10763 shutdown(10000); 10764 Log.i(TAG, "Shutdown complete, restarting!"); 10765 Process.killProcess(Process.myPid()); 10766 System.exit(10); 10767 } 10768 }; 10769 10770 // First send the high-level shut down broadcast. 10771 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10772 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10773 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10774 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10775 mContext.sendOrderedBroadcastAsUser(intent, 10776 UserHandle.ALL, null, br, mHandler, 0, null, null); 10777 */ 10778 br.onReceive(mContext, intent); 10779 } 10780 10781 private long getLowRamTimeSinceIdle(long now) { 10782 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10783 } 10784 10785 @Override 10786 public void performIdleMaintenance() { 10787 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10788 != PackageManager.PERMISSION_GRANTED) { 10789 throw new SecurityException("Requires permission " 10790 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10791 } 10792 10793 synchronized (this) { 10794 final long now = SystemClock.uptimeMillis(); 10795 final long timeSinceLastIdle = now - mLastIdleTime; 10796 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10797 mLastIdleTime = now; 10798 mLowRamTimeSinceLastIdle = 0; 10799 if (mLowRamStartTime != 0) { 10800 mLowRamStartTime = now; 10801 } 10802 10803 StringBuilder sb = new StringBuilder(128); 10804 sb.append("Idle maintenance over "); 10805 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10806 sb.append(" low RAM for "); 10807 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10808 Slog.i(TAG, sb.toString()); 10809 10810 // If at least 1/3 of our time since the last idle period has been spent 10811 // with RAM low, then we want to kill processes. 10812 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10813 10814 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10815 ProcessRecord proc = mLruProcesses.get(i); 10816 if (proc.notCachedSinceIdle) { 10817 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10818 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10819 if (doKilling && proc.initialIdlePss != 0 10820 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10821 proc.kill("idle maint (pss " + proc.lastPss 10822 + " from " + proc.initialIdlePss + ")", true); 10823 } 10824 } 10825 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10826 proc.notCachedSinceIdle = true; 10827 proc.initialIdlePss = 0; 10828 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10829 isSleeping(), now); 10830 } 10831 } 10832 10833 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10834 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10835 } 10836 } 10837 10838 private void retrieveSettings() { 10839 final ContentResolver resolver = mContext.getContentResolver(); 10840 String debugApp = Settings.Global.getString( 10841 resolver, Settings.Global.DEBUG_APP); 10842 boolean waitForDebugger = Settings.Global.getInt( 10843 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10844 boolean alwaysFinishActivities = Settings.Global.getInt( 10845 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10846 boolean forceRtl = Settings.Global.getInt( 10847 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10848 // Transfer any global setting for forcing RTL layout, into a System Property 10849 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10850 10851 Configuration configuration = new Configuration(); 10852 Settings.System.getConfiguration(resolver, configuration); 10853 if (forceRtl) { 10854 // This will take care of setting the correct layout direction flags 10855 configuration.setLayoutDirection(configuration.locale); 10856 } 10857 10858 synchronized (this) { 10859 mDebugApp = mOrigDebugApp = debugApp; 10860 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10861 mAlwaysFinishActivities = alwaysFinishActivities; 10862 // This happens before any activities are started, so we can 10863 // change mConfiguration in-place. 10864 updateConfigurationLocked(configuration, null, false, true); 10865 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10866 } 10867 } 10868 10869 /** Loads resources after the current configuration has been set. */ 10870 private void loadResourcesOnSystemReady() { 10871 final Resources res = mContext.getResources(); 10872 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10873 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10874 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10875 } 10876 10877 public boolean testIsSystemReady() { 10878 // no need to synchronize(this) just to read & return the value 10879 return mSystemReady; 10880 } 10881 10882 private static File getCalledPreBootReceiversFile() { 10883 File dataDir = Environment.getDataDirectory(); 10884 File systemDir = new File(dataDir, "system"); 10885 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10886 return fname; 10887 } 10888 10889 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10890 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10891 File file = getCalledPreBootReceiversFile(); 10892 FileInputStream fis = null; 10893 try { 10894 fis = new FileInputStream(file); 10895 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10896 int fvers = dis.readInt(); 10897 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10898 String vers = dis.readUTF(); 10899 String codename = dis.readUTF(); 10900 String build = dis.readUTF(); 10901 if (android.os.Build.VERSION.RELEASE.equals(vers) 10902 && android.os.Build.VERSION.CODENAME.equals(codename) 10903 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10904 int num = dis.readInt(); 10905 while (num > 0) { 10906 num--; 10907 String pkg = dis.readUTF(); 10908 String cls = dis.readUTF(); 10909 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10910 } 10911 } 10912 } 10913 } catch (FileNotFoundException e) { 10914 } catch (IOException e) { 10915 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10916 } finally { 10917 if (fis != null) { 10918 try { 10919 fis.close(); 10920 } catch (IOException e) { 10921 } 10922 } 10923 } 10924 return lastDoneReceivers; 10925 } 10926 10927 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10928 File file = getCalledPreBootReceiversFile(); 10929 FileOutputStream fos = null; 10930 DataOutputStream dos = null; 10931 try { 10932 fos = new FileOutputStream(file); 10933 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10934 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10935 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10936 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10937 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10938 dos.writeInt(list.size()); 10939 for (int i=0; i<list.size(); i++) { 10940 dos.writeUTF(list.get(i).getPackageName()); 10941 dos.writeUTF(list.get(i).getClassName()); 10942 } 10943 } catch (IOException e) { 10944 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10945 file.delete(); 10946 } finally { 10947 FileUtils.sync(fos); 10948 if (dos != null) { 10949 try { 10950 dos.close(); 10951 } catch (IOException e) { 10952 // TODO Auto-generated catch block 10953 e.printStackTrace(); 10954 } 10955 } 10956 } 10957 } 10958 10959 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10960 ArrayList<ComponentName> doneReceivers, int userId) { 10961 boolean waitingUpdate = false; 10962 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10963 List<ResolveInfo> ris = null; 10964 try { 10965 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10966 intent, null, 0, userId); 10967 } catch (RemoteException e) { 10968 } 10969 if (ris != null) { 10970 for (int i=ris.size()-1; i>=0; i--) { 10971 if ((ris.get(i).activityInfo.applicationInfo.flags 10972 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10973 ris.remove(i); 10974 } 10975 } 10976 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10977 10978 // For User 0, load the version number. When delivering to a new user, deliver 10979 // to all receivers. 10980 if (userId == UserHandle.USER_OWNER) { 10981 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10982 for (int i=0; i<ris.size(); i++) { 10983 ActivityInfo ai = ris.get(i).activityInfo; 10984 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10985 if (lastDoneReceivers.contains(comp)) { 10986 // We already did the pre boot receiver for this app with the current 10987 // platform version, so don't do it again... 10988 ris.remove(i); 10989 i--; 10990 // ...however, do keep it as one that has been done, so we don't 10991 // forget about it when rewriting the file of last done receivers. 10992 doneReceivers.add(comp); 10993 } 10994 } 10995 } 10996 10997 // If primary user, send broadcast to all available users, else just to userId 10998 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10999 : new int[] { userId }; 11000 for (int i = 0; i < ris.size(); i++) { 11001 ActivityInfo ai = ris.get(i).activityInfo; 11002 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11003 doneReceivers.add(comp); 11004 intent.setComponent(comp); 11005 for (int j=0; j<users.length; j++) { 11006 IIntentReceiver finisher = null; 11007 // On last receiver and user, set up a completion callback 11008 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11009 finisher = new IIntentReceiver.Stub() { 11010 public void performReceive(Intent intent, int resultCode, 11011 String data, Bundle extras, boolean ordered, 11012 boolean sticky, int sendingUser) { 11013 // The raw IIntentReceiver interface is called 11014 // with the AM lock held, so redispatch to 11015 // execute our code without the lock. 11016 mHandler.post(onFinishCallback); 11017 } 11018 }; 11019 } 11020 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11021 + " for user " + users[j]); 11022 broadcastIntentLocked(null, null, intent, null, finisher, 11023 0, null, null, null, AppOpsManager.OP_NONE, 11024 true, false, MY_PID, Process.SYSTEM_UID, 11025 users[j]); 11026 if (finisher != null) { 11027 waitingUpdate = true; 11028 } 11029 } 11030 } 11031 } 11032 11033 return waitingUpdate; 11034 } 11035 11036 public void systemReady(final Runnable goingCallback) { 11037 synchronized(this) { 11038 if (mSystemReady) { 11039 // If we're done calling all the receivers, run the next "boot phase" passed in 11040 // by the SystemServer 11041 if (goingCallback != null) { 11042 goingCallback.run(); 11043 } 11044 return; 11045 } 11046 11047 // Make sure we have the current profile info, since it is needed for 11048 // security checks. 11049 updateCurrentProfileIdsLocked(); 11050 11051 if (mRecentTasks == null) { 11052 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11053 if (!mRecentTasks.isEmpty()) { 11054 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11055 } 11056 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11057 mTaskPersister.startPersisting(); 11058 } 11059 11060 // Check to see if there are any update receivers to run. 11061 if (!mDidUpdate) { 11062 if (mWaitingUpdate) { 11063 return; 11064 } 11065 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11066 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11067 public void run() { 11068 synchronized (ActivityManagerService.this) { 11069 mDidUpdate = true; 11070 } 11071 writeLastDonePreBootReceivers(doneReceivers); 11072 showBootMessage(mContext.getText( 11073 R.string.android_upgrading_complete), 11074 false); 11075 systemReady(goingCallback); 11076 } 11077 }, doneReceivers, UserHandle.USER_OWNER); 11078 11079 if (mWaitingUpdate) { 11080 return; 11081 } 11082 mDidUpdate = true; 11083 } 11084 11085 mAppOpsService.systemReady(); 11086 mSystemReady = true; 11087 } 11088 11089 ArrayList<ProcessRecord> procsToKill = null; 11090 synchronized(mPidsSelfLocked) { 11091 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11092 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11093 if (!isAllowedWhileBooting(proc.info)){ 11094 if (procsToKill == null) { 11095 procsToKill = new ArrayList<ProcessRecord>(); 11096 } 11097 procsToKill.add(proc); 11098 } 11099 } 11100 } 11101 11102 synchronized(this) { 11103 if (procsToKill != null) { 11104 for (int i=procsToKill.size()-1; i>=0; i--) { 11105 ProcessRecord proc = procsToKill.get(i); 11106 Slog.i(TAG, "Removing system update proc: " + proc); 11107 removeProcessLocked(proc, true, false, "system update done"); 11108 } 11109 } 11110 11111 // Now that we have cleaned up any update processes, we 11112 // are ready to start launching real processes and know that 11113 // we won't trample on them any more. 11114 mProcessesReady = true; 11115 } 11116 11117 Slog.i(TAG, "System now ready"); 11118 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11119 SystemClock.uptimeMillis()); 11120 11121 synchronized(this) { 11122 // Make sure we have no pre-ready processes sitting around. 11123 11124 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11125 ResolveInfo ri = mContext.getPackageManager() 11126 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11127 STOCK_PM_FLAGS); 11128 CharSequence errorMsg = null; 11129 if (ri != null) { 11130 ActivityInfo ai = ri.activityInfo; 11131 ApplicationInfo app = ai.applicationInfo; 11132 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11133 mTopAction = Intent.ACTION_FACTORY_TEST; 11134 mTopData = null; 11135 mTopComponent = new ComponentName(app.packageName, 11136 ai.name); 11137 } else { 11138 errorMsg = mContext.getResources().getText( 11139 com.android.internal.R.string.factorytest_not_system); 11140 } 11141 } else { 11142 errorMsg = mContext.getResources().getText( 11143 com.android.internal.R.string.factorytest_no_action); 11144 } 11145 if (errorMsg != null) { 11146 mTopAction = null; 11147 mTopData = null; 11148 mTopComponent = null; 11149 Message msg = Message.obtain(); 11150 msg.what = SHOW_FACTORY_ERROR_MSG; 11151 msg.getData().putCharSequence("msg", errorMsg); 11152 mHandler.sendMessage(msg); 11153 } 11154 } 11155 } 11156 11157 retrieveSettings(); 11158 loadResourcesOnSystemReady(); 11159 11160 synchronized (this) { 11161 readGrantedUriPermissionsLocked(); 11162 } 11163 11164 if (goingCallback != null) goingCallback.run(); 11165 11166 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11167 Integer.toString(mCurrentUserId), mCurrentUserId); 11168 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11169 Integer.toString(mCurrentUserId), mCurrentUserId); 11170 mSystemServiceManager.startUser(mCurrentUserId); 11171 11172 synchronized (this) { 11173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11174 try { 11175 List apps = AppGlobals.getPackageManager(). 11176 getPersistentApplications(STOCK_PM_FLAGS); 11177 if (apps != null) { 11178 int N = apps.size(); 11179 int i; 11180 for (i=0; i<N; i++) { 11181 ApplicationInfo info 11182 = (ApplicationInfo)apps.get(i); 11183 if (info != null && 11184 !info.packageName.equals("android")) { 11185 addAppLocked(info, false, null /* ABI override */); 11186 } 11187 } 11188 } 11189 } catch (RemoteException ex) { 11190 // pm is in same process, this will never happen. 11191 } 11192 } 11193 11194 // Start up initial activity. 11195 mBooting = true; 11196 startHomeActivityLocked(mCurrentUserId); 11197 11198 try { 11199 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11200 Message msg = Message.obtain(); 11201 msg.what = SHOW_UID_ERROR_MSG; 11202 mHandler.sendMessage(msg); 11203 } 11204 } catch (RemoteException e) { 11205 } 11206 11207 long ident = Binder.clearCallingIdentity(); 11208 try { 11209 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11210 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11211 | Intent.FLAG_RECEIVER_FOREGROUND); 11212 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11213 broadcastIntentLocked(null, null, intent, 11214 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11215 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11216 intent = new Intent(Intent.ACTION_USER_STARTING); 11217 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11218 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11219 broadcastIntentLocked(null, null, intent, 11220 null, new IIntentReceiver.Stub() { 11221 @Override 11222 public void performReceive(Intent intent, int resultCode, String data, 11223 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11224 throws RemoteException { 11225 } 11226 }, 0, null, null, 11227 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11228 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11229 } catch (Throwable t) { 11230 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11231 } finally { 11232 Binder.restoreCallingIdentity(ident); 11233 } 11234 mStackSupervisor.resumeTopActivitiesLocked(); 11235 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11236 } 11237 } 11238 11239 private boolean makeAppCrashingLocked(ProcessRecord app, 11240 String shortMsg, String longMsg, String stackTrace) { 11241 app.crashing = true; 11242 app.crashingReport = generateProcessError(app, 11243 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11244 startAppProblemLocked(app); 11245 app.stopFreezingAllLocked(); 11246 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11247 } 11248 11249 private void makeAppNotRespondingLocked(ProcessRecord app, 11250 String activity, String shortMsg, String longMsg) { 11251 app.notResponding = true; 11252 app.notRespondingReport = generateProcessError(app, 11253 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11254 activity, shortMsg, longMsg, null); 11255 startAppProblemLocked(app); 11256 app.stopFreezingAllLocked(); 11257 } 11258 11259 /** 11260 * Generate a process error record, suitable for attachment to a ProcessRecord. 11261 * 11262 * @param app The ProcessRecord in which the error occurred. 11263 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11264 * ActivityManager.AppErrorStateInfo 11265 * @param activity The activity associated with the crash, if known. 11266 * @param shortMsg Short message describing the crash. 11267 * @param longMsg Long message describing the crash. 11268 * @param stackTrace Full crash stack trace, may be null. 11269 * 11270 * @return Returns a fully-formed AppErrorStateInfo record. 11271 */ 11272 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11273 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11274 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11275 11276 report.condition = condition; 11277 report.processName = app.processName; 11278 report.pid = app.pid; 11279 report.uid = app.info.uid; 11280 report.tag = activity; 11281 report.shortMsg = shortMsg; 11282 report.longMsg = longMsg; 11283 report.stackTrace = stackTrace; 11284 11285 return report; 11286 } 11287 11288 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11289 synchronized (this) { 11290 app.crashing = false; 11291 app.crashingReport = null; 11292 app.notResponding = false; 11293 app.notRespondingReport = null; 11294 if (app.anrDialog == fromDialog) { 11295 app.anrDialog = null; 11296 } 11297 if (app.waitDialog == fromDialog) { 11298 app.waitDialog = null; 11299 } 11300 if (app.pid > 0 && app.pid != MY_PID) { 11301 handleAppCrashLocked(app, null, null, null); 11302 app.kill("user request after error", true); 11303 } 11304 } 11305 } 11306 11307 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11308 String stackTrace) { 11309 long now = SystemClock.uptimeMillis(); 11310 11311 Long crashTime; 11312 if (!app.isolated) { 11313 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11314 } else { 11315 crashTime = null; 11316 } 11317 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11318 // This process loses! 11319 Slog.w(TAG, "Process " + app.info.processName 11320 + " has crashed too many times: killing!"); 11321 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11322 app.userId, app.info.processName, app.uid); 11323 mStackSupervisor.handleAppCrashLocked(app); 11324 if (!app.persistent) { 11325 // We don't want to start this process again until the user 11326 // explicitly does so... but for persistent process, we really 11327 // need to keep it running. If a persistent process is actually 11328 // repeatedly crashing, then badness for everyone. 11329 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11330 app.info.processName); 11331 if (!app.isolated) { 11332 // XXX We don't have a way to mark isolated processes 11333 // as bad, since they don't have a peristent identity. 11334 mBadProcesses.put(app.info.processName, app.uid, 11335 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11336 mProcessCrashTimes.remove(app.info.processName, app.uid); 11337 } 11338 app.bad = true; 11339 app.removed = true; 11340 // Don't let services in this process be restarted and potentially 11341 // annoy the user repeatedly. Unless it is persistent, since those 11342 // processes run critical code. 11343 removeProcessLocked(app, false, false, "crash"); 11344 mStackSupervisor.resumeTopActivitiesLocked(); 11345 return false; 11346 } 11347 mStackSupervisor.resumeTopActivitiesLocked(); 11348 } else { 11349 mStackSupervisor.finishTopRunningActivityLocked(app); 11350 } 11351 11352 // Bump up the crash count of any services currently running in the proc. 11353 for (int i=app.services.size()-1; i>=0; i--) { 11354 // Any services running in the application need to be placed 11355 // back in the pending list. 11356 ServiceRecord sr = app.services.valueAt(i); 11357 sr.crashCount++; 11358 } 11359 11360 // If the crashing process is what we consider to be the "home process" and it has been 11361 // replaced by a third-party app, clear the package preferred activities from packages 11362 // with a home activity running in the process to prevent a repeatedly crashing app 11363 // from blocking the user to manually clear the list. 11364 final ArrayList<ActivityRecord> activities = app.activities; 11365 if (app == mHomeProcess && activities.size() > 0 11366 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11367 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11368 final ActivityRecord r = activities.get(activityNdx); 11369 if (r.isHomeActivity()) { 11370 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11371 try { 11372 ActivityThread.getPackageManager() 11373 .clearPackagePreferredActivities(r.packageName); 11374 } catch (RemoteException c) { 11375 // pm is in same process, this will never happen. 11376 } 11377 } 11378 } 11379 } 11380 11381 if (!app.isolated) { 11382 // XXX Can't keep track of crash times for isolated processes, 11383 // because they don't have a perisistent identity. 11384 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11385 } 11386 11387 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11388 return true; 11389 } 11390 11391 void startAppProblemLocked(ProcessRecord app) { 11392 // If this app is not running under the current user, then we 11393 // can't give it a report button because that would require 11394 // launching the report UI under a different user. 11395 app.errorReportReceiver = null; 11396 11397 for (int userId : mCurrentProfileIds) { 11398 if (app.userId == userId) { 11399 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11400 mContext, app.info.packageName, app.info.flags); 11401 } 11402 } 11403 skipCurrentReceiverLocked(app); 11404 } 11405 11406 void skipCurrentReceiverLocked(ProcessRecord app) { 11407 for (BroadcastQueue queue : mBroadcastQueues) { 11408 queue.skipCurrentReceiverLocked(app); 11409 } 11410 } 11411 11412 /** 11413 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11414 * The application process will exit immediately after this call returns. 11415 * @param app object of the crashing app, null for the system server 11416 * @param crashInfo describing the exception 11417 */ 11418 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11419 ProcessRecord r = findAppProcess(app, "Crash"); 11420 final String processName = app == null ? "system_server" 11421 : (r == null ? "unknown" : r.processName); 11422 11423 handleApplicationCrashInner("crash", r, processName, crashInfo); 11424 } 11425 11426 /* Native crash reporting uses this inner version because it needs to be somewhat 11427 * decoupled from the AM-managed cleanup lifecycle 11428 */ 11429 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11430 ApplicationErrorReport.CrashInfo crashInfo) { 11431 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11432 UserHandle.getUserId(Binder.getCallingUid()), processName, 11433 r == null ? -1 : r.info.flags, 11434 crashInfo.exceptionClassName, 11435 crashInfo.exceptionMessage, 11436 crashInfo.throwFileName, 11437 crashInfo.throwLineNumber); 11438 11439 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11440 11441 crashApplication(r, crashInfo); 11442 } 11443 11444 public void handleApplicationStrictModeViolation( 11445 IBinder app, 11446 int violationMask, 11447 StrictMode.ViolationInfo info) { 11448 ProcessRecord r = findAppProcess(app, "StrictMode"); 11449 if (r == null) { 11450 return; 11451 } 11452 11453 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11454 Integer stackFingerprint = info.hashCode(); 11455 boolean logIt = true; 11456 synchronized (mAlreadyLoggedViolatedStacks) { 11457 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11458 logIt = false; 11459 // TODO: sub-sample into EventLog for these, with 11460 // the info.durationMillis? Then we'd get 11461 // the relative pain numbers, without logging all 11462 // the stack traces repeatedly. We'd want to do 11463 // likewise in the client code, which also does 11464 // dup suppression, before the Binder call. 11465 } else { 11466 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11467 mAlreadyLoggedViolatedStacks.clear(); 11468 } 11469 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11470 } 11471 } 11472 if (logIt) { 11473 logStrictModeViolationToDropBox(r, info); 11474 } 11475 } 11476 11477 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11478 AppErrorResult result = new AppErrorResult(); 11479 synchronized (this) { 11480 final long origId = Binder.clearCallingIdentity(); 11481 11482 Message msg = Message.obtain(); 11483 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11484 HashMap<String, Object> data = new HashMap<String, Object>(); 11485 data.put("result", result); 11486 data.put("app", r); 11487 data.put("violationMask", violationMask); 11488 data.put("info", info); 11489 msg.obj = data; 11490 mHandler.sendMessage(msg); 11491 11492 Binder.restoreCallingIdentity(origId); 11493 } 11494 int res = result.get(); 11495 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11496 } 11497 } 11498 11499 // Depending on the policy in effect, there could be a bunch of 11500 // these in quick succession so we try to batch these together to 11501 // minimize disk writes, number of dropbox entries, and maximize 11502 // compression, by having more fewer, larger records. 11503 private void logStrictModeViolationToDropBox( 11504 ProcessRecord process, 11505 StrictMode.ViolationInfo info) { 11506 if (info == null) { 11507 return; 11508 } 11509 final boolean isSystemApp = process == null || 11510 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11511 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11512 final String processName = process == null ? "unknown" : process.processName; 11513 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11514 final DropBoxManager dbox = (DropBoxManager) 11515 mContext.getSystemService(Context.DROPBOX_SERVICE); 11516 11517 // Exit early if the dropbox isn't configured to accept this report type. 11518 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11519 11520 boolean bufferWasEmpty; 11521 boolean needsFlush; 11522 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11523 synchronized (sb) { 11524 bufferWasEmpty = sb.length() == 0; 11525 appendDropBoxProcessHeaders(process, processName, sb); 11526 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11527 sb.append("System-App: ").append(isSystemApp).append("\n"); 11528 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11529 if (info.violationNumThisLoop != 0) { 11530 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11531 } 11532 if (info.numAnimationsRunning != 0) { 11533 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11534 } 11535 if (info.broadcastIntentAction != null) { 11536 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11537 } 11538 if (info.durationMillis != -1) { 11539 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11540 } 11541 if (info.numInstances != -1) { 11542 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11543 } 11544 if (info.tags != null) { 11545 for (String tag : info.tags) { 11546 sb.append("Span-Tag: ").append(tag).append("\n"); 11547 } 11548 } 11549 sb.append("\n"); 11550 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11551 sb.append(info.crashInfo.stackTrace); 11552 } 11553 sb.append("\n"); 11554 11555 // Only buffer up to ~64k. Various logging bits truncate 11556 // things at 128k. 11557 needsFlush = (sb.length() > 64 * 1024); 11558 } 11559 11560 // Flush immediately if the buffer's grown too large, or this 11561 // is a non-system app. Non-system apps are isolated with a 11562 // different tag & policy and not batched. 11563 // 11564 // Batching is useful during internal testing with 11565 // StrictMode settings turned up high. Without batching, 11566 // thousands of separate files could be created on boot. 11567 if (!isSystemApp || needsFlush) { 11568 new Thread("Error dump: " + dropboxTag) { 11569 @Override 11570 public void run() { 11571 String report; 11572 synchronized (sb) { 11573 report = sb.toString(); 11574 sb.delete(0, sb.length()); 11575 sb.trimToSize(); 11576 } 11577 if (report.length() != 0) { 11578 dbox.addText(dropboxTag, report); 11579 } 11580 } 11581 }.start(); 11582 return; 11583 } 11584 11585 // System app batching: 11586 if (!bufferWasEmpty) { 11587 // An existing dropbox-writing thread is outstanding, so 11588 // we don't need to start it up. The existing thread will 11589 // catch the buffer appends we just did. 11590 return; 11591 } 11592 11593 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11594 // (After this point, we shouldn't access AMS internal data structures.) 11595 new Thread("Error dump: " + dropboxTag) { 11596 @Override 11597 public void run() { 11598 // 5 second sleep to let stacks arrive and be batched together 11599 try { 11600 Thread.sleep(5000); // 5 seconds 11601 } catch (InterruptedException e) {} 11602 11603 String errorReport; 11604 synchronized (mStrictModeBuffer) { 11605 errorReport = mStrictModeBuffer.toString(); 11606 if (errorReport.length() == 0) { 11607 return; 11608 } 11609 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11610 mStrictModeBuffer.trimToSize(); 11611 } 11612 dbox.addText(dropboxTag, errorReport); 11613 } 11614 }.start(); 11615 } 11616 11617 /** 11618 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11619 * @param app object of the crashing app, null for the system server 11620 * @param tag reported by the caller 11621 * @param system whether this wtf is coming from the system 11622 * @param crashInfo describing the context of the error 11623 * @return true if the process should exit immediately (WTF is fatal) 11624 */ 11625 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11626 final ApplicationErrorReport.CrashInfo crashInfo) { 11627 final int callingUid = Binder.getCallingUid(); 11628 final int callingPid = Binder.getCallingPid(); 11629 11630 if (system) { 11631 // If this is coming from the system, we could very well have low-level 11632 // system locks held, so we want to do this all asynchronously. And we 11633 // never want this to become fatal, so there is that too. 11634 mHandler.post(new Runnable() { 11635 @Override public void run() { 11636 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11637 } 11638 }); 11639 return false; 11640 } 11641 11642 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11643 crashInfo); 11644 11645 if (r != null && r.pid != Process.myPid() && 11646 Settings.Global.getInt(mContext.getContentResolver(), 11647 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11648 crashApplication(r, crashInfo); 11649 return true; 11650 } else { 11651 return false; 11652 } 11653 } 11654 11655 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11656 final ApplicationErrorReport.CrashInfo crashInfo) { 11657 final ProcessRecord r = findAppProcess(app, "WTF"); 11658 final String processName = app == null ? "system_server" 11659 : (r == null ? "unknown" : r.processName); 11660 11661 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11662 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11663 11664 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11665 11666 return r; 11667 } 11668 11669 /** 11670 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11671 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11672 */ 11673 private ProcessRecord findAppProcess(IBinder app, String reason) { 11674 if (app == null) { 11675 return null; 11676 } 11677 11678 synchronized (this) { 11679 final int NP = mProcessNames.getMap().size(); 11680 for (int ip=0; ip<NP; ip++) { 11681 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11682 final int NA = apps.size(); 11683 for (int ia=0; ia<NA; ia++) { 11684 ProcessRecord p = apps.valueAt(ia); 11685 if (p.thread != null && p.thread.asBinder() == app) { 11686 return p; 11687 } 11688 } 11689 } 11690 11691 Slog.w(TAG, "Can't find mystery application for " + reason 11692 + " from pid=" + Binder.getCallingPid() 11693 + " uid=" + Binder.getCallingUid() + ": " + app); 11694 return null; 11695 } 11696 } 11697 11698 /** 11699 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11700 * to append various headers to the dropbox log text. 11701 */ 11702 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11703 StringBuilder sb) { 11704 // Watchdog thread ends up invoking this function (with 11705 // a null ProcessRecord) to add the stack file to dropbox. 11706 // Do not acquire a lock on this (am) in such cases, as it 11707 // could cause a potential deadlock, if and when watchdog 11708 // is invoked due to unavailability of lock on am and it 11709 // would prevent watchdog from killing system_server. 11710 if (process == null) { 11711 sb.append("Process: ").append(processName).append("\n"); 11712 return; 11713 } 11714 // Note: ProcessRecord 'process' is guarded by the service 11715 // instance. (notably process.pkgList, which could otherwise change 11716 // concurrently during execution of this method) 11717 synchronized (this) { 11718 sb.append("Process: ").append(processName).append("\n"); 11719 int flags = process.info.flags; 11720 IPackageManager pm = AppGlobals.getPackageManager(); 11721 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11722 for (int ip=0; ip<process.pkgList.size(); ip++) { 11723 String pkg = process.pkgList.keyAt(ip); 11724 sb.append("Package: ").append(pkg); 11725 try { 11726 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11727 if (pi != null) { 11728 sb.append(" v").append(pi.versionCode); 11729 if (pi.versionName != null) { 11730 sb.append(" (").append(pi.versionName).append(")"); 11731 } 11732 } 11733 } catch (RemoteException e) { 11734 Slog.e(TAG, "Error getting package info: " + pkg, e); 11735 } 11736 sb.append("\n"); 11737 } 11738 } 11739 } 11740 11741 private static String processClass(ProcessRecord process) { 11742 if (process == null || process.pid == MY_PID) { 11743 return "system_server"; 11744 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11745 return "system_app"; 11746 } else { 11747 return "data_app"; 11748 } 11749 } 11750 11751 /** 11752 * Write a description of an error (crash, WTF, ANR) to the drop box. 11753 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11754 * @param process which caused the error, null means the system server 11755 * @param activity which triggered the error, null if unknown 11756 * @param parent activity related to the error, null if unknown 11757 * @param subject line related to the error, null if absent 11758 * @param report in long form describing the error, null if absent 11759 * @param logFile to include in the report, null if none 11760 * @param crashInfo giving an application stack trace, null if absent 11761 */ 11762 public void addErrorToDropBox(String eventType, 11763 ProcessRecord process, String processName, ActivityRecord activity, 11764 ActivityRecord parent, String subject, 11765 final String report, final File logFile, 11766 final ApplicationErrorReport.CrashInfo crashInfo) { 11767 // NOTE -- this must never acquire the ActivityManagerService lock, 11768 // otherwise the watchdog may be prevented from resetting the system. 11769 11770 final String dropboxTag = processClass(process) + "_" + eventType; 11771 final DropBoxManager dbox = (DropBoxManager) 11772 mContext.getSystemService(Context.DROPBOX_SERVICE); 11773 11774 // Exit early if the dropbox isn't configured to accept this report type. 11775 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11776 11777 final StringBuilder sb = new StringBuilder(1024); 11778 appendDropBoxProcessHeaders(process, processName, sb); 11779 if (activity != null) { 11780 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11781 } 11782 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11783 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11784 } 11785 if (parent != null && parent != activity) { 11786 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11787 } 11788 if (subject != null) { 11789 sb.append("Subject: ").append(subject).append("\n"); 11790 } 11791 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11792 if (Debug.isDebuggerConnected()) { 11793 sb.append("Debugger: Connected\n"); 11794 } 11795 sb.append("\n"); 11796 11797 // Do the rest in a worker thread to avoid blocking the caller on I/O 11798 // (After this point, we shouldn't access AMS internal data structures.) 11799 Thread worker = new Thread("Error dump: " + dropboxTag) { 11800 @Override 11801 public void run() { 11802 if (report != null) { 11803 sb.append(report); 11804 } 11805 if (logFile != null) { 11806 try { 11807 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11808 "\n\n[[TRUNCATED]]")); 11809 } catch (IOException e) { 11810 Slog.e(TAG, "Error reading " + logFile, e); 11811 } 11812 } 11813 if (crashInfo != null && crashInfo.stackTrace != null) { 11814 sb.append(crashInfo.stackTrace); 11815 } 11816 11817 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11818 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11819 if (lines > 0) { 11820 sb.append("\n"); 11821 11822 // Merge several logcat streams, and take the last N lines 11823 InputStreamReader input = null; 11824 try { 11825 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11826 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11827 "-b", "crash", 11828 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11829 11830 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11831 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11832 input = new InputStreamReader(logcat.getInputStream()); 11833 11834 int num; 11835 char[] buf = new char[8192]; 11836 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11837 } catch (IOException e) { 11838 Slog.e(TAG, "Error running logcat", e); 11839 } finally { 11840 if (input != null) try { input.close(); } catch (IOException e) {} 11841 } 11842 } 11843 11844 dbox.addText(dropboxTag, sb.toString()); 11845 } 11846 }; 11847 11848 if (process == null) { 11849 // If process is null, we are being called from some internal code 11850 // and may be about to die -- run this synchronously. 11851 worker.run(); 11852 } else { 11853 worker.start(); 11854 } 11855 } 11856 11857 /** 11858 * Bring up the "unexpected error" dialog box for a crashing app. 11859 * Deal with edge cases (intercepts from instrumented applications, 11860 * ActivityController, error intent receivers, that sort of thing). 11861 * @param r the application crashing 11862 * @param crashInfo describing the failure 11863 */ 11864 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11865 long timeMillis = System.currentTimeMillis(); 11866 String shortMsg = crashInfo.exceptionClassName; 11867 String longMsg = crashInfo.exceptionMessage; 11868 String stackTrace = crashInfo.stackTrace; 11869 if (shortMsg != null && longMsg != null) { 11870 longMsg = shortMsg + ": " + longMsg; 11871 } else if (shortMsg != null) { 11872 longMsg = shortMsg; 11873 } 11874 11875 AppErrorResult result = new AppErrorResult(); 11876 synchronized (this) { 11877 if (mController != null) { 11878 try { 11879 String name = r != null ? r.processName : null; 11880 int pid = r != null ? r.pid : Binder.getCallingPid(); 11881 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11882 if (!mController.appCrashed(name, pid, 11883 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11884 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11885 && "Native crash".equals(crashInfo.exceptionClassName)) { 11886 Slog.w(TAG, "Skip killing native crashed app " + name 11887 + "(" + pid + ") during testing"); 11888 } else { 11889 Slog.w(TAG, "Force-killing crashed app " + name 11890 + " at watcher's request"); 11891 if (r != null) { 11892 r.kill("crash", true); 11893 } else { 11894 // Huh. 11895 Process.killProcess(pid); 11896 Process.killProcessGroup(uid, pid); 11897 } 11898 } 11899 return; 11900 } 11901 } catch (RemoteException e) { 11902 mController = null; 11903 Watchdog.getInstance().setActivityController(null); 11904 } 11905 } 11906 11907 final long origId = Binder.clearCallingIdentity(); 11908 11909 // If this process is running instrumentation, finish it. 11910 if (r != null && r.instrumentationClass != null) { 11911 Slog.w(TAG, "Error in app " + r.processName 11912 + " running instrumentation " + r.instrumentationClass + ":"); 11913 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11914 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11915 Bundle info = new Bundle(); 11916 info.putString("shortMsg", shortMsg); 11917 info.putString("longMsg", longMsg); 11918 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11919 Binder.restoreCallingIdentity(origId); 11920 return; 11921 } 11922 11923 // If we can't identify the process or it's already exceeded its crash quota, 11924 // quit right away without showing a crash dialog. 11925 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11926 Binder.restoreCallingIdentity(origId); 11927 return; 11928 } 11929 11930 Message msg = Message.obtain(); 11931 msg.what = SHOW_ERROR_MSG; 11932 HashMap data = new HashMap(); 11933 data.put("result", result); 11934 data.put("app", r); 11935 msg.obj = data; 11936 mHandler.sendMessage(msg); 11937 11938 Binder.restoreCallingIdentity(origId); 11939 } 11940 11941 int res = result.get(); 11942 11943 Intent appErrorIntent = null; 11944 synchronized (this) { 11945 if (r != null && !r.isolated) { 11946 // XXX Can't keep track of crash time for isolated processes, 11947 // since they don't have a persistent identity. 11948 mProcessCrashTimes.put(r.info.processName, r.uid, 11949 SystemClock.uptimeMillis()); 11950 } 11951 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11952 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11953 } 11954 } 11955 11956 if (appErrorIntent != null) { 11957 try { 11958 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11959 } catch (ActivityNotFoundException e) { 11960 Slog.w(TAG, "bug report receiver dissappeared", e); 11961 } 11962 } 11963 } 11964 11965 Intent createAppErrorIntentLocked(ProcessRecord r, 11966 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11967 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11968 if (report == null) { 11969 return null; 11970 } 11971 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11972 result.setComponent(r.errorReportReceiver); 11973 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11974 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11975 return result; 11976 } 11977 11978 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11979 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11980 if (r.errorReportReceiver == null) { 11981 return null; 11982 } 11983 11984 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11985 return null; 11986 } 11987 11988 ApplicationErrorReport report = new ApplicationErrorReport(); 11989 report.packageName = r.info.packageName; 11990 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11991 report.processName = r.processName; 11992 report.time = timeMillis; 11993 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11994 11995 if (r.crashing || r.forceCrashReport) { 11996 report.type = ApplicationErrorReport.TYPE_CRASH; 11997 report.crashInfo = crashInfo; 11998 } else if (r.notResponding) { 11999 report.type = ApplicationErrorReport.TYPE_ANR; 12000 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12001 12002 report.anrInfo.activity = r.notRespondingReport.tag; 12003 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12004 report.anrInfo.info = r.notRespondingReport.longMsg; 12005 } 12006 12007 return report; 12008 } 12009 12010 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12011 enforceNotIsolatedCaller("getProcessesInErrorState"); 12012 // assume our apps are happy - lazy create the list 12013 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12014 12015 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12016 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12017 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12018 12019 synchronized (this) { 12020 12021 // iterate across all processes 12022 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12023 ProcessRecord app = mLruProcesses.get(i); 12024 if (!allUsers && app.userId != userId) { 12025 continue; 12026 } 12027 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12028 // This one's in trouble, so we'll generate a report for it 12029 // crashes are higher priority (in case there's a crash *and* an anr) 12030 ActivityManager.ProcessErrorStateInfo report = null; 12031 if (app.crashing) { 12032 report = app.crashingReport; 12033 } else if (app.notResponding) { 12034 report = app.notRespondingReport; 12035 } 12036 12037 if (report != null) { 12038 if (errList == null) { 12039 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12040 } 12041 errList.add(report); 12042 } else { 12043 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12044 " crashing = " + app.crashing + 12045 " notResponding = " + app.notResponding); 12046 } 12047 } 12048 } 12049 } 12050 12051 return errList; 12052 } 12053 12054 static int procStateToImportance(int procState, int memAdj, 12055 ActivityManager.RunningAppProcessInfo currApp) { 12056 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12057 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12058 currApp.lru = memAdj; 12059 } else { 12060 currApp.lru = 0; 12061 } 12062 return imp; 12063 } 12064 12065 private void fillInProcMemInfo(ProcessRecord app, 12066 ActivityManager.RunningAppProcessInfo outInfo) { 12067 outInfo.pid = app.pid; 12068 outInfo.uid = app.info.uid; 12069 if (mHeavyWeightProcess == app) { 12070 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12071 } 12072 if (app.persistent) { 12073 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12074 } 12075 if (app.activities.size() > 0) { 12076 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12077 } 12078 outInfo.lastTrimLevel = app.trimMemoryLevel; 12079 int adj = app.curAdj; 12080 int procState = app.curProcState; 12081 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12082 outInfo.importanceReasonCode = app.adjTypeCode; 12083 outInfo.processState = app.curProcState; 12084 } 12085 12086 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12087 enforceNotIsolatedCaller("getRunningAppProcesses"); 12088 // Lazy instantiation of list 12089 List<ActivityManager.RunningAppProcessInfo> runList = null; 12090 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12091 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12092 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12093 synchronized (this) { 12094 // Iterate across all processes 12095 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12096 ProcessRecord app = mLruProcesses.get(i); 12097 if (!allUsers && app.userId != userId) { 12098 continue; 12099 } 12100 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12101 // Generate process state info for running application 12102 ActivityManager.RunningAppProcessInfo currApp = 12103 new ActivityManager.RunningAppProcessInfo(app.processName, 12104 app.pid, app.getPackageList()); 12105 fillInProcMemInfo(app, currApp); 12106 if (app.adjSource instanceof ProcessRecord) { 12107 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12108 currApp.importanceReasonImportance = 12109 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12110 app.adjSourceProcState); 12111 } else if (app.adjSource instanceof ActivityRecord) { 12112 ActivityRecord r = (ActivityRecord)app.adjSource; 12113 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12114 } 12115 if (app.adjTarget instanceof ComponentName) { 12116 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12117 } 12118 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12119 // + " lru=" + currApp.lru); 12120 if (runList == null) { 12121 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12122 } 12123 runList.add(currApp); 12124 } 12125 } 12126 } 12127 return runList; 12128 } 12129 12130 public List<ApplicationInfo> getRunningExternalApplications() { 12131 enforceNotIsolatedCaller("getRunningExternalApplications"); 12132 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12133 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12134 if (runningApps != null && runningApps.size() > 0) { 12135 Set<String> extList = new HashSet<String>(); 12136 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12137 if (app.pkgList != null) { 12138 for (String pkg : app.pkgList) { 12139 extList.add(pkg); 12140 } 12141 } 12142 } 12143 IPackageManager pm = AppGlobals.getPackageManager(); 12144 for (String pkg : extList) { 12145 try { 12146 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12147 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12148 retList.add(info); 12149 } 12150 } catch (RemoteException e) { 12151 } 12152 } 12153 } 12154 return retList; 12155 } 12156 12157 @Override 12158 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12159 enforceNotIsolatedCaller("getMyMemoryState"); 12160 synchronized (this) { 12161 ProcessRecord proc; 12162 synchronized (mPidsSelfLocked) { 12163 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12164 } 12165 fillInProcMemInfo(proc, outInfo); 12166 } 12167 } 12168 12169 @Override 12170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12171 if (checkCallingPermission(android.Manifest.permission.DUMP) 12172 != PackageManager.PERMISSION_GRANTED) { 12173 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12174 + Binder.getCallingPid() 12175 + ", uid=" + Binder.getCallingUid() 12176 + " without permission " 12177 + android.Manifest.permission.DUMP); 12178 return; 12179 } 12180 12181 boolean dumpAll = false; 12182 boolean dumpClient = false; 12183 String dumpPackage = null; 12184 12185 int opti = 0; 12186 while (opti < args.length) { 12187 String opt = args[opti]; 12188 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12189 break; 12190 } 12191 opti++; 12192 if ("-a".equals(opt)) { 12193 dumpAll = true; 12194 } else if ("-c".equals(opt)) { 12195 dumpClient = true; 12196 } else if ("-h".equals(opt)) { 12197 pw.println("Activity manager dump options:"); 12198 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12199 pw.println(" cmd may be one of:"); 12200 pw.println(" a[ctivities]: activity stack state"); 12201 pw.println(" r[recents]: recent activities state"); 12202 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12203 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12204 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12205 pw.println(" o[om]: out of memory management"); 12206 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12207 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12208 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12209 pw.println(" service [COMP_SPEC]: service client-side state"); 12210 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12211 pw.println(" all: dump all activities"); 12212 pw.println(" top: dump the top activity"); 12213 pw.println(" write: write all pending state to storage"); 12214 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12215 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12216 pw.println(" a partial substring in a component name, a"); 12217 pw.println(" hex object identifier."); 12218 pw.println(" -a: include all available server state."); 12219 pw.println(" -c: include client state."); 12220 return; 12221 } else { 12222 pw.println("Unknown argument: " + opt + "; use -h for help"); 12223 } 12224 } 12225 12226 long origId = Binder.clearCallingIdentity(); 12227 boolean more = false; 12228 // Is the caller requesting to dump a particular piece of data? 12229 if (opti < args.length) { 12230 String cmd = args[opti]; 12231 opti++; 12232 if ("activities".equals(cmd) || "a".equals(cmd)) { 12233 synchronized (this) { 12234 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12235 } 12236 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12237 synchronized (this) { 12238 dumpRecentsLocked(fd, pw, args, opti, true, null); 12239 } 12240 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12241 String[] newArgs; 12242 String name; 12243 if (opti >= args.length) { 12244 name = null; 12245 newArgs = EMPTY_STRING_ARRAY; 12246 } else { 12247 name = args[opti]; 12248 opti++; 12249 newArgs = new String[args.length - opti]; 12250 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12251 args.length - opti); 12252 } 12253 synchronized (this) { 12254 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12255 } 12256 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12257 String[] newArgs; 12258 String name; 12259 if (opti >= args.length) { 12260 name = null; 12261 newArgs = EMPTY_STRING_ARRAY; 12262 } else { 12263 name = args[opti]; 12264 opti++; 12265 newArgs = new String[args.length - opti]; 12266 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12267 args.length - opti); 12268 } 12269 synchronized (this) { 12270 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12271 } 12272 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12273 String[] newArgs; 12274 String name; 12275 if (opti >= args.length) { 12276 name = null; 12277 newArgs = EMPTY_STRING_ARRAY; 12278 } else { 12279 name = args[opti]; 12280 opti++; 12281 newArgs = new String[args.length - opti]; 12282 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12283 args.length - opti); 12284 } 12285 synchronized (this) { 12286 dumpProcessesLocked(fd, pw, args, opti, true, name); 12287 } 12288 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12289 synchronized (this) { 12290 dumpOomLocked(fd, pw, args, opti, true); 12291 } 12292 } else if ("provider".equals(cmd)) { 12293 String[] newArgs; 12294 String name; 12295 if (opti >= args.length) { 12296 name = null; 12297 newArgs = EMPTY_STRING_ARRAY; 12298 } else { 12299 name = args[opti]; 12300 opti++; 12301 newArgs = new String[args.length - opti]; 12302 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12303 } 12304 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12305 pw.println("No providers match: " + name); 12306 pw.println("Use -h for help."); 12307 } 12308 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12309 synchronized (this) { 12310 dumpProvidersLocked(fd, pw, args, opti, true, null); 12311 } 12312 } else if ("service".equals(cmd)) { 12313 String[] newArgs; 12314 String name; 12315 if (opti >= args.length) { 12316 name = null; 12317 newArgs = EMPTY_STRING_ARRAY; 12318 } else { 12319 name = args[opti]; 12320 opti++; 12321 newArgs = new String[args.length - opti]; 12322 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12323 args.length - opti); 12324 } 12325 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12326 pw.println("No services match: " + name); 12327 pw.println("Use -h for help."); 12328 } 12329 } else if ("package".equals(cmd)) { 12330 String[] newArgs; 12331 if (opti >= args.length) { 12332 pw.println("package: no package name specified"); 12333 pw.println("Use -h for help."); 12334 } else { 12335 dumpPackage = args[opti]; 12336 opti++; 12337 newArgs = new String[args.length - opti]; 12338 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12339 args.length - opti); 12340 args = newArgs; 12341 opti = 0; 12342 more = true; 12343 } 12344 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12345 synchronized (this) { 12346 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12347 } 12348 } else if ("write".equals(cmd)) { 12349 mTaskPersister.flush(); 12350 pw.println("All tasks persisted."); 12351 return; 12352 } else { 12353 // Dumping a single activity? 12354 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12355 pw.println("Bad activity command, or no activities match: " + cmd); 12356 pw.println("Use -h for help."); 12357 } 12358 } 12359 if (!more) { 12360 Binder.restoreCallingIdentity(origId); 12361 return; 12362 } 12363 } 12364 12365 // No piece of data specified, dump everything. 12366 synchronized (this) { 12367 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12368 pw.println(); 12369 if (dumpAll) { 12370 pw.println("-------------------------------------------------------------------------------"); 12371 } 12372 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12373 pw.println(); 12374 if (dumpAll) { 12375 pw.println("-------------------------------------------------------------------------------"); 12376 } 12377 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12378 pw.println(); 12379 if (dumpAll) { 12380 pw.println("-------------------------------------------------------------------------------"); 12381 } 12382 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12383 pw.println(); 12384 if (dumpAll) { 12385 pw.println("-------------------------------------------------------------------------------"); 12386 } 12387 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12388 pw.println(); 12389 if (dumpAll) { 12390 pw.println("-------------------------------------------------------------------------------"); 12391 } 12392 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12393 pw.println(); 12394 if (dumpAll) { 12395 pw.println("-------------------------------------------------------------------------------"); 12396 } 12397 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12398 } 12399 Binder.restoreCallingIdentity(origId); 12400 } 12401 12402 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12403 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12404 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12405 12406 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12407 dumpPackage); 12408 boolean needSep = printedAnything; 12409 12410 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12411 dumpPackage, needSep, " mFocusedActivity: "); 12412 if (printed) { 12413 printedAnything = true; 12414 needSep = false; 12415 } 12416 12417 if (dumpPackage == null) { 12418 if (needSep) { 12419 pw.println(); 12420 } 12421 needSep = true; 12422 printedAnything = true; 12423 mStackSupervisor.dump(pw, " "); 12424 } 12425 12426 if (!printedAnything) { 12427 pw.println(" (nothing)"); 12428 } 12429 } 12430 12431 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12432 int opti, boolean dumpAll, String dumpPackage) { 12433 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12434 12435 boolean printedAnything = false; 12436 12437 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12438 boolean printedHeader = false; 12439 12440 final int N = mRecentTasks.size(); 12441 for (int i=0; i<N; i++) { 12442 TaskRecord tr = mRecentTasks.get(i); 12443 if (dumpPackage != null) { 12444 if (tr.realActivity == null || 12445 !dumpPackage.equals(tr.realActivity)) { 12446 continue; 12447 } 12448 } 12449 if (!printedHeader) { 12450 pw.println(" Recent tasks:"); 12451 printedHeader = true; 12452 printedAnything = true; 12453 } 12454 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12455 pw.println(tr); 12456 if (dumpAll) { 12457 mRecentTasks.get(i).dump(pw, " "); 12458 } 12459 } 12460 } 12461 12462 if (!printedAnything) { 12463 pw.println(" (nothing)"); 12464 } 12465 } 12466 12467 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12468 int opti, boolean dumpAll, String dumpPackage) { 12469 boolean needSep = false; 12470 boolean printedAnything = false; 12471 int numPers = 0; 12472 12473 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12474 12475 if (dumpAll) { 12476 final int NP = mProcessNames.getMap().size(); 12477 for (int ip=0; ip<NP; ip++) { 12478 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12479 final int NA = procs.size(); 12480 for (int ia=0; ia<NA; ia++) { 12481 ProcessRecord r = procs.valueAt(ia); 12482 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12483 continue; 12484 } 12485 if (!needSep) { 12486 pw.println(" All known processes:"); 12487 needSep = true; 12488 printedAnything = true; 12489 } 12490 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12491 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12492 pw.print(" "); pw.println(r); 12493 r.dump(pw, " "); 12494 if (r.persistent) { 12495 numPers++; 12496 } 12497 } 12498 } 12499 } 12500 12501 if (mIsolatedProcesses.size() > 0) { 12502 boolean printed = false; 12503 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12504 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12505 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12506 continue; 12507 } 12508 if (!printed) { 12509 if (needSep) { 12510 pw.println(); 12511 } 12512 pw.println(" Isolated process list (sorted by uid):"); 12513 printedAnything = true; 12514 printed = true; 12515 needSep = true; 12516 } 12517 pw.println(String.format("%sIsolated #%2d: %s", 12518 " ", i, r.toString())); 12519 } 12520 } 12521 12522 if (mLruProcesses.size() > 0) { 12523 if (needSep) { 12524 pw.println(); 12525 } 12526 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12527 pw.print(" total, non-act at "); 12528 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12529 pw.print(", non-svc at "); 12530 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12531 pw.println("):"); 12532 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12533 needSep = true; 12534 printedAnything = true; 12535 } 12536 12537 if (dumpAll || dumpPackage != null) { 12538 synchronized (mPidsSelfLocked) { 12539 boolean printed = false; 12540 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12541 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12542 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12543 continue; 12544 } 12545 if (!printed) { 12546 if (needSep) pw.println(); 12547 needSep = true; 12548 pw.println(" PID mappings:"); 12549 printed = true; 12550 printedAnything = true; 12551 } 12552 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12553 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12554 } 12555 } 12556 } 12557 12558 if (mForegroundProcesses.size() > 0) { 12559 synchronized (mPidsSelfLocked) { 12560 boolean printed = false; 12561 for (int i=0; i<mForegroundProcesses.size(); i++) { 12562 ProcessRecord r = mPidsSelfLocked.get( 12563 mForegroundProcesses.valueAt(i).pid); 12564 if (dumpPackage != null && (r == null 12565 || !r.pkgList.containsKey(dumpPackage))) { 12566 continue; 12567 } 12568 if (!printed) { 12569 if (needSep) pw.println(); 12570 needSep = true; 12571 pw.println(" Foreground Processes:"); 12572 printed = true; 12573 printedAnything = true; 12574 } 12575 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12576 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12577 } 12578 } 12579 } 12580 12581 if (mPersistentStartingProcesses.size() > 0) { 12582 if (needSep) pw.println(); 12583 needSep = true; 12584 printedAnything = true; 12585 pw.println(" Persisent processes that are starting:"); 12586 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12587 "Starting Norm", "Restarting PERS", dumpPackage); 12588 } 12589 12590 if (mRemovedProcesses.size() > 0) { 12591 if (needSep) pw.println(); 12592 needSep = true; 12593 printedAnything = true; 12594 pw.println(" Processes that are being removed:"); 12595 dumpProcessList(pw, this, mRemovedProcesses, " ", 12596 "Removed Norm", "Removed PERS", dumpPackage); 12597 } 12598 12599 if (mProcessesOnHold.size() > 0) { 12600 if (needSep) pw.println(); 12601 needSep = true; 12602 printedAnything = true; 12603 pw.println(" Processes that are on old until the system is ready:"); 12604 dumpProcessList(pw, this, mProcessesOnHold, " ", 12605 "OnHold Norm", "OnHold PERS", dumpPackage); 12606 } 12607 12608 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12609 12610 if (mProcessCrashTimes.getMap().size() > 0) { 12611 boolean printed = false; 12612 long now = SystemClock.uptimeMillis(); 12613 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12614 final int NP = pmap.size(); 12615 for (int ip=0; ip<NP; ip++) { 12616 String pname = pmap.keyAt(ip); 12617 SparseArray<Long> uids = pmap.valueAt(ip); 12618 final int N = uids.size(); 12619 for (int i=0; i<N; i++) { 12620 int puid = uids.keyAt(i); 12621 ProcessRecord r = mProcessNames.get(pname, puid); 12622 if (dumpPackage != null && (r == null 12623 || !r.pkgList.containsKey(dumpPackage))) { 12624 continue; 12625 } 12626 if (!printed) { 12627 if (needSep) pw.println(); 12628 needSep = true; 12629 pw.println(" Time since processes crashed:"); 12630 printed = true; 12631 printedAnything = true; 12632 } 12633 pw.print(" Process "); pw.print(pname); 12634 pw.print(" uid "); pw.print(puid); 12635 pw.print(": last crashed "); 12636 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12637 pw.println(" ago"); 12638 } 12639 } 12640 } 12641 12642 if (mBadProcesses.getMap().size() > 0) { 12643 boolean printed = false; 12644 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12645 final int NP = pmap.size(); 12646 for (int ip=0; ip<NP; ip++) { 12647 String pname = pmap.keyAt(ip); 12648 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12649 final int N = uids.size(); 12650 for (int i=0; i<N; i++) { 12651 int puid = uids.keyAt(i); 12652 ProcessRecord r = mProcessNames.get(pname, puid); 12653 if (dumpPackage != null && (r == null 12654 || !r.pkgList.containsKey(dumpPackage))) { 12655 continue; 12656 } 12657 if (!printed) { 12658 if (needSep) pw.println(); 12659 needSep = true; 12660 pw.println(" Bad processes:"); 12661 printedAnything = true; 12662 } 12663 BadProcessInfo info = uids.valueAt(i); 12664 pw.print(" Bad process "); pw.print(pname); 12665 pw.print(" uid "); pw.print(puid); 12666 pw.print(": crashed at time "); pw.println(info.time); 12667 if (info.shortMsg != null) { 12668 pw.print(" Short msg: "); pw.println(info.shortMsg); 12669 } 12670 if (info.longMsg != null) { 12671 pw.print(" Long msg: "); pw.println(info.longMsg); 12672 } 12673 if (info.stack != null) { 12674 pw.println(" Stack:"); 12675 int lastPos = 0; 12676 for (int pos=0; pos<info.stack.length(); pos++) { 12677 if (info.stack.charAt(pos) == '\n') { 12678 pw.print(" "); 12679 pw.write(info.stack, lastPos, pos-lastPos); 12680 pw.println(); 12681 lastPos = pos+1; 12682 } 12683 } 12684 if (lastPos < info.stack.length()) { 12685 pw.print(" "); 12686 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12687 pw.println(); 12688 } 12689 } 12690 } 12691 } 12692 } 12693 12694 if (dumpPackage == null) { 12695 pw.println(); 12696 needSep = false; 12697 pw.println(" mStartedUsers:"); 12698 for (int i=0; i<mStartedUsers.size(); i++) { 12699 UserStartedState uss = mStartedUsers.valueAt(i); 12700 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12701 pw.print(": "); uss.dump("", pw); 12702 } 12703 pw.print(" mStartedUserArray: ["); 12704 for (int i=0; i<mStartedUserArray.length; i++) { 12705 if (i > 0) pw.print(", "); 12706 pw.print(mStartedUserArray[i]); 12707 } 12708 pw.println("]"); 12709 pw.print(" mUserLru: ["); 12710 for (int i=0; i<mUserLru.size(); i++) { 12711 if (i > 0) pw.print(", "); 12712 pw.print(mUserLru.get(i)); 12713 } 12714 pw.println("]"); 12715 if (dumpAll) { 12716 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12717 } 12718 synchronized (mUserProfileGroupIdsSelfLocked) { 12719 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12720 pw.println(" mUserProfileGroupIds:"); 12721 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12722 pw.print(" User #"); 12723 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12724 pw.print(" -> profile #"); 12725 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12726 } 12727 } 12728 } 12729 } 12730 if (mHomeProcess != null && (dumpPackage == null 12731 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12732 if (needSep) { 12733 pw.println(); 12734 needSep = false; 12735 } 12736 pw.println(" mHomeProcess: " + mHomeProcess); 12737 } 12738 if (mPreviousProcess != null && (dumpPackage == null 12739 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12740 if (needSep) { 12741 pw.println(); 12742 needSep = false; 12743 } 12744 pw.println(" mPreviousProcess: " + mPreviousProcess); 12745 } 12746 if (dumpAll) { 12747 StringBuilder sb = new StringBuilder(128); 12748 sb.append(" mPreviousProcessVisibleTime: "); 12749 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12750 pw.println(sb); 12751 } 12752 if (mHeavyWeightProcess != null && (dumpPackage == null 12753 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12754 if (needSep) { 12755 pw.println(); 12756 needSep = false; 12757 } 12758 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12759 } 12760 if (dumpPackage == null) { 12761 pw.println(" mConfiguration: " + mConfiguration); 12762 } 12763 if (dumpAll) { 12764 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12765 if (mCompatModePackages.getPackages().size() > 0) { 12766 boolean printed = false; 12767 for (Map.Entry<String, Integer> entry 12768 : mCompatModePackages.getPackages().entrySet()) { 12769 String pkg = entry.getKey(); 12770 int mode = entry.getValue(); 12771 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12772 continue; 12773 } 12774 if (!printed) { 12775 pw.println(" mScreenCompatPackages:"); 12776 printed = true; 12777 } 12778 pw.print(" "); pw.print(pkg); pw.print(": "); 12779 pw.print(mode); pw.println(); 12780 } 12781 } 12782 } 12783 if (dumpPackage == null) { 12784 if (mSleeping || mWentToSleep || mLockScreenShown) { 12785 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12786 + " mLockScreenShown " + mLockScreenShown); 12787 } 12788 if (mShuttingDown || mRunningVoice) { 12789 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12790 } 12791 } 12792 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12793 || mOrigWaitForDebugger) { 12794 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12795 || dumpPackage.equals(mOrigDebugApp)) { 12796 if (needSep) { 12797 pw.println(); 12798 needSep = false; 12799 } 12800 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12801 + " mDebugTransient=" + mDebugTransient 12802 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12803 } 12804 } 12805 if (mOpenGlTraceApp != null) { 12806 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12807 if (needSep) { 12808 pw.println(); 12809 needSep = false; 12810 } 12811 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12812 } 12813 } 12814 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12815 || mProfileFd != null) { 12816 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12817 if (needSep) { 12818 pw.println(); 12819 needSep = false; 12820 } 12821 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12822 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12823 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12824 + mAutoStopProfiler); 12825 pw.println(" mProfileType=" + mProfileType); 12826 } 12827 } 12828 if (dumpPackage == null) { 12829 if (mAlwaysFinishActivities || mController != null) { 12830 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12831 + " mController=" + mController); 12832 } 12833 if (dumpAll) { 12834 pw.println(" Total persistent processes: " + numPers); 12835 pw.println(" mProcessesReady=" + mProcessesReady 12836 + " mSystemReady=" + mSystemReady 12837 + " mBooted=" + mBooted 12838 + " mFactoryTest=" + mFactoryTest); 12839 pw.println(" mBooting=" + mBooting 12840 + " mCallFinishBooting=" + mCallFinishBooting 12841 + " mBootAnimationComplete=" + mBootAnimationComplete); 12842 pw.print(" mLastPowerCheckRealtime="); 12843 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12844 pw.println(""); 12845 pw.print(" mLastPowerCheckUptime="); 12846 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12847 pw.println(""); 12848 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12849 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12850 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12851 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12852 + " (" + mLruProcesses.size() + " total)" 12853 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12854 + " mNumServiceProcs=" + mNumServiceProcs 12855 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12856 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12857 + " mLastMemoryLevel" + mLastMemoryLevel 12858 + " mLastNumProcesses" + mLastNumProcesses); 12859 long now = SystemClock.uptimeMillis(); 12860 pw.print(" mLastIdleTime="); 12861 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12862 pw.print(" mLowRamSinceLastIdle="); 12863 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12864 pw.println(); 12865 } 12866 } 12867 12868 if (!printedAnything) { 12869 pw.println(" (nothing)"); 12870 } 12871 } 12872 12873 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12874 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12875 if (mProcessesToGc.size() > 0) { 12876 boolean printed = false; 12877 long now = SystemClock.uptimeMillis(); 12878 for (int i=0; i<mProcessesToGc.size(); i++) { 12879 ProcessRecord proc = mProcessesToGc.get(i); 12880 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12881 continue; 12882 } 12883 if (!printed) { 12884 if (needSep) pw.println(); 12885 needSep = true; 12886 pw.println(" Processes that are waiting to GC:"); 12887 printed = true; 12888 } 12889 pw.print(" Process "); pw.println(proc); 12890 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12891 pw.print(", last gced="); 12892 pw.print(now-proc.lastRequestedGc); 12893 pw.print(" ms ago, last lowMem="); 12894 pw.print(now-proc.lastLowMemory); 12895 pw.println(" ms ago"); 12896 12897 } 12898 } 12899 return needSep; 12900 } 12901 12902 void printOomLevel(PrintWriter pw, String name, int adj) { 12903 pw.print(" "); 12904 if (adj >= 0) { 12905 pw.print(' '); 12906 if (adj < 10) pw.print(' '); 12907 } else { 12908 if (adj > -10) pw.print(' '); 12909 } 12910 pw.print(adj); 12911 pw.print(": "); 12912 pw.print(name); 12913 pw.print(" ("); 12914 pw.print(mProcessList.getMemLevel(adj)/1024); 12915 pw.println(" kB)"); 12916 } 12917 12918 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12919 int opti, boolean dumpAll) { 12920 boolean needSep = false; 12921 12922 if (mLruProcesses.size() > 0) { 12923 if (needSep) pw.println(); 12924 needSep = true; 12925 pw.println(" OOM levels:"); 12926 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12927 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12928 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12929 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12930 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12931 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12932 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12933 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12934 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12935 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12936 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12937 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12938 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12939 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12940 12941 if (needSep) pw.println(); 12942 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12943 pw.print(" total, non-act at "); 12944 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12945 pw.print(", non-svc at "); 12946 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12947 pw.println("):"); 12948 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12949 needSep = true; 12950 } 12951 12952 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12953 12954 pw.println(); 12955 pw.println(" mHomeProcess: " + mHomeProcess); 12956 pw.println(" mPreviousProcess: " + mPreviousProcess); 12957 if (mHeavyWeightProcess != null) { 12958 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12959 } 12960 12961 return true; 12962 } 12963 12964 /** 12965 * There are three ways to call this: 12966 * - no provider specified: dump all the providers 12967 * - a flattened component name that matched an existing provider was specified as the 12968 * first arg: dump that one provider 12969 * - the first arg isn't the flattened component name of an existing provider: 12970 * dump all providers whose component contains the first arg as a substring 12971 */ 12972 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12973 int opti, boolean dumpAll) { 12974 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12975 } 12976 12977 static class ItemMatcher { 12978 ArrayList<ComponentName> components; 12979 ArrayList<String> strings; 12980 ArrayList<Integer> objects; 12981 boolean all; 12982 12983 ItemMatcher() { 12984 all = true; 12985 } 12986 12987 void build(String name) { 12988 ComponentName componentName = ComponentName.unflattenFromString(name); 12989 if (componentName != null) { 12990 if (components == null) { 12991 components = new ArrayList<ComponentName>(); 12992 } 12993 components.add(componentName); 12994 all = false; 12995 } else { 12996 int objectId = 0; 12997 // Not a '/' separated full component name; maybe an object ID? 12998 try { 12999 objectId = Integer.parseInt(name, 16); 13000 if (objects == null) { 13001 objects = new ArrayList<Integer>(); 13002 } 13003 objects.add(objectId); 13004 all = false; 13005 } catch (RuntimeException e) { 13006 // Not an integer; just do string match. 13007 if (strings == null) { 13008 strings = new ArrayList<String>(); 13009 } 13010 strings.add(name); 13011 all = false; 13012 } 13013 } 13014 } 13015 13016 int build(String[] args, int opti) { 13017 for (; opti<args.length; opti++) { 13018 String name = args[opti]; 13019 if ("--".equals(name)) { 13020 return opti+1; 13021 } 13022 build(name); 13023 } 13024 return opti; 13025 } 13026 13027 boolean match(Object object, ComponentName comp) { 13028 if (all) { 13029 return true; 13030 } 13031 if (components != null) { 13032 for (int i=0; i<components.size(); i++) { 13033 if (components.get(i).equals(comp)) { 13034 return true; 13035 } 13036 } 13037 } 13038 if (objects != null) { 13039 for (int i=0; i<objects.size(); i++) { 13040 if (System.identityHashCode(object) == objects.get(i)) { 13041 return true; 13042 } 13043 } 13044 } 13045 if (strings != null) { 13046 String flat = comp.flattenToString(); 13047 for (int i=0; i<strings.size(); i++) { 13048 if (flat.contains(strings.get(i))) { 13049 return true; 13050 } 13051 } 13052 } 13053 return false; 13054 } 13055 } 13056 13057 /** 13058 * There are three things that cmd can be: 13059 * - a flattened component name that matches an existing activity 13060 * - the cmd arg isn't the flattened component name of an existing activity: 13061 * dump all activity whose component contains the cmd as a substring 13062 * - A hex number of the ActivityRecord object instance. 13063 */ 13064 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13065 int opti, boolean dumpAll) { 13066 ArrayList<ActivityRecord> activities; 13067 13068 synchronized (this) { 13069 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13070 } 13071 13072 if (activities.size() <= 0) { 13073 return false; 13074 } 13075 13076 String[] newArgs = new String[args.length - opti]; 13077 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13078 13079 TaskRecord lastTask = null; 13080 boolean needSep = false; 13081 for (int i=activities.size()-1; i>=0; i--) { 13082 ActivityRecord r = activities.get(i); 13083 if (needSep) { 13084 pw.println(); 13085 } 13086 needSep = true; 13087 synchronized (this) { 13088 if (lastTask != r.task) { 13089 lastTask = r.task; 13090 pw.print("TASK "); pw.print(lastTask.affinity); 13091 pw.print(" id="); pw.println(lastTask.taskId); 13092 if (dumpAll) { 13093 lastTask.dump(pw, " "); 13094 } 13095 } 13096 } 13097 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13098 } 13099 return true; 13100 } 13101 13102 /** 13103 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13104 * there is a thread associated with the activity. 13105 */ 13106 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13107 final ActivityRecord r, String[] args, boolean dumpAll) { 13108 String innerPrefix = prefix + " "; 13109 synchronized (this) { 13110 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13111 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13112 pw.print(" pid="); 13113 if (r.app != null) pw.println(r.app.pid); 13114 else pw.println("(not running)"); 13115 if (dumpAll) { 13116 r.dump(pw, innerPrefix); 13117 } 13118 } 13119 if (r.app != null && r.app.thread != null) { 13120 // flush anything that is already in the PrintWriter since the thread is going 13121 // to write to the file descriptor directly 13122 pw.flush(); 13123 try { 13124 TransferPipe tp = new TransferPipe(); 13125 try { 13126 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13127 r.appToken, innerPrefix, args); 13128 tp.go(fd); 13129 } finally { 13130 tp.kill(); 13131 } 13132 } catch (IOException e) { 13133 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13134 } catch (RemoteException e) { 13135 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13136 } 13137 } 13138 } 13139 13140 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13141 int opti, boolean dumpAll, String dumpPackage) { 13142 boolean needSep = false; 13143 boolean onlyHistory = false; 13144 boolean printedAnything = false; 13145 13146 if ("history".equals(dumpPackage)) { 13147 if (opti < args.length && "-s".equals(args[opti])) { 13148 dumpAll = false; 13149 } 13150 onlyHistory = true; 13151 dumpPackage = null; 13152 } 13153 13154 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13155 if (!onlyHistory && dumpAll) { 13156 if (mRegisteredReceivers.size() > 0) { 13157 boolean printed = false; 13158 Iterator it = mRegisteredReceivers.values().iterator(); 13159 while (it.hasNext()) { 13160 ReceiverList r = (ReceiverList)it.next(); 13161 if (dumpPackage != null && (r.app == null || 13162 !dumpPackage.equals(r.app.info.packageName))) { 13163 continue; 13164 } 13165 if (!printed) { 13166 pw.println(" Registered Receivers:"); 13167 needSep = true; 13168 printed = true; 13169 printedAnything = true; 13170 } 13171 pw.print(" * "); pw.println(r); 13172 r.dump(pw, " "); 13173 } 13174 } 13175 13176 if (mReceiverResolver.dump(pw, needSep ? 13177 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13178 " ", dumpPackage, false)) { 13179 needSep = true; 13180 printedAnything = true; 13181 } 13182 } 13183 13184 for (BroadcastQueue q : mBroadcastQueues) { 13185 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13186 printedAnything |= needSep; 13187 } 13188 13189 needSep = true; 13190 13191 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13192 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13193 if (needSep) { 13194 pw.println(); 13195 } 13196 needSep = true; 13197 printedAnything = true; 13198 pw.print(" Sticky broadcasts for user "); 13199 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13200 StringBuilder sb = new StringBuilder(128); 13201 for (Map.Entry<String, ArrayList<Intent>> ent 13202 : mStickyBroadcasts.valueAt(user).entrySet()) { 13203 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13204 if (dumpAll) { 13205 pw.println(":"); 13206 ArrayList<Intent> intents = ent.getValue(); 13207 final int N = intents.size(); 13208 for (int i=0; i<N; i++) { 13209 sb.setLength(0); 13210 sb.append(" Intent: "); 13211 intents.get(i).toShortString(sb, false, true, false, false); 13212 pw.println(sb.toString()); 13213 Bundle bundle = intents.get(i).getExtras(); 13214 if (bundle != null) { 13215 pw.print(" "); 13216 pw.println(bundle.toString()); 13217 } 13218 } 13219 } else { 13220 pw.println(""); 13221 } 13222 } 13223 } 13224 } 13225 13226 if (!onlyHistory && dumpAll) { 13227 pw.println(); 13228 for (BroadcastQueue queue : mBroadcastQueues) { 13229 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13230 + queue.mBroadcastsScheduled); 13231 } 13232 pw.println(" mHandler:"); 13233 mHandler.dump(new PrintWriterPrinter(pw), " "); 13234 needSep = true; 13235 printedAnything = true; 13236 } 13237 13238 if (!printedAnything) { 13239 pw.println(" (nothing)"); 13240 } 13241 } 13242 13243 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13244 int opti, boolean dumpAll, String dumpPackage) { 13245 boolean needSep; 13246 boolean printedAnything = false; 13247 13248 ItemMatcher matcher = new ItemMatcher(); 13249 matcher.build(args, opti); 13250 13251 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13252 13253 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13254 printedAnything |= needSep; 13255 13256 if (mLaunchingProviders.size() > 0) { 13257 boolean printed = false; 13258 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13259 ContentProviderRecord r = mLaunchingProviders.get(i); 13260 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13261 continue; 13262 } 13263 if (!printed) { 13264 if (needSep) pw.println(); 13265 needSep = true; 13266 pw.println(" Launching content providers:"); 13267 printed = true; 13268 printedAnything = true; 13269 } 13270 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13271 pw.println(r); 13272 } 13273 } 13274 13275 if (mGrantedUriPermissions.size() > 0) { 13276 boolean printed = false; 13277 int dumpUid = -2; 13278 if (dumpPackage != null) { 13279 try { 13280 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13281 } catch (NameNotFoundException e) { 13282 dumpUid = -1; 13283 } 13284 } 13285 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13286 int uid = mGrantedUriPermissions.keyAt(i); 13287 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13288 continue; 13289 } 13290 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13291 if (!printed) { 13292 if (needSep) pw.println(); 13293 needSep = true; 13294 pw.println(" Granted Uri Permissions:"); 13295 printed = true; 13296 printedAnything = true; 13297 } 13298 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13299 for (UriPermission perm : perms.values()) { 13300 pw.print(" "); pw.println(perm); 13301 if (dumpAll) { 13302 perm.dump(pw, " "); 13303 } 13304 } 13305 } 13306 } 13307 13308 if (!printedAnything) { 13309 pw.println(" (nothing)"); 13310 } 13311 } 13312 13313 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13314 int opti, boolean dumpAll, String dumpPackage) { 13315 boolean printed = false; 13316 13317 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13318 13319 if (mIntentSenderRecords.size() > 0) { 13320 Iterator<WeakReference<PendingIntentRecord>> it 13321 = mIntentSenderRecords.values().iterator(); 13322 while (it.hasNext()) { 13323 WeakReference<PendingIntentRecord> ref = it.next(); 13324 PendingIntentRecord rec = ref != null ? ref.get(): null; 13325 if (dumpPackage != null && (rec == null 13326 || !dumpPackage.equals(rec.key.packageName))) { 13327 continue; 13328 } 13329 printed = true; 13330 if (rec != null) { 13331 pw.print(" * "); pw.println(rec); 13332 if (dumpAll) { 13333 rec.dump(pw, " "); 13334 } 13335 } else { 13336 pw.print(" * "); pw.println(ref); 13337 } 13338 } 13339 } 13340 13341 if (!printed) { 13342 pw.println(" (nothing)"); 13343 } 13344 } 13345 13346 private static final int dumpProcessList(PrintWriter pw, 13347 ActivityManagerService service, List list, 13348 String prefix, String normalLabel, String persistentLabel, 13349 String dumpPackage) { 13350 int numPers = 0; 13351 final int N = list.size()-1; 13352 for (int i=N; i>=0; i--) { 13353 ProcessRecord r = (ProcessRecord)list.get(i); 13354 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13355 continue; 13356 } 13357 pw.println(String.format("%s%s #%2d: %s", 13358 prefix, (r.persistent ? persistentLabel : normalLabel), 13359 i, r.toString())); 13360 if (r.persistent) { 13361 numPers++; 13362 } 13363 } 13364 return numPers; 13365 } 13366 13367 private static final boolean dumpProcessOomList(PrintWriter pw, 13368 ActivityManagerService service, List<ProcessRecord> origList, 13369 String prefix, String normalLabel, String persistentLabel, 13370 boolean inclDetails, String dumpPackage) { 13371 13372 ArrayList<Pair<ProcessRecord, Integer>> list 13373 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13374 for (int i=0; i<origList.size(); i++) { 13375 ProcessRecord r = origList.get(i); 13376 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13377 continue; 13378 } 13379 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13380 } 13381 13382 if (list.size() <= 0) { 13383 return false; 13384 } 13385 13386 Comparator<Pair<ProcessRecord, Integer>> comparator 13387 = new Comparator<Pair<ProcessRecord, Integer>>() { 13388 @Override 13389 public int compare(Pair<ProcessRecord, Integer> object1, 13390 Pair<ProcessRecord, Integer> object2) { 13391 if (object1.first.setAdj != object2.first.setAdj) { 13392 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13393 } 13394 if (object1.second.intValue() != object2.second.intValue()) { 13395 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13396 } 13397 return 0; 13398 } 13399 }; 13400 13401 Collections.sort(list, comparator); 13402 13403 final long curRealtime = SystemClock.elapsedRealtime(); 13404 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13405 final long curUptime = SystemClock.uptimeMillis(); 13406 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13407 13408 for (int i=list.size()-1; i>=0; i--) { 13409 ProcessRecord r = list.get(i).first; 13410 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13411 char schedGroup; 13412 switch (r.setSchedGroup) { 13413 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13414 schedGroup = 'B'; 13415 break; 13416 case Process.THREAD_GROUP_DEFAULT: 13417 schedGroup = 'F'; 13418 break; 13419 default: 13420 schedGroup = '?'; 13421 break; 13422 } 13423 char foreground; 13424 if (r.foregroundActivities) { 13425 foreground = 'A'; 13426 } else if (r.foregroundServices) { 13427 foreground = 'S'; 13428 } else { 13429 foreground = ' '; 13430 } 13431 String procState = ProcessList.makeProcStateString(r.curProcState); 13432 pw.print(prefix); 13433 pw.print(r.persistent ? persistentLabel : normalLabel); 13434 pw.print(" #"); 13435 int num = (origList.size()-1)-list.get(i).second; 13436 if (num < 10) pw.print(' '); 13437 pw.print(num); 13438 pw.print(": "); 13439 pw.print(oomAdj); 13440 pw.print(' '); 13441 pw.print(schedGroup); 13442 pw.print('/'); 13443 pw.print(foreground); 13444 pw.print('/'); 13445 pw.print(procState); 13446 pw.print(" trm:"); 13447 if (r.trimMemoryLevel < 10) pw.print(' '); 13448 pw.print(r.trimMemoryLevel); 13449 pw.print(' '); 13450 pw.print(r.toShortString()); 13451 pw.print(" ("); 13452 pw.print(r.adjType); 13453 pw.println(')'); 13454 if (r.adjSource != null || r.adjTarget != null) { 13455 pw.print(prefix); 13456 pw.print(" "); 13457 if (r.adjTarget instanceof ComponentName) { 13458 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13459 } else if (r.adjTarget != null) { 13460 pw.print(r.adjTarget.toString()); 13461 } else { 13462 pw.print("{null}"); 13463 } 13464 pw.print("<="); 13465 if (r.adjSource instanceof ProcessRecord) { 13466 pw.print("Proc{"); 13467 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13468 pw.println("}"); 13469 } else if (r.adjSource != null) { 13470 pw.println(r.adjSource.toString()); 13471 } else { 13472 pw.println("{null}"); 13473 } 13474 } 13475 if (inclDetails) { 13476 pw.print(prefix); 13477 pw.print(" "); 13478 pw.print("oom: max="); pw.print(r.maxAdj); 13479 pw.print(" curRaw="); pw.print(r.curRawAdj); 13480 pw.print(" setRaw="); pw.print(r.setRawAdj); 13481 pw.print(" cur="); pw.print(r.curAdj); 13482 pw.print(" set="); pw.println(r.setAdj); 13483 pw.print(prefix); 13484 pw.print(" "); 13485 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13486 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13487 pw.print(" lastPss="); pw.print(r.lastPss); 13488 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13489 pw.print(prefix); 13490 pw.print(" "); 13491 pw.print("cached="); pw.print(r.cached); 13492 pw.print(" empty="); pw.print(r.empty); 13493 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13494 13495 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13496 if (r.lastWakeTime != 0) { 13497 long wtime; 13498 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13499 synchronized (stats) { 13500 wtime = stats.getProcessWakeTime(r.info.uid, 13501 r.pid, curRealtime); 13502 } 13503 long timeUsed = wtime - r.lastWakeTime; 13504 pw.print(prefix); 13505 pw.print(" "); 13506 pw.print("keep awake over "); 13507 TimeUtils.formatDuration(realtimeSince, pw); 13508 pw.print(" used "); 13509 TimeUtils.formatDuration(timeUsed, pw); 13510 pw.print(" ("); 13511 pw.print((timeUsed*100)/realtimeSince); 13512 pw.println("%)"); 13513 } 13514 if (r.lastCpuTime != 0) { 13515 long timeUsed = r.curCpuTime - r.lastCpuTime; 13516 pw.print(prefix); 13517 pw.print(" "); 13518 pw.print("run cpu over "); 13519 TimeUtils.formatDuration(uptimeSince, pw); 13520 pw.print(" used "); 13521 TimeUtils.formatDuration(timeUsed, pw); 13522 pw.print(" ("); 13523 pw.print((timeUsed*100)/uptimeSince); 13524 pw.println("%)"); 13525 } 13526 } 13527 } 13528 } 13529 return true; 13530 } 13531 13532 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13533 String[] args) { 13534 ArrayList<ProcessRecord> procs; 13535 synchronized (this) { 13536 if (args != null && args.length > start 13537 && args[start].charAt(0) != '-') { 13538 procs = new ArrayList<ProcessRecord>(); 13539 int pid = -1; 13540 try { 13541 pid = Integer.parseInt(args[start]); 13542 } catch (NumberFormatException e) { 13543 } 13544 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13545 ProcessRecord proc = mLruProcesses.get(i); 13546 if (proc.pid == pid) { 13547 procs.add(proc); 13548 } else if (allPkgs && proc.pkgList != null 13549 && proc.pkgList.containsKey(args[start])) { 13550 procs.add(proc); 13551 } else if (proc.processName.equals(args[start])) { 13552 procs.add(proc); 13553 } 13554 } 13555 if (procs.size() <= 0) { 13556 return null; 13557 } 13558 } else { 13559 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13560 } 13561 } 13562 return procs; 13563 } 13564 13565 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13566 PrintWriter pw, String[] args) { 13567 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13568 if (procs == null) { 13569 pw.println("No process found for: " + args[0]); 13570 return; 13571 } 13572 13573 long uptime = SystemClock.uptimeMillis(); 13574 long realtime = SystemClock.elapsedRealtime(); 13575 pw.println("Applications Graphics Acceleration Info:"); 13576 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13577 13578 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13579 ProcessRecord r = procs.get(i); 13580 if (r.thread != null) { 13581 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13582 pw.flush(); 13583 try { 13584 TransferPipe tp = new TransferPipe(); 13585 try { 13586 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13587 tp.go(fd); 13588 } finally { 13589 tp.kill(); 13590 } 13591 } catch (IOException e) { 13592 pw.println("Failure while dumping the app: " + r); 13593 pw.flush(); 13594 } catch (RemoteException e) { 13595 pw.println("Got a RemoteException while dumping the app " + r); 13596 pw.flush(); 13597 } 13598 } 13599 } 13600 } 13601 13602 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13603 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13604 if (procs == null) { 13605 pw.println("No process found for: " + args[0]); 13606 return; 13607 } 13608 13609 pw.println("Applications Database Info:"); 13610 13611 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13612 ProcessRecord r = procs.get(i); 13613 if (r.thread != null) { 13614 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13615 pw.flush(); 13616 try { 13617 TransferPipe tp = new TransferPipe(); 13618 try { 13619 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13620 tp.go(fd); 13621 } finally { 13622 tp.kill(); 13623 } 13624 } catch (IOException e) { 13625 pw.println("Failure while dumping the app: " + r); 13626 pw.flush(); 13627 } catch (RemoteException e) { 13628 pw.println("Got a RemoteException while dumping the app " + r); 13629 pw.flush(); 13630 } 13631 } 13632 } 13633 } 13634 13635 final static class MemItem { 13636 final boolean isProc; 13637 final String label; 13638 final String shortLabel; 13639 final long pss; 13640 final int id; 13641 final boolean hasActivities; 13642 ArrayList<MemItem> subitems; 13643 13644 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13645 boolean _hasActivities) { 13646 isProc = true; 13647 label = _label; 13648 shortLabel = _shortLabel; 13649 pss = _pss; 13650 id = _id; 13651 hasActivities = _hasActivities; 13652 } 13653 13654 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13655 isProc = false; 13656 label = _label; 13657 shortLabel = _shortLabel; 13658 pss = _pss; 13659 id = _id; 13660 hasActivities = false; 13661 } 13662 } 13663 13664 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13665 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13666 if (sort && !isCompact) { 13667 Collections.sort(items, new Comparator<MemItem>() { 13668 @Override 13669 public int compare(MemItem lhs, MemItem rhs) { 13670 if (lhs.pss < rhs.pss) { 13671 return 1; 13672 } else if (lhs.pss > rhs.pss) { 13673 return -1; 13674 } 13675 return 0; 13676 } 13677 }); 13678 } 13679 13680 for (int i=0; i<items.size(); i++) { 13681 MemItem mi = items.get(i); 13682 if (!isCompact) { 13683 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13684 } else if (mi.isProc) { 13685 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13686 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13687 pw.println(mi.hasActivities ? ",a" : ",e"); 13688 } else { 13689 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13690 pw.println(mi.pss); 13691 } 13692 if (mi.subitems != null) { 13693 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13694 true, isCompact); 13695 } 13696 } 13697 } 13698 13699 // These are in KB. 13700 static final long[] DUMP_MEM_BUCKETS = new long[] { 13701 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13702 120*1024, 160*1024, 200*1024, 13703 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13704 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13705 }; 13706 13707 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13708 boolean stackLike) { 13709 int start = label.lastIndexOf('.'); 13710 if (start >= 0) start++; 13711 else start = 0; 13712 int end = label.length(); 13713 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13714 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13715 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13716 out.append(bucket); 13717 out.append(stackLike ? "MB." : "MB "); 13718 out.append(label, start, end); 13719 return; 13720 } 13721 } 13722 out.append(memKB/1024); 13723 out.append(stackLike ? "MB." : "MB "); 13724 out.append(label, start, end); 13725 } 13726 13727 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13728 ProcessList.NATIVE_ADJ, 13729 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13730 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13731 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13732 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13733 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13734 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13735 }; 13736 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13737 "Native", 13738 "System", "Persistent", "Persistent Service", "Foreground", 13739 "Visible", "Perceptible", 13740 "Heavy Weight", "Backup", 13741 "A Services", "Home", 13742 "Previous", "B Services", "Cached" 13743 }; 13744 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13745 "native", 13746 "sys", "pers", "persvc", "fore", 13747 "vis", "percept", 13748 "heavy", "backup", 13749 "servicea", "home", 13750 "prev", "serviceb", "cached" 13751 }; 13752 13753 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13754 long realtime, boolean isCheckinRequest, boolean isCompact) { 13755 if (isCheckinRequest || isCompact) { 13756 // short checkin version 13757 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13758 } else { 13759 pw.println("Applications Memory Usage (kB):"); 13760 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13761 } 13762 } 13763 13764 private static final int KSM_SHARED = 0; 13765 private static final int KSM_SHARING = 1; 13766 private static final int KSM_UNSHARED = 2; 13767 private static final int KSM_VOLATILE = 3; 13768 13769 private final long[] getKsmInfo() { 13770 long[] longOut = new long[4]; 13771 final int[] SINGLE_LONG_FORMAT = new int[] { 13772 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13773 }; 13774 long[] longTmp = new long[1]; 13775 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13776 SINGLE_LONG_FORMAT, null, longTmp, null); 13777 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13778 longTmp[0] = 0; 13779 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13780 SINGLE_LONG_FORMAT, null, longTmp, null); 13781 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13782 longTmp[0] = 0; 13783 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13784 SINGLE_LONG_FORMAT, null, longTmp, null); 13785 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13786 longTmp[0] = 0; 13787 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13788 SINGLE_LONG_FORMAT, null, longTmp, null); 13789 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13790 return longOut; 13791 } 13792 13793 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13794 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13795 boolean dumpDetails = false; 13796 boolean dumpFullDetails = false; 13797 boolean dumpDalvik = false; 13798 boolean oomOnly = false; 13799 boolean isCompact = false; 13800 boolean localOnly = false; 13801 boolean packages = false; 13802 13803 int opti = 0; 13804 while (opti < args.length) { 13805 String opt = args[opti]; 13806 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13807 break; 13808 } 13809 opti++; 13810 if ("-a".equals(opt)) { 13811 dumpDetails = true; 13812 dumpFullDetails = true; 13813 dumpDalvik = true; 13814 } else if ("-d".equals(opt)) { 13815 dumpDalvik = true; 13816 } else if ("-c".equals(opt)) { 13817 isCompact = true; 13818 } else if ("--oom".equals(opt)) { 13819 oomOnly = true; 13820 } else if ("--local".equals(opt)) { 13821 localOnly = true; 13822 } else if ("--package".equals(opt)) { 13823 packages = true; 13824 } else if ("-h".equals(opt)) { 13825 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13826 pw.println(" -a: include all available information for each process."); 13827 pw.println(" -d: include dalvik details when dumping process details."); 13828 pw.println(" -c: dump in a compact machine-parseable representation."); 13829 pw.println(" --oom: only show processes organized by oom adj."); 13830 pw.println(" --local: only collect details locally, don't call process."); 13831 pw.println(" --package: interpret process arg as package, dumping all"); 13832 pw.println(" processes that have loaded that package."); 13833 pw.println("If [process] is specified it can be the name or "); 13834 pw.println("pid of a specific process to dump."); 13835 return; 13836 } else { 13837 pw.println("Unknown argument: " + opt + "; use -h for help"); 13838 } 13839 } 13840 13841 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13842 long uptime = SystemClock.uptimeMillis(); 13843 long realtime = SystemClock.elapsedRealtime(); 13844 final long[] tmpLong = new long[1]; 13845 13846 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13847 if (procs == null) { 13848 // No Java processes. Maybe they want to print a native process. 13849 if (args != null && args.length > opti 13850 && args[opti].charAt(0) != '-') { 13851 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13852 = new ArrayList<ProcessCpuTracker.Stats>(); 13853 updateCpuStatsNow(); 13854 int findPid = -1; 13855 try { 13856 findPid = Integer.parseInt(args[opti]); 13857 } catch (NumberFormatException e) { 13858 } 13859 synchronized (mProcessCpuTracker) { 13860 final int N = mProcessCpuTracker.countStats(); 13861 for (int i=0; i<N; i++) { 13862 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13863 if (st.pid == findPid || (st.baseName != null 13864 && st.baseName.equals(args[opti]))) { 13865 nativeProcs.add(st); 13866 } 13867 } 13868 } 13869 if (nativeProcs.size() > 0) { 13870 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13871 isCompact); 13872 Debug.MemoryInfo mi = null; 13873 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13874 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13875 final int pid = r.pid; 13876 if (!isCheckinRequest && dumpDetails) { 13877 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13878 } 13879 if (mi == null) { 13880 mi = new Debug.MemoryInfo(); 13881 } 13882 if (dumpDetails || (!brief && !oomOnly)) { 13883 Debug.getMemoryInfo(pid, mi); 13884 } else { 13885 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13886 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13887 } 13888 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13889 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13890 if (isCheckinRequest) { 13891 pw.println(); 13892 } 13893 } 13894 return; 13895 } 13896 } 13897 pw.println("No process found for: " + args[opti]); 13898 return; 13899 } 13900 13901 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13902 dumpDetails = true; 13903 } 13904 13905 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13906 13907 String[] innerArgs = new String[args.length-opti]; 13908 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13909 13910 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13911 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13912 long nativePss=0, dalvikPss=0, otherPss=0; 13913 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13914 13915 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13916 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13917 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13918 13919 long totalPss = 0; 13920 long cachedPss = 0; 13921 13922 Debug.MemoryInfo mi = null; 13923 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13924 final ProcessRecord r = procs.get(i); 13925 final IApplicationThread thread; 13926 final int pid; 13927 final int oomAdj; 13928 final boolean hasActivities; 13929 synchronized (this) { 13930 thread = r.thread; 13931 pid = r.pid; 13932 oomAdj = r.getSetAdjWithServices(); 13933 hasActivities = r.activities.size() > 0; 13934 } 13935 if (thread != null) { 13936 if (!isCheckinRequest && dumpDetails) { 13937 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13938 } 13939 if (mi == null) { 13940 mi = new Debug.MemoryInfo(); 13941 } 13942 if (dumpDetails || (!brief && !oomOnly)) { 13943 Debug.getMemoryInfo(pid, mi); 13944 } else { 13945 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13946 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13947 } 13948 if (dumpDetails) { 13949 if (localOnly) { 13950 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13951 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13952 if (isCheckinRequest) { 13953 pw.println(); 13954 } 13955 } else { 13956 try { 13957 pw.flush(); 13958 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13959 dumpDalvik, innerArgs); 13960 } catch (RemoteException e) { 13961 if (!isCheckinRequest) { 13962 pw.println("Got RemoteException!"); 13963 pw.flush(); 13964 } 13965 } 13966 } 13967 } 13968 13969 final long myTotalPss = mi.getTotalPss(); 13970 final long myTotalUss = mi.getTotalUss(); 13971 13972 synchronized (this) { 13973 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13974 // Record this for posterity if the process has been stable. 13975 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13976 } 13977 } 13978 13979 if (!isCheckinRequest && mi != null) { 13980 totalPss += myTotalPss; 13981 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13982 (hasActivities ? " / activities)" : ")"), 13983 r.processName, myTotalPss, pid, hasActivities); 13984 procMems.add(pssItem); 13985 procMemsMap.put(pid, pssItem); 13986 13987 nativePss += mi.nativePss; 13988 dalvikPss += mi.dalvikPss; 13989 otherPss += mi.otherPss; 13990 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13991 long mem = mi.getOtherPss(j); 13992 miscPss[j] += mem; 13993 otherPss -= mem; 13994 } 13995 13996 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13997 cachedPss += myTotalPss; 13998 } 13999 14000 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14001 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14002 || oomIndex == (oomPss.length-1)) { 14003 oomPss[oomIndex] += myTotalPss; 14004 if (oomProcs[oomIndex] == null) { 14005 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14006 } 14007 oomProcs[oomIndex].add(pssItem); 14008 break; 14009 } 14010 } 14011 } 14012 } 14013 } 14014 14015 long nativeProcTotalPss = 0; 14016 14017 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14018 // If we are showing aggregations, also look for native processes to 14019 // include so that our aggregations are more accurate. 14020 updateCpuStatsNow(); 14021 synchronized (mProcessCpuTracker) { 14022 final int N = mProcessCpuTracker.countStats(); 14023 for (int i=0; i<N; i++) { 14024 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14025 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14026 if (mi == null) { 14027 mi = new Debug.MemoryInfo(); 14028 } 14029 if (!brief && !oomOnly) { 14030 Debug.getMemoryInfo(st.pid, mi); 14031 } else { 14032 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14033 mi.nativePrivateDirty = (int)tmpLong[0]; 14034 } 14035 14036 final long myTotalPss = mi.getTotalPss(); 14037 totalPss += myTotalPss; 14038 nativeProcTotalPss += myTotalPss; 14039 14040 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14041 st.name, myTotalPss, st.pid, false); 14042 procMems.add(pssItem); 14043 14044 nativePss += mi.nativePss; 14045 dalvikPss += mi.dalvikPss; 14046 otherPss += mi.otherPss; 14047 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14048 long mem = mi.getOtherPss(j); 14049 miscPss[j] += mem; 14050 otherPss -= mem; 14051 } 14052 oomPss[0] += myTotalPss; 14053 if (oomProcs[0] == null) { 14054 oomProcs[0] = new ArrayList<MemItem>(); 14055 } 14056 oomProcs[0].add(pssItem); 14057 } 14058 } 14059 } 14060 14061 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14062 14063 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14064 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14065 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14066 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14067 String label = Debug.MemoryInfo.getOtherLabel(j); 14068 catMems.add(new MemItem(label, label, miscPss[j], j)); 14069 } 14070 14071 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14072 for (int j=0; j<oomPss.length; j++) { 14073 if (oomPss[j] != 0) { 14074 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14075 : DUMP_MEM_OOM_LABEL[j]; 14076 MemItem item = new MemItem(label, label, oomPss[j], 14077 DUMP_MEM_OOM_ADJ[j]); 14078 item.subitems = oomProcs[j]; 14079 oomMems.add(item); 14080 } 14081 } 14082 14083 if (!brief && !oomOnly && !isCompact) { 14084 pw.println(); 14085 pw.println("Total PSS by process:"); 14086 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14087 pw.println(); 14088 } 14089 if (!isCompact) { 14090 pw.println("Total PSS by OOM adjustment:"); 14091 } 14092 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14093 if (!brief && !oomOnly) { 14094 PrintWriter out = categoryPw != null ? categoryPw : pw; 14095 if (!isCompact) { 14096 out.println(); 14097 out.println("Total PSS by category:"); 14098 } 14099 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14100 } 14101 if (!isCompact) { 14102 pw.println(); 14103 } 14104 MemInfoReader memInfo = new MemInfoReader(); 14105 memInfo.readMemInfo(); 14106 if (nativeProcTotalPss > 0) { 14107 synchronized (this) { 14108 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14109 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14110 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14111 } 14112 } 14113 if (!brief) { 14114 if (!isCompact) { 14115 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14116 pw.print(" kB (status "); 14117 switch (mLastMemoryLevel) { 14118 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14119 pw.println("normal)"); 14120 break; 14121 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14122 pw.println("moderate)"); 14123 break; 14124 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14125 pw.println("low)"); 14126 break; 14127 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14128 pw.println("critical)"); 14129 break; 14130 default: 14131 pw.print(mLastMemoryLevel); 14132 pw.println(")"); 14133 break; 14134 } 14135 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14136 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14137 pw.print(cachedPss); pw.print(" cached pss + "); 14138 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14139 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14140 } else { 14141 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14142 pw.print(cachedPss + memInfo.getCachedSizeKb() 14143 + memInfo.getFreeSizeKb()); pw.print(","); 14144 pw.println(totalPss - cachedPss); 14145 } 14146 } 14147 if (!isCompact) { 14148 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14149 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14150 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14151 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14152 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14153 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14154 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14155 } 14156 if (!brief) { 14157 if (memInfo.getZramTotalSizeKb() != 0) { 14158 if (!isCompact) { 14159 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14160 pw.print(" kB physical used for "); 14161 pw.print(memInfo.getSwapTotalSizeKb() 14162 - memInfo.getSwapFreeSizeKb()); 14163 pw.print(" kB in swap ("); 14164 pw.print(memInfo.getSwapTotalSizeKb()); 14165 pw.println(" kB total swap)"); 14166 } else { 14167 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14168 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14169 pw.println(memInfo.getSwapFreeSizeKb()); 14170 } 14171 } 14172 final long[] ksm = getKsmInfo(); 14173 if (!isCompact) { 14174 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14175 || ksm[KSM_VOLATILE] != 0) { 14176 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14177 pw.print(" kB saved from shared "); 14178 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14179 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14180 pw.print(" kB unshared; "); 14181 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14182 } 14183 pw.print(" Tuning: "); 14184 pw.print(ActivityManager.staticGetMemoryClass()); 14185 pw.print(" (large "); 14186 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14187 pw.print("), oom "); 14188 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14189 pw.print(" kB"); 14190 pw.print(", restore limit "); 14191 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14192 pw.print(" kB"); 14193 if (ActivityManager.isLowRamDeviceStatic()) { 14194 pw.print(" (low-ram)"); 14195 } 14196 if (ActivityManager.isHighEndGfx()) { 14197 pw.print(" (high-end-gfx)"); 14198 } 14199 pw.println(); 14200 } else { 14201 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14202 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14203 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14204 pw.print("tuning,"); 14205 pw.print(ActivityManager.staticGetMemoryClass()); 14206 pw.print(','); 14207 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14208 pw.print(','); 14209 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14210 if (ActivityManager.isLowRamDeviceStatic()) { 14211 pw.print(",low-ram"); 14212 } 14213 if (ActivityManager.isHighEndGfx()) { 14214 pw.print(",high-end-gfx"); 14215 } 14216 pw.println(); 14217 } 14218 } 14219 } 14220 } 14221 14222 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14223 String name) { 14224 sb.append(" "); 14225 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14226 sb.append(' '); 14227 sb.append(ProcessList.makeProcStateString(procState)); 14228 sb.append(' '); 14229 ProcessList.appendRamKb(sb, pss); 14230 sb.append(" kB: "); 14231 sb.append(name); 14232 } 14233 14234 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14235 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14236 sb.append(" ("); 14237 sb.append(mi.pid); 14238 sb.append(") "); 14239 sb.append(mi.adjType); 14240 sb.append('\n'); 14241 if (mi.adjReason != null) { 14242 sb.append(" "); 14243 sb.append(mi.adjReason); 14244 sb.append('\n'); 14245 } 14246 } 14247 14248 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14249 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14250 for (int i=0, N=memInfos.size(); i<N; i++) { 14251 ProcessMemInfo mi = memInfos.get(i); 14252 infoMap.put(mi.pid, mi); 14253 } 14254 updateCpuStatsNow(); 14255 synchronized (mProcessCpuTracker) { 14256 final int N = mProcessCpuTracker.countStats(); 14257 for (int i=0; i<N; i++) { 14258 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14259 if (st.vsize > 0) { 14260 long pss = Debug.getPss(st.pid, null); 14261 if (pss > 0) { 14262 if (infoMap.indexOfKey(st.pid) < 0) { 14263 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14264 ProcessList.NATIVE_ADJ, -1, "native", null); 14265 mi.pss = pss; 14266 memInfos.add(mi); 14267 } 14268 } 14269 } 14270 } 14271 } 14272 14273 long totalPss = 0; 14274 for (int i=0, N=memInfos.size(); i<N; i++) { 14275 ProcessMemInfo mi = memInfos.get(i); 14276 if (mi.pss == 0) { 14277 mi.pss = Debug.getPss(mi.pid, null); 14278 } 14279 totalPss += mi.pss; 14280 } 14281 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14282 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14283 if (lhs.oomAdj != rhs.oomAdj) { 14284 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14285 } 14286 if (lhs.pss != rhs.pss) { 14287 return lhs.pss < rhs.pss ? 1 : -1; 14288 } 14289 return 0; 14290 } 14291 }); 14292 14293 StringBuilder tag = new StringBuilder(128); 14294 StringBuilder stack = new StringBuilder(128); 14295 tag.append("Low on memory -- "); 14296 appendMemBucket(tag, totalPss, "total", false); 14297 appendMemBucket(stack, totalPss, "total", true); 14298 14299 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14300 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14301 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14302 14303 boolean firstLine = true; 14304 int lastOomAdj = Integer.MIN_VALUE; 14305 long extraNativeRam = 0; 14306 long cachedPss = 0; 14307 for (int i=0, N=memInfos.size(); i<N; i++) { 14308 ProcessMemInfo mi = memInfos.get(i); 14309 14310 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14311 cachedPss += mi.pss; 14312 } 14313 14314 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14315 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14316 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14317 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14318 if (lastOomAdj != mi.oomAdj) { 14319 lastOomAdj = mi.oomAdj; 14320 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14321 tag.append(" / "); 14322 } 14323 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14324 if (firstLine) { 14325 stack.append(":"); 14326 firstLine = false; 14327 } 14328 stack.append("\n\t at "); 14329 } else { 14330 stack.append("$"); 14331 } 14332 } else { 14333 tag.append(" "); 14334 stack.append("$"); 14335 } 14336 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14337 appendMemBucket(tag, mi.pss, mi.name, false); 14338 } 14339 appendMemBucket(stack, mi.pss, mi.name, true); 14340 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14341 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14342 stack.append("("); 14343 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14344 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14345 stack.append(DUMP_MEM_OOM_LABEL[k]); 14346 stack.append(":"); 14347 stack.append(DUMP_MEM_OOM_ADJ[k]); 14348 } 14349 } 14350 stack.append(")"); 14351 } 14352 } 14353 14354 appendMemInfo(fullNativeBuilder, mi); 14355 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14356 // The short form only has native processes that are >= 1MB. 14357 if (mi.pss >= 1000) { 14358 appendMemInfo(shortNativeBuilder, mi); 14359 } else { 14360 extraNativeRam += mi.pss; 14361 } 14362 } else { 14363 // Short form has all other details, but if we have collected RAM 14364 // from smaller native processes let's dump a summary of that. 14365 if (extraNativeRam > 0) { 14366 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14367 -1, extraNativeRam, "(Other native)"); 14368 shortNativeBuilder.append('\n'); 14369 extraNativeRam = 0; 14370 } 14371 appendMemInfo(fullJavaBuilder, mi); 14372 } 14373 } 14374 14375 fullJavaBuilder.append(" "); 14376 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14377 fullJavaBuilder.append(" kB: TOTAL\n"); 14378 14379 MemInfoReader memInfo = new MemInfoReader(); 14380 memInfo.readMemInfo(); 14381 final long[] infos = memInfo.getRawInfo(); 14382 14383 StringBuilder memInfoBuilder = new StringBuilder(1024); 14384 Debug.getMemInfo(infos); 14385 memInfoBuilder.append(" MemInfo: "); 14386 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14387 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14388 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14389 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14390 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14391 memInfoBuilder.append(" "); 14392 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14393 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14394 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14395 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14396 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14397 memInfoBuilder.append(" ZRAM: "); 14398 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14399 memInfoBuilder.append(" kB RAM, "); 14400 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14401 memInfoBuilder.append(" kB swap total, "); 14402 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14403 memInfoBuilder.append(" kB swap free\n"); 14404 } 14405 final long[] ksm = getKsmInfo(); 14406 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14407 || ksm[KSM_VOLATILE] != 0) { 14408 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14409 memInfoBuilder.append(" kB saved from shared "); 14410 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14411 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14412 memInfoBuilder.append(" kB unshared; "); 14413 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14414 } 14415 memInfoBuilder.append(" Free RAM: "); 14416 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14417 + memInfo.getFreeSizeKb()); 14418 memInfoBuilder.append(" kB\n"); 14419 memInfoBuilder.append(" Used RAM: "); 14420 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14421 memInfoBuilder.append(" kB\n"); 14422 memInfoBuilder.append(" Lost RAM: "); 14423 memInfoBuilder.append(memInfo.getTotalSizeKb() 14424 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14425 - memInfo.getKernelUsedSizeKb()); 14426 memInfoBuilder.append(" kB\n"); 14427 Slog.i(TAG, "Low on memory:"); 14428 Slog.i(TAG, shortNativeBuilder.toString()); 14429 Slog.i(TAG, fullJavaBuilder.toString()); 14430 Slog.i(TAG, memInfoBuilder.toString()); 14431 14432 StringBuilder dropBuilder = new StringBuilder(1024); 14433 /* 14434 StringWriter oomSw = new StringWriter(); 14435 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14436 StringWriter catSw = new StringWriter(); 14437 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14438 String[] emptyArgs = new String[] { }; 14439 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14440 oomPw.flush(); 14441 String oomString = oomSw.toString(); 14442 */ 14443 dropBuilder.append("Low on memory:"); 14444 dropBuilder.append(stack); 14445 dropBuilder.append('\n'); 14446 dropBuilder.append(fullNativeBuilder); 14447 dropBuilder.append(fullJavaBuilder); 14448 dropBuilder.append('\n'); 14449 dropBuilder.append(memInfoBuilder); 14450 dropBuilder.append('\n'); 14451 /* 14452 dropBuilder.append(oomString); 14453 dropBuilder.append('\n'); 14454 */ 14455 StringWriter catSw = new StringWriter(); 14456 synchronized (ActivityManagerService.this) { 14457 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14458 String[] emptyArgs = new String[] { }; 14459 catPw.println(); 14460 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14461 catPw.println(); 14462 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14463 false, false, null); 14464 catPw.println(); 14465 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14466 catPw.flush(); 14467 } 14468 dropBuilder.append(catSw.toString()); 14469 addErrorToDropBox("lowmem", null, "system_server", null, 14470 null, tag.toString(), dropBuilder.toString(), null, null); 14471 //Slog.i(TAG, "Sent to dropbox:"); 14472 //Slog.i(TAG, dropBuilder.toString()); 14473 synchronized (ActivityManagerService.this) { 14474 long now = SystemClock.uptimeMillis(); 14475 if (mLastMemUsageReportTime < now) { 14476 mLastMemUsageReportTime = now; 14477 } 14478 } 14479 } 14480 14481 /** 14482 * Searches array of arguments for the specified string 14483 * @param args array of argument strings 14484 * @param value value to search for 14485 * @return true if the value is contained in the array 14486 */ 14487 private static boolean scanArgs(String[] args, String value) { 14488 if (args != null) { 14489 for (String arg : args) { 14490 if (value.equals(arg)) { 14491 return true; 14492 } 14493 } 14494 } 14495 return false; 14496 } 14497 14498 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14499 ContentProviderRecord cpr, boolean always) { 14500 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14501 14502 if (!inLaunching || always) { 14503 synchronized (cpr) { 14504 cpr.launchingApp = null; 14505 cpr.notifyAll(); 14506 } 14507 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14508 String names[] = cpr.info.authority.split(";"); 14509 for (int j = 0; j < names.length; j++) { 14510 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14511 } 14512 } 14513 14514 for (int i=0; i<cpr.connections.size(); i++) { 14515 ContentProviderConnection conn = cpr.connections.get(i); 14516 if (conn.waiting) { 14517 // If this connection is waiting for the provider, then we don't 14518 // need to mess with its process unless we are always removing 14519 // or for some reason the provider is not currently launching. 14520 if (inLaunching && !always) { 14521 continue; 14522 } 14523 } 14524 ProcessRecord capp = conn.client; 14525 conn.dead = true; 14526 if (conn.stableCount > 0) { 14527 if (!capp.persistent && capp.thread != null 14528 && capp.pid != 0 14529 && capp.pid != MY_PID) { 14530 capp.kill("depends on provider " 14531 + cpr.name.flattenToShortString() 14532 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14533 } 14534 } else if (capp.thread != null && conn.provider.provider != null) { 14535 try { 14536 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14537 } catch (RemoteException e) { 14538 } 14539 // In the protocol here, we don't expect the client to correctly 14540 // clean up this connection, we'll just remove it. 14541 cpr.connections.remove(i); 14542 conn.client.conProviders.remove(conn); 14543 } 14544 } 14545 14546 if (inLaunching && always) { 14547 mLaunchingProviders.remove(cpr); 14548 } 14549 return inLaunching; 14550 } 14551 14552 /** 14553 * Main code for cleaning up a process when it has gone away. This is 14554 * called both as a result of the process dying, or directly when stopping 14555 * a process when running in single process mode. 14556 * 14557 * @return Returns true if the given process has been restarted, so the 14558 * app that was passed in must remain on the process lists. 14559 */ 14560 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14561 boolean restarting, boolean allowRestart, int index) { 14562 if (index >= 0) { 14563 removeLruProcessLocked(app); 14564 ProcessList.remove(app.pid); 14565 } 14566 14567 mProcessesToGc.remove(app); 14568 mPendingPssProcesses.remove(app); 14569 14570 // Dismiss any open dialogs. 14571 if (app.crashDialog != null && !app.forceCrashReport) { 14572 app.crashDialog.dismiss(); 14573 app.crashDialog = null; 14574 } 14575 if (app.anrDialog != null) { 14576 app.anrDialog.dismiss(); 14577 app.anrDialog = null; 14578 } 14579 if (app.waitDialog != null) { 14580 app.waitDialog.dismiss(); 14581 app.waitDialog = null; 14582 } 14583 14584 app.crashing = false; 14585 app.notResponding = false; 14586 14587 app.resetPackageList(mProcessStats); 14588 app.unlinkDeathRecipient(); 14589 app.makeInactive(mProcessStats); 14590 app.waitingToKill = null; 14591 app.forcingToForeground = null; 14592 updateProcessForegroundLocked(app, false, false); 14593 app.foregroundActivities = false; 14594 app.hasShownUi = false; 14595 app.treatLikeActivity = false; 14596 app.hasAboveClient = false; 14597 app.hasClientActivities = false; 14598 14599 mServices.killServicesLocked(app, allowRestart); 14600 14601 boolean restart = false; 14602 14603 // Remove published content providers. 14604 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14605 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14606 final boolean always = app.bad || !allowRestart; 14607 if (removeDyingProviderLocked(app, cpr, always) || always) { 14608 // We left the provider in the launching list, need to 14609 // restart it. 14610 restart = true; 14611 } 14612 14613 cpr.provider = null; 14614 cpr.proc = null; 14615 } 14616 app.pubProviders.clear(); 14617 14618 // Take care of any launching providers waiting for this process. 14619 if (checkAppInLaunchingProvidersLocked(app, false)) { 14620 restart = true; 14621 } 14622 14623 // Unregister from connected content providers. 14624 if (!app.conProviders.isEmpty()) { 14625 for (int i=0; i<app.conProviders.size(); i++) { 14626 ContentProviderConnection conn = app.conProviders.get(i); 14627 conn.provider.connections.remove(conn); 14628 } 14629 app.conProviders.clear(); 14630 } 14631 14632 // At this point there may be remaining entries in mLaunchingProviders 14633 // where we were the only one waiting, so they are no longer of use. 14634 // Look for these and clean up if found. 14635 // XXX Commented out for now. Trying to figure out a way to reproduce 14636 // the actual situation to identify what is actually going on. 14637 if (false) { 14638 for (int i=0; i<mLaunchingProviders.size(); i++) { 14639 ContentProviderRecord cpr = (ContentProviderRecord) 14640 mLaunchingProviders.get(i); 14641 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14642 synchronized (cpr) { 14643 cpr.launchingApp = null; 14644 cpr.notifyAll(); 14645 } 14646 } 14647 } 14648 } 14649 14650 skipCurrentReceiverLocked(app); 14651 14652 // Unregister any receivers. 14653 for (int i=app.receivers.size()-1; i>=0; i--) { 14654 removeReceiverLocked(app.receivers.valueAt(i)); 14655 } 14656 app.receivers.clear(); 14657 14658 // If the app is undergoing backup, tell the backup manager about it 14659 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14660 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14661 + mBackupTarget.appInfo + " died during backup"); 14662 try { 14663 IBackupManager bm = IBackupManager.Stub.asInterface( 14664 ServiceManager.getService(Context.BACKUP_SERVICE)); 14665 bm.agentDisconnected(app.info.packageName); 14666 } catch (RemoteException e) { 14667 // can't happen; backup manager is local 14668 } 14669 } 14670 14671 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14672 ProcessChangeItem item = mPendingProcessChanges.get(i); 14673 if (item.pid == app.pid) { 14674 mPendingProcessChanges.remove(i); 14675 mAvailProcessChanges.add(item); 14676 } 14677 } 14678 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14679 14680 // If the caller is restarting this app, then leave it in its 14681 // current lists and let the caller take care of it. 14682 if (restarting) { 14683 return false; 14684 } 14685 14686 if (!app.persistent || app.isolated) { 14687 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14688 "Removing non-persistent process during cleanup: " + app); 14689 mProcessNames.remove(app.processName, app.uid); 14690 mIsolatedProcesses.remove(app.uid); 14691 if (mHeavyWeightProcess == app) { 14692 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14693 mHeavyWeightProcess.userId, 0)); 14694 mHeavyWeightProcess = null; 14695 } 14696 } else if (!app.removed) { 14697 // This app is persistent, so we need to keep its record around. 14698 // If it is not already on the pending app list, add it there 14699 // and start a new process for it. 14700 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14701 mPersistentStartingProcesses.add(app); 14702 restart = true; 14703 } 14704 } 14705 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14706 "Clean-up removing on hold: " + app); 14707 mProcessesOnHold.remove(app); 14708 14709 if (app == mHomeProcess) { 14710 mHomeProcess = null; 14711 } 14712 if (app == mPreviousProcess) { 14713 mPreviousProcess = null; 14714 } 14715 14716 if (restart && !app.isolated) { 14717 // We have components that still need to be running in the 14718 // process, so re-launch it. 14719 if (index < 0) { 14720 ProcessList.remove(app.pid); 14721 } 14722 mProcessNames.put(app.processName, app.uid, app); 14723 startProcessLocked(app, "restart", app.processName); 14724 return true; 14725 } else if (app.pid > 0 && app.pid != MY_PID) { 14726 // Goodbye! 14727 boolean removed; 14728 synchronized (mPidsSelfLocked) { 14729 mPidsSelfLocked.remove(app.pid); 14730 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14731 } 14732 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14733 if (app.isolated) { 14734 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14735 } 14736 app.setPid(0); 14737 } 14738 return false; 14739 } 14740 14741 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14742 // Look through the content providers we are waiting to have launched, 14743 // and if any run in this process then either schedule a restart of 14744 // the process or kill the client waiting for it if this process has 14745 // gone bad. 14746 int NL = mLaunchingProviders.size(); 14747 boolean restart = false; 14748 for (int i=0; i<NL; i++) { 14749 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14750 if (cpr.launchingApp == app) { 14751 if (!alwaysBad && !app.bad) { 14752 restart = true; 14753 } else { 14754 removeDyingProviderLocked(app, cpr, true); 14755 // cpr should have been removed from mLaunchingProviders 14756 NL = mLaunchingProviders.size(); 14757 i--; 14758 } 14759 } 14760 } 14761 return restart; 14762 } 14763 14764 // ========================================================= 14765 // SERVICES 14766 // ========================================================= 14767 14768 @Override 14769 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14770 int flags) { 14771 enforceNotIsolatedCaller("getServices"); 14772 synchronized (this) { 14773 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14774 } 14775 } 14776 14777 @Override 14778 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14779 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14780 synchronized (this) { 14781 return mServices.getRunningServiceControlPanelLocked(name); 14782 } 14783 } 14784 14785 @Override 14786 public ComponentName startService(IApplicationThread caller, Intent service, 14787 String resolvedType, int userId) { 14788 enforceNotIsolatedCaller("startService"); 14789 // Refuse possible leaked file descriptors 14790 if (service != null && service.hasFileDescriptors() == true) { 14791 throw new IllegalArgumentException("File descriptors passed in Intent"); 14792 } 14793 14794 if (DEBUG_SERVICE) 14795 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14796 synchronized(this) { 14797 final int callingPid = Binder.getCallingPid(); 14798 final int callingUid = Binder.getCallingUid(); 14799 final long origId = Binder.clearCallingIdentity(); 14800 ComponentName res = mServices.startServiceLocked(caller, service, 14801 resolvedType, callingPid, callingUid, userId); 14802 Binder.restoreCallingIdentity(origId); 14803 return res; 14804 } 14805 } 14806 14807 ComponentName startServiceInPackage(int uid, 14808 Intent service, String resolvedType, int userId) { 14809 synchronized(this) { 14810 if (DEBUG_SERVICE) 14811 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14812 final long origId = Binder.clearCallingIdentity(); 14813 ComponentName res = mServices.startServiceLocked(null, service, 14814 resolvedType, -1, uid, userId); 14815 Binder.restoreCallingIdentity(origId); 14816 return res; 14817 } 14818 } 14819 14820 @Override 14821 public int stopService(IApplicationThread caller, Intent service, 14822 String resolvedType, int userId) { 14823 enforceNotIsolatedCaller("stopService"); 14824 // Refuse possible leaked file descriptors 14825 if (service != null && service.hasFileDescriptors() == true) { 14826 throw new IllegalArgumentException("File descriptors passed in Intent"); 14827 } 14828 14829 synchronized(this) { 14830 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14831 } 14832 } 14833 14834 @Override 14835 public IBinder peekService(Intent service, String resolvedType) { 14836 enforceNotIsolatedCaller("peekService"); 14837 // Refuse possible leaked file descriptors 14838 if (service != null && service.hasFileDescriptors() == true) { 14839 throw new IllegalArgumentException("File descriptors passed in Intent"); 14840 } 14841 synchronized(this) { 14842 return mServices.peekServiceLocked(service, resolvedType); 14843 } 14844 } 14845 14846 @Override 14847 public boolean stopServiceToken(ComponentName className, IBinder token, 14848 int startId) { 14849 synchronized(this) { 14850 return mServices.stopServiceTokenLocked(className, token, startId); 14851 } 14852 } 14853 14854 @Override 14855 public void setServiceForeground(ComponentName className, IBinder token, 14856 int id, Notification notification, boolean removeNotification) { 14857 synchronized(this) { 14858 mServices.setServiceForegroundLocked(className, token, id, notification, 14859 removeNotification); 14860 } 14861 } 14862 14863 @Override 14864 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14865 boolean requireFull, String name, String callerPackage) { 14866 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14867 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14868 } 14869 14870 int unsafeConvertIncomingUser(int userId) { 14871 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14872 ? mCurrentUserId : userId; 14873 } 14874 14875 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14876 int allowMode, String name, String callerPackage) { 14877 final int callingUserId = UserHandle.getUserId(callingUid); 14878 if (callingUserId == userId) { 14879 return userId; 14880 } 14881 14882 // Note that we may be accessing mCurrentUserId outside of a lock... 14883 // shouldn't be a big deal, if this is being called outside 14884 // of a locked context there is intrinsically a race with 14885 // the value the caller will receive and someone else changing it. 14886 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14887 // we will switch to the calling user if access to the current user fails. 14888 int targetUserId = unsafeConvertIncomingUser(userId); 14889 14890 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14891 final boolean allow; 14892 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14893 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14894 // If the caller has this permission, they always pass go. And collect $200. 14895 allow = true; 14896 } else if (allowMode == ALLOW_FULL_ONLY) { 14897 // We require full access, sucks to be you. 14898 allow = false; 14899 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14900 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14901 // If the caller does not have either permission, they are always doomed. 14902 allow = false; 14903 } else if (allowMode == ALLOW_NON_FULL) { 14904 // We are blanket allowing non-full access, you lucky caller! 14905 allow = true; 14906 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14907 // We may or may not allow this depending on whether the two users are 14908 // in the same profile. 14909 synchronized (mUserProfileGroupIdsSelfLocked) { 14910 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14911 UserInfo.NO_PROFILE_GROUP_ID); 14912 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14913 UserInfo.NO_PROFILE_GROUP_ID); 14914 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14915 && callingProfile == targetProfile; 14916 } 14917 } else { 14918 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14919 } 14920 if (!allow) { 14921 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14922 // In this case, they would like to just execute as their 14923 // owner user instead of failing. 14924 targetUserId = callingUserId; 14925 } else { 14926 StringBuilder builder = new StringBuilder(128); 14927 builder.append("Permission Denial: "); 14928 builder.append(name); 14929 if (callerPackage != null) { 14930 builder.append(" from "); 14931 builder.append(callerPackage); 14932 } 14933 builder.append(" asks to run as user "); 14934 builder.append(userId); 14935 builder.append(" but is calling from user "); 14936 builder.append(UserHandle.getUserId(callingUid)); 14937 builder.append("; this requires "); 14938 builder.append(INTERACT_ACROSS_USERS_FULL); 14939 if (allowMode != ALLOW_FULL_ONLY) { 14940 builder.append(" or "); 14941 builder.append(INTERACT_ACROSS_USERS); 14942 } 14943 String msg = builder.toString(); 14944 Slog.w(TAG, msg); 14945 throw new SecurityException(msg); 14946 } 14947 } 14948 } 14949 if (!allowAll && targetUserId < 0) { 14950 throw new IllegalArgumentException( 14951 "Call does not support special user #" + targetUserId); 14952 } 14953 // Check shell permission 14954 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14955 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14956 targetUserId)) { 14957 throw new SecurityException("Shell does not have permission to access user " 14958 + targetUserId + "\n " + Debug.getCallers(3)); 14959 } 14960 } 14961 return targetUserId; 14962 } 14963 14964 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14965 String className, int flags) { 14966 boolean result = false; 14967 // For apps that don't have pre-defined UIDs, check for permission 14968 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14969 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14970 if (ActivityManager.checkUidPermission( 14971 INTERACT_ACROSS_USERS, 14972 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14973 ComponentName comp = new ComponentName(aInfo.packageName, className); 14974 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14975 + " requests FLAG_SINGLE_USER, but app does not hold " 14976 + INTERACT_ACROSS_USERS; 14977 Slog.w(TAG, msg); 14978 throw new SecurityException(msg); 14979 } 14980 // Permission passed 14981 result = true; 14982 } 14983 } else if ("system".equals(componentProcessName)) { 14984 result = true; 14985 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14986 // Phone app and persistent apps are allowed to export singleuser providers. 14987 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14988 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14989 } 14990 if (DEBUG_MU) { 14991 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14992 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14993 } 14994 return result; 14995 } 14996 14997 /** 14998 * Checks to see if the caller is in the same app as the singleton 14999 * component, or the component is in a special app. It allows special apps 15000 * to export singleton components but prevents exporting singleton 15001 * components for regular apps. 15002 */ 15003 boolean isValidSingletonCall(int callingUid, int componentUid) { 15004 int componentAppId = UserHandle.getAppId(componentUid); 15005 return UserHandle.isSameApp(callingUid, componentUid) 15006 || componentAppId == Process.SYSTEM_UID 15007 || componentAppId == Process.PHONE_UID 15008 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15009 == PackageManager.PERMISSION_GRANTED; 15010 } 15011 15012 public int bindService(IApplicationThread caller, IBinder token, 15013 Intent service, String resolvedType, 15014 IServiceConnection connection, int flags, int userId) { 15015 enforceNotIsolatedCaller("bindService"); 15016 15017 // Refuse possible leaked file descriptors 15018 if (service != null && service.hasFileDescriptors() == true) { 15019 throw new IllegalArgumentException("File descriptors passed in Intent"); 15020 } 15021 15022 synchronized(this) { 15023 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15024 connection, flags, userId); 15025 } 15026 } 15027 15028 public boolean unbindService(IServiceConnection connection) { 15029 synchronized (this) { 15030 return mServices.unbindServiceLocked(connection); 15031 } 15032 } 15033 15034 public void publishService(IBinder token, Intent intent, IBinder service) { 15035 // Refuse possible leaked file descriptors 15036 if (intent != null && intent.hasFileDescriptors() == true) { 15037 throw new IllegalArgumentException("File descriptors passed in Intent"); 15038 } 15039 15040 synchronized(this) { 15041 if (!(token instanceof ServiceRecord)) { 15042 throw new IllegalArgumentException("Invalid service token"); 15043 } 15044 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15045 } 15046 } 15047 15048 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15049 // Refuse possible leaked file descriptors 15050 if (intent != null && intent.hasFileDescriptors() == true) { 15051 throw new IllegalArgumentException("File descriptors passed in Intent"); 15052 } 15053 15054 synchronized(this) { 15055 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15056 } 15057 } 15058 15059 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15060 synchronized(this) { 15061 if (!(token instanceof ServiceRecord)) { 15062 throw new IllegalArgumentException("Invalid service token"); 15063 } 15064 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15065 } 15066 } 15067 15068 // ========================================================= 15069 // BACKUP AND RESTORE 15070 // ========================================================= 15071 15072 // Cause the target app to be launched if necessary and its backup agent 15073 // instantiated. The backup agent will invoke backupAgentCreated() on the 15074 // activity manager to announce its creation. 15075 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15076 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15077 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15078 15079 synchronized(this) { 15080 // !!! TODO: currently no check here that we're already bound 15081 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15082 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15083 synchronized (stats) { 15084 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15085 } 15086 15087 // Backup agent is now in use, its package can't be stopped. 15088 try { 15089 AppGlobals.getPackageManager().setPackageStoppedState( 15090 app.packageName, false, UserHandle.getUserId(app.uid)); 15091 } catch (RemoteException e) { 15092 } catch (IllegalArgumentException e) { 15093 Slog.w(TAG, "Failed trying to unstop package " 15094 + app.packageName + ": " + e); 15095 } 15096 15097 BackupRecord r = new BackupRecord(ss, app, backupMode); 15098 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15099 ? new ComponentName(app.packageName, app.backupAgentName) 15100 : new ComponentName("android", "FullBackupAgent"); 15101 // startProcessLocked() returns existing proc's record if it's already running 15102 ProcessRecord proc = startProcessLocked(app.processName, app, 15103 false, 0, "backup", hostingName, false, false, false); 15104 if (proc == null) { 15105 Slog.e(TAG, "Unable to start backup agent process " + r); 15106 return false; 15107 } 15108 15109 r.app = proc; 15110 mBackupTarget = r; 15111 mBackupAppName = app.packageName; 15112 15113 // Try not to kill the process during backup 15114 updateOomAdjLocked(proc); 15115 15116 // If the process is already attached, schedule the creation of the backup agent now. 15117 // If it is not yet live, this will be done when it attaches to the framework. 15118 if (proc.thread != null) { 15119 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15120 try { 15121 proc.thread.scheduleCreateBackupAgent(app, 15122 compatibilityInfoForPackageLocked(app), backupMode); 15123 } catch (RemoteException e) { 15124 // Will time out on the backup manager side 15125 } 15126 } else { 15127 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15128 } 15129 // Invariants: at this point, the target app process exists and the application 15130 // is either already running or in the process of coming up. mBackupTarget and 15131 // mBackupAppName describe the app, so that when it binds back to the AM we 15132 // know that it's scheduled for a backup-agent operation. 15133 } 15134 15135 return true; 15136 } 15137 15138 @Override 15139 public void clearPendingBackup() { 15140 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15141 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15142 15143 synchronized (this) { 15144 mBackupTarget = null; 15145 mBackupAppName = null; 15146 } 15147 } 15148 15149 // A backup agent has just come up 15150 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15151 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15152 + " = " + agent); 15153 15154 synchronized(this) { 15155 if (!agentPackageName.equals(mBackupAppName)) { 15156 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15157 return; 15158 } 15159 } 15160 15161 long oldIdent = Binder.clearCallingIdentity(); 15162 try { 15163 IBackupManager bm = IBackupManager.Stub.asInterface( 15164 ServiceManager.getService(Context.BACKUP_SERVICE)); 15165 bm.agentConnected(agentPackageName, agent); 15166 } catch (RemoteException e) { 15167 // can't happen; the backup manager service is local 15168 } catch (Exception e) { 15169 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15170 e.printStackTrace(); 15171 } finally { 15172 Binder.restoreCallingIdentity(oldIdent); 15173 } 15174 } 15175 15176 // done with this agent 15177 public void unbindBackupAgent(ApplicationInfo appInfo) { 15178 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15179 if (appInfo == null) { 15180 Slog.w(TAG, "unbind backup agent for null app"); 15181 return; 15182 } 15183 15184 synchronized(this) { 15185 try { 15186 if (mBackupAppName == null) { 15187 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15188 return; 15189 } 15190 15191 if (!mBackupAppName.equals(appInfo.packageName)) { 15192 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15193 return; 15194 } 15195 15196 // Not backing this app up any more; reset its OOM adjustment 15197 final ProcessRecord proc = mBackupTarget.app; 15198 updateOomAdjLocked(proc); 15199 15200 // If the app crashed during backup, 'thread' will be null here 15201 if (proc.thread != null) { 15202 try { 15203 proc.thread.scheduleDestroyBackupAgent(appInfo, 15204 compatibilityInfoForPackageLocked(appInfo)); 15205 } catch (Exception e) { 15206 Slog.e(TAG, "Exception when unbinding backup agent:"); 15207 e.printStackTrace(); 15208 } 15209 } 15210 } finally { 15211 mBackupTarget = null; 15212 mBackupAppName = null; 15213 } 15214 } 15215 } 15216 // ========================================================= 15217 // BROADCASTS 15218 // ========================================================= 15219 15220 private final List getStickiesLocked(String action, IntentFilter filter, 15221 List cur, int userId) { 15222 final ContentResolver resolver = mContext.getContentResolver(); 15223 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15224 if (stickies == null) { 15225 return cur; 15226 } 15227 final ArrayList<Intent> list = stickies.get(action); 15228 if (list == null) { 15229 return cur; 15230 } 15231 int N = list.size(); 15232 for (int i=0; i<N; i++) { 15233 Intent intent = list.get(i); 15234 if (filter.match(resolver, intent, true, TAG) >= 0) { 15235 if (cur == null) { 15236 cur = new ArrayList<Intent>(); 15237 } 15238 cur.add(intent); 15239 } 15240 } 15241 return cur; 15242 } 15243 15244 boolean isPendingBroadcastProcessLocked(int pid) { 15245 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15246 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15247 } 15248 15249 void skipPendingBroadcastLocked(int pid) { 15250 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15251 for (BroadcastQueue queue : mBroadcastQueues) { 15252 queue.skipPendingBroadcastLocked(pid); 15253 } 15254 } 15255 15256 // The app just attached; send any pending broadcasts that it should receive 15257 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15258 boolean didSomething = false; 15259 for (BroadcastQueue queue : mBroadcastQueues) { 15260 didSomething |= queue.sendPendingBroadcastsLocked(app); 15261 } 15262 return didSomething; 15263 } 15264 15265 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15266 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15267 enforceNotIsolatedCaller("registerReceiver"); 15268 int callingUid; 15269 int callingPid; 15270 synchronized(this) { 15271 ProcessRecord callerApp = null; 15272 if (caller != null) { 15273 callerApp = getRecordForAppLocked(caller); 15274 if (callerApp == null) { 15275 throw new SecurityException( 15276 "Unable to find app for caller " + caller 15277 + " (pid=" + Binder.getCallingPid() 15278 + ") when registering receiver " + receiver); 15279 } 15280 if (callerApp.info.uid != Process.SYSTEM_UID && 15281 !callerApp.pkgList.containsKey(callerPackage) && 15282 !"android".equals(callerPackage)) { 15283 throw new SecurityException("Given caller package " + callerPackage 15284 + " is not running in process " + callerApp); 15285 } 15286 callingUid = callerApp.info.uid; 15287 callingPid = callerApp.pid; 15288 } else { 15289 callerPackage = null; 15290 callingUid = Binder.getCallingUid(); 15291 callingPid = Binder.getCallingPid(); 15292 } 15293 15294 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15295 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15296 15297 List allSticky = null; 15298 15299 // Look for any matching sticky broadcasts... 15300 Iterator actions = filter.actionsIterator(); 15301 if (actions != null) { 15302 while (actions.hasNext()) { 15303 String action = (String)actions.next(); 15304 allSticky = getStickiesLocked(action, filter, allSticky, 15305 UserHandle.USER_ALL); 15306 allSticky = getStickiesLocked(action, filter, allSticky, 15307 UserHandle.getUserId(callingUid)); 15308 } 15309 } else { 15310 allSticky = getStickiesLocked(null, filter, allSticky, 15311 UserHandle.USER_ALL); 15312 allSticky = getStickiesLocked(null, filter, allSticky, 15313 UserHandle.getUserId(callingUid)); 15314 } 15315 15316 // The first sticky in the list is returned directly back to 15317 // the client. 15318 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15319 15320 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15321 + ": " + sticky); 15322 15323 if (receiver == null) { 15324 return sticky; 15325 } 15326 15327 ReceiverList rl 15328 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15329 if (rl == null) { 15330 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15331 userId, receiver); 15332 if (rl.app != null) { 15333 rl.app.receivers.add(rl); 15334 } else { 15335 try { 15336 receiver.asBinder().linkToDeath(rl, 0); 15337 } catch (RemoteException e) { 15338 return sticky; 15339 } 15340 rl.linkedToDeath = true; 15341 } 15342 mRegisteredReceivers.put(receiver.asBinder(), rl); 15343 } else if (rl.uid != callingUid) { 15344 throw new IllegalArgumentException( 15345 "Receiver requested to register for uid " + callingUid 15346 + " was previously registered for uid " + rl.uid); 15347 } else if (rl.pid != callingPid) { 15348 throw new IllegalArgumentException( 15349 "Receiver requested to register for pid " + callingPid 15350 + " was previously registered for pid " + rl.pid); 15351 } else if (rl.userId != userId) { 15352 throw new IllegalArgumentException( 15353 "Receiver requested to register for user " + userId 15354 + " was previously registered for user " + rl.userId); 15355 } 15356 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15357 permission, callingUid, userId); 15358 rl.add(bf); 15359 if (!bf.debugCheck()) { 15360 Slog.w(TAG, "==> For Dynamic broadast"); 15361 } 15362 mReceiverResolver.addFilter(bf); 15363 15364 // Enqueue broadcasts for all existing stickies that match 15365 // this filter. 15366 if (allSticky != null) { 15367 ArrayList receivers = new ArrayList(); 15368 receivers.add(bf); 15369 15370 int N = allSticky.size(); 15371 for (int i=0; i<N; i++) { 15372 Intent intent = (Intent)allSticky.get(i); 15373 BroadcastQueue queue = broadcastQueueForIntent(intent); 15374 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15375 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15376 null, null, false, true, true, -1); 15377 queue.enqueueParallelBroadcastLocked(r); 15378 queue.scheduleBroadcastsLocked(); 15379 } 15380 } 15381 15382 return sticky; 15383 } 15384 } 15385 15386 public void unregisterReceiver(IIntentReceiver receiver) { 15387 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15388 15389 final long origId = Binder.clearCallingIdentity(); 15390 try { 15391 boolean doTrim = false; 15392 15393 synchronized(this) { 15394 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15395 if (rl != null) { 15396 if (rl.curBroadcast != null) { 15397 BroadcastRecord r = rl.curBroadcast; 15398 final boolean doNext = finishReceiverLocked( 15399 receiver.asBinder(), r.resultCode, r.resultData, 15400 r.resultExtras, r.resultAbort); 15401 if (doNext) { 15402 doTrim = true; 15403 r.queue.processNextBroadcast(false); 15404 } 15405 } 15406 15407 if (rl.app != null) { 15408 rl.app.receivers.remove(rl); 15409 } 15410 removeReceiverLocked(rl); 15411 if (rl.linkedToDeath) { 15412 rl.linkedToDeath = false; 15413 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15414 } 15415 } 15416 } 15417 15418 // If we actually concluded any broadcasts, we might now be able 15419 // to trim the recipients' apps from our working set 15420 if (doTrim) { 15421 trimApplications(); 15422 return; 15423 } 15424 15425 } finally { 15426 Binder.restoreCallingIdentity(origId); 15427 } 15428 } 15429 15430 void removeReceiverLocked(ReceiverList rl) { 15431 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15432 int N = rl.size(); 15433 for (int i=0; i<N; i++) { 15434 mReceiverResolver.removeFilter(rl.get(i)); 15435 } 15436 } 15437 15438 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15439 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15440 ProcessRecord r = mLruProcesses.get(i); 15441 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15442 try { 15443 r.thread.dispatchPackageBroadcast(cmd, packages); 15444 } catch (RemoteException ex) { 15445 } 15446 } 15447 } 15448 } 15449 15450 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15451 int callingUid, int[] users) { 15452 List<ResolveInfo> receivers = null; 15453 try { 15454 HashSet<ComponentName> singleUserReceivers = null; 15455 boolean scannedFirstReceivers = false; 15456 for (int user : users) { 15457 // Skip users that have Shell restrictions 15458 if (callingUid == Process.SHELL_UID 15459 && getUserManagerLocked().hasUserRestriction( 15460 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15461 continue; 15462 } 15463 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15464 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15465 if (user != 0 && newReceivers != null) { 15466 // If this is not the primary user, we need to check for 15467 // any receivers that should be filtered out. 15468 for (int i=0; i<newReceivers.size(); i++) { 15469 ResolveInfo ri = newReceivers.get(i); 15470 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15471 newReceivers.remove(i); 15472 i--; 15473 } 15474 } 15475 } 15476 if (newReceivers != null && newReceivers.size() == 0) { 15477 newReceivers = null; 15478 } 15479 if (receivers == null) { 15480 receivers = newReceivers; 15481 } else if (newReceivers != null) { 15482 // We need to concatenate the additional receivers 15483 // found with what we have do far. This would be easy, 15484 // but we also need to de-dup any receivers that are 15485 // singleUser. 15486 if (!scannedFirstReceivers) { 15487 // Collect any single user receivers we had already retrieved. 15488 scannedFirstReceivers = true; 15489 for (int i=0; i<receivers.size(); i++) { 15490 ResolveInfo ri = receivers.get(i); 15491 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15492 ComponentName cn = new ComponentName( 15493 ri.activityInfo.packageName, ri.activityInfo.name); 15494 if (singleUserReceivers == null) { 15495 singleUserReceivers = new HashSet<ComponentName>(); 15496 } 15497 singleUserReceivers.add(cn); 15498 } 15499 } 15500 } 15501 // Add the new results to the existing results, tracking 15502 // and de-dupping single user receivers. 15503 for (int i=0; i<newReceivers.size(); i++) { 15504 ResolveInfo ri = newReceivers.get(i); 15505 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15506 ComponentName cn = new ComponentName( 15507 ri.activityInfo.packageName, ri.activityInfo.name); 15508 if (singleUserReceivers == null) { 15509 singleUserReceivers = new HashSet<ComponentName>(); 15510 } 15511 if (!singleUserReceivers.contains(cn)) { 15512 singleUserReceivers.add(cn); 15513 receivers.add(ri); 15514 } 15515 } else { 15516 receivers.add(ri); 15517 } 15518 } 15519 } 15520 } 15521 } catch (RemoteException ex) { 15522 // pm is in same process, this will never happen. 15523 } 15524 return receivers; 15525 } 15526 15527 private final int broadcastIntentLocked(ProcessRecord callerApp, 15528 String callerPackage, Intent intent, String resolvedType, 15529 IIntentReceiver resultTo, int resultCode, String resultData, 15530 Bundle map, String requiredPermission, int appOp, 15531 boolean ordered, boolean sticky, int callingPid, int callingUid, 15532 int userId) { 15533 intent = new Intent(intent); 15534 15535 // By default broadcasts do not go to stopped apps. 15536 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15537 15538 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15539 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15540 + " ordered=" + ordered + " userid=" + userId); 15541 if ((resultTo != null) && !ordered) { 15542 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15543 } 15544 15545 userId = handleIncomingUser(callingPid, callingUid, userId, 15546 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15547 15548 // Make sure that the user who is receiving this broadcast is started. 15549 // If not, we will just skip it. 15550 15551 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15552 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15553 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15554 Slog.w(TAG, "Skipping broadcast of " + intent 15555 + ": user " + userId + " is stopped"); 15556 return ActivityManager.BROADCAST_SUCCESS; 15557 } 15558 } 15559 15560 /* 15561 * Prevent non-system code (defined here to be non-persistent 15562 * processes) from sending protected broadcasts. 15563 */ 15564 int callingAppId = UserHandle.getAppId(callingUid); 15565 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15566 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15567 || callingAppId == Process.NFC_UID || callingUid == 0) { 15568 // Always okay. 15569 } else if (callerApp == null || !callerApp.persistent) { 15570 try { 15571 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15572 intent.getAction())) { 15573 String msg = "Permission Denial: not allowed to send broadcast " 15574 + intent.getAction() + " from pid=" 15575 + callingPid + ", uid=" + callingUid; 15576 Slog.w(TAG, msg); 15577 throw new SecurityException(msg); 15578 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15579 // Special case for compatibility: we don't want apps to send this, 15580 // but historically it has not been protected and apps may be using it 15581 // to poke their own app widget. So, instead of making it protected, 15582 // just limit it to the caller. 15583 if (callerApp == null) { 15584 String msg = "Permission Denial: not allowed to send broadcast " 15585 + intent.getAction() + " from unknown caller."; 15586 Slog.w(TAG, msg); 15587 throw new SecurityException(msg); 15588 } else if (intent.getComponent() != null) { 15589 // They are good enough to send to an explicit component... verify 15590 // it is being sent to the calling app. 15591 if (!intent.getComponent().getPackageName().equals( 15592 callerApp.info.packageName)) { 15593 String msg = "Permission Denial: not allowed to send broadcast " 15594 + intent.getAction() + " to " 15595 + intent.getComponent().getPackageName() + " from " 15596 + callerApp.info.packageName; 15597 Slog.w(TAG, msg); 15598 throw new SecurityException(msg); 15599 } 15600 } else { 15601 // Limit broadcast to their own package. 15602 intent.setPackage(callerApp.info.packageName); 15603 } 15604 } 15605 } catch (RemoteException e) { 15606 Slog.w(TAG, "Remote exception", e); 15607 return ActivityManager.BROADCAST_SUCCESS; 15608 } 15609 } 15610 15611 // Handle special intents: if this broadcast is from the package 15612 // manager about a package being removed, we need to remove all of 15613 // its activities from the history stack. 15614 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15615 intent.getAction()); 15616 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15617 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15618 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15619 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15620 || uidRemoved) { 15621 if (checkComponentPermission( 15622 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15623 callingPid, callingUid, -1, true) 15624 == PackageManager.PERMISSION_GRANTED) { 15625 if (uidRemoved) { 15626 final Bundle intentExtras = intent.getExtras(); 15627 final int uid = intentExtras != null 15628 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15629 if (uid >= 0) { 15630 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15631 synchronized (bs) { 15632 bs.removeUidStatsLocked(uid); 15633 } 15634 mAppOpsService.uidRemoved(uid); 15635 } 15636 } else { 15637 // If resources are unavailable just force stop all 15638 // those packages and flush the attribute cache as well. 15639 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15640 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15641 if (list != null && (list.length > 0)) { 15642 for (String pkg : list) { 15643 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15644 "storage unmount"); 15645 } 15646 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15647 sendPackageBroadcastLocked( 15648 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15649 } 15650 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15651 intent.getAction())) { 15652 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15653 } else { 15654 Uri data = intent.getData(); 15655 String ssp; 15656 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15657 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15658 intent.getAction()); 15659 boolean fullUninstall = removed && 15660 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15661 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15662 forceStopPackageLocked(ssp, UserHandle.getAppId( 15663 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15664 false, fullUninstall, userId, 15665 removed ? "pkg removed" : "pkg changed"); 15666 } 15667 if (removed) { 15668 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15669 new String[] {ssp}, userId); 15670 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15671 mAppOpsService.packageRemoved( 15672 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15673 15674 // Remove all permissions granted from/to this package 15675 removeUriPermissionsForPackageLocked(ssp, userId, true); 15676 } 15677 } 15678 } 15679 } 15680 } 15681 } else { 15682 String msg = "Permission Denial: " + intent.getAction() 15683 + " broadcast from " + callerPackage + " (pid=" + callingPid 15684 + ", uid=" + callingUid + ")" 15685 + " requires " 15686 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15687 Slog.w(TAG, msg); 15688 throw new SecurityException(msg); 15689 } 15690 15691 // Special case for adding a package: by default turn on compatibility 15692 // mode. 15693 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15694 Uri data = intent.getData(); 15695 String ssp; 15696 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15697 mCompatModePackages.handlePackageAddedLocked(ssp, 15698 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15699 } 15700 } 15701 15702 /* 15703 * If this is the time zone changed action, queue up a message that will reset the timezone 15704 * of all currently running processes. This message will get queued up before the broadcast 15705 * happens. 15706 */ 15707 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15708 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15709 } 15710 15711 /* 15712 * If the user set the time, let all running processes know. 15713 */ 15714 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15715 final int is24Hour = intent.getBooleanExtra( 15716 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15717 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15718 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15719 synchronized (stats) { 15720 stats.noteCurrentTimeChangedLocked(); 15721 } 15722 } 15723 15724 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15725 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15726 } 15727 15728 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15729 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15730 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15731 } 15732 15733 // Add to the sticky list if requested. 15734 if (sticky) { 15735 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15736 callingPid, callingUid) 15737 != PackageManager.PERMISSION_GRANTED) { 15738 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15739 + callingPid + ", uid=" + callingUid 15740 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15741 Slog.w(TAG, msg); 15742 throw new SecurityException(msg); 15743 } 15744 if (requiredPermission != null) { 15745 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15746 + " and enforce permission " + requiredPermission); 15747 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15748 } 15749 if (intent.getComponent() != null) { 15750 throw new SecurityException( 15751 "Sticky broadcasts can't target a specific component"); 15752 } 15753 // We use userId directly here, since the "all" target is maintained 15754 // as a separate set of sticky broadcasts. 15755 if (userId != UserHandle.USER_ALL) { 15756 // But first, if this is not a broadcast to all users, then 15757 // make sure it doesn't conflict with an existing broadcast to 15758 // all users. 15759 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15760 UserHandle.USER_ALL); 15761 if (stickies != null) { 15762 ArrayList<Intent> list = stickies.get(intent.getAction()); 15763 if (list != null) { 15764 int N = list.size(); 15765 int i; 15766 for (i=0; i<N; i++) { 15767 if (intent.filterEquals(list.get(i))) { 15768 throw new IllegalArgumentException( 15769 "Sticky broadcast " + intent + " for user " 15770 + userId + " conflicts with existing global broadcast"); 15771 } 15772 } 15773 } 15774 } 15775 } 15776 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15777 if (stickies == null) { 15778 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15779 mStickyBroadcasts.put(userId, stickies); 15780 } 15781 ArrayList<Intent> list = stickies.get(intent.getAction()); 15782 if (list == null) { 15783 list = new ArrayList<Intent>(); 15784 stickies.put(intent.getAction(), list); 15785 } 15786 int N = list.size(); 15787 int i; 15788 for (i=0; i<N; i++) { 15789 if (intent.filterEquals(list.get(i))) { 15790 // This sticky already exists, replace it. 15791 list.set(i, new Intent(intent)); 15792 break; 15793 } 15794 } 15795 if (i >= N) { 15796 list.add(new Intent(intent)); 15797 } 15798 } 15799 15800 int[] users; 15801 if (userId == UserHandle.USER_ALL) { 15802 // Caller wants broadcast to go to all started users. 15803 users = mStartedUserArray; 15804 } else { 15805 // Caller wants broadcast to go to one specific user. 15806 users = new int[] {userId}; 15807 } 15808 15809 // Figure out who all will receive this broadcast. 15810 List receivers = null; 15811 List<BroadcastFilter> registeredReceivers = null; 15812 // Need to resolve the intent to interested receivers... 15813 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15814 == 0) { 15815 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15816 } 15817 if (intent.getComponent() == null) { 15818 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15819 // Query one target user at a time, excluding shell-restricted users 15820 UserManagerService ums = getUserManagerLocked(); 15821 for (int i = 0; i < users.length; i++) { 15822 if (ums.hasUserRestriction( 15823 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15824 continue; 15825 } 15826 List<BroadcastFilter> registeredReceiversForUser = 15827 mReceiverResolver.queryIntent(intent, 15828 resolvedType, false, users[i]); 15829 if (registeredReceivers == null) { 15830 registeredReceivers = registeredReceiversForUser; 15831 } else if (registeredReceiversForUser != null) { 15832 registeredReceivers.addAll(registeredReceiversForUser); 15833 } 15834 } 15835 } else { 15836 registeredReceivers = mReceiverResolver.queryIntent(intent, 15837 resolvedType, false, userId); 15838 } 15839 } 15840 15841 final boolean replacePending = 15842 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15843 15844 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15845 + " replacePending=" + replacePending); 15846 15847 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15848 if (!ordered && NR > 0) { 15849 // If we are not serializing this broadcast, then send the 15850 // registered receivers separately so they don't wait for the 15851 // components to be launched. 15852 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15853 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15854 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15855 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15856 ordered, sticky, false, userId); 15857 if (DEBUG_BROADCAST) Slog.v( 15858 TAG, "Enqueueing parallel broadcast " + r); 15859 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15860 if (!replaced) { 15861 queue.enqueueParallelBroadcastLocked(r); 15862 queue.scheduleBroadcastsLocked(); 15863 } 15864 registeredReceivers = null; 15865 NR = 0; 15866 } 15867 15868 // Merge into one list. 15869 int ir = 0; 15870 if (receivers != null) { 15871 // A special case for PACKAGE_ADDED: do not allow the package 15872 // being added to see this broadcast. This prevents them from 15873 // using this as a back door to get run as soon as they are 15874 // installed. Maybe in the future we want to have a special install 15875 // broadcast or such for apps, but we'd like to deliberately make 15876 // this decision. 15877 String skipPackages[] = null; 15878 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15879 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15880 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15881 Uri data = intent.getData(); 15882 if (data != null) { 15883 String pkgName = data.getSchemeSpecificPart(); 15884 if (pkgName != null) { 15885 skipPackages = new String[] { pkgName }; 15886 } 15887 } 15888 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15889 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15890 } 15891 if (skipPackages != null && (skipPackages.length > 0)) { 15892 for (String skipPackage : skipPackages) { 15893 if (skipPackage != null) { 15894 int NT = receivers.size(); 15895 for (int it=0; it<NT; it++) { 15896 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15897 if (curt.activityInfo.packageName.equals(skipPackage)) { 15898 receivers.remove(it); 15899 it--; 15900 NT--; 15901 } 15902 } 15903 } 15904 } 15905 } 15906 15907 int NT = receivers != null ? receivers.size() : 0; 15908 int it = 0; 15909 ResolveInfo curt = null; 15910 BroadcastFilter curr = null; 15911 while (it < NT && ir < NR) { 15912 if (curt == null) { 15913 curt = (ResolveInfo)receivers.get(it); 15914 } 15915 if (curr == null) { 15916 curr = registeredReceivers.get(ir); 15917 } 15918 if (curr.getPriority() >= curt.priority) { 15919 // Insert this broadcast record into the final list. 15920 receivers.add(it, curr); 15921 ir++; 15922 curr = null; 15923 it++; 15924 NT++; 15925 } else { 15926 // Skip to the next ResolveInfo in the final list. 15927 it++; 15928 curt = null; 15929 } 15930 } 15931 } 15932 while (ir < NR) { 15933 if (receivers == null) { 15934 receivers = new ArrayList(); 15935 } 15936 receivers.add(registeredReceivers.get(ir)); 15937 ir++; 15938 } 15939 15940 if ((receivers != null && receivers.size() > 0) 15941 || resultTo != null) { 15942 BroadcastQueue queue = broadcastQueueForIntent(intent); 15943 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15944 callerPackage, callingPid, callingUid, resolvedType, 15945 requiredPermission, appOp, receivers, resultTo, resultCode, 15946 resultData, map, ordered, sticky, false, userId); 15947 if (DEBUG_BROADCAST) Slog.v( 15948 TAG, "Enqueueing ordered broadcast " + r 15949 + ": prev had " + queue.mOrderedBroadcasts.size()); 15950 if (DEBUG_BROADCAST) { 15951 int seq = r.intent.getIntExtra("seq", -1); 15952 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15953 } 15954 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15955 if (!replaced) { 15956 queue.enqueueOrderedBroadcastLocked(r); 15957 queue.scheduleBroadcastsLocked(); 15958 } 15959 } 15960 15961 return ActivityManager.BROADCAST_SUCCESS; 15962 } 15963 15964 final Intent verifyBroadcastLocked(Intent intent) { 15965 // Refuse possible leaked file descriptors 15966 if (intent != null && intent.hasFileDescriptors() == true) { 15967 throw new IllegalArgumentException("File descriptors passed in Intent"); 15968 } 15969 15970 int flags = intent.getFlags(); 15971 15972 if (!mProcessesReady) { 15973 // if the caller really truly claims to know what they're doing, go 15974 // ahead and allow the broadcast without launching any receivers 15975 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15976 intent = new Intent(intent); 15977 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15978 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15979 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15980 + " before boot completion"); 15981 throw new IllegalStateException("Cannot broadcast before boot completed"); 15982 } 15983 } 15984 15985 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15986 throw new IllegalArgumentException( 15987 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15988 } 15989 15990 return intent; 15991 } 15992 15993 public final int broadcastIntent(IApplicationThread caller, 15994 Intent intent, String resolvedType, IIntentReceiver resultTo, 15995 int resultCode, String resultData, Bundle map, 15996 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15997 enforceNotIsolatedCaller("broadcastIntent"); 15998 synchronized(this) { 15999 intent = verifyBroadcastLocked(intent); 16000 16001 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16002 final int callingPid = Binder.getCallingPid(); 16003 final int callingUid = Binder.getCallingUid(); 16004 final long origId = Binder.clearCallingIdentity(); 16005 int res = broadcastIntentLocked(callerApp, 16006 callerApp != null ? callerApp.info.packageName : null, 16007 intent, resolvedType, resultTo, 16008 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16009 callingPid, callingUid, userId); 16010 Binder.restoreCallingIdentity(origId); 16011 return res; 16012 } 16013 } 16014 16015 int broadcastIntentInPackage(String packageName, int uid, 16016 Intent intent, String resolvedType, IIntentReceiver resultTo, 16017 int resultCode, String resultData, Bundle map, 16018 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16019 synchronized(this) { 16020 intent = verifyBroadcastLocked(intent); 16021 16022 final long origId = Binder.clearCallingIdentity(); 16023 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16024 resultTo, resultCode, resultData, map, requiredPermission, 16025 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16026 Binder.restoreCallingIdentity(origId); 16027 return res; 16028 } 16029 } 16030 16031 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16032 // Refuse possible leaked file descriptors 16033 if (intent != null && intent.hasFileDescriptors() == true) { 16034 throw new IllegalArgumentException("File descriptors passed in Intent"); 16035 } 16036 16037 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16038 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16039 16040 synchronized(this) { 16041 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16042 != PackageManager.PERMISSION_GRANTED) { 16043 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16044 + Binder.getCallingPid() 16045 + ", uid=" + Binder.getCallingUid() 16046 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16047 Slog.w(TAG, msg); 16048 throw new SecurityException(msg); 16049 } 16050 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16051 if (stickies != null) { 16052 ArrayList<Intent> list = stickies.get(intent.getAction()); 16053 if (list != null) { 16054 int N = list.size(); 16055 int i; 16056 for (i=0; i<N; i++) { 16057 if (intent.filterEquals(list.get(i))) { 16058 list.remove(i); 16059 break; 16060 } 16061 } 16062 if (list.size() <= 0) { 16063 stickies.remove(intent.getAction()); 16064 } 16065 } 16066 if (stickies.size() <= 0) { 16067 mStickyBroadcasts.remove(userId); 16068 } 16069 } 16070 } 16071 } 16072 16073 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16074 String resultData, Bundle resultExtras, boolean resultAbort) { 16075 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16076 if (r == null) { 16077 Slog.w(TAG, "finishReceiver called but not found on queue"); 16078 return false; 16079 } 16080 16081 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16082 } 16083 16084 void backgroundServicesFinishedLocked(int userId) { 16085 for (BroadcastQueue queue : mBroadcastQueues) { 16086 queue.backgroundServicesFinishedLocked(userId); 16087 } 16088 } 16089 16090 public void finishReceiver(IBinder who, int resultCode, String resultData, 16091 Bundle resultExtras, boolean resultAbort) { 16092 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16093 16094 // Refuse possible leaked file descriptors 16095 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16096 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16097 } 16098 16099 final long origId = Binder.clearCallingIdentity(); 16100 try { 16101 boolean doNext = false; 16102 BroadcastRecord r; 16103 16104 synchronized(this) { 16105 r = broadcastRecordForReceiverLocked(who); 16106 if (r != null) { 16107 doNext = r.queue.finishReceiverLocked(r, resultCode, 16108 resultData, resultExtras, resultAbort, true); 16109 } 16110 } 16111 16112 if (doNext) { 16113 r.queue.processNextBroadcast(false); 16114 } 16115 trimApplications(); 16116 } finally { 16117 Binder.restoreCallingIdentity(origId); 16118 } 16119 } 16120 16121 // ========================================================= 16122 // INSTRUMENTATION 16123 // ========================================================= 16124 16125 public boolean startInstrumentation(ComponentName className, 16126 String profileFile, int flags, Bundle arguments, 16127 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16128 int userId, String abiOverride) { 16129 enforceNotIsolatedCaller("startInstrumentation"); 16130 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16131 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16132 // Refuse possible leaked file descriptors 16133 if (arguments != null && arguments.hasFileDescriptors()) { 16134 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16135 } 16136 16137 synchronized(this) { 16138 InstrumentationInfo ii = null; 16139 ApplicationInfo ai = null; 16140 try { 16141 ii = mContext.getPackageManager().getInstrumentationInfo( 16142 className, STOCK_PM_FLAGS); 16143 ai = AppGlobals.getPackageManager().getApplicationInfo( 16144 ii.targetPackage, STOCK_PM_FLAGS, userId); 16145 } catch (PackageManager.NameNotFoundException e) { 16146 } catch (RemoteException e) { 16147 } 16148 if (ii == null) { 16149 reportStartInstrumentationFailure(watcher, className, 16150 "Unable to find instrumentation info for: " + className); 16151 return false; 16152 } 16153 if (ai == null) { 16154 reportStartInstrumentationFailure(watcher, className, 16155 "Unable to find instrumentation target package: " + ii.targetPackage); 16156 return false; 16157 } 16158 16159 int match = mContext.getPackageManager().checkSignatures( 16160 ii.targetPackage, ii.packageName); 16161 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16162 String msg = "Permission Denial: starting instrumentation " 16163 + className + " from pid=" 16164 + Binder.getCallingPid() 16165 + ", uid=" + Binder.getCallingPid() 16166 + " not allowed because package " + ii.packageName 16167 + " does not have a signature matching the target " 16168 + ii.targetPackage; 16169 reportStartInstrumentationFailure(watcher, className, msg); 16170 throw new SecurityException(msg); 16171 } 16172 16173 final long origId = Binder.clearCallingIdentity(); 16174 // Instrumentation can kill and relaunch even persistent processes 16175 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16176 "start instr"); 16177 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16178 app.instrumentationClass = className; 16179 app.instrumentationInfo = ai; 16180 app.instrumentationProfileFile = profileFile; 16181 app.instrumentationArguments = arguments; 16182 app.instrumentationWatcher = watcher; 16183 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16184 app.instrumentationResultClass = className; 16185 Binder.restoreCallingIdentity(origId); 16186 } 16187 16188 return true; 16189 } 16190 16191 /** 16192 * Report errors that occur while attempting to start Instrumentation. Always writes the 16193 * error to the logs, but if somebody is watching, send the report there too. This enables 16194 * the "am" command to report errors with more information. 16195 * 16196 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16197 * @param cn The component name of the instrumentation. 16198 * @param report The error report. 16199 */ 16200 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16201 ComponentName cn, String report) { 16202 Slog.w(TAG, report); 16203 try { 16204 if (watcher != null) { 16205 Bundle results = new Bundle(); 16206 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16207 results.putString("Error", report); 16208 watcher.instrumentationStatus(cn, -1, results); 16209 } 16210 } catch (RemoteException e) { 16211 Slog.w(TAG, e); 16212 } 16213 } 16214 16215 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16216 if (app.instrumentationWatcher != null) { 16217 try { 16218 // NOTE: IInstrumentationWatcher *must* be oneway here 16219 app.instrumentationWatcher.instrumentationFinished( 16220 app.instrumentationClass, 16221 resultCode, 16222 results); 16223 } catch (RemoteException e) { 16224 } 16225 } 16226 if (app.instrumentationUiAutomationConnection != null) { 16227 try { 16228 app.instrumentationUiAutomationConnection.shutdown(); 16229 } catch (RemoteException re) { 16230 /* ignore */ 16231 } 16232 // Only a UiAutomation can set this flag and now that 16233 // it is finished we make sure it is reset to its default. 16234 mUserIsMonkey = false; 16235 } 16236 app.instrumentationWatcher = null; 16237 app.instrumentationUiAutomationConnection = null; 16238 app.instrumentationClass = null; 16239 app.instrumentationInfo = null; 16240 app.instrumentationProfileFile = null; 16241 app.instrumentationArguments = null; 16242 16243 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16244 "finished inst"); 16245 } 16246 16247 public void finishInstrumentation(IApplicationThread target, 16248 int resultCode, Bundle results) { 16249 int userId = UserHandle.getCallingUserId(); 16250 // Refuse possible leaked file descriptors 16251 if (results != null && results.hasFileDescriptors()) { 16252 throw new IllegalArgumentException("File descriptors passed in Intent"); 16253 } 16254 16255 synchronized(this) { 16256 ProcessRecord app = getRecordForAppLocked(target); 16257 if (app == null) { 16258 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16259 return; 16260 } 16261 final long origId = Binder.clearCallingIdentity(); 16262 finishInstrumentationLocked(app, resultCode, results); 16263 Binder.restoreCallingIdentity(origId); 16264 } 16265 } 16266 16267 // ========================================================= 16268 // CONFIGURATION 16269 // ========================================================= 16270 16271 public ConfigurationInfo getDeviceConfigurationInfo() { 16272 ConfigurationInfo config = new ConfigurationInfo(); 16273 synchronized (this) { 16274 config.reqTouchScreen = mConfiguration.touchscreen; 16275 config.reqKeyboardType = mConfiguration.keyboard; 16276 config.reqNavigation = mConfiguration.navigation; 16277 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16278 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16279 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16280 } 16281 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16282 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16283 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16284 } 16285 config.reqGlEsVersion = GL_ES_VERSION; 16286 } 16287 return config; 16288 } 16289 16290 ActivityStack getFocusedStack() { 16291 return mStackSupervisor.getFocusedStack(); 16292 } 16293 16294 public Configuration getConfiguration() { 16295 Configuration ci; 16296 synchronized(this) { 16297 ci = new Configuration(mConfiguration); 16298 } 16299 return ci; 16300 } 16301 16302 public void updatePersistentConfiguration(Configuration values) { 16303 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16304 "updateConfiguration()"); 16305 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16306 "updateConfiguration()"); 16307 if (values == null) { 16308 throw new NullPointerException("Configuration must not be null"); 16309 } 16310 16311 synchronized(this) { 16312 final long origId = Binder.clearCallingIdentity(); 16313 updateConfigurationLocked(values, null, true, false); 16314 Binder.restoreCallingIdentity(origId); 16315 } 16316 } 16317 16318 public void updateConfiguration(Configuration values) { 16319 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16320 "updateConfiguration()"); 16321 16322 synchronized(this) { 16323 if (values == null && mWindowManager != null) { 16324 // sentinel: fetch the current configuration from the window manager 16325 values = mWindowManager.computeNewConfiguration(); 16326 } 16327 16328 if (mWindowManager != null) { 16329 mProcessList.applyDisplaySize(mWindowManager); 16330 } 16331 16332 final long origId = Binder.clearCallingIdentity(); 16333 if (values != null) { 16334 Settings.System.clearConfiguration(values); 16335 } 16336 updateConfigurationLocked(values, null, false, false); 16337 Binder.restoreCallingIdentity(origId); 16338 } 16339 } 16340 16341 /** 16342 * Do either or both things: (1) change the current configuration, and (2) 16343 * make sure the given activity is running with the (now) current 16344 * configuration. Returns true if the activity has been left running, or 16345 * false if <var>starting</var> is being destroyed to match the new 16346 * configuration. 16347 * @param persistent TODO 16348 */ 16349 boolean updateConfigurationLocked(Configuration values, 16350 ActivityRecord starting, boolean persistent, boolean initLocale) { 16351 int changes = 0; 16352 16353 if (values != null) { 16354 Configuration newConfig = new Configuration(mConfiguration); 16355 changes = newConfig.updateFrom(values); 16356 if (changes != 0) { 16357 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16358 Slog.i(TAG, "Updating configuration to: " + values); 16359 } 16360 16361 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16362 16363 if (values.locale != null && !initLocale) { 16364 saveLocaleLocked(values.locale, 16365 !values.locale.equals(mConfiguration.locale), 16366 values.userSetLocale); 16367 } 16368 16369 mConfigurationSeq++; 16370 if (mConfigurationSeq <= 0) { 16371 mConfigurationSeq = 1; 16372 } 16373 newConfig.seq = mConfigurationSeq; 16374 mConfiguration = newConfig; 16375 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16376 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16377 //mUsageStatsService.noteStartConfig(newConfig); 16378 16379 final Configuration configCopy = new Configuration(mConfiguration); 16380 16381 // TODO: If our config changes, should we auto dismiss any currently 16382 // showing dialogs? 16383 mShowDialogs = shouldShowDialogs(newConfig); 16384 16385 AttributeCache ac = AttributeCache.instance(); 16386 if (ac != null) { 16387 ac.updateConfiguration(configCopy); 16388 } 16389 16390 // Make sure all resources in our process are updated 16391 // right now, so that anyone who is going to retrieve 16392 // resource values after we return will be sure to get 16393 // the new ones. This is especially important during 16394 // boot, where the first config change needs to guarantee 16395 // all resources have that config before following boot 16396 // code is executed. 16397 mSystemThread.applyConfigurationToResources(configCopy); 16398 16399 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16400 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16401 msg.obj = new Configuration(configCopy); 16402 mHandler.sendMessage(msg); 16403 } 16404 16405 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16406 ProcessRecord app = mLruProcesses.get(i); 16407 try { 16408 if (app.thread != null) { 16409 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16410 + app.processName + " new config " + mConfiguration); 16411 app.thread.scheduleConfigurationChanged(configCopy); 16412 } 16413 } catch (Exception e) { 16414 } 16415 } 16416 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16418 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16419 | Intent.FLAG_RECEIVER_FOREGROUND); 16420 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16421 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16422 Process.SYSTEM_UID, UserHandle.USER_ALL); 16423 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16424 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16425 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16426 broadcastIntentLocked(null, null, intent, 16427 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16428 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16429 } 16430 } 16431 } 16432 16433 boolean kept = true; 16434 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16435 // mainStack is null during startup. 16436 if (mainStack != null) { 16437 if (changes != 0 && starting == null) { 16438 // If the configuration changed, and the caller is not already 16439 // in the process of starting an activity, then find the top 16440 // activity to check if its configuration needs to change. 16441 starting = mainStack.topRunningActivityLocked(null); 16442 } 16443 16444 if (starting != null) { 16445 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16446 // And we need to make sure at this point that all other activities 16447 // are made visible with the correct configuration. 16448 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16449 } 16450 } 16451 16452 if (values != null && mWindowManager != null) { 16453 mWindowManager.setNewConfiguration(mConfiguration); 16454 } 16455 16456 return kept; 16457 } 16458 16459 /** 16460 * Decide based on the configuration whether we should shouw the ANR, 16461 * crash, etc dialogs. The idea is that if there is no affordnace to 16462 * press the on-screen buttons, we shouldn't show the dialog. 16463 * 16464 * A thought: SystemUI might also want to get told about this, the Power 16465 * dialog / global actions also might want different behaviors. 16466 */ 16467 private static final boolean shouldShowDialogs(Configuration config) { 16468 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16469 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16470 } 16471 16472 /** 16473 * Save the locale. You must be inside a synchronized (this) block. 16474 */ 16475 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16476 if(isDiff) { 16477 SystemProperties.set("user.language", l.getLanguage()); 16478 SystemProperties.set("user.region", l.getCountry()); 16479 } 16480 16481 if(isPersist) { 16482 SystemProperties.set("persist.sys.language", l.getLanguage()); 16483 SystemProperties.set("persist.sys.country", l.getCountry()); 16484 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16485 16486 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16487 } 16488 } 16489 16490 @Override 16491 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16492 synchronized (this) { 16493 ActivityRecord srec = ActivityRecord.forToken(token); 16494 if (srec.task != null && srec.task.stack != null) { 16495 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16496 } 16497 } 16498 return false; 16499 } 16500 16501 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16502 Intent resultData) { 16503 16504 synchronized (this) { 16505 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16506 if (stack != null) { 16507 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16508 } 16509 return false; 16510 } 16511 } 16512 16513 public int getLaunchedFromUid(IBinder activityToken) { 16514 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16515 if (srec == null) { 16516 return -1; 16517 } 16518 return srec.launchedFromUid; 16519 } 16520 16521 public String getLaunchedFromPackage(IBinder activityToken) { 16522 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16523 if (srec == null) { 16524 return null; 16525 } 16526 return srec.launchedFromPackage; 16527 } 16528 16529 // ========================================================= 16530 // LIFETIME MANAGEMENT 16531 // ========================================================= 16532 16533 // Returns which broadcast queue the app is the current [or imminent] receiver 16534 // on, or 'null' if the app is not an active broadcast recipient. 16535 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16536 BroadcastRecord r = app.curReceiver; 16537 if (r != null) { 16538 return r.queue; 16539 } 16540 16541 // It's not the current receiver, but it might be starting up to become one 16542 synchronized (this) { 16543 for (BroadcastQueue queue : mBroadcastQueues) { 16544 r = queue.mPendingBroadcast; 16545 if (r != null && r.curApp == app) { 16546 // found it; report which queue it's in 16547 return queue; 16548 } 16549 } 16550 } 16551 16552 return null; 16553 } 16554 16555 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16556 boolean doingAll, long now) { 16557 if (mAdjSeq == app.adjSeq) { 16558 // This adjustment has already been computed. 16559 return app.curRawAdj; 16560 } 16561 16562 if (app.thread == null) { 16563 app.adjSeq = mAdjSeq; 16564 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16565 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16566 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16567 } 16568 16569 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16570 app.adjSource = null; 16571 app.adjTarget = null; 16572 app.empty = false; 16573 app.cached = false; 16574 16575 final int activitiesSize = app.activities.size(); 16576 16577 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16578 // The max adjustment doesn't allow this app to be anything 16579 // below foreground, so it is not worth doing work for it. 16580 app.adjType = "fixed"; 16581 app.adjSeq = mAdjSeq; 16582 app.curRawAdj = app.maxAdj; 16583 app.foregroundActivities = false; 16584 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16585 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16586 // System processes can do UI, and when they do we want to have 16587 // them trim their memory after the user leaves the UI. To 16588 // facilitate this, here we need to determine whether or not it 16589 // is currently showing UI. 16590 app.systemNoUi = true; 16591 if (app == TOP_APP) { 16592 app.systemNoUi = false; 16593 } else if (activitiesSize > 0) { 16594 for (int j = 0; j < activitiesSize; j++) { 16595 final ActivityRecord r = app.activities.get(j); 16596 if (r.visible) { 16597 app.systemNoUi = false; 16598 } 16599 } 16600 } 16601 if (!app.systemNoUi) { 16602 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16603 } 16604 return (app.curAdj=app.maxAdj); 16605 } 16606 16607 app.systemNoUi = false; 16608 16609 // Determine the importance of the process, starting with most 16610 // important to least, and assign an appropriate OOM adjustment. 16611 int adj; 16612 int schedGroup; 16613 int procState; 16614 boolean foregroundActivities = false; 16615 BroadcastQueue queue; 16616 if (app == TOP_APP) { 16617 // The last app on the list is the foreground app. 16618 adj = ProcessList.FOREGROUND_APP_ADJ; 16619 schedGroup = Process.THREAD_GROUP_DEFAULT; 16620 app.adjType = "top-activity"; 16621 foregroundActivities = true; 16622 procState = ActivityManager.PROCESS_STATE_TOP; 16623 } else if (app.instrumentationClass != null) { 16624 // Don't want to kill running instrumentation. 16625 adj = ProcessList.FOREGROUND_APP_ADJ; 16626 schedGroup = Process.THREAD_GROUP_DEFAULT; 16627 app.adjType = "instrumentation"; 16628 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16629 } else if ((queue = isReceivingBroadcast(app)) != null) { 16630 // An app that is currently receiving a broadcast also 16631 // counts as being in the foreground for OOM killer purposes. 16632 // It's placed in a sched group based on the nature of the 16633 // broadcast as reflected by which queue it's active in. 16634 adj = ProcessList.FOREGROUND_APP_ADJ; 16635 schedGroup = (queue == mFgBroadcastQueue) 16636 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16637 app.adjType = "broadcast"; 16638 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16639 } else if (app.executingServices.size() > 0) { 16640 // An app that is currently executing a service callback also 16641 // counts as being in the foreground. 16642 adj = ProcessList.FOREGROUND_APP_ADJ; 16643 schedGroup = app.execServicesFg ? 16644 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16645 app.adjType = "exec-service"; 16646 procState = ActivityManager.PROCESS_STATE_SERVICE; 16647 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16648 } else { 16649 // As far as we know the process is empty. We may change our mind later. 16650 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16651 // At this point we don't actually know the adjustment. Use the cached adj 16652 // value that the caller wants us to. 16653 adj = cachedAdj; 16654 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16655 app.cached = true; 16656 app.empty = true; 16657 app.adjType = "cch-empty"; 16658 } 16659 16660 // Examine all activities if not already foreground. 16661 if (!foregroundActivities && activitiesSize > 0) { 16662 for (int j = 0; j < activitiesSize; j++) { 16663 final ActivityRecord r = app.activities.get(j); 16664 if (r.app != app) { 16665 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16666 + app + "?!?"); 16667 continue; 16668 } 16669 if (r.visible) { 16670 // App has a visible activity; only upgrade adjustment. 16671 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16672 adj = ProcessList.VISIBLE_APP_ADJ; 16673 app.adjType = "visible"; 16674 } 16675 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16676 procState = ActivityManager.PROCESS_STATE_TOP; 16677 } 16678 schedGroup = Process.THREAD_GROUP_DEFAULT; 16679 app.cached = false; 16680 app.empty = false; 16681 foregroundActivities = true; 16682 break; 16683 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16684 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16685 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16686 app.adjType = "pausing"; 16687 } 16688 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16689 procState = ActivityManager.PROCESS_STATE_TOP; 16690 } 16691 schedGroup = Process.THREAD_GROUP_DEFAULT; 16692 app.cached = false; 16693 app.empty = false; 16694 foregroundActivities = true; 16695 } else if (r.state == ActivityState.STOPPING) { 16696 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16697 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16698 app.adjType = "stopping"; 16699 } 16700 // For the process state, we will at this point consider the 16701 // process to be cached. It will be cached either as an activity 16702 // or empty depending on whether the activity is finishing. We do 16703 // this so that we can treat the process as cached for purposes of 16704 // memory trimming (determing current memory level, trim command to 16705 // send to process) since there can be an arbitrary number of stopping 16706 // processes and they should soon all go into the cached state. 16707 if (!r.finishing) { 16708 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16709 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16710 } 16711 } 16712 app.cached = false; 16713 app.empty = false; 16714 foregroundActivities = true; 16715 } else { 16716 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16717 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16718 app.adjType = "cch-act"; 16719 } 16720 } 16721 } 16722 } 16723 16724 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16725 if (app.foregroundServices) { 16726 // The user is aware of this app, so make it visible. 16727 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16728 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16729 app.cached = false; 16730 app.adjType = "fg-service"; 16731 schedGroup = Process.THREAD_GROUP_DEFAULT; 16732 } else if (app.forcingToForeground != null) { 16733 // The user is aware of this app, so make it visible. 16734 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16735 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16736 app.cached = false; 16737 app.adjType = "force-fg"; 16738 app.adjSource = app.forcingToForeground; 16739 schedGroup = Process.THREAD_GROUP_DEFAULT; 16740 } 16741 } 16742 16743 if (app == mHeavyWeightProcess) { 16744 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16745 // We don't want to kill the current heavy-weight process. 16746 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16747 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16748 app.cached = false; 16749 app.adjType = "heavy"; 16750 } 16751 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16752 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16753 } 16754 } 16755 16756 if (app == mHomeProcess) { 16757 if (adj > ProcessList.HOME_APP_ADJ) { 16758 // This process is hosting what we currently consider to be the 16759 // home app, so we don't want to let it go into the background. 16760 adj = ProcessList.HOME_APP_ADJ; 16761 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16762 app.cached = false; 16763 app.adjType = "home"; 16764 } 16765 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16766 procState = ActivityManager.PROCESS_STATE_HOME; 16767 } 16768 } 16769 16770 if (app == mPreviousProcess && app.activities.size() > 0) { 16771 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16772 // This was the previous process that showed UI to the user. 16773 // We want to try to keep it around more aggressively, to give 16774 // a good experience around switching between two apps. 16775 adj = ProcessList.PREVIOUS_APP_ADJ; 16776 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16777 app.cached = false; 16778 app.adjType = "previous"; 16779 } 16780 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16781 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16782 } 16783 } 16784 16785 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16786 + " reason=" + app.adjType); 16787 16788 // By default, we use the computed adjustment. It may be changed if 16789 // there are applications dependent on our services or providers, but 16790 // this gives us a baseline and makes sure we don't get into an 16791 // infinite recursion. 16792 app.adjSeq = mAdjSeq; 16793 app.curRawAdj = adj; 16794 app.hasStartedServices = false; 16795 16796 if (mBackupTarget != null && app == mBackupTarget.app) { 16797 // If possible we want to avoid killing apps while they're being backed up 16798 if (adj > ProcessList.BACKUP_APP_ADJ) { 16799 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16800 adj = ProcessList.BACKUP_APP_ADJ; 16801 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16802 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16803 } 16804 app.adjType = "backup"; 16805 app.cached = false; 16806 } 16807 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16808 procState = ActivityManager.PROCESS_STATE_BACKUP; 16809 } 16810 } 16811 16812 boolean mayBeTop = false; 16813 16814 for (int is = app.services.size()-1; 16815 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16816 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16817 || procState > ActivityManager.PROCESS_STATE_TOP); 16818 is--) { 16819 ServiceRecord s = app.services.valueAt(is); 16820 if (s.startRequested) { 16821 app.hasStartedServices = true; 16822 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16823 procState = ActivityManager.PROCESS_STATE_SERVICE; 16824 } 16825 if (app.hasShownUi && app != mHomeProcess) { 16826 // If this process has shown some UI, let it immediately 16827 // go to the LRU list because it may be pretty heavy with 16828 // UI stuff. We'll tag it with a label just to help 16829 // debug and understand what is going on. 16830 if (adj > ProcessList.SERVICE_ADJ) { 16831 app.adjType = "cch-started-ui-services"; 16832 } 16833 } else { 16834 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16835 // This service has seen some activity within 16836 // recent memory, so we will keep its process ahead 16837 // of the background processes. 16838 if (adj > ProcessList.SERVICE_ADJ) { 16839 adj = ProcessList.SERVICE_ADJ; 16840 app.adjType = "started-services"; 16841 app.cached = false; 16842 } 16843 } 16844 // If we have let the service slide into the background 16845 // state, still have some text describing what it is doing 16846 // even though the service no longer has an impact. 16847 if (adj > ProcessList.SERVICE_ADJ) { 16848 app.adjType = "cch-started-services"; 16849 } 16850 } 16851 } 16852 for (int conni = s.connections.size()-1; 16853 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16854 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16855 || procState > ActivityManager.PROCESS_STATE_TOP); 16856 conni--) { 16857 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16858 for (int i = 0; 16859 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16860 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16861 || procState > ActivityManager.PROCESS_STATE_TOP); 16862 i++) { 16863 // XXX should compute this based on the max of 16864 // all connected clients. 16865 ConnectionRecord cr = clist.get(i); 16866 if (cr.binding.client == app) { 16867 // Binding to ourself is not interesting. 16868 continue; 16869 } 16870 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16871 ProcessRecord client = cr.binding.client; 16872 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16873 TOP_APP, doingAll, now); 16874 int clientProcState = client.curProcState; 16875 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16876 // If the other app is cached for any reason, for purposes here 16877 // we are going to consider it empty. The specific cached state 16878 // doesn't propagate except under certain conditions. 16879 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16880 } 16881 String adjType = null; 16882 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16883 // Not doing bind OOM management, so treat 16884 // this guy more like a started service. 16885 if (app.hasShownUi && app != mHomeProcess) { 16886 // If this process has shown some UI, let it immediately 16887 // go to the LRU list because it may be pretty heavy with 16888 // UI stuff. We'll tag it with a label just to help 16889 // debug and understand what is going on. 16890 if (adj > clientAdj) { 16891 adjType = "cch-bound-ui-services"; 16892 } 16893 app.cached = false; 16894 clientAdj = adj; 16895 clientProcState = procState; 16896 } else { 16897 if (now >= (s.lastActivity 16898 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16899 // This service has not seen activity within 16900 // recent memory, so allow it to drop to the 16901 // LRU list if there is no other reason to keep 16902 // it around. We'll also tag it with a label just 16903 // to help debug and undertand what is going on. 16904 if (adj > clientAdj) { 16905 adjType = "cch-bound-services"; 16906 } 16907 clientAdj = adj; 16908 } 16909 } 16910 } 16911 if (adj > clientAdj) { 16912 // If this process has recently shown UI, and 16913 // the process that is binding to it is less 16914 // important than being visible, then we don't 16915 // care about the binding as much as we care 16916 // about letting this process get into the LRU 16917 // list to be killed and restarted if needed for 16918 // memory. 16919 if (app.hasShownUi && app != mHomeProcess 16920 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16921 adjType = "cch-bound-ui-services"; 16922 } else { 16923 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16924 |Context.BIND_IMPORTANT)) != 0) { 16925 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16926 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16927 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16928 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16929 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16930 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16931 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16932 adj = clientAdj; 16933 } else { 16934 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16935 adj = ProcessList.VISIBLE_APP_ADJ; 16936 } 16937 } 16938 if (!client.cached) { 16939 app.cached = false; 16940 } 16941 adjType = "service"; 16942 } 16943 } 16944 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16945 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16946 schedGroup = Process.THREAD_GROUP_DEFAULT; 16947 } 16948 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16949 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16950 // Special handling of clients who are in the top state. 16951 // We *may* want to consider this process to be in the 16952 // top state as well, but only if there is not another 16953 // reason for it to be running. Being on the top is a 16954 // special state, meaning you are specifically running 16955 // for the current top app. If the process is already 16956 // running in the background for some other reason, it 16957 // is more important to continue considering it to be 16958 // in the background state. 16959 mayBeTop = true; 16960 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16961 } else { 16962 // Special handling for above-top states (persistent 16963 // processes). These should not bring the current process 16964 // into the top state, since they are not on top. Instead 16965 // give them the best state after that. 16966 clientProcState = 16967 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16968 } 16969 } 16970 } else { 16971 if (clientProcState < 16972 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16973 clientProcState = 16974 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16975 } 16976 } 16977 if (procState > clientProcState) { 16978 procState = clientProcState; 16979 } 16980 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16981 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16982 app.pendingUiClean = true; 16983 } 16984 if (adjType != null) { 16985 app.adjType = adjType; 16986 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16987 .REASON_SERVICE_IN_USE; 16988 app.adjSource = cr.binding.client; 16989 app.adjSourceProcState = clientProcState; 16990 app.adjTarget = s.name; 16991 } 16992 } 16993 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16994 app.treatLikeActivity = true; 16995 } 16996 final ActivityRecord a = cr.activity; 16997 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16998 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16999 (a.visible || a.state == ActivityState.RESUMED 17000 || a.state == ActivityState.PAUSING)) { 17001 adj = ProcessList.FOREGROUND_APP_ADJ; 17002 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17003 schedGroup = Process.THREAD_GROUP_DEFAULT; 17004 } 17005 app.cached = false; 17006 app.adjType = "service"; 17007 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17008 .REASON_SERVICE_IN_USE; 17009 app.adjSource = a; 17010 app.adjSourceProcState = procState; 17011 app.adjTarget = s.name; 17012 } 17013 } 17014 } 17015 } 17016 } 17017 17018 for (int provi = app.pubProviders.size()-1; 17019 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17020 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17021 || procState > ActivityManager.PROCESS_STATE_TOP); 17022 provi--) { 17023 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17024 for (int i = cpr.connections.size()-1; 17025 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17026 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17027 || procState > ActivityManager.PROCESS_STATE_TOP); 17028 i--) { 17029 ContentProviderConnection conn = cpr.connections.get(i); 17030 ProcessRecord client = conn.client; 17031 if (client == app) { 17032 // Being our own client is not interesting. 17033 continue; 17034 } 17035 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17036 int clientProcState = client.curProcState; 17037 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17038 // If the other app is cached for any reason, for purposes here 17039 // we are going to consider it empty. 17040 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17041 } 17042 if (adj > clientAdj) { 17043 if (app.hasShownUi && app != mHomeProcess 17044 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17045 app.adjType = "cch-ui-provider"; 17046 } else { 17047 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17048 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17049 app.adjType = "provider"; 17050 } 17051 app.cached &= client.cached; 17052 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17053 .REASON_PROVIDER_IN_USE; 17054 app.adjSource = client; 17055 app.adjSourceProcState = clientProcState; 17056 app.adjTarget = cpr.name; 17057 } 17058 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17059 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17060 // Special handling of clients who are in the top state. 17061 // We *may* want to consider this process to be in the 17062 // top state as well, but only if there is not another 17063 // reason for it to be running. Being on the top is a 17064 // special state, meaning you are specifically running 17065 // for the current top app. If the process is already 17066 // running in the background for some other reason, it 17067 // is more important to continue considering it to be 17068 // in the background state. 17069 mayBeTop = true; 17070 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17071 } else { 17072 // Special handling for above-top states (persistent 17073 // processes). These should not bring the current process 17074 // into the top state, since they are not on top. Instead 17075 // give them the best state after that. 17076 clientProcState = 17077 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17078 } 17079 } 17080 if (procState > clientProcState) { 17081 procState = clientProcState; 17082 } 17083 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17084 schedGroup = Process.THREAD_GROUP_DEFAULT; 17085 } 17086 } 17087 // If the provider has external (non-framework) process 17088 // dependencies, ensure that its adjustment is at least 17089 // FOREGROUND_APP_ADJ. 17090 if (cpr.hasExternalProcessHandles()) { 17091 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17092 adj = ProcessList.FOREGROUND_APP_ADJ; 17093 schedGroup = Process.THREAD_GROUP_DEFAULT; 17094 app.cached = false; 17095 app.adjType = "provider"; 17096 app.adjTarget = cpr.name; 17097 } 17098 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17099 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17100 } 17101 } 17102 } 17103 17104 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17105 // A client of one of our services or providers is in the top state. We 17106 // *may* want to be in the top state, but not if we are already running in 17107 // the background for some other reason. For the decision here, we are going 17108 // to pick out a few specific states that we want to remain in when a client 17109 // is top (states that tend to be longer-term) and otherwise allow it to go 17110 // to the top state. 17111 switch (procState) { 17112 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17113 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17114 case ActivityManager.PROCESS_STATE_SERVICE: 17115 // These all are longer-term states, so pull them up to the top 17116 // of the background states, but not all the way to the top state. 17117 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17118 break; 17119 default: 17120 // Otherwise, top is a better choice, so take it. 17121 procState = ActivityManager.PROCESS_STATE_TOP; 17122 break; 17123 } 17124 } 17125 17126 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17127 if (app.hasClientActivities) { 17128 // This is a cached process, but with client activities. Mark it so. 17129 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17130 app.adjType = "cch-client-act"; 17131 } else if (app.treatLikeActivity) { 17132 // This is a cached process, but somebody wants us to treat it like it has 17133 // an activity, okay! 17134 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17135 app.adjType = "cch-as-act"; 17136 } 17137 } 17138 17139 if (adj == ProcessList.SERVICE_ADJ) { 17140 if (doingAll) { 17141 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17142 mNewNumServiceProcs++; 17143 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17144 if (!app.serviceb) { 17145 // This service isn't far enough down on the LRU list to 17146 // normally be a B service, but if we are low on RAM and it 17147 // is large we want to force it down since we would prefer to 17148 // keep launcher over it. 17149 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17150 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17151 app.serviceHighRam = true; 17152 app.serviceb = true; 17153 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17154 } else { 17155 mNewNumAServiceProcs++; 17156 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17157 } 17158 } else { 17159 app.serviceHighRam = false; 17160 } 17161 } 17162 if (app.serviceb) { 17163 adj = ProcessList.SERVICE_B_ADJ; 17164 } 17165 } 17166 17167 app.curRawAdj = adj; 17168 17169 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17170 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17171 if (adj > app.maxAdj) { 17172 adj = app.maxAdj; 17173 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17174 schedGroup = Process.THREAD_GROUP_DEFAULT; 17175 } 17176 } 17177 17178 // Do final modification to adj. Everything we do between here and applying 17179 // the final setAdj must be done in this function, because we will also use 17180 // it when computing the final cached adj later. Note that we don't need to 17181 // worry about this for max adj above, since max adj will always be used to 17182 // keep it out of the cached vaues. 17183 app.curAdj = app.modifyRawOomAdj(adj); 17184 app.curSchedGroup = schedGroup; 17185 app.curProcState = procState; 17186 app.foregroundActivities = foregroundActivities; 17187 17188 return app.curRawAdj; 17189 } 17190 17191 /** 17192 * Schedule PSS collection of a process. 17193 */ 17194 void requestPssLocked(ProcessRecord proc, int procState) { 17195 if (mPendingPssProcesses.contains(proc)) { 17196 return; 17197 } 17198 if (mPendingPssProcesses.size() == 0) { 17199 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17200 } 17201 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17202 proc.pssProcState = procState; 17203 mPendingPssProcesses.add(proc); 17204 } 17205 17206 /** 17207 * Schedule PSS collection of all processes. 17208 */ 17209 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17210 if (!always) { 17211 if (now < (mLastFullPssTime + 17212 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17213 return; 17214 } 17215 } 17216 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17217 mLastFullPssTime = now; 17218 mFullPssPending = true; 17219 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17220 mPendingPssProcesses.clear(); 17221 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17222 ProcessRecord app = mLruProcesses.get(i); 17223 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17224 app.pssProcState = app.setProcState; 17225 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17226 isSleeping(), now); 17227 mPendingPssProcesses.add(app); 17228 } 17229 } 17230 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17231 } 17232 17233 /** 17234 * Ask a given process to GC right now. 17235 */ 17236 final void performAppGcLocked(ProcessRecord app) { 17237 try { 17238 app.lastRequestedGc = SystemClock.uptimeMillis(); 17239 if (app.thread != null) { 17240 if (app.reportLowMemory) { 17241 app.reportLowMemory = false; 17242 app.thread.scheduleLowMemory(); 17243 } else { 17244 app.thread.processInBackground(); 17245 } 17246 } 17247 } catch (Exception e) { 17248 // whatever. 17249 } 17250 } 17251 17252 /** 17253 * Returns true if things are idle enough to perform GCs. 17254 */ 17255 private final boolean canGcNowLocked() { 17256 boolean processingBroadcasts = false; 17257 for (BroadcastQueue q : mBroadcastQueues) { 17258 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17259 processingBroadcasts = true; 17260 } 17261 } 17262 return !processingBroadcasts 17263 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17264 } 17265 17266 /** 17267 * Perform GCs on all processes that are waiting for it, but only 17268 * if things are idle. 17269 */ 17270 final void performAppGcsLocked() { 17271 final int N = mProcessesToGc.size(); 17272 if (N <= 0) { 17273 return; 17274 } 17275 if (canGcNowLocked()) { 17276 while (mProcessesToGc.size() > 0) { 17277 ProcessRecord proc = mProcessesToGc.remove(0); 17278 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17279 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17280 <= SystemClock.uptimeMillis()) { 17281 // To avoid spamming the system, we will GC processes one 17282 // at a time, waiting a few seconds between each. 17283 performAppGcLocked(proc); 17284 scheduleAppGcsLocked(); 17285 return; 17286 } else { 17287 // It hasn't been long enough since we last GCed this 17288 // process... put it in the list to wait for its time. 17289 addProcessToGcListLocked(proc); 17290 break; 17291 } 17292 } 17293 } 17294 17295 scheduleAppGcsLocked(); 17296 } 17297 } 17298 17299 /** 17300 * If all looks good, perform GCs on all processes waiting for them. 17301 */ 17302 final void performAppGcsIfAppropriateLocked() { 17303 if (canGcNowLocked()) { 17304 performAppGcsLocked(); 17305 return; 17306 } 17307 // Still not idle, wait some more. 17308 scheduleAppGcsLocked(); 17309 } 17310 17311 /** 17312 * Schedule the execution of all pending app GCs. 17313 */ 17314 final void scheduleAppGcsLocked() { 17315 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17316 17317 if (mProcessesToGc.size() > 0) { 17318 // Schedule a GC for the time to the next process. 17319 ProcessRecord proc = mProcessesToGc.get(0); 17320 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17321 17322 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17323 long now = SystemClock.uptimeMillis(); 17324 if (when < (now+GC_TIMEOUT)) { 17325 when = now + GC_TIMEOUT; 17326 } 17327 mHandler.sendMessageAtTime(msg, when); 17328 } 17329 } 17330 17331 /** 17332 * Add a process to the array of processes waiting to be GCed. Keeps the 17333 * list in sorted order by the last GC time. The process can't already be 17334 * on the list. 17335 */ 17336 final void addProcessToGcListLocked(ProcessRecord proc) { 17337 boolean added = false; 17338 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17339 if (mProcessesToGc.get(i).lastRequestedGc < 17340 proc.lastRequestedGc) { 17341 added = true; 17342 mProcessesToGc.add(i+1, proc); 17343 break; 17344 } 17345 } 17346 if (!added) { 17347 mProcessesToGc.add(0, proc); 17348 } 17349 } 17350 17351 /** 17352 * Set up to ask a process to GC itself. This will either do it 17353 * immediately, or put it on the list of processes to gc the next 17354 * time things are idle. 17355 */ 17356 final void scheduleAppGcLocked(ProcessRecord app) { 17357 long now = SystemClock.uptimeMillis(); 17358 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17359 return; 17360 } 17361 if (!mProcessesToGc.contains(app)) { 17362 addProcessToGcListLocked(app); 17363 scheduleAppGcsLocked(); 17364 } 17365 } 17366 17367 final void checkExcessivePowerUsageLocked(boolean doKills) { 17368 updateCpuStatsNow(); 17369 17370 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17371 boolean doWakeKills = doKills; 17372 boolean doCpuKills = doKills; 17373 if (mLastPowerCheckRealtime == 0) { 17374 doWakeKills = false; 17375 } 17376 if (mLastPowerCheckUptime == 0) { 17377 doCpuKills = false; 17378 } 17379 if (stats.isScreenOn()) { 17380 doWakeKills = false; 17381 } 17382 final long curRealtime = SystemClock.elapsedRealtime(); 17383 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17384 final long curUptime = SystemClock.uptimeMillis(); 17385 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17386 mLastPowerCheckRealtime = curRealtime; 17387 mLastPowerCheckUptime = curUptime; 17388 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17389 doWakeKills = false; 17390 } 17391 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17392 doCpuKills = false; 17393 } 17394 int i = mLruProcesses.size(); 17395 while (i > 0) { 17396 i--; 17397 ProcessRecord app = mLruProcesses.get(i); 17398 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17399 long wtime; 17400 synchronized (stats) { 17401 wtime = stats.getProcessWakeTime(app.info.uid, 17402 app.pid, curRealtime); 17403 } 17404 long wtimeUsed = wtime - app.lastWakeTime; 17405 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17406 if (DEBUG_POWER) { 17407 StringBuilder sb = new StringBuilder(128); 17408 sb.append("Wake for "); 17409 app.toShortString(sb); 17410 sb.append(": over "); 17411 TimeUtils.formatDuration(realtimeSince, sb); 17412 sb.append(" used "); 17413 TimeUtils.formatDuration(wtimeUsed, sb); 17414 sb.append(" ("); 17415 sb.append((wtimeUsed*100)/realtimeSince); 17416 sb.append("%)"); 17417 Slog.i(TAG, sb.toString()); 17418 sb.setLength(0); 17419 sb.append("CPU for "); 17420 app.toShortString(sb); 17421 sb.append(": over "); 17422 TimeUtils.formatDuration(uptimeSince, sb); 17423 sb.append(" used "); 17424 TimeUtils.formatDuration(cputimeUsed, sb); 17425 sb.append(" ("); 17426 sb.append((cputimeUsed*100)/uptimeSince); 17427 sb.append("%)"); 17428 Slog.i(TAG, sb.toString()); 17429 } 17430 // If a process has held a wake lock for more 17431 // than 50% of the time during this period, 17432 // that sounds bad. Kill! 17433 if (doWakeKills && realtimeSince > 0 17434 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17435 synchronized (stats) { 17436 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17437 realtimeSince, wtimeUsed); 17438 } 17439 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17440 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17441 } else if (doCpuKills && uptimeSince > 0 17442 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17443 synchronized (stats) { 17444 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17445 uptimeSince, cputimeUsed); 17446 } 17447 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17448 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17449 } else { 17450 app.lastWakeTime = wtime; 17451 app.lastCpuTime = app.curCpuTime; 17452 } 17453 } 17454 } 17455 } 17456 17457 private final boolean applyOomAdjLocked(ProcessRecord app, 17458 ProcessRecord TOP_APP, boolean doingAll, long now) { 17459 boolean success = true; 17460 17461 if (app.curRawAdj != app.setRawAdj) { 17462 app.setRawAdj = app.curRawAdj; 17463 } 17464 17465 int changes = 0; 17466 17467 if (app.curAdj != app.setAdj) { 17468 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17469 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17470 TAG, "Set " + app.pid + " " + app.processName + 17471 " adj " + app.curAdj + ": " + app.adjType); 17472 app.setAdj = app.curAdj; 17473 } 17474 17475 if (app.setSchedGroup != app.curSchedGroup) { 17476 app.setSchedGroup = app.curSchedGroup; 17477 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17478 "Setting process group of " + app.processName 17479 + " to " + app.curSchedGroup); 17480 if (app.waitingToKill != null && 17481 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17482 app.kill(app.waitingToKill, true); 17483 success = false; 17484 } else { 17485 if (true) { 17486 long oldId = Binder.clearCallingIdentity(); 17487 try { 17488 Process.setProcessGroup(app.pid, app.curSchedGroup); 17489 } catch (Exception e) { 17490 Slog.w(TAG, "Failed setting process group of " + app.pid 17491 + " to " + app.curSchedGroup); 17492 e.printStackTrace(); 17493 } finally { 17494 Binder.restoreCallingIdentity(oldId); 17495 } 17496 } else { 17497 if (app.thread != null) { 17498 try { 17499 app.thread.setSchedulingGroup(app.curSchedGroup); 17500 } catch (RemoteException e) { 17501 } 17502 } 17503 } 17504 Process.setSwappiness(app.pid, 17505 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17506 } 17507 } 17508 if (app.repForegroundActivities != app.foregroundActivities) { 17509 app.repForegroundActivities = app.foregroundActivities; 17510 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17511 } 17512 if (app.repProcState != app.curProcState) { 17513 app.repProcState = app.curProcState; 17514 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17515 if (app.thread != null) { 17516 try { 17517 if (false) { 17518 //RuntimeException h = new RuntimeException("here"); 17519 Slog.i(TAG, "Sending new process state " + app.repProcState 17520 + " to " + app /*, h*/); 17521 } 17522 app.thread.setProcessState(app.repProcState); 17523 } catch (RemoteException e) { 17524 } 17525 } 17526 } 17527 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17528 app.setProcState)) { 17529 app.lastStateTime = now; 17530 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17531 isSleeping(), now); 17532 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17533 + ProcessList.makeProcStateString(app.setProcState) + " to " 17534 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17535 + (app.nextPssTime-now) + ": " + app); 17536 } else { 17537 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17538 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17539 requestPssLocked(app, app.setProcState); 17540 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17541 isSleeping(), now); 17542 } else if (false && DEBUG_PSS) { 17543 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17544 } 17545 } 17546 if (app.setProcState != app.curProcState) { 17547 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17548 "Proc state change of " + app.processName 17549 + " to " + app.curProcState); 17550 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17551 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17552 if (setImportant && !curImportant) { 17553 // This app is no longer something we consider important enough to allow to 17554 // use arbitrary amounts of battery power. Note 17555 // its current wake lock time to later know to kill it if 17556 // it is not behaving well. 17557 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17558 synchronized (stats) { 17559 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17560 app.pid, SystemClock.elapsedRealtime()); 17561 } 17562 app.lastCpuTime = app.curCpuTime; 17563 17564 } 17565 app.setProcState = app.curProcState; 17566 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17567 app.notCachedSinceIdle = false; 17568 } 17569 if (!doingAll) { 17570 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17571 } else { 17572 app.procStateChanged = true; 17573 } 17574 } 17575 17576 if (changes != 0) { 17577 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17578 int i = mPendingProcessChanges.size()-1; 17579 ProcessChangeItem item = null; 17580 while (i >= 0) { 17581 item = mPendingProcessChanges.get(i); 17582 if (item.pid == app.pid) { 17583 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17584 break; 17585 } 17586 i--; 17587 } 17588 if (i < 0) { 17589 // No existing item in pending changes; need a new one. 17590 final int NA = mAvailProcessChanges.size(); 17591 if (NA > 0) { 17592 item = mAvailProcessChanges.remove(NA-1); 17593 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17594 } else { 17595 item = new ProcessChangeItem(); 17596 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17597 } 17598 item.changes = 0; 17599 item.pid = app.pid; 17600 item.uid = app.info.uid; 17601 if (mPendingProcessChanges.size() == 0) { 17602 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17603 "*** Enqueueing dispatch processes changed!"); 17604 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17605 } 17606 mPendingProcessChanges.add(item); 17607 } 17608 item.changes |= changes; 17609 item.processState = app.repProcState; 17610 item.foregroundActivities = app.repForegroundActivities; 17611 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17612 + Integer.toHexString(System.identityHashCode(item)) 17613 + " " + app.toShortString() + ": changes=" + item.changes 17614 + " procState=" + item.processState 17615 + " foreground=" + item.foregroundActivities 17616 + " type=" + app.adjType + " source=" + app.adjSource 17617 + " target=" + app.adjTarget); 17618 } 17619 17620 return success; 17621 } 17622 17623 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17624 if (proc.thread != null) { 17625 if (proc.baseProcessTracker != null) { 17626 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17627 } 17628 if (proc.repProcState >= 0) { 17629 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17630 proc.repProcState); 17631 } 17632 } 17633 } 17634 17635 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17636 ProcessRecord TOP_APP, boolean doingAll, long now) { 17637 if (app.thread == null) { 17638 return false; 17639 } 17640 17641 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17642 17643 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17644 } 17645 17646 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17647 boolean oomAdj) { 17648 if (isForeground != proc.foregroundServices) { 17649 proc.foregroundServices = isForeground; 17650 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17651 proc.info.uid); 17652 if (isForeground) { 17653 if (curProcs == null) { 17654 curProcs = new ArrayList<ProcessRecord>(); 17655 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17656 } 17657 if (!curProcs.contains(proc)) { 17658 curProcs.add(proc); 17659 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17660 proc.info.packageName, proc.info.uid); 17661 } 17662 } else { 17663 if (curProcs != null) { 17664 if (curProcs.remove(proc)) { 17665 mBatteryStatsService.noteEvent( 17666 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17667 proc.info.packageName, proc.info.uid); 17668 if (curProcs.size() <= 0) { 17669 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17670 } 17671 } 17672 } 17673 } 17674 if (oomAdj) { 17675 updateOomAdjLocked(); 17676 } 17677 } 17678 } 17679 17680 private final ActivityRecord resumedAppLocked() { 17681 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17682 String pkg; 17683 int uid; 17684 if (act != null) { 17685 pkg = act.packageName; 17686 uid = act.info.applicationInfo.uid; 17687 } else { 17688 pkg = null; 17689 uid = -1; 17690 } 17691 // Has the UID or resumed package name changed? 17692 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17693 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17694 if (mCurResumedPackage != null) { 17695 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17696 mCurResumedPackage, mCurResumedUid); 17697 } 17698 mCurResumedPackage = pkg; 17699 mCurResumedUid = uid; 17700 if (mCurResumedPackage != null) { 17701 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17702 mCurResumedPackage, mCurResumedUid); 17703 } 17704 } 17705 return act; 17706 } 17707 17708 final boolean updateOomAdjLocked(ProcessRecord app) { 17709 final ActivityRecord TOP_ACT = resumedAppLocked(); 17710 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17711 final boolean wasCached = app.cached; 17712 17713 mAdjSeq++; 17714 17715 // This is the desired cached adjusment we want to tell it to use. 17716 // If our app is currently cached, we know it, and that is it. Otherwise, 17717 // we don't know it yet, and it needs to now be cached we will then 17718 // need to do a complete oom adj. 17719 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17720 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17721 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17722 SystemClock.uptimeMillis()); 17723 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17724 // Changed to/from cached state, so apps after it in the LRU 17725 // list may also be changed. 17726 updateOomAdjLocked(); 17727 } 17728 return success; 17729 } 17730 17731 final void updateOomAdjLocked() { 17732 final ActivityRecord TOP_ACT = resumedAppLocked(); 17733 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17734 final long now = SystemClock.uptimeMillis(); 17735 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17736 final int N = mLruProcesses.size(); 17737 17738 if (false) { 17739 RuntimeException e = new RuntimeException(); 17740 e.fillInStackTrace(); 17741 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17742 } 17743 17744 mAdjSeq++; 17745 mNewNumServiceProcs = 0; 17746 mNewNumAServiceProcs = 0; 17747 17748 final int emptyProcessLimit; 17749 final int cachedProcessLimit; 17750 if (mProcessLimit <= 0) { 17751 emptyProcessLimit = cachedProcessLimit = 0; 17752 } else if (mProcessLimit == 1) { 17753 emptyProcessLimit = 1; 17754 cachedProcessLimit = 0; 17755 } else { 17756 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17757 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17758 } 17759 17760 // Let's determine how many processes we have running vs. 17761 // how many slots we have for background processes; we may want 17762 // to put multiple processes in a slot of there are enough of 17763 // them. 17764 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17765 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17766 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17767 if (numEmptyProcs > cachedProcessLimit) { 17768 // If there are more empty processes than our limit on cached 17769 // processes, then use the cached process limit for the factor. 17770 // This ensures that the really old empty processes get pushed 17771 // down to the bottom, so if we are running low on memory we will 17772 // have a better chance at keeping around more cached processes 17773 // instead of a gazillion empty processes. 17774 numEmptyProcs = cachedProcessLimit; 17775 } 17776 int emptyFactor = numEmptyProcs/numSlots; 17777 if (emptyFactor < 1) emptyFactor = 1; 17778 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17779 if (cachedFactor < 1) cachedFactor = 1; 17780 int stepCached = 0; 17781 int stepEmpty = 0; 17782 int numCached = 0; 17783 int numEmpty = 0; 17784 int numTrimming = 0; 17785 17786 mNumNonCachedProcs = 0; 17787 mNumCachedHiddenProcs = 0; 17788 17789 // First update the OOM adjustment for each of the 17790 // application processes based on their current state. 17791 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17792 int nextCachedAdj = curCachedAdj+1; 17793 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17794 int nextEmptyAdj = curEmptyAdj+2; 17795 for (int i=N-1; i>=0; i--) { 17796 ProcessRecord app = mLruProcesses.get(i); 17797 if (!app.killedByAm && app.thread != null) { 17798 app.procStateChanged = false; 17799 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17800 17801 // If we haven't yet assigned the final cached adj 17802 // to the process, do that now. 17803 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17804 switch (app.curProcState) { 17805 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17806 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17807 // This process is a cached process holding activities... 17808 // assign it the next cached value for that type, and then 17809 // step that cached level. 17810 app.curRawAdj = curCachedAdj; 17811 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17812 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17813 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17814 + ")"); 17815 if (curCachedAdj != nextCachedAdj) { 17816 stepCached++; 17817 if (stepCached >= cachedFactor) { 17818 stepCached = 0; 17819 curCachedAdj = nextCachedAdj; 17820 nextCachedAdj += 2; 17821 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17822 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17823 } 17824 } 17825 } 17826 break; 17827 default: 17828 // For everything else, assign next empty cached process 17829 // level and bump that up. Note that this means that 17830 // long-running services that have dropped down to the 17831 // cached level will be treated as empty (since their process 17832 // state is still as a service), which is what we want. 17833 app.curRawAdj = curEmptyAdj; 17834 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17835 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17836 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17837 + ")"); 17838 if (curEmptyAdj != nextEmptyAdj) { 17839 stepEmpty++; 17840 if (stepEmpty >= emptyFactor) { 17841 stepEmpty = 0; 17842 curEmptyAdj = nextEmptyAdj; 17843 nextEmptyAdj += 2; 17844 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17845 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17846 } 17847 } 17848 } 17849 break; 17850 } 17851 } 17852 17853 applyOomAdjLocked(app, TOP_APP, true, now); 17854 17855 // Count the number of process types. 17856 switch (app.curProcState) { 17857 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17858 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17859 mNumCachedHiddenProcs++; 17860 numCached++; 17861 if (numCached > cachedProcessLimit) { 17862 app.kill("cached #" + numCached, true); 17863 } 17864 break; 17865 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17866 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17867 && app.lastActivityTime < oldTime) { 17868 app.kill("empty for " 17869 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17870 / 1000) + "s", true); 17871 } else { 17872 numEmpty++; 17873 if (numEmpty > emptyProcessLimit) { 17874 app.kill("empty #" + numEmpty, true); 17875 } 17876 } 17877 break; 17878 default: 17879 mNumNonCachedProcs++; 17880 break; 17881 } 17882 17883 if (app.isolated && app.services.size() <= 0) { 17884 // If this is an isolated process, and there are no 17885 // services running in it, then the process is no longer 17886 // needed. We agressively kill these because we can by 17887 // definition not re-use the same process again, and it is 17888 // good to avoid having whatever code was running in them 17889 // left sitting around after no longer needed. 17890 app.kill("isolated not needed", true); 17891 } 17892 17893 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17894 && !app.killedByAm) { 17895 numTrimming++; 17896 } 17897 } 17898 } 17899 17900 mNumServiceProcs = mNewNumServiceProcs; 17901 17902 // Now determine the memory trimming level of background processes. 17903 // Unfortunately we need to start at the back of the list to do this 17904 // properly. We only do this if the number of background apps we 17905 // are managing to keep around is less than half the maximum we desire; 17906 // if we are keeping a good number around, we'll let them use whatever 17907 // memory they want. 17908 final int numCachedAndEmpty = numCached + numEmpty; 17909 int memFactor; 17910 if (numCached <= ProcessList.TRIM_CACHED_APPS 17911 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17912 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17913 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17914 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17915 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17916 } else { 17917 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17918 } 17919 } else { 17920 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17921 } 17922 // We always allow the memory level to go up (better). We only allow it to go 17923 // down if we are in a state where that is allowed, *and* the total number of processes 17924 // has gone down since last time. 17925 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17926 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17927 + " last=" + mLastNumProcesses); 17928 if (memFactor > mLastMemoryLevel) { 17929 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17930 memFactor = mLastMemoryLevel; 17931 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17932 } 17933 } 17934 mLastMemoryLevel = memFactor; 17935 mLastNumProcesses = mLruProcesses.size(); 17936 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17937 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17938 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17939 if (mLowRamStartTime == 0) { 17940 mLowRamStartTime = now; 17941 } 17942 int step = 0; 17943 int fgTrimLevel; 17944 switch (memFactor) { 17945 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17946 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17947 break; 17948 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17949 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17950 break; 17951 default: 17952 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17953 break; 17954 } 17955 int factor = numTrimming/3; 17956 int minFactor = 2; 17957 if (mHomeProcess != null) minFactor++; 17958 if (mPreviousProcess != null) minFactor++; 17959 if (factor < minFactor) factor = minFactor; 17960 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17961 for (int i=N-1; i>=0; i--) { 17962 ProcessRecord app = mLruProcesses.get(i); 17963 if (allChanged || app.procStateChanged) { 17964 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17965 app.procStateChanged = false; 17966 } 17967 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17968 && !app.killedByAm) { 17969 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17970 try { 17971 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17972 "Trimming memory of " + app.processName 17973 + " to " + curLevel); 17974 app.thread.scheduleTrimMemory(curLevel); 17975 } catch (RemoteException e) { 17976 } 17977 if (false) { 17978 // For now we won't do this; our memory trimming seems 17979 // to be good enough at this point that destroying 17980 // activities causes more harm than good. 17981 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17982 && app != mHomeProcess && app != mPreviousProcess) { 17983 // Need to do this on its own message because the stack may not 17984 // be in a consistent state at this point. 17985 // For these apps we will also finish their activities 17986 // to help them free memory. 17987 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17988 } 17989 } 17990 } 17991 app.trimMemoryLevel = curLevel; 17992 step++; 17993 if (step >= factor) { 17994 step = 0; 17995 switch (curLevel) { 17996 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17997 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17998 break; 17999 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18000 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18001 break; 18002 } 18003 } 18004 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18005 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18006 && app.thread != null) { 18007 try { 18008 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18009 "Trimming memory of heavy-weight " + app.processName 18010 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18011 app.thread.scheduleTrimMemory( 18012 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18013 } catch (RemoteException e) { 18014 } 18015 } 18016 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18017 } else { 18018 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18019 || app.systemNoUi) && app.pendingUiClean) { 18020 // If this application is now in the background and it 18021 // had done UI, then give it the special trim level to 18022 // have it free UI resources. 18023 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18024 if (app.trimMemoryLevel < level && app.thread != null) { 18025 try { 18026 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18027 "Trimming memory of bg-ui " + app.processName 18028 + " to " + level); 18029 app.thread.scheduleTrimMemory(level); 18030 } catch (RemoteException e) { 18031 } 18032 } 18033 app.pendingUiClean = false; 18034 } 18035 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18036 try { 18037 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18038 "Trimming memory of fg " + app.processName 18039 + " to " + fgTrimLevel); 18040 app.thread.scheduleTrimMemory(fgTrimLevel); 18041 } catch (RemoteException e) { 18042 } 18043 } 18044 app.trimMemoryLevel = fgTrimLevel; 18045 } 18046 } 18047 } else { 18048 if (mLowRamStartTime != 0) { 18049 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18050 mLowRamStartTime = 0; 18051 } 18052 for (int i=N-1; i>=0; i--) { 18053 ProcessRecord app = mLruProcesses.get(i); 18054 if (allChanged || app.procStateChanged) { 18055 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18056 app.procStateChanged = false; 18057 } 18058 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18059 || app.systemNoUi) && app.pendingUiClean) { 18060 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18061 && app.thread != null) { 18062 try { 18063 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18064 "Trimming memory of ui hidden " + app.processName 18065 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18066 app.thread.scheduleTrimMemory( 18067 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18068 } catch (RemoteException e) { 18069 } 18070 } 18071 app.pendingUiClean = false; 18072 } 18073 app.trimMemoryLevel = 0; 18074 } 18075 } 18076 18077 if (mAlwaysFinishActivities) { 18078 // Need to do this on its own message because the stack may not 18079 // be in a consistent state at this point. 18080 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18081 } 18082 18083 if (allChanged) { 18084 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18085 } 18086 18087 if (mProcessStats.shouldWriteNowLocked(now)) { 18088 mHandler.post(new Runnable() { 18089 @Override public void run() { 18090 synchronized (ActivityManagerService.this) { 18091 mProcessStats.writeStateAsyncLocked(); 18092 } 18093 } 18094 }); 18095 } 18096 18097 if (DEBUG_OOM_ADJ) { 18098 if (false) { 18099 RuntimeException here = new RuntimeException("here"); 18100 here.fillInStackTrace(); 18101 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18102 } else { 18103 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18104 } 18105 } 18106 } 18107 18108 final void trimApplications() { 18109 synchronized (this) { 18110 int i; 18111 18112 // First remove any unused application processes whose package 18113 // has been removed. 18114 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18115 final ProcessRecord app = mRemovedProcesses.get(i); 18116 if (app.activities.size() == 0 18117 && app.curReceiver == null && app.services.size() == 0) { 18118 Slog.i( 18119 TAG, "Exiting empty application process " 18120 + app.processName + " (" 18121 + (app.thread != null ? app.thread.asBinder() : null) 18122 + ")\n"); 18123 if (app.pid > 0 && app.pid != MY_PID) { 18124 app.kill("empty", false); 18125 } else { 18126 try { 18127 app.thread.scheduleExit(); 18128 } catch (Exception e) { 18129 // Ignore exceptions. 18130 } 18131 } 18132 cleanUpApplicationRecordLocked(app, false, true, -1); 18133 mRemovedProcesses.remove(i); 18134 18135 if (app.persistent) { 18136 addAppLocked(app.info, false, null /* ABI override */); 18137 } 18138 } 18139 } 18140 18141 // Now update the oom adj for all processes. 18142 updateOomAdjLocked(); 18143 } 18144 } 18145 18146 /** This method sends the specified signal to each of the persistent apps */ 18147 public void signalPersistentProcesses(int sig) throws RemoteException { 18148 if (sig != Process.SIGNAL_USR1) { 18149 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18150 } 18151 18152 synchronized (this) { 18153 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18154 != PackageManager.PERMISSION_GRANTED) { 18155 throw new SecurityException("Requires permission " 18156 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18157 } 18158 18159 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18160 ProcessRecord r = mLruProcesses.get(i); 18161 if (r.thread != null && r.persistent) { 18162 Process.sendSignal(r.pid, sig); 18163 } 18164 } 18165 } 18166 } 18167 18168 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18169 if (proc == null || proc == mProfileProc) { 18170 proc = mProfileProc; 18171 profileType = mProfileType; 18172 clearProfilerLocked(); 18173 } 18174 if (proc == null) { 18175 return; 18176 } 18177 try { 18178 proc.thread.profilerControl(false, null, profileType); 18179 } catch (RemoteException e) { 18180 throw new IllegalStateException("Process disappeared"); 18181 } 18182 } 18183 18184 private void clearProfilerLocked() { 18185 if (mProfileFd != null) { 18186 try { 18187 mProfileFd.close(); 18188 } catch (IOException e) { 18189 } 18190 } 18191 mProfileApp = null; 18192 mProfileProc = null; 18193 mProfileFile = null; 18194 mProfileType = 0; 18195 mAutoStopProfiler = false; 18196 mSamplingInterval = 0; 18197 } 18198 18199 public boolean profileControl(String process, int userId, boolean start, 18200 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18201 18202 try { 18203 synchronized (this) { 18204 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18205 // its own permission. 18206 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18207 != PackageManager.PERMISSION_GRANTED) { 18208 throw new SecurityException("Requires permission " 18209 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18210 } 18211 18212 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18213 throw new IllegalArgumentException("null profile info or fd"); 18214 } 18215 18216 ProcessRecord proc = null; 18217 if (process != null) { 18218 proc = findProcessLocked(process, userId, "profileControl"); 18219 } 18220 18221 if (start && (proc == null || proc.thread == null)) { 18222 throw new IllegalArgumentException("Unknown process: " + process); 18223 } 18224 18225 if (start) { 18226 stopProfilerLocked(null, 0); 18227 setProfileApp(proc.info, proc.processName, profilerInfo); 18228 mProfileProc = proc; 18229 mProfileType = profileType; 18230 ParcelFileDescriptor fd = profilerInfo.profileFd; 18231 try { 18232 fd = fd.dup(); 18233 } catch (IOException e) { 18234 fd = null; 18235 } 18236 profilerInfo.profileFd = fd; 18237 proc.thread.profilerControl(start, profilerInfo, profileType); 18238 fd = null; 18239 mProfileFd = null; 18240 } else { 18241 stopProfilerLocked(proc, profileType); 18242 if (profilerInfo != null && profilerInfo.profileFd != null) { 18243 try { 18244 profilerInfo.profileFd.close(); 18245 } catch (IOException e) { 18246 } 18247 } 18248 } 18249 18250 return true; 18251 } 18252 } catch (RemoteException e) { 18253 throw new IllegalStateException("Process disappeared"); 18254 } finally { 18255 if (profilerInfo != null && profilerInfo.profileFd != null) { 18256 try { 18257 profilerInfo.profileFd.close(); 18258 } catch (IOException e) { 18259 } 18260 } 18261 } 18262 } 18263 18264 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18265 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18266 userId, true, ALLOW_FULL_ONLY, callName, null); 18267 ProcessRecord proc = null; 18268 try { 18269 int pid = Integer.parseInt(process); 18270 synchronized (mPidsSelfLocked) { 18271 proc = mPidsSelfLocked.get(pid); 18272 } 18273 } catch (NumberFormatException e) { 18274 } 18275 18276 if (proc == null) { 18277 ArrayMap<String, SparseArray<ProcessRecord>> all 18278 = mProcessNames.getMap(); 18279 SparseArray<ProcessRecord> procs = all.get(process); 18280 if (procs != null && procs.size() > 0) { 18281 proc = procs.valueAt(0); 18282 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18283 for (int i=1; i<procs.size(); i++) { 18284 ProcessRecord thisProc = procs.valueAt(i); 18285 if (thisProc.userId == userId) { 18286 proc = thisProc; 18287 break; 18288 } 18289 } 18290 } 18291 } 18292 } 18293 18294 return proc; 18295 } 18296 18297 public boolean dumpHeap(String process, int userId, boolean managed, 18298 String path, ParcelFileDescriptor fd) throws RemoteException { 18299 18300 try { 18301 synchronized (this) { 18302 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18303 // its own permission (same as profileControl). 18304 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18305 != PackageManager.PERMISSION_GRANTED) { 18306 throw new SecurityException("Requires permission " 18307 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18308 } 18309 18310 if (fd == null) { 18311 throw new IllegalArgumentException("null fd"); 18312 } 18313 18314 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18315 if (proc == null || proc.thread == null) { 18316 throw new IllegalArgumentException("Unknown process: " + process); 18317 } 18318 18319 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18320 if (!isDebuggable) { 18321 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18322 throw new SecurityException("Process not debuggable: " + proc); 18323 } 18324 } 18325 18326 proc.thread.dumpHeap(managed, path, fd); 18327 fd = null; 18328 return true; 18329 } 18330 } catch (RemoteException e) { 18331 throw new IllegalStateException("Process disappeared"); 18332 } finally { 18333 if (fd != null) { 18334 try { 18335 fd.close(); 18336 } catch (IOException e) { 18337 } 18338 } 18339 } 18340 } 18341 18342 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18343 public void monitor() { 18344 synchronized (this) { } 18345 } 18346 18347 void onCoreSettingsChange(Bundle settings) { 18348 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18349 ProcessRecord processRecord = mLruProcesses.get(i); 18350 try { 18351 if (processRecord.thread != null) { 18352 processRecord.thread.setCoreSettings(settings); 18353 } 18354 } catch (RemoteException re) { 18355 /* ignore */ 18356 } 18357 } 18358 } 18359 18360 // Multi-user methods 18361 18362 /** 18363 * Start user, if its not already running, but don't bring it to foreground. 18364 */ 18365 @Override 18366 public boolean startUserInBackground(final int userId) { 18367 return startUser(userId, /* foreground */ false); 18368 } 18369 18370 /** 18371 * Start user, if its not already running, and bring it to foreground. 18372 */ 18373 boolean startUserInForeground(final int userId, Dialog dlg) { 18374 boolean result = startUser(userId, /* foreground */ true); 18375 dlg.dismiss(); 18376 return result; 18377 } 18378 18379 /** 18380 * Refreshes the list of users related to the current user when either a 18381 * user switch happens or when a new related user is started in the 18382 * background. 18383 */ 18384 private void updateCurrentProfileIdsLocked() { 18385 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18386 mCurrentUserId, false /* enabledOnly */); 18387 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18388 for (int i = 0; i < currentProfileIds.length; i++) { 18389 currentProfileIds[i] = profiles.get(i).id; 18390 } 18391 mCurrentProfileIds = currentProfileIds; 18392 18393 synchronized (mUserProfileGroupIdsSelfLocked) { 18394 mUserProfileGroupIdsSelfLocked.clear(); 18395 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18396 for (int i = 0; i < users.size(); i++) { 18397 UserInfo user = users.get(i); 18398 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18399 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18400 } 18401 } 18402 } 18403 } 18404 18405 private Set getProfileIdsLocked(int userId) { 18406 Set userIds = new HashSet<Integer>(); 18407 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18408 userId, false /* enabledOnly */); 18409 for (UserInfo user : profiles) { 18410 userIds.add(Integer.valueOf(user.id)); 18411 } 18412 return userIds; 18413 } 18414 18415 @Override 18416 public boolean switchUser(final int userId) { 18417 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18418 String userName; 18419 synchronized (this) { 18420 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18421 if (userInfo == null) { 18422 Slog.w(TAG, "No user info for user #" + userId); 18423 return false; 18424 } 18425 if (userInfo.isManagedProfile()) { 18426 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18427 return false; 18428 } 18429 userName = userInfo.name; 18430 mTargetUserId = userId; 18431 } 18432 mHandler.removeMessages(START_USER_SWITCH_MSG); 18433 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18434 return true; 18435 } 18436 18437 private void showUserSwitchDialog(int userId, String userName) { 18438 // The dialog will show and then initiate the user switch by calling startUserInForeground 18439 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18440 true /* above system */); 18441 d.show(); 18442 } 18443 18444 private boolean startUser(final int userId, final boolean foreground) { 18445 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18446 != PackageManager.PERMISSION_GRANTED) { 18447 String msg = "Permission Denial: switchUser() from pid=" 18448 + Binder.getCallingPid() 18449 + ", uid=" + Binder.getCallingUid() 18450 + " requires " + INTERACT_ACROSS_USERS_FULL; 18451 Slog.w(TAG, msg); 18452 throw new SecurityException(msg); 18453 } 18454 18455 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18456 18457 final long ident = Binder.clearCallingIdentity(); 18458 try { 18459 synchronized (this) { 18460 final int oldUserId = mCurrentUserId; 18461 if (oldUserId == userId) { 18462 return true; 18463 } 18464 18465 mStackSupervisor.setLockTaskModeLocked(null, false); 18466 18467 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18468 if (userInfo == null) { 18469 Slog.w(TAG, "No user info for user #" + userId); 18470 return false; 18471 } 18472 if (foreground && userInfo.isManagedProfile()) { 18473 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18474 return false; 18475 } 18476 18477 if (foreground) { 18478 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18479 R.anim.screen_user_enter); 18480 } 18481 18482 boolean needStart = false; 18483 18484 // If the user we are switching to is not currently started, then 18485 // we need to start it now. 18486 if (mStartedUsers.get(userId) == null) { 18487 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18488 updateStartedUserArrayLocked(); 18489 needStart = true; 18490 } 18491 18492 final Integer userIdInt = Integer.valueOf(userId); 18493 mUserLru.remove(userIdInt); 18494 mUserLru.add(userIdInt); 18495 18496 if (foreground) { 18497 mCurrentUserId = userId; 18498 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18499 updateCurrentProfileIdsLocked(); 18500 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18501 // Once the internal notion of the active user has switched, we lock the device 18502 // with the option to show the user switcher on the keyguard. 18503 mWindowManager.lockNow(null); 18504 } else { 18505 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18506 updateCurrentProfileIdsLocked(); 18507 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18508 mUserLru.remove(currentUserIdInt); 18509 mUserLru.add(currentUserIdInt); 18510 } 18511 18512 final UserStartedState uss = mStartedUsers.get(userId); 18513 18514 // Make sure user is in the started state. If it is currently 18515 // stopping, we need to knock that off. 18516 if (uss.mState == UserStartedState.STATE_STOPPING) { 18517 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18518 // so we can just fairly silently bring the user back from 18519 // the almost-dead. 18520 uss.mState = UserStartedState.STATE_RUNNING; 18521 updateStartedUserArrayLocked(); 18522 needStart = true; 18523 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18524 // This means ACTION_SHUTDOWN has been sent, so we will 18525 // need to treat this as a new boot of the user. 18526 uss.mState = UserStartedState.STATE_BOOTING; 18527 updateStartedUserArrayLocked(); 18528 needStart = true; 18529 } 18530 18531 if (uss.mState == UserStartedState.STATE_BOOTING) { 18532 // Booting up a new user, need to tell system services about it. 18533 // Note that this is on the same handler as scheduling of broadcasts, 18534 // which is important because it needs to go first. 18535 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18536 } 18537 18538 if (foreground) { 18539 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18540 oldUserId)); 18541 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18542 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18543 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18544 oldUserId, userId, uss)); 18545 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18546 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18547 } 18548 18549 if (needStart) { 18550 // Send USER_STARTED broadcast 18551 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18552 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18553 | Intent.FLAG_RECEIVER_FOREGROUND); 18554 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18555 broadcastIntentLocked(null, null, intent, 18556 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18557 false, false, MY_PID, Process.SYSTEM_UID, userId); 18558 } 18559 18560 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18561 if (userId != UserHandle.USER_OWNER) { 18562 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18563 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18564 broadcastIntentLocked(null, null, intent, null, 18565 new IIntentReceiver.Stub() { 18566 public void performReceive(Intent intent, int resultCode, 18567 String data, Bundle extras, boolean ordered, 18568 boolean sticky, int sendingUser) { 18569 onUserInitialized(uss, foreground, oldUserId, userId); 18570 } 18571 }, 0, null, null, null, AppOpsManager.OP_NONE, 18572 true, false, MY_PID, Process.SYSTEM_UID, 18573 userId); 18574 uss.initializing = true; 18575 } else { 18576 getUserManagerLocked().makeInitialized(userInfo.id); 18577 } 18578 } 18579 18580 if (foreground) { 18581 if (!uss.initializing) { 18582 moveUserToForeground(uss, oldUserId, userId); 18583 } 18584 } else { 18585 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18586 } 18587 18588 if (needStart) { 18589 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18590 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18591 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18592 broadcastIntentLocked(null, null, intent, 18593 null, new IIntentReceiver.Stub() { 18594 @Override 18595 public void performReceive(Intent intent, int resultCode, String data, 18596 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18597 throws RemoteException { 18598 } 18599 }, 0, null, null, 18600 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18601 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18602 } 18603 } 18604 } finally { 18605 Binder.restoreCallingIdentity(ident); 18606 } 18607 18608 return true; 18609 } 18610 18611 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18612 long ident = Binder.clearCallingIdentity(); 18613 try { 18614 Intent intent; 18615 if (oldUserId >= 0) { 18616 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18617 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18618 int count = profiles.size(); 18619 for (int i = 0; i < count; i++) { 18620 int profileUserId = profiles.get(i).id; 18621 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18623 | Intent.FLAG_RECEIVER_FOREGROUND); 18624 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18625 broadcastIntentLocked(null, null, intent, 18626 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18627 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18628 } 18629 } 18630 if (newUserId >= 0) { 18631 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18632 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18633 int count = profiles.size(); 18634 for (int i = 0; i < count; i++) { 18635 int profileUserId = profiles.get(i).id; 18636 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18637 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18638 | Intent.FLAG_RECEIVER_FOREGROUND); 18639 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18640 broadcastIntentLocked(null, null, intent, 18641 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18642 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18643 } 18644 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18645 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18646 | Intent.FLAG_RECEIVER_FOREGROUND); 18647 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18648 broadcastIntentLocked(null, null, intent, 18649 null, null, 0, null, null, 18650 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18651 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18652 } 18653 } finally { 18654 Binder.restoreCallingIdentity(ident); 18655 } 18656 } 18657 18658 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18659 final int newUserId) { 18660 final int N = mUserSwitchObservers.beginBroadcast(); 18661 if (N > 0) { 18662 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18663 int mCount = 0; 18664 @Override 18665 public void sendResult(Bundle data) throws RemoteException { 18666 synchronized (ActivityManagerService.this) { 18667 if (mCurUserSwitchCallback == this) { 18668 mCount++; 18669 if (mCount == N) { 18670 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18671 } 18672 } 18673 } 18674 } 18675 }; 18676 synchronized (this) { 18677 uss.switching = true; 18678 mCurUserSwitchCallback = callback; 18679 } 18680 for (int i=0; i<N; i++) { 18681 try { 18682 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18683 newUserId, callback); 18684 } catch (RemoteException e) { 18685 } 18686 } 18687 } else { 18688 synchronized (this) { 18689 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18690 } 18691 } 18692 mUserSwitchObservers.finishBroadcast(); 18693 } 18694 18695 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18696 synchronized (this) { 18697 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18698 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18699 } 18700 } 18701 18702 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18703 mCurUserSwitchCallback = null; 18704 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18705 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18706 oldUserId, newUserId, uss)); 18707 } 18708 18709 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18710 synchronized (this) { 18711 if (foreground) { 18712 moveUserToForeground(uss, oldUserId, newUserId); 18713 } 18714 } 18715 18716 completeSwitchAndInitalize(uss, newUserId, true, false); 18717 } 18718 18719 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18720 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18721 if (homeInFront) { 18722 startHomeActivityLocked(newUserId); 18723 } else { 18724 mStackSupervisor.resumeTopActivitiesLocked(); 18725 } 18726 EventLogTags.writeAmSwitchUser(newUserId); 18727 getUserManagerLocked().userForeground(newUserId); 18728 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18729 } 18730 18731 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18732 completeSwitchAndInitalize(uss, newUserId, false, true); 18733 } 18734 18735 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18736 boolean clearInitializing, boolean clearSwitching) { 18737 boolean unfrozen = false; 18738 synchronized (this) { 18739 if (clearInitializing) { 18740 uss.initializing = false; 18741 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18742 } 18743 if (clearSwitching) { 18744 uss.switching = false; 18745 } 18746 if (!uss.switching && !uss.initializing) { 18747 mWindowManager.stopFreezingScreen(); 18748 unfrozen = true; 18749 } 18750 } 18751 if (unfrozen) { 18752 final int N = mUserSwitchObservers.beginBroadcast(); 18753 for (int i=0; i<N; i++) { 18754 try { 18755 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18756 } catch (RemoteException e) { 18757 } 18758 } 18759 mUserSwitchObservers.finishBroadcast(); 18760 } 18761 } 18762 18763 void scheduleStartProfilesLocked() { 18764 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18765 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18766 DateUtils.SECOND_IN_MILLIS); 18767 } 18768 } 18769 18770 void startProfilesLocked() { 18771 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18772 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18773 mCurrentUserId, false /* enabledOnly */); 18774 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18775 for (UserInfo user : profiles) { 18776 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18777 && user.id != mCurrentUserId) { 18778 toStart.add(user); 18779 } 18780 } 18781 final int n = toStart.size(); 18782 int i = 0; 18783 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18784 startUserInBackground(toStart.get(i).id); 18785 } 18786 if (i < n) { 18787 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18788 } 18789 } 18790 18791 void finishUserBoot(UserStartedState uss) { 18792 synchronized (this) { 18793 if (uss.mState == UserStartedState.STATE_BOOTING 18794 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18795 uss.mState = UserStartedState.STATE_RUNNING; 18796 final int userId = uss.mHandle.getIdentifier(); 18797 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18798 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18799 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18800 broadcastIntentLocked(null, null, intent, 18801 null, null, 0, null, null, 18802 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18803 true, false, MY_PID, Process.SYSTEM_UID, userId); 18804 } 18805 } 18806 } 18807 18808 void finishUserSwitch(UserStartedState uss) { 18809 synchronized (this) { 18810 finishUserBoot(uss); 18811 18812 startProfilesLocked(); 18813 18814 int num = mUserLru.size(); 18815 int i = 0; 18816 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18817 Integer oldUserId = mUserLru.get(i); 18818 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18819 if (oldUss == null) { 18820 // Shouldn't happen, but be sane if it does. 18821 mUserLru.remove(i); 18822 num--; 18823 continue; 18824 } 18825 if (oldUss.mState == UserStartedState.STATE_STOPPING 18826 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18827 // This user is already stopping, doesn't count. 18828 num--; 18829 i++; 18830 continue; 18831 } 18832 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18833 // Owner and current can't be stopped, but count as running. 18834 i++; 18835 continue; 18836 } 18837 // This is a user to be stopped. 18838 stopUserLocked(oldUserId, null); 18839 num--; 18840 i++; 18841 } 18842 } 18843 } 18844 18845 @Override 18846 public int stopUser(final int userId, final IStopUserCallback callback) { 18847 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18848 != PackageManager.PERMISSION_GRANTED) { 18849 String msg = "Permission Denial: switchUser() from pid=" 18850 + Binder.getCallingPid() 18851 + ", uid=" + Binder.getCallingUid() 18852 + " requires " + INTERACT_ACROSS_USERS_FULL; 18853 Slog.w(TAG, msg); 18854 throw new SecurityException(msg); 18855 } 18856 if (userId <= 0) { 18857 throw new IllegalArgumentException("Can't stop primary user " + userId); 18858 } 18859 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18860 synchronized (this) { 18861 return stopUserLocked(userId, callback); 18862 } 18863 } 18864 18865 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18866 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18867 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18868 return ActivityManager.USER_OP_IS_CURRENT; 18869 } 18870 18871 final UserStartedState uss = mStartedUsers.get(userId); 18872 if (uss == null) { 18873 // User is not started, nothing to do... but we do need to 18874 // callback if requested. 18875 if (callback != null) { 18876 mHandler.post(new Runnable() { 18877 @Override 18878 public void run() { 18879 try { 18880 callback.userStopped(userId); 18881 } catch (RemoteException e) { 18882 } 18883 } 18884 }); 18885 } 18886 return ActivityManager.USER_OP_SUCCESS; 18887 } 18888 18889 if (callback != null) { 18890 uss.mStopCallbacks.add(callback); 18891 } 18892 18893 if (uss.mState != UserStartedState.STATE_STOPPING 18894 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18895 uss.mState = UserStartedState.STATE_STOPPING; 18896 updateStartedUserArrayLocked(); 18897 18898 long ident = Binder.clearCallingIdentity(); 18899 try { 18900 // We are going to broadcast ACTION_USER_STOPPING and then 18901 // once that is done send a final ACTION_SHUTDOWN and then 18902 // stop the user. 18903 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18904 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18905 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18906 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18907 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18908 // This is the result receiver for the final shutdown broadcast. 18909 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18910 @Override 18911 public void performReceive(Intent intent, int resultCode, String data, 18912 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18913 finishUserStop(uss); 18914 } 18915 }; 18916 // This is the result receiver for the initial stopping broadcast. 18917 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18918 @Override 18919 public void performReceive(Intent intent, int resultCode, String data, 18920 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18921 // On to the next. 18922 synchronized (ActivityManagerService.this) { 18923 if (uss.mState != UserStartedState.STATE_STOPPING) { 18924 // Whoops, we are being started back up. Abort, abort! 18925 return; 18926 } 18927 uss.mState = UserStartedState.STATE_SHUTDOWN; 18928 } 18929 mBatteryStatsService.noteEvent( 18930 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18931 Integer.toString(userId), userId); 18932 mSystemServiceManager.stopUser(userId); 18933 broadcastIntentLocked(null, null, shutdownIntent, 18934 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18935 true, false, MY_PID, Process.SYSTEM_UID, userId); 18936 } 18937 }; 18938 // Kick things off. 18939 broadcastIntentLocked(null, null, stoppingIntent, 18940 null, stoppingReceiver, 0, null, null, 18941 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18942 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18943 } finally { 18944 Binder.restoreCallingIdentity(ident); 18945 } 18946 } 18947 18948 return ActivityManager.USER_OP_SUCCESS; 18949 } 18950 18951 void finishUserStop(UserStartedState uss) { 18952 final int userId = uss.mHandle.getIdentifier(); 18953 boolean stopped; 18954 ArrayList<IStopUserCallback> callbacks; 18955 synchronized (this) { 18956 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18957 if (mStartedUsers.get(userId) != uss) { 18958 stopped = false; 18959 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18960 stopped = false; 18961 } else { 18962 stopped = true; 18963 // User can no longer run. 18964 mStartedUsers.remove(userId); 18965 mUserLru.remove(Integer.valueOf(userId)); 18966 updateStartedUserArrayLocked(); 18967 18968 // Clean up all state and processes associated with the user. 18969 // Kill all the processes for the user. 18970 forceStopUserLocked(userId, "finish user"); 18971 } 18972 18973 // Explicitly remove the old information in mRecentTasks. 18974 removeRecentTasksForUserLocked(userId); 18975 } 18976 18977 for (int i=0; i<callbacks.size(); i++) { 18978 try { 18979 if (stopped) callbacks.get(i).userStopped(userId); 18980 else callbacks.get(i).userStopAborted(userId); 18981 } catch (RemoteException e) { 18982 } 18983 } 18984 18985 if (stopped) { 18986 mSystemServiceManager.cleanupUser(userId); 18987 synchronized (this) { 18988 mStackSupervisor.removeUserLocked(userId); 18989 } 18990 } 18991 } 18992 18993 @Override 18994 public UserInfo getCurrentUser() { 18995 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18996 != PackageManager.PERMISSION_GRANTED) && ( 18997 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18998 != PackageManager.PERMISSION_GRANTED)) { 18999 String msg = "Permission Denial: getCurrentUser() from pid=" 19000 + Binder.getCallingPid() 19001 + ", uid=" + Binder.getCallingUid() 19002 + " requires " + INTERACT_ACROSS_USERS; 19003 Slog.w(TAG, msg); 19004 throw new SecurityException(msg); 19005 } 19006 synchronized (this) { 19007 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19008 return getUserManagerLocked().getUserInfo(userId); 19009 } 19010 } 19011 19012 int getCurrentUserIdLocked() { 19013 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19014 } 19015 19016 @Override 19017 public boolean isUserRunning(int userId, boolean orStopped) { 19018 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19019 != PackageManager.PERMISSION_GRANTED) { 19020 String msg = "Permission Denial: isUserRunning() from pid=" 19021 + Binder.getCallingPid() 19022 + ", uid=" + Binder.getCallingUid() 19023 + " requires " + INTERACT_ACROSS_USERS; 19024 Slog.w(TAG, msg); 19025 throw new SecurityException(msg); 19026 } 19027 synchronized (this) { 19028 return isUserRunningLocked(userId, orStopped); 19029 } 19030 } 19031 19032 boolean isUserRunningLocked(int userId, boolean orStopped) { 19033 UserStartedState state = mStartedUsers.get(userId); 19034 if (state == null) { 19035 return false; 19036 } 19037 if (orStopped) { 19038 return true; 19039 } 19040 return state.mState != UserStartedState.STATE_STOPPING 19041 && state.mState != UserStartedState.STATE_SHUTDOWN; 19042 } 19043 19044 @Override 19045 public int[] getRunningUserIds() { 19046 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19047 != PackageManager.PERMISSION_GRANTED) { 19048 String msg = "Permission Denial: isUserRunning() from pid=" 19049 + Binder.getCallingPid() 19050 + ", uid=" + Binder.getCallingUid() 19051 + " requires " + INTERACT_ACROSS_USERS; 19052 Slog.w(TAG, msg); 19053 throw new SecurityException(msg); 19054 } 19055 synchronized (this) { 19056 return mStartedUserArray; 19057 } 19058 } 19059 19060 private void updateStartedUserArrayLocked() { 19061 int num = 0; 19062 for (int i=0; i<mStartedUsers.size(); i++) { 19063 UserStartedState uss = mStartedUsers.valueAt(i); 19064 // This list does not include stopping users. 19065 if (uss.mState != UserStartedState.STATE_STOPPING 19066 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19067 num++; 19068 } 19069 } 19070 mStartedUserArray = new int[num]; 19071 num = 0; 19072 for (int i=0; i<mStartedUsers.size(); i++) { 19073 UserStartedState uss = mStartedUsers.valueAt(i); 19074 if (uss.mState != UserStartedState.STATE_STOPPING 19075 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19076 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19077 num++; 19078 } 19079 } 19080 } 19081 19082 @Override 19083 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19084 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19085 != PackageManager.PERMISSION_GRANTED) { 19086 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19087 + Binder.getCallingPid() 19088 + ", uid=" + Binder.getCallingUid() 19089 + " requires " + INTERACT_ACROSS_USERS_FULL; 19090 Slog.w(TAG, msg); 19091 throw new SecurityException(msg); 19092 } 19093 19094 mUserSwitchObservers.register(observer); 19095 } 19096 19097 @Override 19098 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19099 mUserSwitchObservers.unregister(observer); 19100 } 19101 19102 private boolean userExists(int userId) { 19103 if (userId == 0) { 19104 return true; 19105 } 19106 UserManagerService ums = getUserManagerLocked(); 19107 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19108 } 19109 19110 int[] getUsersLocked() { 19111 UserManagerService ums = getUserManagerLocked(); 19112 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19113 } 19114 19115 UserManagerService getUserManagerLocked() { 19116 if (mUserManager == null) { 19117 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19118 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19119 } 19120 return mUserManager; 19121 } 19122 19123 private int applyUserId(int uid, int userId) { 19124 return UserHandle.getUid(userId, uid); 19125 } 19126 19127 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19128 if (info == null) return null; 19129 ApplicationInfo newInfo = new ApplicationInfo(info); 19130 newInfo.uid = applyUserId(info.uid, userId); 19131 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19132 + info.packageName; 19133 return newInfo; 19134 } 19135 19136 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19137 if (aInfo == null 19138 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19139 return aInfo; 19140 } 19141 19142 ActivityInfo info = new ActivityInfo(aInfo); 19143 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19144 return info; 19145 } 19146 19147 private final class LocalService extends ActivityManagerInternal { 19148 @Override 19149 public void goingToSleep() { 19150 ActivityManagerService.this.goingToSleep(); 19151 } 19152 19153 @Override 19154 public void wakingUp() { 19155 ActivityManagerService.this.wakingUp(); 19156 } 19157 19158 @Override 19159 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19160 String processName, String abiOverride, int uid, Runnable crashHandler) { 19161 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19162 processName, abiOverride, uid, crashHandler); 19163 } 19164 } 19165 19166 /** 19167 * An implementation of IAppTask, that allows an app to manage its own tasks via 19168 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19169 * only the process that calls getAppTasks() can call the AppTask methods. 19170 */ 19171 class AppTaskImpl extends IAppTask.Stub { 19172 private int mTaskId; 19173 private int mCallingUid; 19174 19175 public AppTaskImpl(int taskId, int callingUid) { 19176 mTaskId = taskId; 19177 mCallingUid = callingUid; 19178 } 19179 19180 private void checkCaller() { 19181 if (mCallingUid != Binder.getCallingUid()) { 19182 throw new SecurityException("Caller " + mCallingUid 19183 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19184 } 19185 } 19186 19187 @Override 19188 public void finishAndRemoveTask() { 19189 checkCaller(); 19190 19191 synchronized (ActivityManagerService.this) { 19192 long origId = Binder.clearCallingIdentity(); 19193 try { 19194 if (!removeTaskByIdLocked(mTaskId, false)) { 19195 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19196 } 19197 } finally { 19198 Binder.restoreCallingIdentity(origId); 19199 } 19200 } 19201 } 19202 19203 @Override 19204 public ActivityManager.RecentTaskInfo getTaskInfo() { 19205 checkCaller(); 19206 19207 synchronized (ActivityManagerService.this) { 19208 long origId = Binder.clearCallingIdentity(); 19209 try { 19210 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19211 if (tr == null) { 19212 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19213 } 19214 return createRecentTaskInfoFromTaskRecord(tr); 19215 } finally { 19216 Binder.restoreCallingIdentity(origId); 19217 } 19218 } 19219 } 19220 19221 @Override 19222 public void moveToFront() { 19223 checkCaller(); 19224 19225 final TaskRecord tr; 19226 synchronized (ActivityManagerService.this) { 19227 tr = recentTaskForIdLocked(mTaskId); 19228 if (tr == null) { 19229 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19230 } 19231 if (tr.getRootActivity() != null) { 19232 moveTaskToFrontLocked(tr.taskId, 0, null); 19233 return; 19234 } 19235 } 19236 19237 startActivityFromRecentsInner(tr.taskId, null); 19238 } 19239 19240 @Override 19241 public int startActivity(IBinder whoThread, String callingPackage, 19242 Intent intent, String resolvedType, Bundle options) { 19243 checkCaller(); 19244 19245 int callingUser = UserHandle.getCallingUserId(); 19246 TaskRecord tr; 19247 IApplicationThread appThread; 19248 synchronized (ActivityManagerService.this) { 19249 tr = recentTaskForIdLocked(mTaskId); 19250 if (tr == null) { 19251 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19252 } 19253 appThread = ApplicationThreadNative.asInterface(whoThread); 19254 if (appThread == null) { 19255 throw new IllegalArgumentException("Bad app thread " + appThread); 19256 } 19257 } 19258 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19259 resolvedType, null, null, null, null, 0, 0, null, null, 19260 null, options, callingUser, null, tr); 19261 } 19262 19263 @Override 19264 public void setExcludeFromRecents(boolean exclude) { 19265 checkCaller(); 19266 19267 synchronized (ActivityManagerService.this) { 19268 long origId = Binder.clearCallingIdentity(); 19269 try { 19270 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19271 if (tr == null) { 19272 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19273 } 19274 Intent intent = tr.getBaseIntent(); 19275 if (exclude) { 19276 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19277 } else { 19278 intent.setFlags(intent.getFlags() 19279 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19280 } 19281 } finally { 19282 Binder.restoreCallingIdentity(origId); 19283 } 19284 } 19285 } 19286 } 19287} 19288