ActivityManagerService.java revision 6edb5c665dcb024ae7cfb95b9a92e30dcc5777c1
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 and kill the process 1840 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 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 // Remove the task but don't kill the process (since other components in that 1895 // package may still be running and in the background) 1896 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1897 } 1898 } 1899 } 1900 1901 @Override 1902 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1903 // Force stop the specified packages 1904 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1905 if (packages != null) { 1906 for (String pkg : packages) { 1907 synchronized (ActivityManagerService.this) { 1908 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1909 userId, "finished booting")) { 1910 return true; 1911 } 1912 } 1913 } 1914 } 1915 return false; 1916 } 1917 }; 1918 1919 public void setSystemProcess() { 1920 try { 1921 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1922 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1923 ServiceManager.addService("meminfo", new MemBinder(this)); 1924 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1925 ServiceManager.addService("dbinfo", new DbBinder(this)); 1926 if (MONITOR_CPU_USAGE) { 1927 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1928 } 1929 ServiceManager.addService("permission", new PermissionController(this)); 1930 1931 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1932 "android", STOCK_PM_FLAGS); 1933 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1934 1935 synchronized (this) { 1936 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1937 app.persistent = true; 1938 app.pid = MY_PID; 1939 app.maxAdj = ProcessList.SYSTEM_ADJ; 1940 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1941 mProcessNames.put(app.processName, app.uid, app); 1942 synchronized (mPidsSelfLocked) { 1943 mPidsSelfLocked.put(app.pid, app); 1944 } 1945 updateLruProcessLocked(app, false, null); 1946 updateOomAdjLocked(); 1947 } 1948 } catch (PackageManager.NameNotFoundException e) { 1949 throw new RuntimeException( 1950 "Unable to find android system package", e); 1951 } 1952 } 1953 1954 public void setWindowManager(WindowManagerService wm) { 1955 mWindowManager = wm; 1956 mStackSupervisor.setWindowManager(wm); 1957 } 1958 1959 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1960 mUsageStatsService = usageStatsManager; 1961 } 1962 1963 public void startObservingNativeCrashes() { 1964 final NativeCrashListener ncl = new NativeCrashListener(this); 1965 ncl.start(); 1966 } 1967 1968 public IAppOpsService getAppOpsService() { 1969 return mAppOpsService; 1970 } 1971 1972 static class MemBinder extends Binder { 1973 ActivityManagerService mActivityManagerService; 1974 MemBinder(ActivityManagerService activityManagerService) { 1975 mActivityManagerService = activityManagerService; 1976 } 1977 1978 @Override 1979 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1980 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1981 != PackageManager.PERMISSION_GRANTED) { 1982 pw.println("Permission Denial: can't dump meminfo from from pid=" 1983 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1984 + " without permission " + android.Manifest.permission.DUMP); 1985 return; 1986 } 1987 1988 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1989 } 1990 } 1991 1992 static class GraphicsBinder extends Binder { 1993 ActivityManagerService mActivityManagerService; 1994 GraphicsBinder(ActivityManagerService activityManagerService) { 1995 mActivityManagerService = activityManagerService; 1996 } 1997 1998 @Override 1999 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2000 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2001 != PackageManager.PERMISSION_GRANTED) { 2002 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2003 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2004 + " without permission " + android.Manifest.permission.DUMP); 2005 return; 2006 } 2007 2008 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2009 } 2010 } 2011 2012 static class DbBinder extends Binder { 2013 ActivityManagerService mActivityManagerService; 2014 DbBinder(ActivityManagerService activityManagerService) { 2015 mActivityManagerService = activityManagerService; 2016 } 2017 2018 @Override 2019 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2020 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2021 != PackageManager.PERMISSION_GRANTED) { 2022 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2023 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2024 + " without permission " + android.Manifest.permission.DUMP); 2025 return; 2026 } 2027 2028 mActivityManagerService.dumpDbInfo(fd, pw, args); 2029 } 2030 } 2031 2032 static class CpuBinder extends Binder { 2033 ActivityManagerService mActivityManagerService; 2034 CpuBinder(ActivityManagerService activityManagerService) { 2035 mActivityManagerService = activityManagerService; 2036 } 2037 2038 @Override 2039 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2040 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2041 != PackageManager.PERMISSION_GRANTED) { 2042 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2043 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2044 + " without permission " + android.Manifest.permission.DUMP); 2045 return; 2046 } 2047 2048 synchronized (mActivityManagerService.mProcessCpuTracker) { 2049 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2050 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2051 SystemClock.uptimeMillis())); 2052 } 2053 } 2054 } 2055 2056 public static final class Lifecycle extends SystemService { 2057 private final ActivityManagerService mService; 2058 2059 public Lifecycle(Context context) { 2060 super(context); 2061 mService = new ActivityManagerService(context); 2062 } 2063 2064 @Override 2065 public void onStart() { 2066 mService.start(); 2067 } 2068 2069 public ActivityManagerService getService() { 2070 return mService; 2071 } 2072 } 2073 2074 // Note: This method is invoked on the main thread but may need to attach various 2075 // handlers to other threads. So take care to be explicit about the looper. 2076 public ActivityManagerService(Context systemContext) { 2077 mContext = systemContext; 2078 mFactoryTest = FactoryTest.getMode(); 2079 mSystemThread = ActivityThread.currentActivityThread(); 2080 2081 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2082 2083 mHandlerThread = new ServiceThread(TAG, 2084 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2085 mHandlerThread.start(); 2086 mHandler = new MainHandler(mHandlerThread.getLooper()); 2087 2088 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2089 "foreground", BROADCAST_FG_TIMEOUT, false); 2090 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2091 "background", BROADCAST_BG_TIMEOUT, true); 2092 mBroadcastQueues[0] = mFgBroadcastQueue; 2093 mBroadcastQueues[1] = mBgBroadcastQueue; 2094 2095 mServices = new ActiveServices(this); 2096 mProviderMap = new ProviderMap(this); 2097 2098 // TODO: Move creation of battery stats service outside of activity manager service. 2099 File dataDir = Environment.getDataDirectory(); 2100 File systemDir = new File(dataDir, "system"); 2101 systemDir.mkdirs(); 2102 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2103 mBatteryStatsService.getActiveStatistics().readLocked(); 2104 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2105 mOnBattery = DEBUG_POWER ? true 2106 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2107 mBatteryStatsService.getActiveStatistics().setCallback(this); 2108 2109 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2110 2111 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2112 2113 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2114 2115 // User 0 is the first and only user that runs at boot. 2116 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2117 mUserLru.add(Integer.valueOf(0)); 2118 updateStartedUserArrayLocked(); 2119 2120 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2121 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2122 2123 mConfiguration.setToDefaults(); 2124 mConfiguration.setLocale(Locale.getDefault()); 2125 2126 mConfigurationSeq = mConfiguration.seq = 1; 2127 mProcessCpuTracker.init(); 2128 2129 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2130 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2131 mStackSupervisor = new ActivityStackSupervisor(this); 2132 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2133 2134 mProcessCpuThread = new Thread("CpuTracker") { 2135 @Override 2136 public void run() { 2137 while (true) { 2138 try { 2139 try { 2140 synchronized(this) { 2141 final long now = SystemClock.uptimeMillis(); 2142 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2143 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2144 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2145 // + ", write delay=" + nextWriteDelay); 2146 if (nextWriteDelay < nextCpuDelay) { 2147 nextCpuDelay = nextWriteDelay; 2148 } 2149 if (nextCpuDelay > 0) { 2150 mProcessCpuMutexFree.set(true); 2151 this.wait(nextCpuDelay); 2152 } 2153 } 2154 } catch (InterruptedException e) { 2155 } 2156 updateCpuStatsNow(); 2157 } catch (Exception e) { 2158 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2159 } 2160 } 2161 } 2162 }; 2163 2164 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2165 2166 Watchdog.getInstance().addMonitor(this); 2167 Watchdog.getInstance().addThread(mHandler); 2168 } 2169 2170 public void setSystemServiceManager(SystemServiceManager mgr) { 2171 mSystemServiceManager = mgr; 2172 } 2173 2174 private void start() { 2175 Process.removeAllProcessGroups(); 2176 mProcessCpuThread.start(); 2177 2178 mBatteryStatsService.publish(mContext); 2179 mAppOpsService.publish(mContext); 2180 Slog.d("AppOps", "AppOpsService published"); 2181 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2182 } 2183 2184 public void initPowerManagement() { 2185 mStackSupervisor.initPowerManagement(); 2186 mBatteryStatsService.initPowerManagement(); 2187 } 2188 2189 @Override 2190 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2191 throws RemoteException { 2192 if (code == SYSPROPS_TRANSACTION) { 2193 // We need to tell all apps about the system property change. 2194 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2195 synchronized(this) { 2196 final int NP = mProcessNames.getMap().size(); 2197 for (int ip=0; ip<NP; ip++) { 2198 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2199 final int NA = apps.size(); 2200 for (int ia=0; ia<NA; ia++) { 2201 ProcessRecord app = apps.valueAt(ia); 2202 if (app.thread != null) { 2203 procs.add(app.thread.asBinder()); 2204 } 2205 } 2206 } 2207 } 2208 2209 int N = procs.size(); 2210 for (int i=0; i<N; i++) { 2211 Parcel data2 = Parcel.obtain(); 2212 try { 2213 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2214 } catch (RemoteException e) { 2215 } 2216 data2.recycle(); 2217 } 2218 } 2219 try { 2220 return super.onTransact(code, data, reply, flags); 2221 } catch (RuntimeException e) { 2222 // The activity manager only throws security exceptions, so let's 2223 // log all others. 2224 if (!(e instanceof SecurityException)) { 2225 Slog.wtf(TAG, "Activity Manager Crash", e); 2226 } 2227 throw e; 2228 } 2229 } 2230 2231 void updateCpuStats() { 2232 final long now = SystemClock.uptimeMillis(); 2233 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2234 return; 2235 } 2236 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2237 synchronized (mProcessCpuThread) { 2238 mProcessCpuThread.notify(); 2239 } 2240 } 2241 } 2242 2243 void updateCpuStatsNow() { 2244 synchronized (mProcessCpuTracker) { 2245 mProcessCpuMutexFree.set(false); 2246 final long now = SystemClock.uptimeMillis(); 2247 boolean haveNewCpuStats = false; 2248 2249 if (MONITOR_CPU_USAGE && 2250 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2251 mLastCpuTime.set(now); 2252 haveNewCpuStats = true; 2253 mProcessCpuTracker.update(); 2254 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2255 //Slog.i(TAG, "Total CPU usage: " 2256 // + mProcessCpu.getTotalCpuPercent() + "%"); 2257 2258 // Slog the cpu usage if the property is set. 2259 if ("true".equals(SystemProperties.get("events.cpu"))) { 2260 int user = mProcessCpuTracker.getLastUserTime(); 2261 int system = mProcessCpuTracker.getLastSystemTime(); 2262 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2263 int irq = mProcessCpuTracker.getLastIrqTime(); 2264 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2265 int idle = mProcessCpuTracker.getLastIdleTime(); 2266 2267 int total = user + system + iowait + irq + softIrq + idle; 2268 if (total == 0) total = 1; 2269 2270 EventLog.writeEvent(EventLogTags.CPU, 2271 ((user+system+iowait+irq+softIrq) * 100) / total, 2272 (user * 100) / total, 2273 (system * 100) / total, 2274 (iowait * 100) / total, 2275 (irq * 100) / total, 2276 (softIrq * 100) / total); 2277 } 2278 } 2279 2280 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2281 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2282 synchronized(bstats) { 2283 synchronized(mPidsSelfLocked) { 2284 if (haveNewCpuStats) { 2285 if (mOnBattery) { 2286 int perc = bstats.startAddingCpuLocked(); 2287 int totalUTime = 0; 2288 int totalSTime = 0; 2289 final int N = mProcessCpuTracker.countStats(); 2290 for (int i=0; i<N; i++) { 2291 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2292 if (!st.working) { 2293 continue; 2294 } 2295 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2296 int otherUTime = (st.rel_utime*perc)/100; 2297 int otherSTime = (st.rel_stime*perc)/100; 2298 totalUTime += otherUTime; 2299 totalSTime += otherSTime; 2300 if (pr != null) { 2301 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2302 if (ps == null || !ps.isActive()) { 2303 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2304 pr.info.uid, pr.processName); 2305 } 2306 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2307 st.rel_stime-otherSTime); 2308 ps.addSpeedStepTimes(cpuSpeedTimes); 2309 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2310 } else { 2311 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2312 if (ps == null || !ps.isActive()) { 2313 st.batteryStats = ps = bstats.getProcessStatsLocked( 2314 bstats.mapUid(st.uid), st.name); 2315 } 2316 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2317 st.rel_stime-otherSTime); 2318 ps.addSpeedStepTimes(cpuSpeedTimes); 2319 } 2320 } 2321 bstats.finishAddingCpuLocked(perc, totalUTime, 2322 totalSTime, cpuSpeedTimes); 2323 } 2324 } 2325 } 2326 2327 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2328 mLastWriteTime = now; 2329 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2330 } 2331 } 2332 } 2333 } 2334 2335 @Override 2336 public void batteryNeedsCpuUpdate() { 2337 updateCpuStatsNow(); 2338 } 2339 2340 @Override 2341 public void batteryPowerChanged(boolean onBattery) { 2342 // When plugging in, update the CPU stats first before changing 2343 // the plug state. 2344 updateCpuStatsNow(); 2345 synchronized (this) { 2346 synchronized(mPidsSelfLocked) { 2347 mOnBattery = DEBUG_POWER ? true : onBattery; 2348 } 2349 } 2350 } 2351 2352 /** 2353 * Initialize the application bind args. These are passed to each 2354 * process when the bindApplication() IPC is sent to the process. They're 2355 * lazily setup to make sure the services are running when they're asked for. 2356 */ 2357 private HashMap<String, IBinder> getCommonServicesLocked() { 2358 if (mAppBindArgs == null) { 2359 mAppBindArgs = new HashMap<String, IBinder>(); 2360 2361 // Setup the application init args 2362 mAppBindArgs.put("package", ServiceManager.getService("package")); 2363 mAppBindArgs.put("window", ServiceManager.getService("window")); 2364 mAppBindArgs.put(Context.ALARM_SERVICE, 2365 ServiceManager.getService(Context.ALARM_SERVICE)); 2366 } 2367 return mAppBindArgs; 2368 } 2369 2370 final void setFocusedActivityLocked(ActivityRecord r) { 2371 if (mFocusedActivity != r) { 2372 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2373 mFocusedActivity = r; 2374 if (r.task != null && r.task.voiceInteractor != null) { 2375 startRunningVoiceLocked(); 2376 } else { 2377 finishRunningVoiceLocked(); 2378 } 2379 mStackSupervisor.setFocusedStack(r); 2380 if (r != null) { 2381 mWindowManager.setFocusedApp(r.appToken, true); 2382 } 2383 applyUpdateLockStateLocked(r); 2384 } 2385 } 2386 2387 final void clearFocusedActivity(ActivityRecord r) { 2388 if (mFocusedActivity == r) { 2389 mFocusedActivity = null; 2390 } 2391 } 2392 2393 @Override 2394 public void setFocusedStack(int stackId) { 2395 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2396 synchronized (ActivityManagerService.this) { 2397 ActivityStack stack = mStackSupervisor.getStack(stackId); 2398 if (stack != null) { 2399 ActivityRecord r = stack.topRunningActivityLocked(null); 2400 if (r != null) { 2401 setFocusedActivityLocked(r); 2402 } 2403 } 2404 } 2405 } 2406 2407 @Override 2408 public void notifyActivityDrawn(IBinder token) { 2409 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2410 synchronized (this) { 2411 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2412 if (r != null) { 2413 r.task.stack.notifyActivityDrawnLocked(r); 2414 } 2415 } 2416 } 2417 2418 final void applyUpdateLockStateLocked(ActivityRecord r) { 2419 // Modifications to the UpdateLock state are done on our handler, outside 2420 // the activity manager's locks. The new state is determined based on the 2421 // state *now* of the relevant activity record. The object is passed to 2422 // the handler solely for logging detail, not to be consulted/modified. 2423 final boolean nextState = r != null && r.immersive; 2424 mHandler.sendMessage( 2425 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2426 } 2427 2428 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2429 Message msg = Message.obtain(); 2430 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2431 msg.obj = r.task.askedCompatMode ? null : r; 2432 mHandler.sendMessage(msg); 2433 } 2434 2435 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2436 String what, Object obj, ProcessRecord srcApp) { 2437 app.lastActivityTime = now; 2438 2439 if (app.activities.size() > 0) { 2440 // Don't want to touch dependent processes that are hosting activities. 2441 return index; 2442 } 2443 2444 int lrui = mLruProcesses.lastIndexOf(app); 2445 if (lrui < 0) { 2446 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2447 + what + " " + obj + " from " + srcApp); 2448 return index; 2449 } 2450 2451 if (lrui >= index) { 2452 // Don't want to cause this to move dependent processes *back* in the 2453 // list as if they were less frequently used. 2454 return index; 2455 } 2456 2457 if (lrui >= mLruProcessActivityStart) { 2458 // Don't want to touch dependent processes that are hosting activities. 2459 return index; 2460 } 2461 2462 mLruProcesses.remove(lrui); 2463 if (index > 0) { 2464 index--; 2465 } 2466 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2467 + " in LRU list: " + app); 2468 mLruProcesses.add(index, app); 2469 return index; 2470 } 2471 2472 final void removeLruProcessLocked(ProcessRecord app) { 2473 int lrui = mLruProcesses.lastIndexOf(app); 2474 if (lrui >= 0) { 2475 if (!app.killed) { 2476 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2477 Process.killProcessQuiet(app.pid); 2478 Process.killProcessGroup(app.info.uid, app.pid); 2479 } 2480 if (lrui <= mLruProcessActivityStart) { 2481 mLruProcessActivityStart--; 2482 } 2483 if (lrui <= mLruProcessServiceStart) { 2484 mLruProcessServiceStart--; 2485 } 2486 mLruProcesses.remove(lrui); 2487 } 2488 } 2489 2490 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2491 ProcessRecord client) { 2492 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2493 || app.treatLikeActivity; 2494 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2495 if (!activityChange && hasActivity) { 2496 // The process has activities, so we are only allowing activity-based adjustments 2497 // to move it. It should be kept in the front of the list with other 2498 // processes that have activities, and we don't want those to change their 2499 // order except due to activity operations. 2500 return; 2501 } 2502 2503 mLruSeq++; 2504 final long now = SystemClock.uptimeMillis(); 2505 app.lastActivityTime = now; 2506 2507 // First a quick reject: if the app is already at the position we will 2508 // put it, then there is nothing to do. 2509 if (hasActivity) { 2510 final int N = mLruProcesses.size(); 2511 if (N > 0 && mLruProcesses.get(N-1) == app) { 2512 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2513 return; 2514 } 2515 } else { 2516 if (mLruProcessServiceStart > 0 2517 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2518 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2519 return; 2520 } 2521 } 2522 2523 int lrui = mLruProcesses.lastIndexOf(app); 2524 2525 if (app.persistent && lrui >= 0) { 2526 // We don't care about the position of persistent processes, as long as 2527 // they are in the list. 2528 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2529 return; 2530 } 2531 2532 /* In progress: compute new position first, so we can avoid doing work 2533 if the process is not actually going to move. Not yet working. 2534 int addIndex; 2535 int nextIndex; 2536 boolean inActivity = false, inService = false; 2537 if (hasActivity) { 2538 // Process has activities, put it at the very tipsy-top. 2539 addIndex = mLruProcesses.size(); 2540 nextIndex = mLruProcessServiceStart; 2541 inActivity = true; 2542 } else if (hasService) { 2543 // Process has services, put it at the top of the service list. 2544 addIndex = mLruProcessActivityStart; 2545 nextIndex = mLruProcessServiceStart; 2546 inActivity = true; 2547 inService = true; 2548 } else { 2549 // Process not otherwise of interest, it goes to the top of the non-service area. 2550 addIndex = mLruProcessServiceStart; 2551 if (client != null) { 2552 int clientIndex = mLruProcesses.lastIndexOf(client); 2553 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2554 + app); 2555 if (clientIndex >= 0 && addIndex > clientIndex) { 2556 addIndex = clientIndex; 2557 } 2558 } 2559 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2560 } 2561 2562 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2563 + mLruProcessActivityStart + "): " + app); 2564 */ 2565 2566 if (lrui >= 0) { 2567 if (lrui < mLruProcessActivityStart) { 2568 mLruProcessActivityStart--; 2569 } 2570 if (lrui < mLruProcessServiceStart) { 2571 mLruProcessServiceStart--; 2572 } 2573 /* 2574 if (addIndex > lrui) { 2575 addIndex--; 2576 } 2577 if (nextIndex > lrui) { 2578 nextIndex--; 2579 } 2580 */ 2581 mLruProcesses.remove(lrui); 2582 } 2583 2584 /* 2585 mLruProcesses.add(addIndex, app); 2586 if (inActivity) { 2587 mLruProcessActivityStart++; 2588 } 2589 if (inService) { 2590 mLruProcessActivityStart++; 2591 } 2592 */ 2593 2594 int nextIndex; 2595 if (hasActivity) { 2596 final int N = mLruProcesses.size(); 2597 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2598 // Process doesn't have activities, but has clients with 2599 // activities... move it up, but one below the top (the top 2600 // should always have a real activity). 2601 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2602 mLruProcesses.add(N-1, app); 2603 // To keep it from spamming the LRU list (by making a bunch of clients), 2604 // we will push down any other entries owned by the app. 2605 final int uid = app.info.uid; 2606 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2607 ProcessRecord subProc = mLruProcesses.get(i); 2608 if (subProc.info.uid == uid) { 2609 // We want to push this one down the list. If the process after 2610 // it is for the same uid, however, don't do so, because we don't 2611 // want them internally to be re-ordered. 2612 if (mLruProcesses.get(i-1).info.uid != uid) { 2613 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2614 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2615 ProcessRecord tmp = mLruProcesses.get(i); 2616 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2617 mLruProcesses.set(i-1, tmp); 2618 i--; 2619 } 2620 } else { 2621 // A gap, we can stop here. 2622 break; 2623 } 2624 } 2625 } else { 2626 // Process has activities, put it at the very tipsy-top. 2627 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2628 mLruProcesses.add(app); 2629 } 2630 nextIndex = mLruProcessServiceStart; 2631 } else if (hasService) { 2632 // Process has services, put it at the top of the service list. 2633 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2634 mLruProcesses.add(mLruProcessActivityStart, app); 2635 nextIndex = mLruProcessServiceStart; 2636 mLruProcessActivityStart++; 2637 } else { 2638 // Process not otherwise of interest, it goes to the top of the non-service area. 2639 int index = mLruProcessServiceStart; 2640 if (client != null) { 2641 // If there is a client, don't allow the process to be moved up higher 2642 // in the list than that client. 2643 int clientIndex = mLruProcesses.lastIndexOf(client); 2644 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2645 + " when updating " + app); 2646 if (clientIndex <= lrui) { 2647 // Don't allow the client index restriction to push it down farther in the 2648 // list than it already is. 2649 clientIndex = lrui; 2650 } 2651 if (clientIndex >= 0 && index > clientIndex) { 2652 index = clientIndex; 2653 } 2654 } 2655 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2656 mLruProcesses.add(index, app); 2657 nextIndex = index-1; 2658 mLruProcessActivityStart++; 2659 mLruProcessServiceStart++; 2660 } 2661 2662 // If the app is currently using a content provider or service, 2663 // bump those processes as well. 2664 for (int j=app.connections.size()-1; j>=0; j--) { 2665 ConnectionRecord cr = app.connections.valueAt(j); 2666 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2667 && cr.binding.service.app != null 2668 && cr.binding.service.app.lruSeq != mLruSeq 2669 && !cr.binding.service.app.persistent) { 2670 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2671 "service connection", cr, app); 2672 } 2673 } 2674 for (int j=app.conProviders.size()-1; j>=0; j--) { 2675 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2676 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2677 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2678 "provider reference", cpr, app); 2679 } 2680 } 2681 } 2682 2683 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2684 if (uid == Process.SYSTEM_UID) { 2685 // The system gets to run in any process. If there are multiple 2686 // processes with the same uid, just pick the first (this 2687 // should never happen). 2688 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2689 if (procs == null) return null; 2690 final int N = procs.size(); 2691 for (int i = 0; i < N; i++) { 2692 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2693 } 2694 } 2695 ProcessRecord proc = mProcessNames.get(processName, uid); 2696 if (false && proc != null && !keepIfLarge 2697 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2698 && proc.lastCachedPss >= 4000) { 2699 // Turn this condition on to cause killing to happen regularly, for testing. 2700 if (proc.baseProcessTracker != null) { 2701 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2702 } 2703 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2704 } else if (proc != null && !keepIfLarge 2705 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2706 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2707 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2708 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2709 if (proc.baseProcessTracker != null) { 2710 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2711 } 2712 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2713 } 2714 } 2715 return proc; 2716 } 2717 2718 void ensurePackageDexOpt(String packageName) { 2719 IPackageManager pm = AppGlobals.getPackageManager(); 2720 try { 2721 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2722 mDidDexOpt = true; 2723 } 2724 } catch (RemoteException e) { 2725 } 2726 } 2727 2728 boolean isNextTransitionForward() { 2729 int transit = mWindowManager.getPendingAppTransition(); 2730 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2731 || transit == AppTransition.TRANSIT_TASK_OPEN 2732 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2733 } 2734 2735 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2736 String processName, String abiOverride, int uid, Runnable crashHandler) { 2737 synchronized(this) { 2738 ApplicationInfo info = new ApplicationInfo(); 2739 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2740 // For isolated processes, the former contains the parent's uid and the latter the 2741 // actual uid of the isolated process. 2742 // In the special case introduced by this method (which is, starting an isolated 2743 // process directly from the SystemServer without an actual parent app process) the 2744 // closest thing to a parent's uid is SYSTEM_UID. 2745 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2746 // the |isolated| logic in the ProcessRecord constructor. 2747 info.uid = Process.SYSTEM_UID; 2748 info.processName = processName; 2749 info.className = entryPoint; 2750 info.packageName = "android"; 2751 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2752 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2753 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2754 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2755 crashHandler); 2756 return proc != null ? proc.pid : 0; 2757 } 2758 } 2759 2760 final ProcessRecord startProcessLocked(String processName, 2761 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2762 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2763 boolean isolated, boolean keepIfLarge) { 2764 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2765 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2766 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2767 null /* crashHandler */); 2768 } 2769 2770 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2771 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2772 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2773 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2774 long startTime = SystemClock.elapsedRealtime(); 2775 ProcessRecord app; 2776 if (!isolated) { 2777 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2778 checkTime(startTime, "startProcess: after getProcessRecord"); 2779 } else { 2780 // If this is an isolated process, it can't re-use an existing process. 2781 app = null; 2782 } 2783 // We don't have to do anything more if: 2784 // (1) There is an existing application record; and 2785 // (2) The caller doesn't think it is dead, OR there is no thread 2786 // object attached to it so we know it couldn't have crashed; and 2787 // (3) There is a pid assigned to it, so it is either starting or 2788 // already running. 2789 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2790 + " app=" + app + " knownToBeDead=" + knownToBeDead 2791 + " thread=" + (app != null ? app.thread : null) 2792 + " pid=" + (app != null ? app.pid : -1)); 2793 if (app != null && app.pid > 0) { 2794 if (!knownToBeDead || app.thread == null) { 2795 // We already have the app running, or are waiting for it to 2796 // come up (we have a pid but not yet its thread), so keep it. 2797 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2798 // If this is a new package in the process, add the package to the list 2799 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2800 checkTime(startTime, "startProcess: done, added package to proc"); 2801 return app; 2802 } 2803 2804 // An application record is attached to a previous process, 2805 // clean it up now. 2806 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2807 checkTime(startTime, "startProcess: bad proc running, killing"); 2808 Process.killProcessGroup(app.info.uid, app.pid); 2809 handleAppDiedLocked(app, true, true); 2810 checkTime(startTime, "startProcess: done killing old proc"); 2811 } 2812 2813 String hostingNameStr = hostingName != null 2814 ? hostingName.flattenToShortString() : null; 2815 2816 if (!isolated) { 2817 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2818 // If we are in the background, then check to see if this process 2819 // is bad. If so, we will just silently fail. 2820 if (mBadProcesses.get(info.processName, info.uid) != null) { 2821 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2822 + "/" + info.processName); 2823 return null; 2824 } 2825 } else { 2826 // When the user is explicitly starting a process, then clear its 2827 // crash count so that we won't make it bad until they see at 2828 // least one crash dialog again, and make the process good again 2829 // if it had been bad. 2830 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2831 + "/" + info.processName); 2832 mProcessCrashTimes.remove(info.processName, info.uid); 2833 if (mBadProcesses.get(info.processName, info.uid) != null) { 2834 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2835 UserHandle.getUserId(info.uid), info.uid, 2836 info.processName); 2837 mBadProcesses.remove(info.processName, info.uid); 2838 if (app != null) { 2839 app.bad = false; 2840 } 2841 } 2842 } 2843 } 2844 2845 if (app == null) { 2846 checkTime(startTime, "startProcess: creating new process record"); 2847 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2848 app.crashHandler = crashHandler; 2849 if (app == null) { 2850 Slog.w(TAG, "Failed making new process record for " 2851 + processName + "/" + info.uid + " isolated=" + isolated); 2852 return null; 2853 } 2854 mProcessNames.put(processName, app.uid, app); 2855 if (isolated) { 2856 mIsolatedProcesses.put(app.uid, app); 2857 } 2858 checkTime(startTime, "startProcess: done creating new process record"); 2859 } else { 2860 // If this is a new package in the process, add the package to the list 2861 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2862 checkTime(startTime, "startProcess: added package to existing proc"); 2863 } 2864 2865 // If the system is not ready yet, then hold off on starting this 2866 // process until it is. 2867 if (!mProcessesReady 2868 && !isAllowedWhileBooting(info) 2869 && !allowWhileBooting) { 2870 if (!mProcessesOnHold.contains(app)) { 2871 mProcessesOnHold.add(app); 2872 } 2873 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2874 checkTime(startTime, "startProcess: returning with proc on hold"); 2875 return app; 2876 } 2877 2878 checkTime(startTime, "startProcess: stepping in to startProcess"); 2879 startProcessLocked( 2880 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2881 checkTime(startTime, "startProcess: done starting proc!"); 2882 return (app.pid != 0) ? app : null; 2883 } 2884 2885 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2886 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2887 } 2888 2889 private final void startProcessLocked(ProcessRecord app, 2890 String hostingType, String hostingNameStr) { 2891 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2892 null /* entryPoint */, null /* entryPointArgs */); 2893 } 2894 2895 private final void startProcessLocked(ProcessRecord app, String hostingType, 2896 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2897 long startTime = SystemClock.elapsedRealtime(); 2898 if (app.pid > 0 && app.pid != MY_PID) { 2899 checkTime(startTime, "startProcess: removing from pids map"); 2900 synchronized (mPidsSelfLocked) { 2901 mPidsSelfLocked.remove(app.pid); 2902 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2903 } 2904 checkTime(startTime, "startProcess: done removing from pids map"); 2905 app.setPid(0); 2906 } 2907 2908 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2909 "startProcessLocked removing on hold: " + app); 2910 mProcessesOnHold.remove(app); 2911 2912 checkTime(startTime, "startProcess: starting to update cpu stats"); 2913 updateCpuStats(); 2914 checkTime(startTime, "startProcess: done updating cpu stats"); 2915 2916 try { 2917 int uid = app.uid; 2918 2919 int[] gids = null; 2920 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2921 if (!app.isolated) { 2922 int[] permGids = null; 2923 try { 2924 checkTime(startTime, "startProcess: getting gids from package manager"); 2925 final PackageManager pm = mContext.getPackageManager(); 2926 permGids = pm.getPackageGids(app.info.packageName); 2927 2928 if (Environment.isExternalStorageEmulated()) { 2929 checkTime(startTime, "startProcess: checking external storage perm"); 2930 if (pm.checkPermission( 2931 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2932 app.info.packageName) == PERMISSION_GRANTED) { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2934 } else { 2935 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2936 } 2937 } 2938 } catch (PackageManager.NameNotFoundException e) { 2939 Slog.w(TAG, "Unable to retrieve gids", e); 2940 } 2941 2942 /* 2943 * Add shared application and profile GIDs so applications can share some 2944 * resources like shared libraries and access user-wide resources 2945 */ 2946 if (permGids == null) { 2947 gids = new int[2]; 2948 } else { 2949 gids = new int[permGids.length + 2]; 2950 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2951 } 2952 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2953 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2954 } 2955 checkTime(startTime, "startProcess: building args"); 2956 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2957 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2958 && mTopComponent != null 2959 && app.processName.equals(mTopComponent.getPackageName())) { 2960 uid = 0; 2961 } 2962 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2963 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2964 uid = 0; 2965 } 2966 } 2967 int debugFlags = 0; 2968 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2969 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2970 // Also turn on CheckJNI for debuggable apps. It's quite 2971 // awkward to turn on otherwise. 2972 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2973 } 2974 // Run the app in safe mode if its manifest requests so or the 2975 // system is booted in safe mode. 2976 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2977 mSafeMode == true) { 2978 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2979 } 2980 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2982 } 2983 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2985 } 2986 if ("1".equals(SystemProperties.get("debug.assert"))) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2988 } 2989 2990 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2991 if (requiredAbi == null) { 2992 requiredAbi = Build.SUPPORTED_ABIS[0]; 2993 } 2994 2995 String instructionSet = null; 2996 if (app.info.primaryCpuAbi != null) { 2997 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2998 } 2999 3000 // Start the process. It will either succeed and return a result containing 3001 // the PID of the new process, or else throw a RuntimeException. 3002 boolean isActivityProcess = (entryPoint == null); 3003 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3004 checkTime(startTime, "startProcess: asking zygote to start proc"); 3005 Process.ProcessStartResult startResult = Process.start(entryPoint, 3006 app.processName, uid, uid, gids, debugFlags, mountExternal, 3007 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3008 app.info.dataDir, entryPointArgs); 3009 checkTime(startTime, "startProcess: returned from zygote!"); 3010 3011 if (app.isolated) { 3012 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3013 } 3014 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3015 checkTime(startTime, "startProcess: done updating battery stats"); 3016 3017 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3018 UserHandle.getUserId(uid), startResult.pid, uid, 3019 app.processName, hostingType, 3020 hostingNameStr != null ? hostingNameStr : ""); 3021 3022 if (app.persistent) { 3023 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3024 } 3025 3026 checkTime(startTime, "startProcess: building log message"); 3027 StringBuilder buf = mStringBuilder; 3028 buf.setLength(0); 3029 buf.append("Start proc "); 3030 buf.append(app.processName); 3031 if (!isActivityProcess) { 3032 buf.append(" ["); 3033 buf.append(entryPoint); 3034 buf.append("]"); 3035 } 3036 buf.append(" for "); 3037 buf.append(hostingType); 3038 if (hostingNameStr != null) { 3039 buf.append(" "); 3040 buf.append(hostingNameStr); 3041 } 3042 buf.append(": pid="); 3043 buf.append(startResult.pid); 3044 buf.append(" uid="); 3045 buf.append(uid); 3046 buf.append(" gids={"); 3047 if (gids != null) { 3048 for (int gi=0; gi<gids.length; gi++) { 3049 if (gi != 0) buf.append(", "); 3050 buf.append(gids[gi]); 3051 3052 } 3053 } 3054 buf.append("}"); 3055 if (requiredAbi != null) { 3056 buf.append(" abi="); 3057 buf.append(requiredAbi); 3058 } 3059 Slog.i(TAG, buf.toString()); 3060 app.setPid(startResult.pid); 3061 app.usingWrapper = startResult.usingWrapper; 3062 app.removed = false; 3063 app.killed = false; 3064 app.killedByAm = false; 3065 checkTime(startTime, "startProcess: starting to update pids map"); 3066 synchronized (mPidsSelfLocked) { 3067 this.mPidsSelfLocked.put(startResult.pid, app); 3068 if (isActivityProcess) { 3069 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3070 msg.obj = app; 3071 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3072 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3073 } 3074 } 3075 checkTime(startTime, "startProcess: done updating pids map"); 3076 } catch (RuntimeException e) { 3077 // XXX do better error recovery. 3078 app.setPid(0); 3079 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3080 if (app.isolated) { 3081 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3082 } 3083 Slog.e(TAG, "Failure starting process " + app.processName, e); 3084 } 3085 } 3086 3087 void updateUsageStats(ActivityRecord component, boolean resumed) { 3088 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3089 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3090 if (resumed) { 3091 if (mUsageStatsService != null) { 3092 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3093 UsageEvents.Event.MOVE_TO_FOREGROUND); 3094 } 3095 synchronized (stats) { 3096 stats.noteActivityResumedLocked(component.app.uid); 3097 } 3098 } else { 3099 if (mUsageStatsService != null) { 3100 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3101 UsageEvents.Event.MOVE_TO_BACKGROUND); 3102 } 3103 synchronized (stats) { 3104 stats.noteActivityPausedLocked(component.app.uid); 3105 } 3106 } 3107 } 3108 3109 Intent getHomeIntent() { 3110 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3111 intent.setComponent(mTopComponent); 3112 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3113 intent.addCategory(Intent.CATEGORY_HOME); 3114 } 3115 return intent; 3116 } 3117 3118 boolean startHomeActivityLocked(int userId) { 3119 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3120 && mTopAction == null) { 3121 // We are running in factory test mode, but unable to find 3122 // the factory test app, so just sit around displaying the 3123 // error message and don't try to start anything. 3124 return false; 3125 } 3126 Intent intent = getHomeIntent(); 3127 ActivityInfo aInfo = 3128 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3129 if (aInfo != null) { 3130 intent.setComponent(new ComponentName( 3131 aInfo.applicationInfo.packageName, aInfo.name)); 3132 // Don't do this if the home app is currently being 3133 // instrumented. 3134 aInfo = new ActivityInfo(aInfo); 3135 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3136 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3137 aInfo.applicationInfo.uid, true); 3138 if (app == null || app.instrumentationClass == null) { 3139 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3140 mStackSupervisor.startHomeActivity(intent, aInfo); 3141 } 3142 } 3143 3144 return true; 3145 } 3146 3147 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3148 ActivityInfo ai = null; 3149 ComponentName comp = intent.getComponent(); 3150 try { 3151 if (comp != null) { 3152 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3153 } else { 3154 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3155 intent, 3156 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3157 flags, userId); 3158 3159 if (info != null) { 3160 ai = info.activityInfo; 3161 } 3162 } 3163 } catch (RemoteException e) { 3164 // ignore 3165 } 3166 3167 return ai; 3168 } 3169 3170 /** 3171 * Starts the "new version setup screen" if appropriate. 3172 */ 3173 void startSetupActivityLocked() { 3174 // Only do this once per boot. 3175 if (mCheckedForSetup) { 3176 return; 3177 } 3178 3179 // We will show this screen if the current one is a different 3180 // version than the last one shown, and we are not running in 3181 // low-level factory test mode. 3182 final ContentResolver resolver = mContext.getContentResolver(); 3183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3184 Settings.Global.getInt(resolver, 3185 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3186 mCheckedForSetup = true; 3187 3188 // See if we should be showing the platform update setup UI. 3189 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3190 List<ResolveInfo> ris = mContext.getPackageManager() 3191 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3192 3193 // We don't allow third party apps to replace this. 3194 ResolveInfo ri = null; 3195 for (int i=0; ris != null && i<ris.size(); i++) { 3196 if ((ris.get(i).activityInfo.applicationInfo.flags 3197 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3198 ri = ris.get(i); 3199 break; 3200 } 3201 } 3202 3203 if (ri != null) { 3204 String vers = ri.activityInfo.metaData != null 3205 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3206 : null; 3207 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3208 vers = ri.activityInfo.applicationInfo.metaData.getString( 3209 Intent.METADATA_SETUP_VERSION); 3210 } 3211 String lastVers = Settings.Secure.getString( 3212 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3213 if (vers != null && !vers.equals(lastVers)) { 3214 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3215 intent.setComponent(new ComponentName( 3216 ri.activityInfo.packageName, ri.activityInfo.name)); 3217 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3218 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3219 null); 3220 } 3221 } 3222 } 3223 } 3224 3225 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3226 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3227 } 3228 3229 void enforceNotIsolatedCaller(String caller) { 3230 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3231 throw new SecurityException("Isolated process not allowed to call " + caller); 3232 } 3233 } 3234 3235 void enforceShellRestriction(String restriction, int userHandle) { 3236 if (Binder.getCallingUid() == Process.SHELL_UID) { 3237 if (userHandle < 0 3238 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3239 throw new SecurityException("Shell does not have permission to access user " 3240 + userHandle); 3241 } 3242 } 3243 } 3244 3245 @Override 3246 public int getFrontActivityScreenCompatMode() { 3247 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3248 synchronized (this) { 3249 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3250 } 3251 } 3252 3253 @Override 3254 public void setFrontActivityScreenCompatMode(int mode) { 3255 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3256 "setFrontActivityScreenCompatMode"); 3257 synchronized (this) { 3258 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3259 } 3260 } 3261 3262 @Override 3263 public int getPackageScreenCompatMode(String packageName) { 3264 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3265 synchronized (this) { 3266 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3267 } 3268 } 3269 3270 @Override 3271 public void setPackageScreenCompatMode(String packageName, int mode) { 3272 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3273 "setPackageScreenCompatMode"); 3274 synchronized (this) { 3275 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3276 } 3277 } 3278 3279 @Override 3280 public boolean getPackageAskScreenCompat(String packageName) { 3281 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3282 synchronized (this) { 3283 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3284 } 3285 } 3286 3287 @Override 3288 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3289 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3290 "setPackageAskScreenCompat"); 3291 synchronized (this) { 3292 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3293 } 3294 } 3295 3296 private void dispatchProcessesChanged() { 3297 int N; 3298 synchronized (this) { 3299 N = mPendingProcessChanges.size(); 3300 if (mActiveProcessChanges.length < N) { 3301 mActiveProcessChanges = new ProcessChangeItem[N]; 3302 } 3303 mPendingProcessChanges.toArray(mActiveProcessChanges); 3304 mAvailProcessChanges.addAll(mPendingProcessChanges); 3305 mPendingProcessChanges.clear(); 3306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3307 } 3308 3309 int i = mProcessObservers.beginBroadcast(); 3310 while (i > 0) { 3311 i--; 3312 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3313 if (observer != null) { 3314 try { 3315 for (int j=0; j<N; j++) { 3316 ProcessChangeItem item = mActiveProcessChanges[j]; 3317 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3318 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3319 + item.pid + " uid=" + item.uid + ": " 3320 + item.foregroundActivities); 3321 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3322 item.foregroundActivities); 3323 } 3324 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3325 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3326 + item.pid + " uid=" + item.uid + ": " + item.processState); 3327 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3328 } 3329 } 3330 } catch (RemoteException e) { 3331 } 3332 } 3333 } 3334 mProcessObservers.finishBroadcast(); 3335 } 3336 3337 private void dispatchProcessDied(int pid, int uid) { 3338 int i = mProcessObservers.beginBroadcast(); 3339 while (i > 0) { 3340 i--; 3341 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3342 if (observer != null) { 3343 try { 3344 observer.onProcessDied(pid, uid); 3345 } catch (RemoteException e) { 3346 } 3347 } 3348 } 3349 mProcessObservers.finishBroadcast(); 3350 } 3351 3352 @Override 3353 public final int startActivity(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3355 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3356 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3357 resultWho, requestCode, startFlags, profilerInfo, options, 3358 UserHandle.getCallingUserId()); 3359 } 3360 3361 @Override 3362 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3363 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3364 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3365 enforceNotIsolatedCaller("startActivity"); 3366 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3367 false, ALLOW_FULL_ONLY, "startActivity", null); 3368 // TODO: Switch to user app stacks here. 3369 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3370 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3371 profilerInfo, null, null, options, userId, null, null); 3372 } 3373 3374 @Override 3375 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3376 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3377 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3378 3379 // This is very dangerous -- it allows you to perform a start activity (including 3380 // permission grants) as any app that may launch one of your own activities. So 3381 // we will only allow this to be done from activities that are part of the core framework, 3382 // and then only when they are running as the system. 3383 final ActivityRecord sourceRecord; 3384 final int targetUid; 3385 final String targetPackage; 3386 synchronized (this) { 3387 if (resultTo == null) { 3388 throw new SecurityException("Must be called from an activity"); 3389 } 3390 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3391 if (sourceRecord == null) { 3392 throw new SecurityException("Called with bad activity token: " + resultTo); 3393 } 3394 if (!sourceRecord.info.packageName.equals("android")) { 3395 throw new SecurityException( 3396 "Must be called from an activity that is declared in the android package"); 3397 } 3398 if (sourceRecord.app == null) { 3399 throw new SecurityException("Called without a process attached to activity"); 3400 } 3401 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3402 // This is still okay, as long as this activity is running under the 3403 // uid of the original calling activity. 3404 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3405 throw new SecurityException( 3406 "Calling activity in uid " + sourceRecord.app.uid 3407 + " must be system uid or original calling uid " 3408 + sourceRecord.launchedFromUid); 3409 } 3410 } 3411 targetUid = sourceRecord.launchedFromUid; 3412 targetPackage = sourceRecord.launchedFromPackage; 3413 } 3414 3415 if (userId == UserHandle.USER_NULL) { 3416 userId = UserHandle.getUserId(sourceRecord.app.uid); 3417 } 3418 3419 // TODO: Switch to user app stacks here. 3420 try { 3421 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3422 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3423 null, null, options, userId, null, null); 3424 return ret; 3425 } catch (SecurityException e) { 3426 // XXX need to figure out how to propagate to original app. 3427 // A SecurityException here is generally actually a fault of the original 3428 // calling activity (such as a fairly granting permissions), so propagate it 3429 // back to them. 3430 /* 3431 StringBuilder msg = new StringBuilder(); 3432 msg.append("While launching"); 3433 msg.append(intent.toString()); 3434 msg.append(": "); 3435 msg.append(e.getMessage()); 3436 */ 3437 throw e; 3438 } 3439 } 3440 3441 @Override 3442 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3443 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3444 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3445 enforceNotIsolatedCaller("startActivityAndWait"); 3446 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3447 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3448 WaitResult res = new WaitResult(); 3449 // TODO: Switch to user app stacks here. 3450 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3451 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3452 options, userId, null, null); 3453 return res; 3454 } 3455 3456 @Override 3457 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3458 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3459 int startFlags, Configuration config, Bundle options, int userId) { 3460 enforceNotIsolatedCaller("startActivityWithConfig"); 3461 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3462 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3463 // TODO: Switch to user app stacks here. 3464 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3465 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3466 null, null, config, options, userId, null, null); 3467 return ret; 3468 } 3469 3470 @Override 3471 public int startActivityIntentSender(IApplicationThread caller, 3472 IntentSender intent, Intent fillInIntent, String resolvedType, 3473 IBinder resultTo, String resultWho, int requestCode, 3474 int flagsMask, int flagsValues, Bundle options) { 3475 enforceNotIsolatedCaller("startActivityIntentSender"); 3476 // Refuse possible leaked file descriptors 3477 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3478 throw new IllegalArgumentException("File descriptors passed in Intent"); 3479 } 3480 3481 IIntentSender sender = intent.getTarget(); 3482 if (!(sender instanceof PendingIntentRecord)) { 3483 throw new IllegalArgumentException("Bad PendingIntent object"); 3484 } 3485 3486 PendingIntentRecord pir = (PendingIntentRecord)sender; 3487 3488 synchronized (this) { 3489 // If this is coming from the currently resumed activity, it is 3490 // effectively saying that app switches are allowed at this point. 3491 final ActivityStack stack = getFocusedStack(); 3492 if (stack.mResumedActivity != null && 3493 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3494 mAppSwitchesAllowedTime = 0; 3495 } 3496 } 3497 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3498 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3499 return ret; 3500 } 3501 3502 @Override 3503 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3504 Intent intent, String resolvedType, IVoiceInteractionSession session, 3505 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3506 Bundle options, int userId) { 3507 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3508 != PackageManager.PERMISSION_GRANTED) { 3509 String msg = "Permission Denial: startVoiceActivity() from pid=" 3510 + Binder.getCallingPid() 3511 + ", uid=" + Binder.getCallingUid() 3512 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3513 Slog.w(TAG, msg); 3514 throw new SecurityException(msg); 3515 } 3516 if (session == null || interactor == null) { 3517 throw new NullPointerException("null session or interactor"); 3518 } 3519 userId = handleIncomingUser(callingPid, callingUid, userId, 3520 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3521 // TODO: Switch to user app stacks here. 3522 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3523 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3524 null, options, userId, null, null); 3525 } 3526 3527 @Override 3528 public boolean startNextMatchingActivity(IBinder callingActivity, 3529 Intent intent, Bundle options) { 3530 // Refuse possible leaked file descriptors 3531 if (intent != null && intent.hasFileDescriptors() == true) { 3532 throw new IllegalArgumentException("File descriptors passed in Intent"); 3533 } 3534 3535 synchronized (this) { 3536 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3537 if (r == null) { 3538 ActivityOptions.abort(options); 3539 return false; 3540 } 3541 if (r.app == null || r.app.thread == null) { 3542 // The caller is not running... d'oh! 3543 ActivityOptions.abort(options); 3544 return false; 3545 } 3546 intent = new Intent(intent); 3547 // The caller is not allowed to change the data. 3548 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3549 // And we are resetting to find the next component... 3550 intent.setComponent(null); 3551 3552 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3553 3554 ActivityInfo aInfo = null; 3555 try { 3556 List<ResolveInfo> resolves = 3557 AppGlobals.getPackageManager().queryIntentActivities( 3558 intent, r.resolvedType, 3559 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3560 UserHandle.getCallingUserId()); 3561 3562 // Look for the original activity in the list... 3563 final int N = resolves != null ? resolves.size() : 0; 3564 for (int i=0; i<N; i++) { 3565 ResolveInfo rInfo = resolves.get(i); 3566 if (rInfo.activityInfo.packageName.equals(r.packageName) 3567 && rInfo.activityInfo.name.equals(r.info.name)) { 3568 // We found the current one... the next matching is 3569 // after it. 3570 i++; 3571 if (i<N) { 3572 aInfo = resolves.get(i).activityInfo; 3573 } 3574 if (debug) { 3575 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3576 + "/" + r.info.name); 3577 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3578 + "/" + aInfo.name); 3579 } 3580 break; 3581 } 3582 } 3583 } catch (RemoteException e) { 3584 } 3585 3586 if (aInfo == null) { 3587 // Nobody who is next! 3588 ActivityOptions.abort(options); 3589 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3590 return false; 3591 } 3592 3593 intent.setComponent(new ComponentName( 3594 aInfo.applicationInfo.packageName, aInfo.name)); 3595 intent.setFlags(intent.getFlags()&~( 3596 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3597 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3598 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3599 Intent.FLAG_ACTIVITY_NEW_TASK)); 3600 3601 // Okay now we need to start the new activity, replacing the 3602 // currently running activity. This is a little tricky because 3603 // we want to start the new one as if the current one is finished, 3604 // but not finish the current one first so that there is no flicker. 3605 // And thus... 3606 final boolean wasFinishing = r.finishing; 3607 r.finishing = true; 3608 3609 // Propagate reply information over to the new activity. 3610 final ActivityRecord resultTo = r.resultTo; 3611 final String resultWho = r.resultWho; 3612 final int requestCode = r.requestCode; 3613 r.resultTo = null; 3614 if (resultTo != null) { 3615 resultTo.removeResultsLocked(r, resultWho, requestCode); 3616 } 3617 3618 final long origId = Binder.clearCallingIdentity(); 3619 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3620 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3621 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3622 -1, r.launchedFromUid, 0, options, false, null, null, null); 3623 Binder.restoreCallingIdentity(origId); 3624 3625 r.finishing = wasFinishing; 3626 if (res != ActivityManager.START_SUCCESS) { 3627 return false; 3628 } 3629 return true; 3630 } 3631 } 3632 3633 @Override 3634 public final int startActivityFromRecents(int taskId, Bundle options) { 3635 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3636 String msg = "Permission Denial: startActivityFromRecents called without " + 3637 START_TASKS_FROM_RECENTS; 3638 Slog.w(TAG, msg); 3639 throw new SecurityException(msg); 3640 } 3641 return startActivityFromRecentsInner(taskId, options); 3642 } 3643 3644 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3645 final TaskRecord task; 3646 final int callingUid; 3647 final String callingPackage; 3648 final Intent intent; 3649 final int userId; 3650 synchronized (this) { 3651 task = recentTaskForIdLocked(taskId); 3652 if (task == null) { 3653 throw new IllegalArgumentException("Task " + taskId + " not found."); 3654 } 3655 callingUid = task.mCallingUid; 3656 callingPackage = task.mCallingPackage; 3657 intent = task.intent; 3658 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3659 userId = task.userId; 3660 } 3661 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3662 options, userId, null, task); 3663 } 3664 3665 final int startActivityInPackage(int uid, String callingPackage, 3666 Intent intent, String resolvedType, IBinder resultTo, 3667 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3668 IActivityContainer container, TaskRecord inTask) { 3669 3670 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3671 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3672 3673 // TODO: Switch to user app stacks here. 3674 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3675 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3676 null, null, null, options, userId, container, inTask); 3677 return ret; 3678 } 3679 3680 @Override 3681 public final int startActivities(IApplicationThread caller, String callingPackage, 3682 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3683 int userId) { 3684 enforceNotIsolatedCaller("startActivities"); 3685 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3686 false, ALLOW_FULL_ONLY, "startActivity", null); 3687 // TODO: Switch to user app stacks here. 3688 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3689 resolvedTypes, resultTo, options, userId); 3690 return ret; 3691 } 3692 3693 final int startActivitiesInPackage(int uid, String callingPackage, 3694 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3695 Bundle options, int userId) { 3696 3697 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3698 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3699 // TODO: Switch to user app stacks here. 3700 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3701 resultTo, options, userId); 3702 return ret; 3703 } 3704 3705 //explicitly remove thd old information in mRecentTasks when removing existing user. 3706 private void removeRecentTasksForUserLocked(int userId) { 3707 if(userId <= 0) { 3708 Slog.i(TAG, "Can't remove recent task on user " + userId); 3709 return; 3710 } 3711 3712 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3713 TaskRecord tr = mRecentTasks.get(i); 3714 if (tr.userId == userId) { 3715 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3716 + " when finishing user" + userId); 3717 mRecentTasks.remove(i); 3718 tr.removedFromRecents(mTaskPersister); 3719 } 3720 } 3721 3722 // Remove tasks from persistent storage. 3723 mTaskPersister.wakeup(null, true); 3724 } 3725 3726 // Sort by taskId 3727 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3728 @Override 3729 public int compare(TaskRecord lhs, TaskRecord rhs) { 3730 return rhs.taskId - lhs.taskId; 3731 } 3732 }; 3733 3734 // Extract the affiliates of the chain containing mRecentTasks[start]. 3735 private int processNextAffiliateChain(int start) { 3736 final TaskRecord startTask = mRecentTasks.get(start); 3737 final int affiliateId = startTask.mAffiliatedTaskId; 3738 3739 // Quick identification of isolated tasks. I.e. those not launched behind. 3740 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3741 startTask.mNextAffiliate == null) { 3742 // There is still a slim chance that there are other tasks that point to this task 3743 // and that the chain is so messed up that this task no longer points to them but 3744 // the gain of this optimization outweighs the risk. 3745 startTask.inRecents = true; 3746 return start + 1; 3747 } 3748 3749 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3750 mTmpRecents.clear(); 3751 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3752 final TaskRecord task = mRecentTasks.get(i); 3753 if (task.mAffiliatedTaskId == affiliateId) { 3754 mRecentTasks.remove(i); 3755 mTmpRecents.add(task); 3756 } 3757 } 3758 3759 // Sort them all by taskId. That is the order they were create in and that order will 3760 // always be correct. 3761 Collections.sort(mTmpRecents, mTaskRecordComparator); 3762 3763 // Go through and fix up the linked list. 3764 // The first one is the end of the chain and has no next. 3765 final TaskRecord first = mTmpRecents.get(0); 3766 first.inRecents = true; 3767 if (first.mNextAffiliate != null) { 3768 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3769 first.setNextAffiliate(null); 3770 mTaskPersister.wakeup(first, false); 3771 } 3772 // Everything in the middle is doubly linked from next to prev. 3773 final int tmpSize = mTmpRecents.size(); 3774 for (int i = 0; i < tmpSize - 1; ++i) { 3775 final TaskRecord next = mTmpRecents.get(i); 3776 final TaskRecord prev = mTmpRecents.get(i + 1); 3777 if (next.mPrevAffiliate != prev) { 3778 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3779 " setting prev=" + prev); 3780 next.setPrevAffiliate(prev); 3781 mTaskPersister.wakeup(next, false); 3782 } 3783 if (prev.mNextAffiliate != next) { 3784 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3785 " setting next=" + next); 3786 prev.setNextAffiliate(next); 3787 mTaskPersister.wakeup(prev, false); 3788 } 3789 prev.inRecents = true; 3790 } 3791 // The last one is the beginning of the list and has no prev. 3792 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3793 if (last.mPrevAffiliate != null) { 3794 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3795 last.setPrevAffiliate(null); 3796 mTaskPersister.wakeup(last, false); 3797 } 3798 3799 // Insert the group back into mRecentTasks at start. 3800 mRecentTasks.addAll(start, mTmpRecents); 3801 3802 // Let the caller know where we left off. 3803 return start + tmpSize; 3804 } 3805 3806 /** 3807 * Update the recent tasks lists: make sure tasks should still be here (their 3808 * applications / activities still exist), update their availability, fixup ordering 3809 * of affiliations. 3810 */ 3811 void cleanupRecentTasksLocked(int userId) { 3812 if (mRecentTasks == null) { 3813 // Happens when called from the packagemanager broadcast before boot. 3814 return; 3815 } 3816 3817 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3818 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3819 final IPackageManager pm = AppGlobals.getPackageManager(); 3820 final ActivityInfo dummyAct = new ActivityInfo(); 3821 final ApplicationInfo dummyApp = new ApplicationInfo(); 3822 3823 int N = mRecentTasks.size(); 3824 3825 int[] users = userId == UserHandle.USER_ALL 3826 ? getUsersLocked() : new int[] { userId }; 3827 for (int user : users) { 3828 for (int i = 0; i < N; i++) { 3829 TaskRecord task = mRecentTasks.get(i); 3830 if (task.userId != user) { 3831 // Only look at tasks for the user ID of interest. 3832 continue; 3833 } 3834 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3835 // This situation is broken, and we should just get rid of it now. 3836 mRecentTasks.remove(i); 3837 task.removedFromRecents(mTaskPersister); 3838 i--; 3839 N--; 3840 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3841 continue; 3842 } 3843 // Check whether this activity is currently available. 3844 if (task.realActivity != null) { 3845 ActivityInfo ai = availActCache.get(task.realActivity); 3846 if (ai == null) { 3847 try { 3848 ai = pm.getActivityInfo(task.realActivity, 3849 PackageManager.GET_UNINSTALLED_PACKAGES 3850 | PackageManager.GET_DISABLED_COMPONENTS, user); 3851 } catch (RemoteException e) { 3852 // Will never happen. 3853 continue; 3854 } 3855 if (ai == null) { 3856 ai = dummyAct; 3857 } 3858 availActCache.put(task.realActivity, ai); 3859 } 3860 if (ai == dummyAct) { 3861 // This could be either because the activity no longer exists, or the 3862 // app is temporarily gone. For the former we want to remove the recents 3863 // entry; for the latter we want to mark it as unavailable. 3864 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3865 if (app == null) { 3866 try { 3867 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3868 PackageManager.GET_UNINSTALLED_PACKAGES 3869 | PackageManager.GET_DISABLED_COMPONENTS, user); 3870 } catch (RemoteException e) { 3871 // Will never happen. 3872 continue; 3873 } 3874 if (app == null) { 3875 app = dummyApp; 3876 } 3877 availAppCache.put(task.realActivity.getPackageName(), app); 3878 } 3879 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3880 // Doesn't exist any more! Good-bye. 3881 mRecentTasks.remove(i); 3882 task.removedFromRecents(mTaskPersister); 3883 i--; 3884 N--; 3885 Slog.w(TAG, "Removing no longer valid recent: " + task); 3886 continue; 3887 } else { 3888 // Otherwise just not available for now. 3889 if (task.isAvailable) { 3890 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3891 + task); 3892 } 3893 task.isAvailable = false; 3894 } 3895 } else { 3896 if (!ai.enabled || !ai.applicationInfo.enabled 3897 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3898 if (task.isAvailable) { 3899 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3900 + task + " (enabled=" + ai.enabled + "/" 3901 + ai.applicationInfo.enabled + " flags=" 3902 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3903 } 3904 task.isAvailable = false; 3905 } else { 3906 if (!task.isAvailable) { 3907 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3908 + task); 3909 } 3910 task.isAvailable = true; 3911 } 3912 } 3913 } 3914 } 3915 } 3916 3917 // Verify the affiliate chain for each task. 3918 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3919 } 3920 3921 mTmpRecents.clear(); 3922 // mRecentTasks is now in sorted, affiliated order. 3923 } 3924 3925 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3926 int N = mRecentTasks.size(); 3927 TaskRecord top = task; 3928 int topIndex = taskIndex; 3929 while (top.mNextAffiliate != null && topIndex > 0) { 3930 top = top.mNextAffiliate; 3931 topIndex--; 3932 } 3933 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3934 + topIndex + " from intial " + taskIndex); 3935 // Find the end of the chain, doing a sanity check along the way. 3936 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3937 int endIndex = topIndex; 3938 TaskRecord prev = top; 3939 while (endIndex < N) { 3940 TaskRecord cur = mRecentTasks.get(endIndex); 3941 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3942 + endIndex + " " + cur); 3943 if (cur == top) { 3944 // Verify start of the chain. 3945 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3946 Slog.wtf(TAG, "Bad chain @" + endIndex 3947 + ": first task has next affiliate: " + prev); 3948 sane = false; 3949 break; 3950 } 3951 } else { 3952 // Verify middle of the chain's next points back to the one before. 3953 if (cur.mNextAffiliate != prev 3954 || cur.mNextAffiliateTaskId != prev.taskId) { 3955 Slog.wtf(TAG, "Bad chain @" + endIndex 3956 + ": middle task " + cur + " @" + endIndex 3957 + " has bad next affiliate " 3958 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3959 + ", expected " + prev); 3960 sane = false; 3961 break; 3962 } 3963 } 3964 if (cur.mPrevAffiliateTaskId == -1) { 3965 // Chain ends here. 3966 if (cur.mPrevAffiliate != null) { 3967 Slog.wtf(TAG, "Bad chain @" + endIndex 3968 + ": last task " + cur + " has previous affiliate " 3969 + cur.mPrevAffiliate); 3970 sane = false; 3971 } 3972 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3973 break; 3974 } else { 3975 // Verify middle of the chain's prev points to a valid item. 3976 if (cur.mPrevAffiliate == null) { 3977 Slog.wtf(TAG, "Bad chain @" + endIndex 3978 + ": task " + cur + " has previous affiliate " 3979 + cur.mPrevAffiliate + " but should be id " 3980 + cur.mPrevAffiliate); 3981 sane = false; 3982 break; 3983 } 3984 } 3985 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3986 Slog.wtf(TAG, "Bad chain @" + endIndex 3987 + ": task " + cur + " has affiliated id " 3988 + cur.mAffiliatedTaskId + " but should be " 3989 + task.mAffiliatedTaskId); 3990 sane = false; 3991 break; 3992 } 3993 prev = cur; 3994 endIndex++; 3995 if (endIndex >= N) { 3996 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3997 + ": last task " + prev); 3998 sane = false; 3999 break; 4000 } 4001 } 4002 if (sane) { 4003 if (endIndex < taskIndex) { 4004 Slog.wtf(TAG, "Bad chain @" + endIndex 4005 + ": did not extend to task " + task + " @" + taskIndex); 4006 sane = false; 4007 } 4008 } 4009 if (sane) { 4010 // All looks good, we can just move all of the affiliated tasks 4011 // to the top. 4012 for (int i=topIndex; i<=endIndex; i++) { 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4014 + " from " + i + " to " + (i-topIndex)); 4015 TaskRecord cur = mRecentTasks.remove(i); 4016 mRecentTasks.add(i-topIndex, cur); 4017 } 4018 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4019 + " to " + endIndex); 4020 return true; 4021 } 4022 4023 // Whoops, couldn't do it. 4024 return false; 4025 } 4026 4027 final void addRecentTaskLocked(TaskRecord task) { 4028 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4029 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4030 4031 int N = mRecentTasks.size(); 4032 // Quick case: check if the top-most recent task is the same. 4033 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4034 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4035 return; 4036 } 4037 // Another quick case: check if this is part of a set of affiliated 4038 // tasks that are at the top. 4039 if (isAffiliated && N > 0 && task.inRecents 4040 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4041 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4042 + " at top when adding " + task); 4043 return; 4044 } 4045 // Another quick case: never add voice sessions. 4046 if (task.voiceSession != null) { 4047 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4048 return; 4049 } 4050 4051 boolean needAffiliationFix = false; 4052 4053 // Slightly less quick case: the task is already in recents, so all we need 4054 // to do is move it. 4055 if (task.inRecents) { 4056 int taskIndex = mRecentTasks.indexOf(task); 4057 if (taskIndex >= 0) { 4058 if (!isAffiliated) { 4059 // Simple case: this is not an affiliated task, so we just move it to the front. 4060 mRecentTasks.remove(taskIndex); 4061 mRecentTasks.add(0, task); 4062 notifyTaskPersisterLocked(task, false); 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4064 + " from " + taskIndex); 4065 return; 4066 } else { 4067 // More complicated: need to keep all affiliated tasks together. 4068 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4069 // All went well. 4070 return; 4071 } 4072 4073 // Uh oh... something bad in the affiliation chain, try to rebuild 4074 // everything and then go through our general path of adding a new task. 4075 needAffiliationFix = true; 4076 } 4077 } else { 4078 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4079 needAffiliationFix = true; 4080 } 4081 } 4082 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4084 trimRecentsForTask(task, true); 4085 4086 N = mRecentTasks.size(); 4087 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4088 final TaskRecord tr = mRecentTasks.remove(N - 1); 4089 tr.removedFromRecents(mTaskPersister); 4090 N--; 4091 } 4092 task.inRecents = true; 4093 if (!isAffiliated || needAffiliationFix) { 4094 // If this is a simple non-affiliated task, or we had some failure trying to 4095 // handle it as part of an affilated task, then just place it at the top. 4096 mRecentTasks.add(0, task); 4097 } else if (isAffiliated) { 4098 // If this is a new affiliated task, then move all of the affiliated tasks 4099 // to the front and insert this new one. 4100 TaskRecord other = task.mNextAffiliate; 4101 if (other == null) { 4102 other = task.mPrevAffiliate; 4103 } 4104 if (other != null) { 4105 int otherIndex = mRecentTasks.indexOf(other); 4106 if (otherIndex >= 0) { 4107 // Insert new task at appropriate location. 4108 int taskIndex; 4109 if (other == task.mNextAffiliate) { 4110 // We found the index of our next affiliation, which is who is 4111 // before us in the list, so add after that point. 4112 taskIndex = otherIndex+1; 4113 } else { 4114 // We found the index of our previous affiliation, which is who is 4115 // after us in the list, so add at their position. 4116 taskIndex = otherIndex; 4117 } 4118 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4119 + taskIndex + ": " + task); 4120 mRecentTasks.add(taskIndex, task); 4121 4122 // Now move everything to the front. 4123 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4124 // All went well. 4125 return; 4126 } 4127 4128 // Uh oh... something bad in the affiliation chain, try to rebuild 4129 // everything and then go through our general path of adding a new task. 4130 needAffiliationFix = true; 4131 } else { 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4133 + other); 4134 needAffiliationFix = true; 4135 } 4136 } else { 4137 if (DEBUG_RECENTS) Slog.d(TAG, 4138 "addRecent: adding affiliated task without next/prev:" + task); 4139 needAffiliationFix = true; 4140 } 4141 } 4142 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4143 4144 if (needAffiliationFix) { 4145 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4146 cleanupRecentTasksLocked(task.userId); 4147 } 4148 } 4149 4150 /** 4151 * If needed, remove oldest existing entries in recents that are for the same kind 4152 * of task as the given one. 4153 */ 4154 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4155 int N = mRecentTasks.size(); 4156 final Intent intent = task.intent; 4157 final boolean document = intent != null && intent.isDocument(); 4158 4159 int maxRecents = task.maxRecents - 1; 4160 for (int i=0; i<N; i++) { 4161 final TaskRecord tr = mRecentTasks.get(i); 4162 if (task != tr) { 4163 if (task.userId != tr.userId) { 4164 continue; 4165 } 4166 if (i > MAX_RECENT_BITMAPS) { 4167 tr.freeLastThumbnail(); 4168 } 4169 final Intent trIntent = tr.intent; 4170 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4171 (intent == null || !intent.filterEquals(trIntent))) { 4172 continue; 4173 } 4174 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4175 if (document && trIsDocument) { 4176 // These are the same document activity (not necessarily the same doc). 4177 if (maxRecents > 0) { 4178 --maxRecents; 4179 continue; 4180 } 4181 // Hit the maximum number of documents for this task. Fall through 4182 // and remove this document from recents. 4183 } else if (document || trIsDocument) { 4184 // Only one of these is a document. Not the droid we're looking for. 4185 continue; 4186 } 4187 } 4188 4189 if (!doTrim) { 4190 // If the caller is not actually asking for a trim, just tell them we reached 4191 // a point where the trim would happen. 4192 return i; 4193 } 4194 4195 // Either task and tr are the same or, their affinities match or their intents match 4196 // and neither of them is a document, or they are documents using the same activity 4197 // and their maxRecents has been reached. 4198 tr.disposeThumbnail(); 4199 mRecentTasks.remove(i); 4200 if (task != tr) { 4201 tr.removedFromRecents(mTaskPersister); 4202 } 4203 i--; 4204 N--; 4205 if (task.intent == null) { 4206 // If the new recent task we are adding is not fully 4207 // specified, then replace it with the existing recent task. 4208 task = tr; 4209 } 4210 notifyTaskPersisterLocked(tr, false); 4211 } 4212 4213 return -1; 4214 } 4215 4216 @Override 4217 public void reportActivityFullyDrawn(IBinder token) { 4218 synchronized (this) { 4219 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4220 if (r == null) { 4221 return; 4222 } 4223 r.reportFullyDrawnLocked(); 4224 } 4225 } 4226 4227 @Override 4228 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4229 synchronized (this) { 4230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4231 if (r == null) { 4232 return; 4233 } 4234 final long origId = Binder.clearCallingIdentity(); 4235 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4236 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4237 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4238 if (config != null) { 4239 r.frozenBeforeDestroy = true; 4240 if (!updateConfigurationLocked(config, r, false, false)) { 4241 mStackSupervisor.resumeTopActivitiesLocked(); 4242 } 4243 } 4244 Binder.restoreCallingIdentity(origId); 4245 } 4246 } 4247 4248 @Override 4249 public int getRequestedOrientation(IBinder token) { 4250 synchronized (this) { 4251 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4252 if (r == null) { 4253 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4254 } 4255 return mWindowManager.getAppOrientation(r.appToken); 4256 } 4257 } 4258 4259 /** 4260 * This is the internal entry point for handling Activity.finish(). 4261 * 4262 * @param token The Binder token referencing the Activity we want to finish. 4263 * @param resultCode Result code, if any, from this Activity. 4264 * @param resultData Result data (Intent), if any, from this Activity. 4265 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4266 * the root Activity in the task. 4267 * 4268 * @return Returns true if the activity successfully finished, or false if it is still running. 4269 */ 4270 @Override 4271 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4272 boolean finishTask) { 4273 // Refuse possible leaked file descriptors 4274 if (resultData != null && resultData.hasFileDescriptors() == true) { 4275 throw new IllegalArgumentException("File descriptors passed in Intent"); 4276 } 4277 4278 synchronized(this) { 4279 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4280 if (r == null) { 4281 return true; 4282 } 4283 // Keep track of the root activity of the task before we finish it 4284 TaskRecord tr = r.task; 4285 ActivityRecord rootR = tr.getRootActivity(); 4286 // Do not allow task to finish in Lock Task mode. 4287 if (tr == mStackSupervisor.mLockTaskModeTask) { 4288 if (rootR == r) { 4289 mStackSupervisor.showLockTaskToast(); 4290 return false; 4291 } 4292 } 4293 if (mController != null) { 4294 // Find the first activity that is not finishing. 4295 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4296 if (next != null) { 4297 // ask watcher if this is allowed 4298 boolean resumeOK = true; 4299 try { 4300 resumeOK = mController.activityResuming(next.packageName); 4301 } catch (RemoteException e) { 4302 mController = null; 4303 Watchdog.getInstance().setActivityController(null); 4304 } 4305 4306 if (!resumeOK) { 4307 return false; 4308 } 4309 } 4310 } 4311 final long origId = Binder.clearCallingIdentity(); 4312 try { 4313 boolean res; 4314 if (finishTask && r == rootR) { 4315 // If requested, remove the task that is associated to this activity only if it 4316 // was the root activity in the task. The result code and data is ignored because 4317 // we don't support returning them across task boundaries. 4318 res = removeTaskByIdLocked(tr.taskId, 0); 4319 } else { 4320 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4321 resultData, "app-request", true); 4322 } 4323 return res; 4324 } finally { 4325 Binder.restoreCallingIdentity(origId); 4326 } 4327 } 4328 } 4329 4330 @Override 4331 public final void finishHeavyWeightApp() { 4332 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4333 != PackageManager.PERMISSION_GRANTED) { 4334 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4335 + Binder.getCallingPid() 4336 + ", uid=" + Binder.getCallingUid() 4337 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4338 Slog.w(TAG, msg); 4339 throw new SecurityException(msg); 4340 } 4341 4342 synchronized(this) { 4343 if (mHeavyWeightProcess == null) { 4344 return; 4345 } 4346 4347 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4348 mHeavyWeightProcess.activities); 4349 for (int i=0; i<activities.size(); i++) { 4350 ActivityRecord r = activities.get(i); 4351 if (!r.finishing) { 4352 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4353 null, "finish-heavy", true); 4354 } 4355 } 4356 4357 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4358 mHeavyWeightProcess.userId, 0)); 4359 mHeavyWeightProcess = null; 4360 } 4361 } 4362 4363 @Override 4364 public void crashApplication(int uid, int initialPid, String packageName, 4365 String message) { 4366 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4367 != PackageManager.PERMISSION_GRANTED) { 4368 String msg = "Permission Denial: crashApplication() from pid=" 4369 + Binder.getCallingPid() 4370 + ", uid=" + Binder.getCallingUid() 4371 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4372 Slog.w(TAG, msg); 4373 throw new SecurityException(msg); 4374 } 4375 4376 synchronized(this) { 4377 ProcessRecord proc = null; 4378 4379 // Figure out which process to kill. We don't trust that initialPid 4380 // still has any relation to current pids, so must scan through the 4381 // list. 4382 synchronized (mPidsSelfLocked) { 4383 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4384 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4385 if (p.uid != uid) { 4386 continue; 4387 } 4388 if (p.pid == initialPid) { 4389 proc = p; 4390 break; 4391 } 4392 if (p.pkgList.containsKey(packageName)) { 4393 proc = p; 4394 } 4395 } 4396 } 4397 4398 if (proc == null) { 4399 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4400 + " initialPid=" + initialPid 4401 + " packageName=" + packageName); 4402 return; 4403 } 4404 4405 if (proc.thread != null) { 4406 if (proc.pid == Process.myPid()) { 4407 Log.w(TAG, "crashApplication: trying to crash self!"); 4408 return; 4409 } 4410 long ident = Binder.clearCallingIdentity(); 4411 try { 4412 proc.thread.scheduleCrash(message); 4413 } catch (RemoteException e) { 4414 } 4415 Binder.restoreCallingIdentity(ident); 4416 } 4417 } 4418 } 4419 4420 @Override 4421 public final void finishSubActivity(IBinder token, String resultWho, 4422 int requestCode) { 4423 synchronized(this) { 4424 final long origId = Binder.clearCallingIdentity(); 4425 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4426 if (r != null) { 4427 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4428 } 4429 Binder.restoreCallingIdentity(origId); 4430 } 4431 } 4432 4433 @Override 4434 public boolean finishActivityAffinity(IBinder token) { 4435 synchronized(this) { 4436 final long origId = Binder.clearCallingIdentity(); 4437 try { 4438 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4439 4440 ActivityRecord rootR = r.task.getRootActivity(); 4441 // Do not allow task to finish in Lock Task mode. 4442 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4443 if (rootR == r) { 4444 mStackSupervisor.showLockTaskToast(); 4445 return false; 4446 } 4447 } 4448 boolean res = false; 4449 if (r != null) { 4450 res = r.task.stack.finishActivityAffinityLocked(r); 4451 } 4452 return res; 4453 } finally { 4454 Binder.restoreCallingIdentity(origId); 4455 } 4456 } 4457 } 4458 4459 @Override 4460 public void finishVoiceTask(IVoiceInteractionSession session) { 4461 synchronized(this) { 4462 final long origId = Binder.clearCallingIdentity(); 4463 try { 4464 mStackSupervisor.finishVoiceTask(session); 4465 } finally { 4466 Binder.restoreCallingIdentity(origId); 4467 } 4468 } 4469 4470 } 4471 4472 @Override 4473 public boolean releaseActivityInstance(IBinder token) { 4474 synchronized(this) { 4475 final long origId = Binder.clearCallingIdentity(); 4476 try { 4477 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4478 if (r.task == null || r.task.stack == null) { 4479 return false; 4480 } 4481 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4482 } finally { 4483 Binder.restoreCallingIdentity(origId); 4484 } 4485 } 4486 } 4487 4488 @Override 4489 public void releaseSomeActivities(IApplicationThread appInt) { 4490 synchronized(this) { 4491 final long origId = Binder.clearCallingIdentity(); 4492 try { 4493 ProcessRecord app = getRecordForAppLocked(appInt); 4494 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4495 } finally { 4496 Binder.restoreCallingIdentity(origId); 4497 } 4498 } 4499 } 4500 4501 @Override 4502 public boolean willActivityBeVisible(IBinder token) { 4503 synchronized(this) { 4504 ActivityStack stack = ActivityRecord.getStackLocked(token); 4505 if (stack != null) { 4506 return stack.willActivityBeVisibleLocked(token); 4507 } 4508 return false; 4509 } 4510 } 4511 4512 @Override 4513 public void overridePendingTransition(IBinder token, String packageName, 4514 int enterAnim, int exitAnim) { 4515 synchronized(this) { 4516 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4517 if (self == null) { 4518 return; 4519 } 4520 4521 final long origId = Binder.clearCallingIdentity(); 4522 4523 if (self.state == ActivityState.RESUMED 4524 || self.state == ActivityState.PAUSING) { 4525 mWindowManager.overridePendingAppTransition(packageName, 4526 enterAnim, exitAnim, null); 4527 } 4528 4529 Binder.restoreCallingIdentity(origId); 4530 } 4531 } 4532 4533 /** 4534 * Main function for removing an existing process from the activity manager 4535 * as a result of that process going away. Clears out all connections 4536 * to the process. 4537 */ 4538 private final void handleAppDiedLocked(ProcessRecord app, 4539 boolean restarting, boolean allowRestart) { 4540 int pid = app.pid; 4541 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4542 if (!kept && !restarting) { 4543 removeLruProcessLocked(app); 4544 if (pid > 0) { 4545 ProcessList.remove(pid); 4546 } 4547 } 4548 4549 if (mProfileProc == app) { 4550 clearProfilerLocked(); 4551 } 4552 4553 // Remove this application's activities from active lists. 4554 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4555 4556 app.activities.clear(); 4557 4558 if (app.instrumentationClass != null) { 4559 Slog.w(TAG, "Crash of app " + app.processName 4560 + " running instrumentation " + app.instrumentationClass); 4561 Bundle info = new Bundle(); 4562 info.putString("shortMsg", "Process crashed."); 4563 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4564 } 4565 4566 if (!restarting) { 4567 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4568 // If there was nothing to resume, and we are not already 4569 // restarting this process, but there is a visible activity that 4570 // is hosted by the process... then make sure all visible 4571 // activities are running, taking care of restarting this 4572 // process. 4573 if (hasVisibleActivities) { 4574 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4575 } 4576 } 4577 } 4578 } 4579 4580 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4581 IBinder threadBinder = thread.asBinder(); 4582 // Find the application record. 4583 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4584 ProcessRecord rec = mLruProcesses.get(i); 4585 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4586 return i; 4587 } 4588 } 4589 return -1; 4590 } 4591 4592 final ProcessRecord getRecordForAppLocked( 4593 IApplicationThread thread) { 4594 if (thread == null) { 4595 return null; 4596 } 4597 4598 int appIndex = getLRURecordIndexForAppLocked(thread); 4599 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4600 } 4601 4602 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4603 // If there are no longer any background processes running, 4604 // and the app that died was not running instrumentation, 4605 // then tell everyone we are now low on memory. 4606 boolean haveBg = false; 4607 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4608 ProcessRecord rec = mLruProcesses.get(i); 4609 if (rec.thread != null 4610 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4611 haveBg = true; 4612 break; 4613 } 4614 } 4615 4616 if (!haveBg) { 4617 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4618 if (doReport) { 4619 long now = SystemClock.uptimeMillis(); 4620 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4621 doReport = false; 4622 } else { 4623 mLastMemUsageReportTime = now; 4624 } 4625 } 4626 final ArrayList<ProcessMemInfo> memInfos 4627 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4628 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4629 long now = SystemClock.uptimeMillis(); 4630 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4631 ProcessRecord rec = mLruProcesses.get(i); 4632 if (rec == dyingProc || rec.thread == null) { 4633 continue; 4634 } 4635 if (doReport) { 4636 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4637 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4638 } 4639 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4640 // The low memory report is overriding any current 4641 // state for a GC request. Make sure to do 4642 // heavy/important/visible/foreground processes first. 4643 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4644 rec.lastRequestedGc = 0; 4645 } else { 4646 rec.lastRequestedGc = rec.lastLowMemory; 4647 } 4648 rec.reportLowMemory = true; 4649 rec.lastLowMemory = now; 4650 mProcessesToGc.remove(rec); 4651 addProcessToGcListLocked(rec); 4652 } 4653 } 4654 if (doReport) { 4655 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4656 mHandler.sendMessage(msg); 4657 } 4658 scheduleAppGcsLocked(); 4659 } 4660 } 4661 4662 final void appDiedLocked(ProcessRecord app) { 4663 appDiedLocked(app, app.pid, app.thread); 4664 } 4665 4666 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4667 // First check if this ProcessRecord is actually active for the pid. 4668 synchronized (mPidsSelfLocked) { 4669 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4670 if (curProc != app) { 4671 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4672 return; 4673 } 4674 } 4675 4676 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4677 synchronized (stats) { 4678 stats.noteProcessDiedLocked(app.info.uid, pid); 4679 } 4680 4681 Process.killProcessQuiet(pid); 4682 Process.killProcessGroup(app.info.uid, pid); 4683 app.killed = true; 4684 4685 // Clean up already done if the process has been re-started. 4686 if (app.pid == pid && app.thread != null && 4687 app.thread.asBinder() == thread.asBinder()) { 4688 boolean doLowMem = app.instrumentationClass == null; 4689 boolean doOomAdj = doLowMem; 4690 if (!app.killedByAm) { 4691 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4692 + ") has died"); 4693 mAllowLowerMemLevel = true; 4694 } else { 4695 // Note that we always want to do oom adj to update our state with the 4696 // new number of procs. 4697 mAllowLowerMemLevel = false; 4698 doLowMem = false; 4699 } 4700 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4701 if (DEBUG_CLEANUP) Slog.v( 4702 TAG, "Dying app: " + app + ", pid: " + pid 4703 + ", thread: " + thread.asBinder()); 4704 handleAppDiedLocked(app, false, true); 4705 4706 if (doOomAdj) { 4707 updateOomAdjLocked(); 4708 } 4709 if (doLowMem) { 4710 doLowMemReportIfNeededLocked(app); 4711 } 4712 } else if (app.pid != pid) { 4713 // A new process has already been started. 4714 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4715 + ") has died and restarted (pid " + app.pid + ")."); 4716 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4717 } else if (DEBUG_PROCESSES) { 4718 Slog.d(TAG, "Received spurious death notification for thread " 4719 + thread.asBinder()); 4720 } 4721 } 4722 4723 /** 4724 * If a stack trace dump file is configured, dump process stack traces. 4725 * @param clearTraces causes the dump file to be erased prior to the new 4726 * traces being written, if true; when false, the new traces will be 4727 * appended to any existing file content. 4728 * @param firstPids of dalvik VM processes to dump stack traces for first 4729 * @param lastPids of dalvik VM processes to dump stack traces for last 4730 * @param nativeProcs optional list of native process names to dump stack crawls 4731 * @return file containing stack traces, or null if no dump file is configured 4732 */ 4733 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4734 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4735 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4736 if (tracesPath == null || tracesPath.length() == 0) { 4737 return null; 4738 } 4739 4740 File tracesFile = new File(tracesPath); 4741 try { 4742 File tracesDir = tracesFile.getParentFile(); 4743 if (!tracesDir.exists()) { 4744 tracesDir.mkdirs(); 4745 if (!SELinux.restorecon(tracesDir)) { 4746 return null; 4747 } 4748 } 4749 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4750 4751 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4752 tracesFile.createNewFile(); 4753 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4754 } catch (IOException e) { 4755 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4756 return null; 4757 } 4758 4759 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4760 return tracesFile; 4761 } 4762 4763 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4764 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4765 // Use a FileObserver to detect when traces finish writing. 4766 // The order of traces is considered important to maintain for legibility. 4767 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4768 @Override 4769 public synchronized void onEvent(int event, String path) { notify(); } 4770 }; 4771 4772 try { 4773 observer.startWatching(); 4774 4775 // First collect all of the stacks of the most important pids. 4776 if (firstPids != null) { 4777 try { 4778 int num = firstPids.size(); 4779 for (int i = 0; i < num; i++) { 4780 synchronized (observer) { 4781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4782 observer.wait(200); // Wait for write-close, give up after 200msec 4783 } 4784 } 4785 } catch (InterruptedException e) { 4786 Slog.wtf(TAG, e); 4787 } 4788 } 4789 4790 // Next collect the stacks of the native pids 4791 if (nativeProcs != null) { 4792 int[] pids = Process.getPidsForCommands(nativeProcs); 4793 if (pids != null) { 4794 for (int pid : pids) { 4795 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4796 } 4797 } 4798 } 4799 4800 // Lastly, measure CPU usage. 4801 if (processCpuTracker != null) { 4802 processCpuTracker.init(); 4803 System.gc(); 4804 processCpuTracker.update(); 4805 try { 4806 synchronized (processCpuTracker) { 4807 processCpuTracker.wait(500); // measure over 1/2 second. 4808 } 4809 } catch (InterruptedException e) { 4810 } 4811 processCpuTracker.update(); 4812 4813 // We'll take the stack crawls of just the top apps using CPU. 4814 final int N = processCpuTracker.countWorkingStats(); 4815 int numProcs = 0; 4816 for (int i=0; i<N && numProcs<5; i++) { 4817 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4818 if (lastPids.indexOfKey(stats.pid) >= 0) { 4819 numProcs++; 4820 try { 4821 synchronized (observer) { 4822 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4823 observer.wait(200); // Wait for write-close, give up after 200msec 4824 } 4825 } catch (InterruptedException e) { 4826 Slog.wtf(TAG, e); 4827 } 4828 4829 } 4830 } 4831 } 4832 } finally { 4833 observer.stopWatching(); 4834 } 4835 } 4836 4837 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4838 if (true || IS_USER_BUILD) { 4839 return; 4840 } 4841 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4842 if (tracesPath == null || tracesPath.length() == 0) { 4843 return; 4844 } 4845 4846 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4847 StrictMode.allowThreadDiskWrites(); 4848 try { 4849 final File tracesFile = new File(tracesPath); 4850 final File tracesDir = tracesFile.getParentFile(); 4851 final File tracesTmp = new File(tracesDir, "__tmp__"); 4852 try { 4853 if (!tracesDir.exists()) { 4854 tracesDir.mkdirs(); 4855 if (!SELinux.restorecon(tracesDir.getPath())) { 4856 return; 4857 } 4858 } 4859 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4860 4861 if (tracesFile.exists()) { 4862 tracesTmp.delete(); 4863 tracesFile.renameTo(tracesTmp); 4864 } 4865 StringBuilder sb = new StringBuilder(); 4866 Time tobj = new Time(); 4867 tobj.set(System.currentTimeMillis()); 4868 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4869 sb.append(": "); 4870 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4871 sb.append(" since "); 4872 sb.append(msg); 4873 FileOutputStream fos = new FileOutputStream(tracesFile); 4874 fos.write(sb.toString().getBytes()); 4875 if (app == null) { 4876 fos.write("\n*** No application process!".getBytes()); 4877 } 4878 fos.close(); 4879 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4880 } catch (IOException e) { 4881 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4882 return; 4883 } 4884 4885 if (app != null) { 4886 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4887 firstPids.add(app.pid); 4888 dumpStackTraces(tracesPath, firstPids, null, null, null); 4889 } 4890 4891 File lastTracesFile = null; 4892 File curTracesFile = null; 4893 for (int i=9; i>=0; i--) { 4894 String name = String.format(Locale.US, "slow%02d.txt", i); 4895 curTracesFile = new File(tracesDir, name); 4896 if (curTracesFile.exists()) { 4897 if (lastTracesFile != null) { 4898 curTracesFile.renameTo(lastTracesFile); 4899 } else { 4900 curTracesFile.delete(); 4901 } 4902 } 4903 lastTracesFile = curTracesFile; 4904 } 4905 tracesFile.renameTo(curTracesFile); 4906 if (tracesTmp.exists()) { 4907 tracesTmp.renameTo(tracesFile); 4908 } 4909 } finally { 4910 StrictMode.setThreadPolicy(oldPolicy); 4911 } 4912 } 4913 4914 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4915 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4916 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4917 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4918 4919 if (mController != null) { 4920 try { 4921 // 0 == continue, -1 = kill process immediately 4922 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4923 if (res < 0 && app.pid != MY_PID) { 4924 app.kill("anr", true); 4925 } 4926 } catch (RemoteException e) { 4927 mController = null; 4928 Watchdog.getInstance().setActivityController(null); 4929 } 4930 } 4931 4932 long anrTime = SystemClock.uptimeMillis(); 4933 if (MONITOR_CPU_USAGE) { 4934 updateCpuStatsNow(); 4935 } 4936 4937 synchronized (this) { 4938 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4939 if (mShuttingDown) { 4940 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4941 return; 4942 } else if (app.notResponding) { 4943 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4944 return; 4945 } else if (app.crashing) { 4946 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4947 return; 4948 } 4949 4950 // In case we come through here for the same app before completing 4951 // this one, mark as anring now so we will bail out. 4952 app.notResponding = true; 4953 4954 // Log the ANR to the event log. 4955 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4956 app.processName, app.info.flags, annotation); 4957 4958 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4959 firstPids.add(app.pid); 4960 4961 int parentPid = app.pid; 4962 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4963 if (parentPid != app.pid) firstPids.add(parentPid); 4964 4965 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4966 4967 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4968 ProcessRecord r = mLruProcesses.get(i); 4969 if (r != null && r.thread != null) { 4970 int pid = r.pid; 4971 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4972 if (r.persistent) { 4973 firstPids.add(pid); 4974 } else { 4975 lastPids.put(pid, Boolean.TRUE); 4976 } 4977 } 4978 } 4979 } 4980 } 4981 4982 // Log the ANR to the main log. 4983 StringBuilder info = new StringBuilder(); 4984 info.setLength(0); 4985 info.append("ANR in ").append(app.processName); 4986 if (activity != null && activity.shortComponentName != null) { 4987 info.append(" (").append(activity.shortComponentName).append(")"); 4988 } 4989 info.append("\n"); 4990 info.append("PID: ").append(app.pid).append("\n"); 4991 if (annotation != null) { 4992 info.append("Reason: ").append(annotation).append("\n"); 4993 } 4994 if (parent != null && parent != activity) { 4995 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4996 } 4997 4998 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4999 5000 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5001 NATIVE_STACKS_OF_INTEREST); 5002 5003 String cpuInfo = null; 5004 if (MONITOR_CPU_USAGE) { 5005 updateCpuStatsNow(); 5006 synchronized (mProcessCpuTracker) { 5007 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5008 } 5009 info.append(processCpuTracker.printCurrentLoad()); 5010 info.append(cpuInfo); 5011 } 5012 5013 info.append(processCpuTracker.printCurrentState(anrTime)); 5014 5015 Slog.e(TAG, info.toString()); 5016 if (tracesFile == null) { 5017 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5018 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5019 } 5020 5021 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5022 cpuInfo, tracesFile, null); 5023 5024 if (mController != null) { 5025 try { 5026 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5027 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5028 if (res != 0) { 5029 if (res < 0 && app.pid != MY_PID) { 5030 app.kill("anr", true); 5031 } else { 5032 synchronized (this) { 5033 mServices.scheduleServiceTimeoutLocked(app); 5034 } 5035 } 5036 return; 5037 } 5038 } catch (RemoteException e) { 5039 mController = null; 5040 Watchdog.getInstance().setActivityController(null); 5041 } 5042 } 5043 5044 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5045 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5046 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5047 5048 synchronized (this) { 5049 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5050 app.kill("bg anr", true); 5051 return; 5052 } 5053 5054 // Set the app's notResponding state, and look up the errorReportReceiver 5055 makeAppNotRespondingLocked(app, 5056 activity != null ? activity.shortComponentName : null, 5057 annotation != null ? "ANR " + annotation : "ANR", 5058 info.toString()); 5059 5060 // Bring up the infamous App Not Responding dialog 5061 Message msg = Message.obtain(); 5062 HashMap<String, Object> map = new HashMap<String, Object>(); 5063 msg.what = SHOW_NOT_RESPONDING_MSG; 5064 msg.obj = map; 5065 msg.arg1 = aboveSystem ? 1 : 0; 5066 map.put("app", app); 5067 if (activity != null) { 5068 map.put("activity", activity); 5069 } 5070 5071 mHandler.sendMessage(msg); 5072 } 5073 } 5074 5075 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5076 if (!mLaunchWarningShown) { 5077 mLaunchWarningShown = true; 5078 mHandler.post(new Runnable() { 5079 @Override 5080 public void run() { 5081 synchronized (ActivityManagerService.this) { 5082 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5083 d.show(); 5084 mHandler.postDelayed(new Runnable() { 5085 @Override 5086 public void run() { 5087 synchronized (ActivityManagerService.this) { 5088 d.dismiss(); 5089 mLaunchWarningShown = false; 5090 } 5091 } 5092 }, 4000); 5093 } 5094 } 5095 }); 5096 } 5097 } 5098 5099 @Override 5100 public boolean clearApplicationUserData(final String packageName, 5101 final IPackageDataObserver observer, int userId) { 5102 enforceNotIsolatedCaller("clearApplicationUserData"); 5103 int uid = Binder.getCallingUid(); 5104 int pid = Binder.getCallingPid(); 5105 userId = handleIncomingUser(pid, uid, 5106 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5107 long callingId = Binder.clearCallingIdentity(); 5108 try { 5109 IPackageManager pm = AppGlobals.getPackageManager(); 5110 int pkgUid = -1; 5111 synchronized(this) { 5112 try { 5113 pkgUid = pm.getPackageUid(packageName, userId); 5114 } catch (RemoteException e) { 5115 } 5116 if (pkgUid == -1) { 5117 Slog.w(TAG, "Invalid packageName: " + packageName); 5118 if (observer != null) { 5119 try { 5120 observer.onRemoveCompleted(packageName, false); 5121 } catch (RemoteException e) { 5122 Slog.i(TAG, "Observer no longer exists."); 5123 } 5124 } 5125 return false; 5126 } 5127 if (uid == pkgUid || checkComponentPermission( 5128 android.Manifest.permission.CLEAR_APP_USER_DATA, 5129 pid, uid, -1, true) 5130 == PackageManager.PERMISSION_GRANTED) { 5131 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5132 } else { 5133 throw new SecurityException("PID " + pid + " does not have permission " 5134 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5135 + " of package " + packageName); 5136 } 5137 5138 // Remove all tasks match the cleared application package and user 5139 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5140 final TaskRecord tr = mRecentTasks.get(i); 5141 final String taskPackageName = 5142 tr.getBaseIntent().getComponent().getPackageName(); 5143 if (tr.userId != userId) continue; 5144 if (!taskPackageName.equals(packageName)) continue; 5145 removeTaskByIdLocked(tr.taskId, 0); 5146 } 5147 } 5148 5149 try { 5150 // Clear application user data 5151 pm.clearApplicationUserData(packageName, observer, userId); 5152 5153 synchronized(this) { 5154 // Remove all permissions granted from/to this package 5155 removeUriPermissionsForPackageLocked(packageName, userId, true); 5156 } 5157 5158 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5159 Uri.fromParts("package", packageName, null)); 5160 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5161 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5162 null, null, 0, null, null, null, false, false, userId); 5163 } catch (RemoteException e) { 5164 } 5165 } finally { 5166 Binder.restoreCallingIdentity(callingId); 5167 } 5168 return true; 5169 } 5170 5171 @Override 5172 public void killBackgroundProcesses(final String packageName, int userId) { 5173 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5174 != PackageManager.PERMISSION_GRANTED && 5175 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5176 != PackageManager.PERMISSION_GRANTED) { 5177 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5178 + Binder.getCallingPid() 5179 + ", uid=" + Binder.getCallingUid() 5180 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5181 Slog.w(TAG, msg); 5182 throw new SecurityException(msg); 5183 } 5184 5185 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5186 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5187 long callingId = Binder.clearCallingIdentity(); 5188 try { 5189 IPackageManager pm = AppGlobals.getPackageManager(); 5190 synchronized(this) { 5191 int appId = -1; 5192 try { 5193 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5194 } catch (RemoteException e) { 5195 } 5196 if (appId == -1) { 5197 Slog.w(TAG, "Invalid packageName: " + packageName); 5198 return; 5199 } 5200 killPackageProcessesLocked(packageName, appId, userId, 5201 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5202 } 5203 } finally { 5204 Binder.restoreCallingIdentity(callingId); 5205 } 5206 } 5207 5208 @Override 5209 public void killAllBackgroundProcesses() { 5210 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5211 != PackageManager.PERMISSION_GRANTED) { 5212 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5213 + Binder.getCallingPid() 5214 + ", uid=" + Binder.getCallingUid() 5215 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5216 Slog.w(TAG, msg); 5217 throw new SecurityException(msg); 5218 } 5219 5220 long callingId = Binder.clearCallingIdentity(); 5221 try { 5222 synchronized(this) { 5223 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5224 final int NP = mProcessNames.getMap().size(); 5225 for (int ip=0; ip<NP; ip++) { 5226 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5227 final int NA = apps.size(); 5228 for (int ia=0; ia<NA; ia++) { 5229 ProcessRecord app = apps.valueAt(ia); 5230 if (app.persistent) { 5231 // we don't kill persistent processes 5232 continue; 5233 } 5234 if (app.removed) { 5235 procs.add(app); 5236 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5237 app.removed = true; 5238 procs.add(app); 5239 } 5240 } 5241 } 5242 5243 int N = procs.size(); 5244 for (int i=0; i<N; i++) { 5245 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5246 } 5247 mAllowLowerMemLevel = true; 5248 updateOomAdjLocked(); 5249 doLowMemReportIfNeededLocked(null); 5250 } 5251 } finally { 5252 Binder.restoreCallingIdentity(callingId); 5253 } 5254 } 5255 5256 @Override 5257 public void forceStopPackage(final String packageName, int userId) { 5258 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5259 != PackageManager.PERMISSION_GRANTED) { 5260 String msg = "Permission Denial: forceStopPackage() from pid=" 5261 + Binder.getCallingPid() 5262 + ", uid=" + Binder.getCallingUid() 5263 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5264 Slog.w(TAG, msg); 5265 throw new SecurityException(msg); 5266 } 5267 final int callingPid = Binder.getCallingPid(); 5268 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5269 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5270 long callingId = Binder.clearCallingIdentity(); 5271 try { 5272 IPackageManager pm = AppGlobals.getPackageManager(); 5273 synchronized(this) { 5274 int[] users = userId == UserHandle.USER_ALL 5275 ? getUsersLocked() : new int[] { userId }; 5276 for (int user : users) { 5277 int pkgUid = -1; 5278 try { 5279 pkgUid = pm.getPackageUid(packageName, user); 5280 } catch (RemoteException e) { 5281 } 5282 if (pkgUid == -1) { 5283 Slog.w(TAG, "Invalid packageName: " + packageName); 5284 continue; 5285 } 5286 try { 5287 pm.setPackageStoppedState(packageName, true, user); 5288 } catch (RemoteException e) { 5289 } catch (IllegalArgumentException e) { 5290 Slog.w(TAG, "Failed trying to unstop package " 5291 + packageName + ": " + e); 5292 } 5293 if (isUserRunningLocked(user, false)) { 5294 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5295 } 5296 } 5297 } 5298 } finally { 5299 Binder.restoreCallingIdentity(callingId); 5300 } 5301 } 5302 5303 @Override 5304 public void addPackageDependency(String packageName) { 5305 synchronized (this) { 5306 int callingPid = Binder.getCallingPid(); 5307 if (callingPid == Process.myPid()) { 5308 // Yeah, um, no. 5309 Slog.w(TAG, "Can't addPackageDependency on system process"); 5310 return; 5311 } 5312 ProcessRecord proc; 5313 synchronized (mPidsSelfLocked) { 5314 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5315 } 5316 if (proc != null) { 5317 if (proc.pkgDeps == null) { 5318 proc.pkgDeps = new ArraySet<String>(1); 5319 } 5320 proc.pkgDeps.add(packageName); 5321 } 5322 } 5323 } 5324 5325 /* 5326 * The pkg name and app id have to be specified. 5327 */ 5328 @Override 5329 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5330 if (pkg == null) { 5331 return; 5332 } 5333 // Make sure the uid is valid. 5334 if (appid < 0) { 5335 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5336 return; 5337 } 5338 int callerUid = Binder.getCallingUid(); 5339 // Only the system server can kill an application 5340 if (callerUid == Process.SYSTEM_UID) { 5341 // Post an aysnc message to kill the application 5342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5343 msg.arg1 = appid; 5344 msg.arg2 = 0; 5345 Bundle bundle = new Bundle(); 5346 bundle.putString("pkg", pkg); 5347 bundle.putString("reason", reason); 5348 msg.obj = bundle; 5349 mHandler.sendMessage(msg); 5350 } else { 5351 throw new SecurityException(callerUid + " cannot kill pkg: " + 5352 pkg); 5353 } 5354 } 5355 5356 @Override 5357 public void closeSystemDialogs(String reason) { 5358 enforceNotIsolatedCaller("closeSystemDialogs"); 5359 5360 final int pid = Binder.getCallingPid(); 5361 final int uid = Binder.getCallingUid(); 5362 final long origId = Binder.clearCallingIdentity(); 5363 try { 5364 synchronized (this) { 5365 // Only allow this from foreground processes, so that background 5366 // applications can't abuse it to prevent system UI from being shown. 5367 if (uid >= Process.FIRST_APPLICATION_UID) { 5368 ProcessRecord proc; 5369 synchronized (mPidsSelfLocked) { 5370 proc = mPidsSelfLocked.get(pid); 5371 } 5372 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5373 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5374 + " from background process " + proc); 5375 return; 5376 } 5377 } 5378 closeSystemDialogsLocked(reason); 5379 } 5380 } finally { 5381 Binder.restoreCallingIdentity(origId); 5382 } 5383 } 5384 5385 void closeSystemDialogsLocked(String reason) { 5386 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5387 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5388 | Intent.FLAG_RECEIVER_FOREGROUND); 5389 if (reason != null) { 5390 intent.putExtra("reason", reason); 5391 } 5392 mWindowManager.closeSystemDialogs(reason); 5393 5394 mStackSupervisor.closeSystemDialogsLocked(); 5395 5396 broadcastIntentLocked(null, null, intent, null, 5397 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5398 Process.SYSTEM_UID, UserHandle.USER_ALL); 5399 } 5400 5401 @Override 5402 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5403 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5404 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5405 for (int i=pids.length-1; i>=0; i--) { 5406 ProcessRecord proc; 5407 int oomAdj; 5408 synchronized (this) { 5409 synchronized (mPidsSelfLocked) { 5410 proc = mPidsSelfLocked.get(pids[i]); 5411 oomAdj = proc != null ? proc.setAdj : 0; 5412 } 5413 } 5414 infos[i] = new Debug.MemoryInfo(); 5415 Debug.getMemoryInfo(pids[i], infos[i]); 5416 if (proc != null) { 5417 synchronized (this) { 5418 if (proc.thread != null && proc.setAdj == oomAdj) { 5419 // Record this for posterity if the process has been stable. 5420 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5421 infos[i].getTotalUss(), false, proc.pkgList); 5422 } 5423 } 5424 } 5425 } 5426 return infos; 5427 } 5428 5429 @Override 5430 public long[] getProcessPss(int[] pids) { 5431 enforceNotIsolatedCaller("getProcessPss"); 5432 long[] pss = new long[pids.length]; 5433 for (int i=pids.length-1; i>=0; i--) { 5434 ProcessRecord proc; 5435 int oomAdj; 5436 synchronized (this) { 5437 synchronized (mPidsSelfLocked) { 5438 proc = mPidsSelfLocked.get(pids[i]); 5439 oomAdj = proc != null ? proc.setAdj : 0; 5440 } 5441 } 5442 long[] tmpUss = new long[1]; 5443 pss[i] = Debug.getPss(pids[i], tmpUss); 5444 if (proc != null) { 5445 synchronized (this) { 5446 if (proc.thread != null && proc.setAdj == oomAdj) { 5447 // Record this for posterity if the process has been stable. 5448 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5449 } 5450 } 5451 } 5452 } 5453 return pss; 5454 } 5455 5456 @Override 5457 public void killApplicationProcess(String processName, int uid) { 5458 if (processName == null) { 5459 return; 5460 } 5461 5462 int callerUid = Binder.getCallingUid(); 5463 // Only the system server can kill an application 5464 if (callerUid == Process.SYSTEM_UID) { 5465 synchronized (this) { 5466 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5467 if (app != null && app.thread != null) { 5468 try { 5469 app.thread.scheduleSuicide(); 5470 } catch (RemoteException e) { 5471 // If the other end already died, then our work here is done. 5472 } 5473 } else { 5474 Slog.w(TAG, "Process/uid not found attempting kill of " 5475 + processName + " / " + uid); 5476 } 5477 } 5478 } else { 5479 throw new SecurityException(callerUid + " cannot kill app process: " + 5480 processName); 5481 } 5482 } 5483 5484 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5485 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5486 false, true, false, false, UserHandle.getUserId(uid), reason); 5487 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5488 Uri.fromParts("package", packageName, null)); 5489 if (!mProcessesReady) { 5490 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5491 | Intent.FLAG_RECEIVER_FOREGROUND); 5492 } 5493 intent.putExtra(Intent.EXTRA_UID, uid); 5494 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5495 broadcastIntentLocked(null, null, intent, 5496 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5497 false, false, 5498 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5499 } 5500 5501 private void forceStopUserLocked(int userId, String reason) { 5502 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5503 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5505 | Intent.FLAG_RECEIVER_FOREGROUND); 5506 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5507 broadcastIntentLocked(null, null, intent, 5508 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5509 false, false, 5510 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5511 } 5512 5513 private final boolean killPackageProcessesLocked(String packageName, int appId, 5514 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5515 boolean doit, boolean evenPersistent, String reason) { 5516 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5517 5518 // Remove all processes this package may have touched: all with the 5519 // same UID (except for the system or root user), and all whose name 5520 // matches the package name. 5521 final int NP = mProcessNames.getMap().size(); 5522 for (int ip=0; ip<NP; ip++) { 5523 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5524 final int NA = apps.size(); 5525 for (int ia=0; ia<NA; ia++) { 5526 ProcessRecord app = apps.valueAt(ia); 5527 if (app.persistent && !evenPersistent) { 5528 // we don't kill persistent processes 5529 continue; 5530 } 5531 if (app.removed) { 5532 if (doit) { 5533 procs.add(app); 5534 } 5535 continue; 5536 } 5537 5538 // Skip process if it doesn't meet our oom adj requirement. 5539 if (app.setAdj < minOomAdj) { 5540 continue; 5541 } 5542 5543 // If no package is specified, we call all processes under the 5544 // give user id. 5545 if (packageName == null) { 5546 if (app.userId != userId) { 5547 continue; 5548 } 5549 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5550 continue; 5551 } 5552 // Package has been specified, we want to hit all processes 5553 // that match it. We need to qualify this by the processes 5554 // that are running under the specified app and user ID. 5555 } else { 5556 final boolean isDep = app.pkgDeps != null 5557 && app.pkgDeps.contains(packageName); 5558 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5559 continue; 5560 } 5561 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5562 continue; 5563 } 5564 if (!app.pkgList.containsKey(packageName) && !isDep) { 5565 continue; 5566 } 5567 } 5568 5569 // Process has passed all conditions, kill it! 5570 if (!doit) { 5571 return true; 5572 } 5573 app.removed = true; 5574 procs.add(app); 5575 } 5576 } 5577 5578 int N = procs.size(); 5579 for (int i=0; i<N; i++) { 5580 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5581 } 5582 updateOomAdjLocked(); 5583 return N > 0; 5584 } 5585 5586 private final boolean forceStopPackageLocked(String name, int appId, 5587 boolean callerWillRestart, boolean purgeCache, boolean doit, 5588 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5589 int i; 5590 int N; 5591 5592 if (userId == UserHandle.USER_ALL && name == null) { 5593 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5594 } 5595 5596 if (appId < 0 && name != null) { 5597 try { 5598 appId = UserHandle.getAppId( 5599 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5600 } catch (RemoteException e) { 5601 } 5602 } 5603 5604 if (doit) { 5605 if (name != null) { 5606 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5607 + " user=" + userId + ": " + reason); 5608 } else { 5609 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5610 } 5611 5612 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5613 for (int ip=pmap.size()-1; ip>=0; ip--) { 5614 SparseArray<Long> ba = pmap.valueAt(ip); 5615 for (i=ba.size()-1; i>=0; i--) { 5616 boolean remove = false; 5617 final int entUid = ba.keyAt(i); 5618 if (name != null) { 5619 if (userId == UserHandle.USER_ALL) { 5620 if (UserHandle.getAppId(entUid) == appId) { 5621 remove = true; 5622 } 5623 } else { 5624 if (entUid == UserHandle.getUid(userId, appId)) { 5625 remove = true; 5626 } 5627 } 5628 } else if (UserHandle.getUserId(entUid) == userId) { 5629 remove = true; 5630 } 5631 if (remove) { 5632 ba.removeAt(i); 5633 } 5634 } 5635 if (ba.size() == 0) { 5636 pmap.removeAt(ip); 5637 } 5638 } 5639 } 5640 5641 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5642 -100, callerWillRestart, true, doit, evenPersistent, 5643 name == null ? ("stop user " + userId) : ("stop " + name)); 5644 5645 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5646 if (!doit) { 5647 return true; 5648 } 5649 didSomething = true; 5650 } 5651 5652 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5653 if (!doit) { 5654 return true; 5655 } 5656 didSomething = true; 5657 } 5658 5659 if (name == null) { 5660 // Remove all sticky broadcasts from this user. 5661 mStickyBroadcasts.remove(userId); 5662 } 5663 5664 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5665 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5666 userId, providers)) { 5667 if (!doit) { 5668 return true; 5669 } 5670 didSomething = true; 5671 } 5672 N = providers.size(); 5673 for (i=0; i<N; i++) { 5674 removeDyingProviderLocked(null, providers.get(i), true); 5675 } 5676 5677 // Remove transient permissions granted from/to this package/user 5678 removeUriPermissionsForPackageLocked(name, userId, false); 5679 5680 if (name == null || uninstalling) { 5681 // Remove pending intents. For now we only do this when force 5682 // stopping users, because we have some problems when doing this 5683 // for packages -- app widgets are not currently cleaned up for 5684 // such packages, so they can be left with bad pending intents. 5685 if (mIntentSenderRecords.size() > 0) { 5686 Iterator<WeakReference<PendingIntentRecord>> it 5687 = mIntentSenderRecords.values().iterator(); 5688 while (it.hasNext()) { 5689 WeakReference<PendingIntentRecord> wpir = it.next(); 5690 if (wpir == null) { 5691 it.remove(); 5692 continue; 5693 } 5694 PendingIntentRecord pir = wpir.get(); 5695 if (pir == null) { 5696 it.remove(); 5697 continue; 5698 } 5699 if (name == null) { 5700 // Stopping user, remove all objects for the user. 5701 if (pir.key.userId != userId) { 5702 // Not the same user, skip it. 5703 continue; 5704 } 5705 } else { 5706 if (UserHandle.getAppId(pir.uid) != appId) { 5707 // Different app id, skip it. 5708 continue; 5709 } 5710 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5711 // Different user, skip it. 5712 continue; 5713 } 5714 if (!pir.key.packageName.equals(name)) { 5715 // Different package, skip it. 5716 continue; 5717 } 5718 } 5719 if (!doit) { 5720 return true; 5721 } 5722 didSomething = true; 5723 it.remove(); 5724 pir.canceled = true; 5725 if (pir.key.activity != null) { 5726 pir.key.activity.pendingResults.remove(pir.ref); 5727 } 5728 } 5729 } 5730 } 5731 5732 if (doit) { 5733 if (purgeCache && name != null) { 5734 AttributeCache ac = AttributeCache.instance(); 5735 if (ac != null) { 5736 ac.removePackage(name); 5737 } 5738 } 5739 if (mBooted) { 5740 mStackSupervisor.resumeTopActivitiesLocked(); 5741 mStackSupervisor.scheduleIdleLocked(); 5742 } 5743 } 5744 5745 return didSomething; 5746 } 5747 5748 private final boolean removeProcessLocked(ProcessRecord app, 5749 boolean callerWillRestart, boolean allowRestart, String reason) { 5750 final String name = app.processName; 5751 final int uid = app.uid; 5752 if (DEBUG_PROCESSES) Slog.d( 5753 TAG, "Force removing proc " + app.toShortString() + " (" + name 5754 + "/" + uid + ")"); 5755 5756 mProcessNames.remove(name, uid); 5757 mIsolatedProcesses.remove(app.uid); 5758 if (mHeavyWeightProcess == app) { 5759 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5760 mHeavyWeightProcess.userId, 0)); 5761 mHeavyWeightProcess = null; 5762 } 5763 boolean needRestart = false; 5764 if (app.pid > 0 && app.pid != MY_PID) { 5765 int pid = app.pid; 5766 synchronized (mPidsSelfLocked) { 5767 mPidsSelfLocked.remove(pid); 5768 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5769 } 5770 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5771 if (app.isolated) { 5772 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5773 } 5774 app.kill(reason, true); 5775 handleAppDiedLocked(app, true, allowRestart); 5776 removeLruProcessLocked(app); 5777 5778 if (app.persistent && !app.isolated) { 5779 if (!callerWillRestart) { 5780 addAppLocked(app.info, false, null /* ABI override */); 5781 } else { 5782 needRestart = true; 5783 } 5784 } 5785 } else { 5786 mRemovedProcesses.add(app); 5787 } 5788 5789 return needRestart; 5790 } 5791 5792 private final void processStartTimedOutLocked(ProcessRecord app) { 5793 final int pid = app.pid; 5794 boolean gone = false; 5795 synchronized (mPidsSelfLocked) { 5796 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5797 if (knownApp != null && knownApp.thread == null) { 5798 mPidsSelfLocked.remove(pid); 5799 gone = true; 5800 } 5801 } 5802 5803 if (gone) { 5804 Slog.w(TAG, "Process " + app + " failed to attach"); 5805 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5806 pid, app.uid, app.processName); 5807 mProcessNames.remove(app.processName, app.uid); 5808 mIsolatedProcesses.remove(app.uid); 5809 if (mHeavyWeightProcess == app) { 5810 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5811 mHeavyWeightProcess.userId, 0)); 5812 mHeavyWeightProcess = null; 5813 } 5814 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5815 if (app.isolated) { 5816 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5817 } 5818 // Take care of any launching providers waiting for this process. 5819 checkAppInLaunchingProvidersLocked(app, true); 5820 // Take care of any services that are waiting for the process. 5821 mServices.processStartTimedOutLocked(app); 5822 app.kill("start timeout", true); 5823 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5824 Slog.w(TAG, "Unattached app died before backup, skipping"); 5825 try { 5826 IBackupManager bm = IBackupManager.Stub.asInterface( 5827 ServiceManager.getService(Context.BACKUP_SERVICE)); 5828 bm.agentDisconnected(app.info.packageName); 5829 } catch (RemoteException e) { 5830 // Can't happen; the backup manager is local 5831 } 5832 } 5833 if (isPendingBroadcastProcessLocked(pid)) { 5834 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5835 skipPendingBroadcastLocked(pid); 5836 } 5837 } else { 5838 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5839 } 5840 } 5841 5842 private final boolean attachApplicationLocked(IApplicationThread thread, 5843 int pid) { 5844 5845 // Find the application record that is being attached... either via 5846 // the pid if we are running in multiple processes, or just pull the 5847 // next app record if we are emulating process with anonymous threads. 5848 ProcessRecord app; 5849 if (pid != MY_PID && pid >= 0) { 5850 synchronized (mPidsSelfLocked) { 5851 app = mPidsSelfLocked.get(pid); 5852 } 5853 } else { 5854 app = null; 5855 } 5856 5857 if (app == null) { 5858 Slog.w(TAG, "No pending application record for pid " + pid 5859 + " (IApplicationThread " + thread + "); dropping process"); 5860 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5861 if (pid > 0 && pid != MY_PID) { 5862 Process.killProcessQuiet(pid); 5863 //TODO: Process.killProcessGroup(app.info.uid, pid); 5864 } else { 5865 try { 5866 thread.scheduleExit(); 5867 } catch (Exception e) { 5868 // Ignore exceptions. 5869 } 5870 } 5871 return false; 5872 } 5873 5874 // If this application record is still attached to a previous 5875 // process, clean it up now. 5876 if (app.thread != null) { 5877 handleAppDiedLocked(app, true, true); 5878 } 5879 5880 // Tell the process all about itself. 5881 5882 if (localLOGV) Slog.v( 5883 TAG, "Binding process pid " + pid + " to record " + app); 5884 5885 final String processName = app.processName; 5886 try { 5887 AppDeathRecipient adr = new AppDeathRecipient( 5888 app, pid, thread); 5889 thread.asBinder().linkToDeath(adr, 0); 5890 app.deathRecipient = adr; 5891 } catch (RemoteException e) { 5892 app.resetPackageList(mProcessStats); 5893 startProcessLocked(app, "link fail", processName); 5894 return false; 5895 } 5896 5897 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5898 5899 app.makeActive(thread, mProcessStats); 5900 app.curAdj = app.setAdj = -100; 5901 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5902 app.forcingToForeground = null; 5903 updateProcessForegroundLocked(app, false, false); 5904 app.hasShownUi = false; 5905 app.debugging = false; 5906 app.cached = false; 5907 5908 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5909 5910 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5911 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5912 5913 if (!normalMode) { 5914 Slog.i(TAG, "Launching preboot mode app: " + app); 5915 } 5916 5917 if (localLOGV) Slog.v( 5918 TAG, "New app record " + app 5919 + " thread=" + thread.asBinder() + " pid=" + pid); 5920 try { 5921 int testMode = IApplicationThread.DEBUG_OFF; 5922 if (mDebugApp != null && mDebugApp.equals(processName)) { 5923 testMode = mWaitForDebugger 5924 ? IApplicationThread.DEBUG_WAIT 5925 : IApplicationThread.DEBUG_ON; 5926 app.debugging = true; 5927 if (mDebugTransient) { 5928 mDebugApp = mOrigDebugApp; 5929 mWaitForDebugger = mOrigWaitForDebugger; 5930 } 5931 } 5932 String profileFile = app.instrumentationProfileFile; 5933 ParcelFileDescriptor profileFd = null; 5934 int samplingInterval = 0; 5935 boolean profileAutoStop = false; 5936 if (mProfileApp != null && mProfileApp.equals(processName)) { 5937 mProfileProc = app; 5938 profileFile = mProfileFile; 5939 profileFd = mProfileFd; 5940 samplingInterval = mSamplingInterval; 5941 profileAutoStop = mAutoStopProfiler; 5942 } 5943 boolean enableOpenGlTrace = false; 5944 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5945 enableOpenGlTrace = true; 5946 mOpenGlTraceApp = null; 5947 } 5948 5949 // If the app is being launched for restore or full backup, set it up specially 5950 boolean isRestrictedBackupMode = false; 5951 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5952 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5953 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5954 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5955 } 5956 5957 ensurePackageDexOpt(app.instrumentationInfo != null 5958 ? app.instrumentationInfo.packageName 5959 : app.info.packageName); 5960 if (app.instrumentationClass != null) { 5961 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5962 } 5963 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5964 + processName + " with config " + mConfiguration); 5965 ApplicationInfo appInfo = app.instrumentationInfo != null 5966 ? app.instrumentationInfo : app.info; 5967 app.compat = compatibilityInfoForPackageLocked(appInfo); 5968 if (profileFd != null) { 5969 profileFd = profileFd.dup(); 5970 } 5971 ProfilerInfo profilerInfo = profileFile == null ? null 5972 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5973 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5974 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5975 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5976 isRestrictedBackupMode || !normalMode, app.persistent, 5977 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5978 mCoreSettingsObserver.getCoreSettingsLocked()); 5979 updateLruProcessLocked(app, false, null); 5980 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5981 } catch (Exception e) { 5982 // todo: Yikes! What should we do? For now we will try to 5983 // start another process, but that could easily get us in 5984 // an infinite loop of restarting processes... 5985 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5986 5987 app.resetPackageList(mProcessStats); 5988 app.unlinkDeathRecipient(); 5989 startProcessLocked(app, "bind fail", processName); 5990 return false; 5991 } 5992 5993 // Remove this record from the list of starting applications. 5994 mPersistentStartingProcesses.remove(app); 5995 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5996 "Attach application locked removing on hold: " + app); 5997 mProcessesOnHold.remove(app); 5998 5999 boolean badApp = false; 6000 boolean didSomething = false; 6001 6002 // See if the top visible activity is waiting to run in this process... 6003 if (normalMode) { 6004 try { 6005 if (mStackSupervisor.attachApplicationLocked(app)) { 6006 didSomething = true; 6007 } 6008 } catch (Exception e) { 6009 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6010 badApp = true; 6011 } 6012 } 6013 6014 // Find any services that should be running in this process... 6015 if (!badApp) { 6016 try { 6017 didSomething |= mServices.attachApplicationLocked(app, processName); 6018 } catch (Exception e) { 6019 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6020 badApp = true; 6021 } 6022 } 6023 6024 // Check if a next-broadcast receiver is in this process... 6025 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6026 try { 6027 didSomething |= sendPendingBroadcastsLocked(app); 6028 } catch (Exception e) { 6029 // If the app died trying to launch the receiver we declare it 'bad' 6030 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6031 badApp = true; 6032 } 6033 } 6034 6035 // Check whether the next backup agent is in this process... 6036 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6037 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6038 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6039 try { 6040 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6041 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6042 mBackupTarget.backupMode); 6043 } catch (Exception e) { 6044 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6045 badApp = true; 6046 } 6047 } 6048 6049 if (badApp) { 6050 app.kill("error during init", true); 6051 handleAppDiedLocked(app, false, true); 6052 return false; 6053 } 6054 6055 if (!didSomething) { 6056 updateOomAdjLocked(); 6057 } 6058 6059 return true; 6060 } 6061 6062 @Override 6063 public final void attachApplication(IApplicationThread thread) { 6064 synchronized (this) { 6065 int callingPid = Binder.getCallingPid(); 6066 final long origId = Binder.clearCallingIdentity(); 6067 attachApplicationLocked(thread, callingPid); 6068 Binder.restoreCallingIdentity(origId); 6069 } 6070 } 6071 6072 @Override 6073 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6074 final long origId = Binder.clearCallingIdentity(); 6075 synchronized (this) { 6076 ActivityStack stack = ActivityRecord.getStackLocked(token); 6077 if (stack != null) { 6078 ActivityRecord r = 6079 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6080 if (stopProfiling) { 6081 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6082 try { 6083 mProfileFd.close(); 6084 } catch (IOException e) { 6085 } 6086 clearProfilerLocked(); 6087 } 6088 } 6089 } 6090 } 6091 Binder.restoreCallingIdentity(origId); 6092 } 6093 6094 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6095 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6096 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6097 } 6098 6099 void enableScreenAfterBoot() { 6100 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6101 SystemClock.uptimeMillis()); 6102 mWindowManager.enableScreenAfterBoot(); 6103 6104 synchronized (this) { 6105 updateEventDispatchingLocked(); 6106 } 6107 } 6108 6109 @Override 6110 public void showBootMessage(final CharSequence msg, final boolean always) { 6111 enforceNotIsolatedCaller("showBootMessage"); 6112 mWindowManager.showBootMessage(msg, always); 6113 } 6114 6115 @Override 6116 public void keyguardWaitingForActivityDrawn() { 6117 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6118 final long token = Binder.clearCallingIdentity(); 6119 try { 6120 synchronized (this) { 6121 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6122 mWindowManager.keyguardWaitingForActivityDrawn(); 6123 if (mLockScreenShown) { 6124 mLockScreenShown = false; 6125 comeOutOfSleepIfNeededLocked(); 6126 } 6127 } 6128 } finally { 6129 Binder.restoreCallingIdentity(token); 6130 } 6131 } 6132 6133 final void finishBooting() { 6134 synchronized (this) { 6135 if (!mBootAnimationComplete) { 6136 mCallFinishBooting = true; 6137 return; 6138 } 6139 mCallFinishBooting = false; 6140 } 6141 6142 // Register receivers to handle package update events 6143 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6144 6145 // Let system services know. 6146 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6147 6148 synchronized (this) { 6149 // Ensure that any processes we had put on hold are now started 6150 // up. 6151 final int NP = mProcessesOnHold.size(); 6152 if (NP > 0) { 6153 ArrayList<ProcessRecord> procs = 6154 new ArrayList<ProcessRecord>(mProcessesOnHold); 6155 for (int ip=0; ip<NP; ip++) { 6156 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6157 + procs.get(ip)); 6158 startProcessLocked(procs.get(ip), "on-hold", null); 6159 } 6160 } 6161 6162 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6163 // Start looking for apps that are abusing wake locks. 6164 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6165 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6166 // Tell anyone interested that we are done booting! 6167 SystemProperties.set("sys.boot_completed", "1"); 6168 6169 // And trigger dev.bootcomplete if we are not showing encryption progress 6170 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6171 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6172 SystemProperties.set("dev.bootcomplete", "1"); 6173 } 6174 for (int i=0; i<mStartedUsers.size(); i++) { 6175 UserStartedState uss = mStartedUsers.valueAt(i); 6176 if (uss.mState == UserStartedState.STATE_BOOTING) { 6177 uss.mState = UserStartedState.STATE_RUNNING; 6178 final int userId = mStartedUsers.keyAt(i); 6179 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6180 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6181 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6182 broadcastIntentLocked(null, null, intent, null, 6183 new IIntentReceiver.Stub() { 6184 @Override 6185 public void performReceive(Intent intent, int resultCode, 6186 String data, Bundle extras, boolean ordered, 6187 boolean sticky, int sendingUser) { 6188 synchronized (ActivityManagerService.this) { 6189 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6190 true, false); 6191 } 6192 } 6193 }, 6194 0, null, null, 6195 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6196 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6197 userId); 6198 } 6199 } 6200 scheduleStartProfilesLocked(); 6201 } 6202 } 6203 } 6204 6205 @Override 6206 public void bootAnimationComplete() { 6207 final boolean callFinishBooting; 6208 synchronized (this) { 6209 callFinishBooting = mCallFinishBooting; 6210 mBootAnimationComplete = true; 6211 } 6212 if (callFinishBooting) { 6213 finishBooting(); 6214 } 6215 } 6216 6217 final void ensureBootCompleted() { 6218 boolean booting; 6219 boolean enableScreen; 6220 synchronized (this) { 6221 booting = mBooting; 6222 mBooting = false; 6223 enableScreen = !mBooted; 6224 mBooted = true; 6225 } 6226 6227 if (booting) { 6228 finishBooting(); 6229 } 6230 6231 if (enableScreen) { 6232 enableScreenAfterBoot(); 6233 } 6234 } 6235 6236 @Override 6237 public final void activityResumed(IBinder token) { 6238 final long origId = Binder.clearCallingIdentity(); 6239 synchronized(this) { 6240 ActivityStack stack = ActivityRecord.getStackLocked(token); 6241 if (stack != null) { 6242 ActivityRecord.activityResumedLocked(token); 6243 } 6244 } 6245 Binder.restoreCallingIdentity(origId); 6246 } 6247 6248 @Override 6249 public final void activityPaused(IBinder token) { 6250 final long origId = Binder.clearCallingIdentity(); 6251 synchronized(this) { 6252 ActivityStack stack = ActivityRecord.getStackLocked(token); 6253 if (stack != null) { 6254 stack.activityPausedLocked(token, false); 6255 } 6256 } 6257 Binder.restoreCallingIdentity(origId); 6258 } 6259 6260 @Override 6261 public final void activityStopped(IBinder token, Bundle icicle, 6262 PersistableBundle persistentState, CharSequence description) { 6263 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6264 6265 // Refuse possible leaked file descriptors 6266 if (icicle != null && icicle.hasFileDescriptors()) { 6267 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6268 } 6269 6270 final long origId = Binder.clearCallingIdentity(); 6271 6272 synchronized (this) { 6273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6274 if (r != null) { 6275 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6276 } 6277 } 6278 6279 trimApplications(); 6280 6281 Binder.restoreCallingIdentity(origId); 6282 } 6283 6284 @Override 6285 public final void activityDestroyed(IBinder token) { 6286 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6287 synchronized (this) { 6288 ActivityStack stack = ActivityRecord.getStackLocked(token); 6289 if (stack != null) { 6290 stack.activityDestroyedLocked(token); 6291 } 6292 } 6293 } 6294 6295 @Override 6296 public final void backgroundResourcesReleased(IBinder token) { 6297 final long origId = Binder.clearCallingIdentity(); 6298 try { 6299 synchronized (this) { 6300 ActivityStack stack = ActivityRecord.getStackLocked(token); 6301 if (stack != null) { 6302 stack.backgroundResourcesReleased(token); 6303 } 6304 } 6305 } finally { 6306 Binder.restoreCallingIdentity(origId); 6307 } 6308 } 6309 6310 @Override 6311 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6312 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6313 } 6314 6315 @Override 6316 public final void notifyEnterAnimationComplete(IBinder token) { 6317 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6318 } 6319 6320 @Override 6321 public String getCallingPackage(IBinder token) { 6322 synchronized (this) { 6323 ActivityRecord r = getCallingRecordLocked(token); 6324 return r != null ? r.info.packageName : null; 6325 } 6326 } 6327 6328 @Override 6329 public ComponentName getCallingActivity(IBinder token) { 6330 synchronized (this) { 6331 ActivityRecord r = getCallingRecordLocked(token); 6332 return r != null ? r.intent.getComponent() : null; 6333 } 6334 } 6335 6336 private ActivityRecord getCallingRecordLocked(IBinder token) { 6337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6338 if (r == null) { 6339 return null; 6340 } 6341 return r.resultTo; 6342 } 6343 6344 @Override 6345 public ComponentName getActivityClassForToken(IBinder token) { 6346 synchronized(this) { 6347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6348 if (r == null) { 6349 return null; 6350 } 6351 return r.intent.getComponent(); 6352 } 6353 } 6354 6355 @Override 6356 public String getPackageForToken(IBinder token) { 6357 synchronized(this) { 6358 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6359 if (r == null) { 6360 return null; 6361 } 6362 return r.packageName; 6363 } 6364 } 6365 6366 @Override 6367 public IIntentSender getIntentSender(int type, 6368 String packageName, IBinder token, String resultWho, 6369 int requestCode, Intent[] intents, String[] resolvedTypes, 6370 int flags, Bundle options, int userId) { 6371 enforceNotIsolatedCaller("getIntentSender"); 6372 // Refuse possible leaked file descriptors 6373 if (intents != null) { 6374 if (intents.length < 1) { 6375 throw new IllegalArgumentException("Intents array length must be >= 1"); 6376 } 6377 for (int i=0; i<intents.length; i++) { 6378 Intent intent = intents[i]; 6379 if (intent != null) { 6380 if (intent.hasFileDescriptors()) { 6381 throw new IllegalArgumentException("File descriptors passed in Intent"); 6382 } 6383 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6384 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6385 throw new IllegalArgumentException( 6386 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6387 } 6388 intents[i] = new Intent(intent); 6389 } 6390 } 6391 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6392 throw new IllegalArgumentException( 6393 "Intent array length does not match resolvedTypes length"); 6394 } 6395 } 6396 if (options != null) { 6397 if (options.hasFileDescriptors()) { 6398 throw new IllegalArgumentException("File descriptors passed in options"); 6399 } 6400 } 6401 6402 synchronized(this) { 6403 int callingUid = Binder.getCallingUid(); 6404 int origUserId = userId; 6405 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6406 type == ActivityManager.INTENT_SENDER_BROADCAST, 6407 ALLOW_NON_FULL, "getIntentSender", null); 6408 if (origUserId == UserHandle.USER_CURRENT) { 6409 // We don't want to evaluate this until the pending intent is 6410 // actually executed. However, we do want to always do the 6411 // security checking for it above. 6412 userId = UserHandle.USER_CURRENT; 6413 } 6414 try { 6415 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6416 int uid = AppGlobals.getPackageManager() 6417 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6418 if (!UserHandle.isSameApp(callingUid, uid)) { 6419 String msg = "Permission Denial: getIntentSender() from pid=" 6420 + Binder.getCallingPid() 6421 + ", uid=" + Binder.getCallingUid() 6422 + ", (need uid=" + uid + ")" 6423 + " is not allowed to send as package " + packageName; 6424 Slog.w(TAG, msg); 6425 throw new SecurityException(msg); 6426 } 6427 } 6428 6429 return getIntentSenderLocked(type, packageName, callingUid, userId, 6430 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6431 6432 } catch (RemoteException e) { 6433 throw new SecurityException(e); 6434 } 6435 } 6436 } 6437 6438 IIntentSender getIntentSenderLocked(int type, String packageName, 6439 int callingUid, int userId, IBinder token, String resultWho, 6440 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6441 Bundle options) { 6442 if (DEBUG_MU) 6443 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6444 ActivityRecord activity = null; 6445 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6446 activity = ActivityRecord.isInStackLocked(token); 6447 if (activity == null) { 6448 return null; 6449 } 6450 if (activity.finishing) { 6451 return null; 6452 } 6453 } 6454 6455 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6456 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6457 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6458 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6459 |PendingIntent.FLAG_UPDATE_CURRENT); 6460 6461 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6462 type, packageName, activity, resultWho, 6463 requestCode, intents, resolvedTypes, flags, options, userId); 6464 WeakReference<PendingIntentRecord> ref; 6465 ref = mIntentSenderRecords.get(key); 6466 PendingIntentRecord rec = ref != null ? ref.get() : null; 6467 if (rec != null) { 6468 if (!cancelCurrent) { 6469 if (updateCurrent) { 6470 if (rec.key.requestIntent != null) { 6471 rec.key.requestIntent.replaceExtras(intents != null ? 6472 intents[intents.length - 1] : null); 6473 } 6474 if (intents != null) { 6475 intents[intents.length-1] = rec.key.requestIntent; 6476 rec.key.allIntents = intents; 6477 rec.key.allResolvedTypes = resolvedTypes; 6478 } else { 6479 rec.key.allIntents = null; 6480 rec.key.allResolvedTypes = null; 6481 } 6482 } 6483 return rec; 6484 } 6485 rec.canceled = true; 6486 mIntentSenderRecords.remove(key); 6487 } 6488 if (noCreate) { 6489 return rec; 6490 } 6491 rec = new PendingIntentRecord(this, key, callingUid); 6492 mIntentSenderRecords.put(key, rec.ref); 6493 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6494 if (activity.pendingResults == null) { 6495 activity.pendingResults 6496 = new HashSet<WeakReference<PendingIntentRecord>>(); 6497 } 6498 activity.pendingResults.add(rec.ref); 6499 } 6500 return rec; 6501 } 6502 6503 @Override 6504 public void cancelIntentSender(IIntentSender sender) { 6505 if (!(sender instanceof PendingIntentRecord)) { 6506 return; 6507 } 6508 synchronized(this) { 6509 PendingIntentRecord rec = (PendingIntentRecord)sender; 6510 try { 6511 int uid = AppGlobals.getPackageManager() 6512 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6513 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6514 String msg = "Permission Denial: cancelIntentSender() from pid=" 6515 + Binder.getCallingPid() 6516 + ", uid=" + Binder.getCallingUid() 6517 + " is not allowed to cancel packges " 6518 + rec.key.packageName; 6519 Slog.w(TAG, msg); 6520 throw new SecurityException(msg); 6521 } 6522 } catch (RemoteException e) { 6523 throw new SecurityException(e); 6524 } 6525 cancelIntentSenderLocked(rec, true); 6526 } 6527 } 6528 6529 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6530 rec.canceled = true; 6531 mIntentSenderRecords.remove(rec.key); 6532 if (cleanActivity && rec.key.activity != null) { 6533 rec.key.activity.pendingResults.remove(rec.ref); 6534 } 6535 } 6536 6537 @Override 6538 public String getPackageForIntentSender(IIntentSender pendingResult) { 6539 if (!(pendingResult instanceof PendingIntentRecord)) { 6540 return null; 6541 } 6542 try { 6543 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6544 return res.key.packageName; 6545 } catch (ClassCastException e) { 6546 } 6547 return null; 6548 } 6549 6550 @Override 6551 public int getUidForIntentSender(IIntentSender sender) { 6552 if (sender instanceof PendingIntentRecord) { 6553 try { 6554 PendingIntentRecord res = (PendingIntentRecord)sender; 6555 return res.uid; 6556 } catch (ClassCastException e) { 6557 } 6558 } 6559 return -1; 6560 } 6561 6562 @Override 6563 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6564 if (!(pendingResult instanceof PendingIntentRecord)) { 6565 return false; 6566 } 6567 try { 6568 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6569 if (res.key.allIntents == null) { 6570 return false; 6571 } 6572 for (int i=0; i<res.key.allIntents.length; i++) { 6573 Intent intent = res.key.allIntents[i]; 6574 if (intent.getPackage() != null && intent.getComponent() != null) { 6575 return false; 6576 } 6577 } 6578 return true; 6579 } catch (ClassCastException e) { 6580 } 6581 return false; 6582 } 6583 6584 @Override 6585 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6586 if (!(pendingResult instanceof PendingIntentRecord)) { 6587 return false; 6588 } 6589 try { 6590 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6591 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6592 return true; 6593 } 6594 return false; 6595 } catch (ClassCastException e) { 6596 } 6597 return false; 6598 } 6599 6600 @Override 6601 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6602 if (!(pendingResult instanceof PendingIntentRecord)) { 6603 return null; 6604 } 6605 try { 6606 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6607 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6608 } catch (ClassCastException e) { 6609 } 6610 return null; 6611 } 6612 6613 @Override 6614 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6615 if (!(pendingResult instanceof PendingIntentRecord)) { 6616 return null; 6617 } 6618 try { 6619 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6620 Intent intent = res.key.requestIntent; 6621 if (intent != null) { 6622 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6623 || res.lastTagPrefix.equals(prefix))) { 6624 return res.lastTag; 6625 } 6626 res.lastTagPrefix = prefix; 6627 StringBuilder sb = new StringBuilder(128); 6628 if (prefix != null) { 6629 sb.append(prefix); 6630 } 6631 if (intent.getAction() != null) { 6632 sb.append(intent.getAction()); 6633 } else if (intent.getComponent() != null) { 6634 intent.getComponent().appendShortString(sb); 6635 } else { 6636 sb.append("?"); 6637 } 6638 return res.lastTag = sb.toString(); 6639 } 6640 } catch (ClassCastException e) { 6641 } 6642 return null; 6643 } 6644 6645 @Override 6646 public void setProcessLimit(int max) { 6647 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6648 "setProcessLimit()"); 6649 synchronized (this) { 6650 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6651 mProcessLimitOverride = max; 6652 } 6653 trimApplications(); 6654 } 6655 6656 @Override 6657 public int getProcessLimit() { 6658 synchronized (this) { 6659 return mProcessLimitOverride; 6660 } 6661 } 6662 6663 void foregroundTokenDied(ForegroundToken token) { 6664 synchronized (ActivityManagerService.this) { 6665 synchronized (mPidsSelfLocked) { 6666 ForegroundToken cur 6667 = mForegroundProcesses.get(token.pid); 6668 if (cur != token) { 6669 return; 6670 } 6671 mForegroundProcesses.remove(token.pid); 6672 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6673 if (pr == null) { 6674 return; 6675 } 6676 pr.forcingToForeground = null; 6677 updateProcessForegroundLocked(pr, false, false); 6678 } 6679 updateOomAdjLocked(); 6680 } 6681 } 6682 6683 @Override 6684 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6685 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6686 "setProcessForeground()"); 6687 synchronized(this) { 6688 boolean changed = false; 6689 6690 synchronized (mPidsSelfLocked) { 6691 ProcessRecord pr = mPidsSelfLocked.get(pid); 6692 if (pr == null && isForeground) { 6693 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6694 return; 6695 } 6696 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6697 if (oldToken != null) { 6698 oldToken.token.unlinkToDeath(oldToken, 0); 6699 mForegroundProcesses.remove(pid); 6700 if (pr != null) { 6701 pr.forcingToForeground = null; 6702 } 6703 changed = true; 6704 } 6705 if (isForeground && token != null) { 6706 ForegroundToken newToken = new ForegroundToken() { 6707 @Override 6708 public void binderDied() { 6709 foregroundTokenDied(this); 6710 } 6711 }; 6712 newToken.pid = pid; 6713 newToken.token = token; 6714 try { 6715 token.linkToDeath(newToken, 0); 6716 mForegroundProcesses.put(pid, newToken); 6717 pr.forcingToForeground = token; 6718 changed = true; 6719 } catch (RemoteException e) { 6720 // If the process died while doing this, we will later 6721 // do the cleanup with the process death link. 6722 } 6723 } 6724 } 6725 6726 if (changed) { 6727 updateOomAdjLocked(); 6728 } 6729 } 6730 } 6731 6732 // ========================================================= 6733 // PERMISSIONS 6734 // ========================================================= 6735 6736 static class PermissionController extends IPermissionController.Stub { 6737 ActivityManagerService mActivityManagerService; 6738 PermissionController(ActivityManagerService activityManagerService) { 6739 mActivityManagerService = activityManagerService; 6740 } 6741 6742 @Override 6743 public boolean checkPermission(String permission, int pid, int uid) { 6744 return mActivityManagerService.checkPermission(permission, pid, 6745 uid) == PackageManager.PERMISSION_GRANTED; 6746 } 6747 } 6748 6749 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6750 @Override 6751 public int checkComponentPermission(String permission, int pid, int uid, 6752 int owningUid, boolean exported) { 6753 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6754 owningUid, exported); 6755 } 6756 6757 @Override 6758 public Object getAMSLock() { 6759 return ActivityManagerService.this; 6760 } 6761 } 6762 6763 /** 6764 * This can be called with or without the global lock held. 6765 */ 6766 int checkComponentPermission(String permission, int pid, int uid, 6767 int owningUid, boolean exported) { 6768 // We might be performing an operation on behalf of an indirect binder 6769 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6770 // client identity accordingly before proceeding. 6771 Identity tlsIdentity = sCallerIdentity.get(); 6772 if (tlsIdentity != null) { 6773 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6774 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6775 uid = tlsIdentity.uid; 6776 pid = tlsIdentity.pid; 6777 } 6778 6779 if (pid == MY_PID) { 6780 return PackageManager.PERMISSION_GRANTED; 6781 } 6782 6783 return ActivityManager.checkComponentPermission(permission, uid, 6784 owningUid, exported); 6785 } 6786 6787 /** 6788 * As the only public entry point for permissions checking, this method 6789 * can enforce the semantic that requesting a check on a null global 6790 * permission is automatically denied. (Internally a null permission 6791 * string is used when calling {@link #checkComponentPermission} in cases 6792 * when only uid-based security is needed.) 6793 * 6794 * This can be called with or without the global lock held. 6795 */ 6796 @Override 6797 public int checkPermission(String permission, int pid, int uid) { 6798 if (permission == null) { 6799 return PackageManager.PERMISSION_DENIED; 6800 } 6801 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6802 } 6803 6804 /** 6805 * Binder IPC calls go through the public entry point. 6806 * This can be called with or without the global lock held. 6807 */ 6808 int checkCallingPermission(String permission) { 6809 return checkPermission(permission, 6810 Binder.getCallingPid(), 6811 UserHandle.getAppId(Binder.getCallingUid())); 6812 } 6813 6814 /** 6815 * This can be called with or without the global lock held. 6816 */ 6817 void enforceCallingPermission(String permission, String func) { 6818 if (checkCallingPermission(permission) 6819 == PackageManager.PERMISSION_GRANTED) { 6820 return; 6821 } 6822 6823 String msg = "Permission Denial: " + func + " from pid=" 6824 + Binder.getCallingPid() 6825 + ", uid=" + Binder.getCallingUid() 6826 + " requires " + permission; 6827 Slog.w(TAG, msg); 6828 throw new SecurityException(msg); 6829 } 6830 6831 /** 6832 * Determine if UID is holding permissions required to access {@link Uri} in 6833 * the given {@link ProviderInfo}. Final permission checking is always done 6834 * in {@link ContentProvider}. 6835 */ 6836 private final boolean checkHoldingPermissionsLocked( 6837 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6838 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6839 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6840 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6841 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6842 != PERMISSION_GRANTED) { 6843 return false; 6844 } 6845 } 6846 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6847 } 6848 6849 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6850 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6851 if (pi.applicationInfo.uid == uid) { 6852 return true; 6853 } else if (!pi.exported) { 6854 return false; 6855 } 6856 6857 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6858 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6859 try { 6860 // check if target holds top-level <provider> permissions 6861 if (!readMet && pi.readPermission != null && considerUidPermissions 6862 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6863 readMet = true; 6864 } 6865 if (!writeMet && pi.writePermission != null && considerUidPermissions 6866 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6867 writeMet = true; 6868 } 6869 6870 // track if unprotected read/write is allowed; any denied 6871 // <path-permission> below removes this ability 6872 boolean allowDefaultRead = pi.readPermission == null; 6873 boolean allowDefaultWrite = pi.writePermission == null; 6874 6875 // check if target holds any <path-permission> that match uri 6876 final PathPermission[] pps = pi.pathPermissions; 6877 if (pps != null) { 6878 final String path = grantUri.uri.getPath(); 6879 int i = pps.length; 6880 while (i > 0 && (!readMet || !writeMet)) { 6881 i--; 6882 PathPermission pp = pps[i]; 6883 if (pp.match(path)) { 6884 if (!readMet) { 6885 final String pprperm = pp.getReadPermission(); 6886 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6887 + pprperm + " for " + pp.getPath() 6888 + ": match=" + pp.match(path) 6889 + " check=" + pm.checkUidPermission(pprperm, uid)); 6890 if (pprperm != null) { 6891 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6892 == PERMISSION_GRANTED) { 6893 readMet = true; 6894 } else { 6895 allowDefaultRead = false; 6896 } 6897 } 6898 } 6899 if (!writeMet) { 6900 final String ppwperm = pp.getWritePermission(); 6901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6902 + ppwperm + " for " + pp.getPath() 6903 + ": match=" + pp.match(path) 6904 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6905 if (ppwperm != null) { 6906 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6907 == PERMISSION_GRANTED) { 6908 writeMet = true; 6909 } else { 6910 allowDefaultWrite = false; 6911 } 6912 } 6913 } 6914 } 6915 } 6916 } 6917 6918 // grant unprotected <provider> read/write, if not blocked by 6919 // <path-permission> above 6920 if (allowDefaultRead) readMet = true; 6921 if (allowDefaultWrite) writeMet = true; 6922 6923 } catch (RemoteException e) { 6924 return false; 6925 } 6926 6927 return readMet && writeMet; 6928 } 6929 6930 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6931 ProviderInfo pi = null; 6932 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6933 if (cpr != null) { 6934 pi = cpr.info; 6935 } else { 6936 try { 6937 pi = AppGlobals.getPackageManager().resolveContentProvider( 6938 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6939 } catch (RemoteException ex) { 6940 } 6941 } 6942 return pi; 6943 } 6944 6945 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6946 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6947 if (targetUris != null) { 6948 return targetUris.get(grantUri); 6949 } 6950 return null; 6951 } 6952 6953 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6954 String targetPkg, int targetUid, GrantUri grantUri) { 6955 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6956 if (targetUris == null) { 6957 targetUris = Maps.newArrayMap(); 6958 mGrantedUriPermissions.put(targetUid, targetUris); 6959 } 6960 6961 UriPermission perm = targetUris.get(grantUri); 6962 if (perm == null) { 6963 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6964 targetUris.put(grantUri, perm); 6965 } 6966 6967 return perm; 6968 } 6969 6970 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6971 final int modeFlags) { 6972 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6973 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6974 : UriPermission.STRENGTH_OWNED; 6975 6976 // Root gets to do everything. 6977 if (uid == 0) { 6978 return true; 6979 } 6980 6981 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6982 if (perms == null) return false; 6983 6984 // First look for exact match 6985 final UriPermission exactPerm = perms.get(grantUri); 6986 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6987 return true; 6988 } 6989 6990 // No exact match, look for prefixes 6991 final int N = perms.size(); 6992 for (int i = 0; i < N; i++) { 6993 final UriPermission perm = perms.valueAt(i); 6994 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6995 && perm.getStrength(modeFlags) >= minStrength) { 6996 return true; 6997 } 6998 } 6999 7000 return false; 7001 } 7002 7003 /** 7004 * @param uri This uri must NOT contain an embedded userId. 7005 * @param userId The userId in which the uri is to be resolved. 7006 */ 7007 @Override 7008 public int checkUriPermission(Uri uri, int pid, int uid, 7009 final int modeFlags, int userId) { 7010 enforceNotIsolatedCaller("checkUriPermission"); 7011 7012 // Another redirected-binder-call permissions check as in 7013 // {@link checkComponentPermission}. 7014 Identity tlsIdentity = sCallerIdentity.get(); 7015 if (tlsIdentity != null) { 7016 uid = tlsIdentity.uid; 7017 pid = tlsIdentity.pid; 7018 } 7019 7020 // Our own process gets to do everything. 7021 if (pid == MY_PID) { 7022 return PackageManager.PERMISSION_GRANTED; 7023 } 7024 synchronized (this) { 7025 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7026 ? PackageManager.PERMISSION_GRANTED 7027 : PackageManager.PERMISSION_DENIED; 7028 } 7029 } 7030 7031 /** 7032 * Check if the targetPkg can be granted permission to access uri by 7033 * the callingUid using the given modeFlags. Throws a security exception 7034 * if callingUid is not allowed to do this. Returns the uid of the target 7035 * if the URI permission grant should be performed; returns -1 if it is not 7036 * needed (for example targetPkg already has permission to access the URI). 7037 * If you already know the uid of the target, you can supply it in 7038 * lastTargetUid else set that to -1. 7039 */ 7040 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7041 final int modeFlags, int lastTargetUid) { 7042 if (!Intent.isAccessUriMode(modeFlags)) { 7043 return -1; 7044 } 7045 7046 if (targetPkg != null) { 7047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7048 "Checking grant " + targetPkg + " permission to " + grantUri); 7049 } 7050 7051 final IPackageManager pm = AppGlobals.getPackageManager(); 7052 7053 // If this is not a content: uri, we can't do anything with it. 7054 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7055 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7056 "Can't grant URI permission for non-content URI: " + grantUri); 7057 return -1; 7058 } 7059 7060 final String authority = grantUri.uri.getAuthority(); 7061 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7062 if (pi == null) { 7063 Slog.w(TAG, "No content provider found for permission check: " + 7064 grantUri.uri.toSafeString()); 7065 return -1; 7066 } 7067 7068 int targetUid = lastTargetUid; 7069 if (targetUid < 0 && targetPkg != null) { 7070 try { 7071 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7072 if (targetUid < 0) { 7073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7074 "Can't grant URI permission no uid for: " + targetPkg); 7075 return -1; 7076 } 7077 } catch (RemoteException ex) { 7078 return -1; 7079 } 7080 } 7081 7082 if (targetUid >= 0) { 7083 // First... does the target actually need this permission? 7084 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7085 // No need to grant the target this permission. 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Target " + targetPkg + " already has full permission to " + grantUri); 7088 return -1; 7089 } 7090 } else { 7091 // First... there is no target package, so can anyone access it? 7092 boolean allowed = pi.exported; 7093 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7094 if (pi.readPermission != null) { 7095 allowed = false; 7096 } 7097 } 7098 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7099 if (pi.writePermission != null) { 7100 allowed = false; 7101 } 7102 } 7103 if (allowed) { 7104 return -1; 7105 } 7106 } 7107 7108 /* There is a special cross user grant if: 7109 * - The target is on another user. 7110 * - Apps on the current user can access the uri without any uid permissions. 7111 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7112 * grant uri permissions. 7113 */ 7114 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7115 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7116 modeFlags, false /*without considering the uid permissions*/); 7117 7118 // Second... is the provider allowing granting of URI permissions? 7119 if (!specialCrossUserGrant) { 7120 if (!pi.grantUriPermissions) { 7121 throw new SecurityException("Provider " + pi.packageName 7122 + "/" + pi.name 7123 + " does not allow granting of Uri permissions (uri " 7124 + grantUri + ")"); 7125 } 7126 if (pi.uriPermissionPatterns != null) { 7127 final int N = pi.uriPermissionPatterns.length; 7128 boolean allowed = false; 7129 for (int i=0; i<N; i++) { 7130 if (pi.uriPermissionPatterns[i] != null 7131 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7132 allowed = true; 7133 break; 7134 } 7135 } 7136 if (!allowed) { 7137 throw new SecurityException("Provider " + pi.packageName 7138 + "/" + pi.name 7139 + " does not allow granting of permission to path of Uri " 7140 + grantUri); 7141 } 7142 } 7143 } 7144 7145 // Third... does the caller itself have permission to access 7146 // this uri? 7147 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7148 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7149 // Require they hold a strong enough Uri permission 7150 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7151 throw new SecurityException("Uid " + callingUid 7152 + " does not have permission to uri " + grantUri); 7153 } 7154 } 7155 } 7156 return targetUid; 7157 } 7158 7159 /** 7160 * @param uri This uri must NOT contain an embedded userId. 7161 * @param userId The userId in which the uri is to be resolved. 7162 */ 7163 @Override 7164 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7165 final int modeFlags, int userId) { 7166 enforceNotIsolatedCaller("checkGrantUriPermission"); 7167 synchronized(this) { 7168 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7169 new GrantUri(userId, uri, false), modeFlags, -1); 7170 } 7171 } 7172 7173 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7174 final int modeFlags, UriPermissionOwner owner) { 7175 if (!Intent.isAccessUriMode(modeFlags)) { 7176 return; 7177 } 7178 7179 // So here we are: the caller has the assumed permission 7180 // to the uri, and the target doesn't. Let's now give this to 7181 // the target. 7182 7183 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7184 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7185 7186 final String authority = grantUri.uri.getAuthority(); 7187 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7188 if (pi == null) { 7189 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7190 return; 7191 } 7192 7193 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7194 grantUri.prefix = true; 7195 } 7196 final UriPermission perm = findOrCreateUriPermissionLocked( 7197 pi.packageName, targetPkg, targetUid, grantUri); 7198 perm.grantModes(modeFlags, owner); 7199 } 7200 7201 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7202 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7203 if (targetPkg == null) { 7204 throw new NullPointerException("targetPkg"); 7205 } 7206 int targetUid; 7207 final IPackageManager pm = AppGlobals.getPackageManager(); 7208 try { 7209 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7210 } catch (RemoteException ex) { 7211 return; 7212 } 7213 7214 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7215 targetUid); 7216 if (targetUid < 0) { 7217 return; 7218 } 7219 7220 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7221 owner); 7222 } 7223 7224 static class NeededUriGrants extends ArrayList<GrantUri> { 7225 final String targetPkg; 7226 final int targetUid; 7227 final int flags; 7228 7229 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7230 this.targetPkg = targetPkg; 7231 this.targetUid = targetUid; 7232 this.flags = flags; 7233 } 7234 } 7235 7236 /** 7237 * Like checkGrantUriPermissionLocked, but takes an Intent. 7238 */ 7239 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7240 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7241 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7242 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7243 + " clip=" + (intent != null ? intent.getClipData() : null) 7244 + " from " + intent + "; flags=0x" 7245 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7246 7247 if (targetPkg == null) { 7248 throw new NullPointerException("targetPkg"); 7249 } 7250 7251 if (intent == null) { 7252 return null; 7253 } 7254 Uri data = intent.getData(); 7255 ClipData clip = intent.getClipData(); 7256 if (data == null && clip == null) { 7257 return null; 7258 } 7259 // Default userId for uris in the intent (if they don't specify it themselves) 7260 int contentUserHint = intent.getContentUserHint(); 7261 if (contentUserHint == UserHandle.USER_CURRENT) { 7262 contentUserHint = UserHandle.getUserId(callingUid); 7263 } 7264 final IPackageManager pm = AppGlobals.getPackageManager(); 7265 int targetUid; 7266 if (needed != null) { 7267 targetUid = needed.targetUid; 7268 } else { 7269 try { 7270 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7271 } catch (RemoteException ex) { 7272 return null; 7273 } 7274 if (targetUid < 0) { 7275 if (DEBUG_URI_PERMISSION) { 7276 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7277 + " on user " + targetUserId); 7278 } 7279 return null; 7280 } 7281 } 7282 if (data != null) { 7283 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7284 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7285 targetUid); 7286 if (targetUid > 0) { 7287 if (needed == null) { 7288 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7289 } 7290 needed.add(grantUri); 7291 } 7292 } 7293 if (clip != null) { 7294 for (int i=0; i<clip.getItemCount(); i++) { 7295 Uri uri = clip.getItemAt(i).getUri(); 7296 if (uri != null) { 7297 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7298 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7299 targetUid); 7300 if (targetUid > 0) { 7301 if (needed == null) { 7302 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7303 } 7304 needed.add(grantUri); 7305 } 7306 } else { 7307 Intent clipIntent = clip.getItemAt(i).getIntent(); 7308 if (clipIntent != null) { 7309 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7310 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7311 if (newNeeded != null) { 7312 needed = newNeeded; 7313 } 7314 } 7315 } 7316 } 7317 } 7318 7319 return needed; 7320 } 7321 7322 /** 7323 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7324 */ 7325 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7326 UriPermissionOwner owner) { 7327 if (needed != null) { 7328 for (int i=0; i<needed.size(); i++) { 7329 GrantUri grantUri = needed.get(i); 7330 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7331 grantUri, needed.flags, owner); 7332 } 7333 } 7334 } 7335 7336 void grantUriPermissionFromIntentLocked(int callingUid, 7337 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7338 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7339 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7340 if (needed == null) { 7341 return; 7342 } 7343 7344 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7345 } 7346 7347 /** 7348 * @param uri This uri must NOT contain an embedded userId. 7349 * @param userId The userId in which the uri is to be resolved. 7350 */ 7351 @Override 7352 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7353 final int modeFlags, int userId) { 7354 enforceNotIsolatedCaller("grantUriPermission"); 7355 GrantUri grantUri = new GrantUri(userId, uri, false); 7356 synchronized(this) { 7357 final ProcessRecord r = getRecordForAppLocked(caller); 7358 if (r == null) { 7359 throw new SecurityException("Unable to find app for caller " 7360 + caller 7361 + " when granting permission to uri " + grantUri); 7362 } 7363 if (targetPkg == null) { 7364 throw new IllegalArgumentException("null target"); 7365 } 7366 if (grantUri == null) { 7367 throw new IllegalArgumentException("null uri"); 7368 } 7369 7370 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7371 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7372 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7373 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7374 7375 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7376 UserHandle.getUserId(r.uid)); 7377 } 7378 } 7379 7380 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7381 if (perm.modeFlags == 0) { 7382 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7383 perm.targetUid); 7384 if (perms != null) { 7385 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7386 "Removing " + perm.targetUid + " permission to " + perm.uri); 7387 7388 perms.remove(perm.uri); 7389 if (perms.isEmpty()) { 7390 mGrantedUriPermissions.remove(perm.targetUid); 7391 } 7392 } 7393 } 7394 } 7395 7396 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7397 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7398 7399 final IPackageManager pm = AppGlobals.getPackageManager(); 7400 final String authority = grantUri.uri.getAuthority(); 7401 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7402 if (pi == null) { 7403 Slog.w(TAG, "No content provider found for permission revoke: " 7404 + grantUri.toSafeString()); 7405 return; 7406 } 7407 7408 // Does the caller have this permission on the URI? 7409 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7410 // If they don't have direct access to the URI, then revoke any 7411 // ownerless URI permissions that have been granted to them. 7412 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7413 if (perms != null) { 7414 boolean persistChanged = false; 7415 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7416 final UriPermission perm = it.next(); 7417 if (perm.uri.sourceUserId == grantUri.sourceUserId 7418 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7419 if (DEBUG_URI_PERMISSION) 7420 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7421 " permission to " + perm.uri); 7422 persistChanged |= perm.revokeModes( 7423 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7424 if (perm.modeFlags == 0) { 7425 it.remove(); 7426 } 7427 } 7428 } 7429 if (perms.isEmpty()) { 7430 mGrantedUriPermissions.remove(callingUid); 7431 } 7432 if (persistChanged) { 7433 schedulePersistUriGrants(); 7434 } 7435 } 7436 return; 7437 } 7438 7439 boolean persistChanged = false; 7440 7441 // Go through all of the permissions and remove any that match. 7442 int N = mGrantedUriPermissions.size(); 7443 for (int i = 0; i < N; i++) { 7444 final int targetUid = mGrantedUriPermissions.keyAt(i); 7445 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7446 7447 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7448 final UriPermission perm = it.next(); 7449 if (perm.uri.sourceUserId == grantUri.sourceUserId 7450 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7451 if (DEBUG_URI_PERMISSION) 7452 Slog.v(TAG, 7453 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7454 persistChanged |= perm.revokeModes( 7455 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7456 if (perm.modeFlags == 0) { 7457 it.remove(); 7458 } 7459 } 7460 } 7461 7462 if (perms.isEmpty()) { 7463 mGrantedUriPermissions.remove(targetUid); 7464 N--; 7465 i--; 7466 } 7467 } 7468 7469 if (persistChanged) { 7470 schedulePersistUriGrants(); 7471 } 7472 } 7473 7474 /** 7475 * @param uri This uri must NOT contain an embedded userId. 7476 * @param userId The userId in which the uri is to be resolved. 7477 */ 7478 @Override 7479 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7480 int userId) { 7481 enforceNotIsolatedCaller("revokeUriPermission"); 7482 synchronized(this) { 7483 final ProcessRecord r = getRecordForAppLocked(caller); 7484 if (r == null) { 7485 throw new SecurityException("Unable to find app for caller " 7486 + caller 7487 + " when revoking permission to uri " + uri); 7488 } 7489 if (uri == null) { 7490 Slog.w(TAG, "revokeUriPermission: null uri"); 7491 return; 7492 } 7493 7494 if (!Intent.isAccessUriMode(modeFlags)) { 7495 return; 7496 } 7497 7498 final IPackageManager pm = AppGlobals.getPackageManager(); 7499 final String authority = uri.getAuthority(); 7500 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7501 if (pi == null) { 7502 Slog.w(TAG, "No content provider found for permission revoke: " 7503 + uri.toSafeString()); 7504 return; 7505 } 7506 7507 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7508 } 7509 } 7510 7511 /** 7512 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7513 * given package. 7514 * 7515 * @param packageName Package name to match, or {@code null} to apply to all 7516 * packages. 7517 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7518 * to all users. 7519 * @param persistable If persistable grants should be removed. 7520 */ 7521 private void removeUriPermissionsForPackageLocked( 7522 String packageName, int userHandle, boolean persistable) { 7523 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7524 throw new IllegalArgumentException("Must narrow by either package or user"); 7525 } 7526 7527 boolean persistChanged = false; 7528 7529 int N = mGrantedUriPermissions.size(); 7530 for (int i = 0; i < N; i++) { 7531 final int targetUid = mGrantedUriPermissions.keyAt(i); 7532 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7533 7534 // Only inspect grants matching user 7535 if (userHandle == UserHandle.USER_ALL 7536 || userHandle == UserHandle.getUserId(targetUid)) { 7537 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7538 final UriPermission perm = it.next(); 7539 7540 // Only inspect grants matching package 7541 if (packageName == null || perm.sourcePkg.equals(packageName) 7542 || perm.targetPkg.equals(packageName)) { 7543 persistChanged |= perm.revokeModes(persistable 7544 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7545 7546 // Only remove when no modes remain; any persisted grants 7547 // will keep this alive. 7548 if (perm.modeFlags == 0) { 7549 it.remove(); 7550 } 7551 } 7552 } 7553 7554 if (perms.isEmpty()) { 7555 mGrantedUriPermissions.remove(targetUid); 7556 N--; 7557 i--; 7558 } 7559 } 7560 } 7561 7562 if (persistChanged) { 7563 schedulePersistUriGrants(); 7564 } 7565 } 7566 7567 @Override 7568 public IBinder newUriPermissionOwner(String name) { 7569 enforceNotIsolatedCaller("newUriPermissionOwner"); 7570 synchronized(this) { 7571 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7572 return owner.getExternalTokenLocked(); 7573 } 7574 } 7575 7576 /** 7577 * @param uri This uri must NOT contain an embedded userId. 7578 * @param sourceUserId The userId in which the uri is to be resolved. 7579 * @param targetUserId The userId of the app that receives the grant. 7580 */ 7581 @Override 7582 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7583 final int modeFlags, int sourceUserId, int targetUserId) { 7584 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7585 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7586 synchronized(this) { 7587 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7588 if (owner == null) { 7589 throw new IllegalArgumentException("Unknown owner: " + token); 7590 } 7591 if (fromUid != Binder.getCallingUid()) { 7592 if (Binder.getCallingUid() != Process.myUid()) { 7593 // Only system code can grant URI permissions on behalf 7594 // of other users. 7595 throw new SecurityException("nice try"); 7596 } 7597 } 7598 if (targetPkg == null) { 7599 throw new IllegalArgumentException("null target"); 7600 } 7601 if (uri == null) { 7602 throw new IllegalArgumentException("null uri"); 7603 } 7604 7605 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7606 modeFlags, owner, targetUserId); 7607 } 7608 } 7609 7610 /** 7611 * @param uri This uri must NOT contain an embedded userId. 7612 * @param userId The userId in which the uri is to be resolved. 7613 */ 7614 @Override 7615 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7616 synchronized(this) { 7617 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7618 if (owner == null) { 7619 throw new IllegalArgumentException("Unknown owner: " + token); 7620 } 7621 7622 if (uri == null) { 7623 owner.removeUriPermissionsLocked(mode); 7624 } else { 7625 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7626 } 7627 } 7628 } 7629 7630 private void schedulePersistUriGrants() { 7631 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7632 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7633 10 * DateUtils.SECOND_IN_MILLIS); 7634 } 7635 } 7636 7637 private void writeGrantedUriPermissions() { 7638 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7639 7640 // Snapshot permissions so we can persist without lock 7641 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7642 synchronized (this) { 7643 final int size = mGrantedUriPermissions.size(); 7644 for (int i = 0; i < size; i++) { 7645 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7646 for (UriPermission perm : perms.values()) { 7647 if (perm.persistedModeFlags != 0) { 7648 persist.add(perm.snapshot()); 7649 } 7650 } 7651 } 7652 } 7653 7654 FileOutputStream fos = null; 7655 try { 7656 fos = mGrantFile.startWrite(); 7657 7658 XmlSerializer out = new FastXmlSerializer(); 7659 out.setOutput(fos, "utf-8"); 7660 out.startDocument(null, true); 7661 out.startTag(null, TAG_URI_GRANTS); 7662 for (UriPermission.Snapshot perm : persist) { 7663 out.startTag(null, TAG_URI_GRANT); 7664 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7665 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7666 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7667 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7668 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7669 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7670 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7671 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7672 out.endTag(null, TAG_URI_GRANT); 7673 } 7674 out.endTag(null, TAG_URI_GRANTS); 7675 out.endDocument(); 7676 7677 mGrantFile.finishWrite(fos); 7678 } catch (IOException e) { 7679 if (fos != null) { 7680 mGrantFile.failWrite(fos); 7681 } 7682 } 7683 } 7684 7685 private void readGrantedUriPermissionsLocked() { 7686 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7687 7688 final long now = System.currentTimeMillis(); 7689 7690 FileInputStream fis = null; 7691 try { 7692 fis = mGrantFile.openRead(); 7693 final XmlPullParser in = Xml.newPullParser(); 7694 in.setInput(fis, null); 7695 7696 int type; 7697 while ((type = in.next()) != END_DOCUMENT) { 7698 final String tag = in.getName(); 7699 if (type == START_TAG) { 7700 if (TAG_URI_GRANT.equals(tag)) { 7701 final int sourceUserId; 7702 final int targetUserId; 7703 final int userHandle = readIntAttribute(in, 7704 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7705 if (userHandle != UserHandle.USER_NULL) { 7706 // For backwards compatibility. 7707 sourceUserId = userHandle; 7708 targetUserId = userHandle; 7709 } else { 7710 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7711 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7712 } 7713 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7714 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7715 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7716 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7717 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7718 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7719 7720 // Sanity check that provider still belongs to source package 7721 final ProviderInfo pi = getProviderInfoLocked( 7722 uri.getAuthority(), sourceUserId); 7723 if (pi != null && sourcePkg.equals(pi.packageName)) { 7724 int targetUid = -1; 7725 try { 7726 targetUid = AppGlobals.getPackageManager() 7727 .getPackageUid(targetPkg, targetUserId); 7728 } catch (RemoteException e) { 7729 } 7730 if (targetUid != -1) { 7731 final UriPermission perm = findOrCreateUriPermissionLocked( 7732 sourcePkg, targetPkg, targetUid, 7733 new GrantUri(sourceUserId, uri, prefix)); 7734 perm.initPersistedModes(modeFlags, createdTime); 7735 } 7736 } else { 7737 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7738 + " but instead found " + pi); 7739 } 7740 } 7741 } 7742 } 7743 } catch (FileNotFoundException e) { 7744 // Missing grants is okay 7745 } catch (IOException e) { 7746 Slog.wtf(TAG, "Failed reading Uri grants", e); 7747 } catch (XmlPullParserException e) { 7748 Slog.wtf(TAG, "Failed reading Uri grants", e); 7749 } finally { 7750 IoUtils.closeQuietly(fis); 7751 } 7752 } 7753 7754 /** 7755 * @param uri This uri must NOT contain an embedded userId. 7756 * @param userId The userId in which the uri is to be resolved. 7757 */ 7758 @Override 7759 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7760 enforceNotIsolatedCaller("takePersistableUriPermission"); 7761 7762 Preconditions.checkFlagsArgument(modeFlags, 7763 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7764 7765 synchronized (this) { 7766 final int callingUid = Binder.getCallingUid(); 7767 boolean persistChanged = false; 7768 GrantUri grantUri = new GrantUri(userId, uri, false); 7769 7770 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7771 new GrantUri(userId, uri, false)); 7772 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7773 new GrantUri(userId, uri, true)); 7774 7775 final boolean exactValid = (exactPerm != null) 7776 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7777 final boolean prefixValid = (prefixPerm != null) 7778 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7779 7780 if (!(exactValid || prefixValid)) { 7781 throw new SecurityException("No persistable permission grants found for UID " 7782 + callingUid + " and Uri " + grantUri.toSafeString()); 7783 } 7784 7785 if (exactValid) { 7786 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7787 } 7788 if (prefixValid) { 7789 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7790 } 7791 7792 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7793 7794 if (persistChanged) { 7795 schedulePersistUriGrants(); 7796 } 7797 } 7798 } 7799 7800 /** 7801 * @param uri This uri must NOT contain an embedded userId. 7802 * @param userId The userId in which the uri is to be resolved. 7803 */ 7804 @Override 7805 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7806 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7807 7808 Preconditions.checkFlagsArgument(modeFlags, 7809 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7810 7811 synchronized (this) { 7812 final int callingUid = Binder.getCallingUid(); 7813 boolean persistChanged = false; 7814 7815 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7816 new GrantUri(userId, uri, false)); 7817 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7818 new GrantUri(userId, uri, true)); 7819 if (exactPerm == null && prefixPerm == null) { 7820 throw new SecurityException("No permission grants found for UID " + callingUid 7821 + " and Uri " + uri.toSafeString()); 7822 } 7823 7824 if (exactPerm != null) { 7825 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7826 removeUriPermissionIfNeededLocked(exactPerm); 7827 } 7828 if (prefixPerm != null) { 7829 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7830 removeUriPermissionIfNeededLocked(prefixPerm); 7831 } 7832 7833 if (persistChanged) { 7834 schedulePersistUriGrants(); 7835 } 7836 } 7837 } 7838 7839 /** 7840 * Prune any older {@link UriPermission} for the given UID until outstanding 7841 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7842 * 7843 * @return if any mutations occured that require persisting. 7844 */ 7845 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7846 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7847 if (perms == null) return false; 7848 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7849 7850 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7851 for (UriPermission perm : perms.values()) { 7852 if (perm.persistedModeFlags != 0) { 7853 persisted.add(perm); 7854 } 7855 } 7856 7857 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7858 if (trimCount <= 0) return false; 7859 7860 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7861 for (int i = 0; i < trimCount; i++) { 7862 final UriPermission perm = persisted.get(i); 7863 7864 if (DEBUG_URI_PERMISSION) { 7865 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7866 } 7867 7868 perm.releasePersistableModes(~0); 7869 removeUriPermissionIfNeededLocked(perm); 7870 } 7871 7872 return true; 7873 } 7874 7875 @Override 7876 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7877 String packageName, boolean incoming) { 7878 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7879 Preconditions.checkNotNull(packageName, "packageName"); 7880 7881 final int callingUid = Binder.getCallingUid(); 7882 final IPackageManager pm = AppGlobals.getPackageManager(); 7883 try { 7884 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7885 if (packageUid != callingUid) { 7886 throw new SecurityException( 7887 "Package " + packageName + " does not belong to calling UID " + callingUid); 7888 } 7889 } catch (RemoteException e) { 7890 throw new SecurityException("Failed to verify package name ownership"); 7891 } 7892 7893 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7894 synchronized (this) { 7895 if (incoming) { 7896 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7897 callingUid); 7898 if (perms == null) { 7899 Slog.w(TAG, "No permission grants found for " + packageName); 7900 } else { 7901 for (UriPermission perm : perms.values()) { 7902 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7903 result.add(perm.buildPersistedPublicApiObject()); 7904 } 7905 } 7906 } 7907 } else { 7908 final int size = mGrantedUriPermissions.size(); 7909 for (int i = 0; i < size; i++) { 7910 final ArrayMap<GrantUri, UriPermission> perms = 7911 mGrantedUriPermissions.valueAt(i); 7912 for (UriPermission perm : perms.values()) { 7913 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7914 result.add(perm.buildPersistedPublicApiObject()); 7915 } 7916 } 7917 } 7918 } 7919 } 7920 return new ParceledListSlice<android.content.UriPermission>(result); 7921 } 7922 7923 @Override 7924 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7925 synchronized (this) { 7926 ProcessRecord app = 7927 who != null ? getRecordForAppLocked(who) : null; 7928 if (app == null) return; 7929 7930 Message msg = Message.obtain(); 7931 msg.what = WAIT_FOR_DEBUGGER_MSG; 7932 msg.obj = app; 7933 msg.arg1 = waiting ? 1 : 0; 7934 mHandler.sendMessage(msg); 7935 } 7936 } 7937 7938 @Override 7939 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7940 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7941 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7942 outInfo.availMem = Process.getFreeMemory(); 7943 outInfo.totalMem = Process.getTotalMemory(); 7944 outInfo.threshold = homeAppMem; 7945 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7946 outInfo.hiddenAppThreshold = cachedAppMem; 7947 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7948 ProcessList.SERVICE_ADJ); 7949 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7950 ProcessList.VISIBLE_APP_ADJ); 7951 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7952 ProcessList.FOREGROUND_APP_ADJ); 7953 } 7954 7955 // ========================================================= 7956 // TASK MANAGEMENT 7957 // ========================================================= 7958 7959 @Override 7960 public List<IAppTask> getAppTasks(String callingPackage) { 7961 int callingUid = Binder.getCallingUid(); 7962 long ident = Binder.clearCallingIdentity(); 7963 7964 synchronized(this) { 7965 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7966 try { 7967 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7968 7969 final int N = mRecentTasks.size(); 7970 for (int i = 0; i < N; i++) { 7971 TaskRecord tr = mRecentTasks.get(i); 7972 // Skip tasks that do not match the caller. We don't need to verify 7973 // callingPackage, because we are also limiting to callingUid and know 7974 // that will limit to the correct security sandbox. 7975 if (tr.effectiveUid != callingUid) { 7976 continue; 7977 } 7978 Intent intent = tr.getBaseIntent(); 7979 if (intent == null || 7980 !callingPackage.equals(intent.getComponent().getPackageName())) { 7981 continue; 7982 } 7983 ActivityManager.RecentTaskInfo taskInfo = 7984 createRecentTaskInfoFromTaskRecord(tr); 7985 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7986 list.add(taskImpl); 7987 } 7988 } finally { 7989 Binder.restoreCallingIdentity(ident); 7990 } 7991 return list; 7992 } 7993 } 7994 7995 @Override 7996 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7997 final int callingUid = Binder.getCallingUid(); 7998 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7999 8000 synchronized(this) { 8001 if (localLOGV) Slog.v( 8002 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8003 8004 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8005 callingUid); 8006 8007 // TODO: Improve with MRU list from all ActivityStacks. 8008 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8009 } 8010 8011 return list; 8012 } 8013 8014 TaskRecord getMostRecentTask() { 8015 return mRecentTasks.get(0); 8016 } 8017 8018 /** 8019 * Creates a new RecentTaskInfo from a TaskRecord. 8020 */ 8021 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8022 // Update the task description to reflect any changes in the task stack 8023 tr.updateTaskDescription(); 8024 8025 // Compose the recent task info 8026 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8027 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8028 rti.persistentId = tr.taskId; 8029 rti.baseIntent = new Intent(tr.getBaseIntent()); 8030 rti.origActivity = tr.origActivity; 8031 rti.description = tr.lastDescription; 8032 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8033 rti.userId = tr.userId; 8034 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8035 rti.firstActiveTime = tr.firstActiveTime; 8036 rti.lastActiveTime = tr.lastActiveTime; 8037 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8038 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8039 return rti; 8040 } 8041 8042 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8043 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8044 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8045 if (!allowed) { 8046 if (checkPermission(android.Manifest.permission.GET_TASKS, 8047 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8048 // Temporary compatibility: some existing apps on the system image may 8049 // still be requesting the old permission and not switched to the new 8050 // one; if so, we'll still allow them full access. This means we need 8051 // to see if they are holding the old permission and are a system app. 8052 try { 8053 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8054 allowed = true; 8055 Slog.w(TAG, caller + ": caller " + callingUid 8056 + " is using old GET_TASKS but privileged; allowing"); 8057 } 8058 } catch (RemoteException e) { 8059 } 8060 } 8061 } 8062 if (!allowed) { 8063 Slog.w(TAG, caller + ": caller " + callingUid 8064 + " does not hold GET_TASKS; limiting output"); 8065 } 8066 return allowed; 8067 } 8068 8069 @Override 8070 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8071 final int callingUid = Binder.getCallingUid(); 8072 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8073 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8074 8075 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8076 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8077 synchronized (this) { 8078 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8079 callingUid); 8080 final boolean detailed = checkCallingPermission( 8081 android.Manifest.permission.GET_DETAILED_TASKS) 8082 == PackageManager.PERMISSION_GRANTED; 8083 8084 final int N = mRecentTasks.size(); 8085 ArrayList<ActivityManager.RecentTaskInfo> res 8086 = new ArrayList<ActivityManager.RecentTaskInfo>( 8087 maxNum < N ? maxNum : N); 8088 8089 final Set<Integer> includedUsers; 8090 if (includeProfiles) { 8091 includedUsers = getProfileIdsLocked(userId); 8092 } else { 8093 includedUsers = new HashSet<Integer>(); 8094 } 8095 includedUsers.add(Integer.valueOf(userId)); 8096 8097 for (int i=0; i<N && maxNum > 0; i++) { 8098 TaskRecord tr = mRecentTasks.get(i); 8099 // Only add calling user or related users recent tasks 8100 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8101 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8102 continue; 8103 } 8104 8105 // Return the entry if desired by the caller. We always return 8106 // the first entry, because callers always expect this to be the 8107 // foreground app. We may filter others if the caller has 8108 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8109 // we should exclude the entry. 8110 8111 if (i == 0 8112 || withExcluded 8113 || (tr.intent == null) 8114 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8115 == 0)) { 8116 if (!allowed) { 8117 // If the caller doesn't have the GET_TASKS permission, then only 8118 // allow them to see a small subset of tasks -- their own and home. 8119 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8120 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8121 continue; 8122 } 8123 } 8124 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8125 if (tr.stack != null && tr.stack.isHomeStack()) { 8126 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8127 continue; 8128 } 8129 } 8130 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8131 // Don't include auto remove tasks that are finished or finishing. 8132 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8133 + tr); 8134 continue; 8135 } 8136 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8137 && !tr.isAvailable) { 8138 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8139 continue; 8140 } 8141 8142 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8143 if (!detailed) { 8144 rti.baseIntent.replaceExtras((Bundle)null); 8145 } 8146 8147 res.add(rti); 8148 maxNum--; 8149 } 8150 } 8151 return res; 8152 } 8153 } 8154 8155 private TaskRecord recentTaskForIdLocked(int id) { 8156 final int N = mRecentTasks.size(); 8157 for (int i=0; i<N; i++) { 8158 TaskRecord tr = mRecentTasks.get(i); 8159 if (tr.taskId == id) { 8160 return tr; 8161 } 8162 } 8163 return null; 8164 } 8165 8166 @Override 8167 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8168 synchronized (this) { 8169 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8170 "getTaskThumbnail()"); 8171 TaskRecord tr = recentTaskForIdLocked(id); 8172 if (tr != null) { 8173 return tr.getTaskThumbnailLocked(); 8174 } 8175 } 8176 return null; 8177 } 8178 8179 @Override 8180 public int addAppTask(IBinder activityToken, Intent intent, 8181 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8182 final int callingUid = Binder.getCallingUid(); 8183 final long callingIdent = Binder.clearCallingIdentity(); 8184 8185 try { 8186 synchronized (this) { 8187 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8188 if (r == null) { 8189 throw new IllegalArgumentException("Activity does not exist; token=" 8190 + activityToken); 8191 } 8192 ComponentName comp = intent.getComponent(); 8193 if (comp == null) { 8194 throw new IllegalArgumentException("Intent " + intent 8195 + " must specify explicit component"); 8196 } 8197 if (thumbnail.getWidth() != mThumbnailWidth 8198 || thumbnail.getHeight() != mThumbnailHeight) { 8199 throw new IllegalArgumentException("Bad thumbnail size: got " 8200 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8201 + mThumbnailWidth + "x" + mThumbnailHeight); 8202 } 8203 if (intent.getSelector() != null) { 8204 intent.setSelector(null); 8205 } 8206 if (intent.getSourceBounds() != null) { 8207 intent.setSourceBounds(null); 8208 } 8209 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8210 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8211 // The caller has added this as an auto-remove task... that makes no 8212 // sense, so turn off auto-remove. 8213 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8214 } 8215 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8216 // Must be a new task. 8217 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8218 } 8219 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8220 mLastAddedTaskActivity = null; 8221 } 8222 ActivityInfo ainfo = mLastAddedTaskActivity; 8223 if (ainfo == null) { 8224 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8225 comp, 0, UserHandle.getUserId(callingUid)); 8226 if (ainfo.applicationInfo.uid != callingUid) { 8227 throw new SecurityException( 8228 "Can't add task for another application: target uid=" 8229 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8230 } 8231 } 8232 8233 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8234 intent, description); 8235 8236 int trimIdx = trimRecentsForTask(task, false); 8237 if (trimIdx >= 0) { 8238 // If this would have caused a trim, then we'll abort because that 8239 // means it would be added at the end of the list but then just removed. 8240 return -1; 8241 } 8242 8243 final int N = mRecentTasks.size(); 8244 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8245 final TaskRecord tr = mRecentTasks.remove(N - 1); 8246 tr.removedFromRecents(mTaskPersister); 8247 } 8248 8249 task.inRecents = true; 8250 mRecentTasks.add(task); 8251 r.task.stack.addTask(task, false, false); 8252 8253 task.setLastThumbnail(thumbnail); 8254 task.freeLastThumbnail(); 8255 8256 return task.taskId; 8257 } 8258 } finally { 8259 Binder.restoreCallingIdentity(callingIdent); 8260 } 8261 } 8262 8263 @Override 8264 public Point getAppTaskThumbnailSize() { 8265 synchronized (this) { 8266 return new Point(mThumbnailWidth, mThumbnailHeight); 8267 } 8268 } 8269 8270 @Override 8271 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8272 synchronized (this) { 8273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8274 if (r != null) { 8275 r.setTaskDescription(td); 8276 r.task.updateTaskDescription(); 8277 } 8278 } 8279 } 8280 8281 @Override 8282 public Bitmap getTaskDescriptionIcon(String filename) { 8283 if (!FileUtils.isValidExtFilename(filename) 8284 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8285 throw new IllegalArgumentException("Bad filename: " + filename); 8286 } 8287 return mTaskPersister.getTaskDescriptionIcon(filename); 8288 } 8289 8290 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8291 mRecentTasks.remove(tr); 8292 tr.removedFromRecents(mTaskPersister); 8293 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8294 Intent baseIntent = new Intent( 8295 tr.intent != null ? tr.intent : tr.affinityIntent); 8296 ComponentName component = baseIntent.getComponent(); 8297 if (component == null) { 8298 Slog.w(TAG, "Now component for base intent of task: " + tr); 8299 return; 8300 } 8301 8302 // Find any running services associated with this app. 8303 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8304 8305 if (killProcesses) { 8306 // Find any running processes associated with this app. 8307 final String pkg = component.getPackageName(); 8308 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8309 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8310 for (int i=0; i<pmap.size(); i++) { 8311 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8312 for (int j=0; j<uids.size(); j++) { 8313 ProcessRecord proc = uids.valueAt(j); 8314 if (proc.userId != tr.userId) { 8315 continue; 8316 } 8317 if (!proc.pkgList.containsKey(pkg)) { 8318 continue; 8319 } 8320 procs.add(proc); 8321 } 8322 } 8323 8324 // Kill the running processes. 8325 for (int i=0; i<procs.size(); i++) { 8326 ProcessRecord pr = procs.get(i); 8327 if (pr == mHomeProcess) { 8328 // Don't kill the home process along with tasks from the same package. 8329 continue; 8330 } 8331 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8332 pr.kill("remove task", true); 8333 } else { 8334 pr.waitingToKill = "remove task"; 8335 } 8336 } 8337 } 8338 } 8339 8340 /** 8341 * Removes the task with the specified task id. 8342 * 8343 * @param taskId Identifier of the task to be removed. 8344 * @param flags Additional operational flags. May be 0 or 8345 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8346 * @return Returns true if the given task was found and removed. 8347 */ 8348 private boolean removeTaskByIdLocked(int taskId, int flags) { 8349 TaskRecord tr = recentTaskForIdLocked(taskId); 8350 if (tr != null) { 8351 tr.removeTaskActivitiesLocked(); 8352 cleanUpRemovedTaskLocked(tr, flags); 8353 if (tr.isPersistable) { 8354 notifyTaskPersisterLocked(null, true); 8355 } 8356 return true; 8357 } 8358 return false; 8359 } 8360 8361 @Override 8362 public boolean removeTask(int taskId, int flags) { 8363 synchronized (this) { 8364 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8365 "removeTask()"); 8366 long ident = Binder.clearCallingIdentity(); 8367 try { 8368 return removeTaskByIdLocked(taskId, flags); 8369 } finally { 8370 Binder.restoreCallingIdentity(ident); 8371 } 8372 } 8373 } 8374 8375 /** 8376 * TODO: Add mController hook 8377 */ 8378 @Override 8379 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8380 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8381 "moveTaskToFront()"); 8382 8383 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8384 synchronized(this) { 8385 moveTaskToFrontLocked(taskId, flags, options); 8386 } 8387 } 8388 8389 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8390 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8391 Binder.getCallingUid(), -1, -1, "Task to front")) { 8392 ActivityOptions.abort(options); 8393 return; 8394 } 8395 final long origId = Binder.clearCallingIdentity(); 8396 try { 8397 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8398 if (task == null) { 8399 return; 8400 } 8401 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8402 mStackSupervisor.showLockTaskToast(); 8403 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8404 return; 8405 } 8406 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8407 if (prev != null && prev.isRecentsActivity()) { 8408 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8409 } 8410 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8411 } finally { 8412 Binder.restoreCallingIdentity(origId); 8413 } 8414 ActivityOptions.abort(options); 8415 } 8416 8417 @Override 8418 public void moveTaskToBack(int taskId) { 8419 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8420 "moveTaskToBack()"); 8421 8422 synchronized(this) { 8423 TaskRecord tr = recentTaskForIdLocked(taskId); 8424 if (tr != null) { 8425 if (tr == mStackSupervisor.mLockTaskModeTask) { 8426 mStackSupervisor.showLockTaskToast(); 8427 return; 8428 } 8429 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8430 ActivityStack stack = tr.stack; 8431 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8432 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8433 Binder.getCallingUid(), -1, -1, "Task to back")) { 8434 return; 8435 } 8436 } 8437 final long origId = Binder.clearCallingIdentity(); 8438 try { 8439 stack.moveTaskToBackLocked(taskId, null); 8440 } finally { 8441 Binder.restoreCallingIdentity(origId); 8442 } 8443 } 8444 } 8445 } 8446 8447 /** 8448 * Moves an activity, and all of the other activities within the same task, to the bottom 8449 * of the history stack. The activity's order within the task is unchanged. 8450 * 8451 * @param token A reference to the activity we wish to move 8452 * @param nonRoot If false then this only works if the activity is the root 8453 * of a task; if true it will work for any activity in a task. 8454 * @return Returns true if the move completed, false if not. 8455 */ 8456 @Override 8457 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8458 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8459 synchronized(this) { 8460 final long origId = Binder.clearCallingIdentity(); 8461 try { 8462 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8463 if (taskId >= 0) { 8464 if ((mStackSupervisor.mLockTaskModeTask != null) 8465 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8466 mStackSupervisor.showLockTaskToast(); 8467 return false; 8468 } 8469 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8470 } 8471 } finally { 8472 Binder.restoreCallingIdentity(origId); 8473 } 8474 } 8475 return false; 8476 } 8477 8478 @Override 8479 public void moveTaskBackwards(int task) { 8480 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8481 "moveTaskBackwards()"); 8482 8483 synchronized(this) { 8484 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8485 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8486 return; 8487 } 8488 final long origId = Binder.clearCallingIdentity(); 8489 moveTaskBackwardsLocked(task); 8490 Binder.restoreCallingIdentity(origId); 8491 } 8492 } 8493 8494 private final void moveTaskBackwardsLocked(int task) { 8495 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8496 } 8497 8498 @Override 8499 public IBinder getHomeActivityToken() throws RemoteException { 8500 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8501 "getHomeActivityToken()"); 8502 synchronized (this) { 8503 return mStackSupervisor.getHomeActivityToken(); 8504 } 8505 } 8506 8507 @Override 8508 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8509 IActivityContainerCallback callback) throws RemoteException { 8510 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8511 "createActivityContainer()"); 8512 synchronized (this) { 8513 if (parentActivityToken == null) { 8514 throw new IllegalArgumentException("parent token must not be null"); 8515 } 8516 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8517 if (r == null) { 8518 return null; 8519 } 8520 if (callback == null) { 8521 throw new IllegalArgumentException("callback must not be null"); 8522 } 8523 return mStackSupervisor.createActivityContainer(r, callback); 8524 } 8525 } 8526 8527 @Override 8528 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8529 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8530 "deleteActivityContainer()"); 8531 synchronized (this) { 8532 mStackSupervisor.deleteActivityContainer(container); 8533 } 8534 } 8535 8536 @Override 8537 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8538 throws RemoteException { 8539 synchronized (this) { 8540 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8541 if (stack != null) { 8542 return stack.mActivityContainer; 8543 } 8544 return null; 8545 } 8546 } 8547 8548 @Override 8549 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8550 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8551 "moveTaskToStack()"); 8552 if (stackId == HOME_STACK_ID) { 8553 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8554 new RuntimeException("here").fillInStackTrace()); 8555 } 8556 synchronized (this) { 8557 long ident = Binder.clearCallingIdentity(); 8558 try { 8559 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8560 + stackId + " toTop=" + toTop); 8561 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8562 } finally { 8563 Binder.restoreCallingIdentity(ident); 8564 } 8565 } 8566 } 8567 8568 @Override 8569 public void resizeStack(int stackBoxId, Rect bounds) { 8570 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8571 "resizeStackBox()"); 8572 long ident = Binder.clearCallingIdentity(); 8573 try { 8574 mWindowManager.resizeStack(stackBoxId, bounds); 8575 } finally { 8576 Binder.restoreCallingIdentity(ident); 8577 } 8578 } 8579 8580 @Override 8581 public List<StackInfo> getAllStackInfos() { 8582 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8583 "getAllStackInfos()"); 8584 long ident = Binder.clearCallingIdentity(); 8585 try { 8586 synchronized (this) { 8587 return mStackSupervisor.getAllStackInfosLocked(); 8588 } 8589 } finally { 8590 Binder.restoreCallingIdentity(ident); 8591 } 8592 } 8593 8594 @Override 8595 public StackInfo getStackInfo(int stackId) { 8596 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8597 "getStackInfo()"); 8598 long ident = Binder.clearCallingIdentity(); 8599 try { 8600 synchronized (this) { 8601 return mStackSupervisor.getStackInfoLocked(stackId); 8602 } 8603 } finally { 8604 Binder.restoreCallingIdentity(ident); 8605 } 8606 } 8607 8608 @Override 8609 public boolean isInHomeStack(int taskId) { 8610 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8611 "getStackInfo()"); 8612 long ident = Binder.clearCallingIdentity(); 8613 try { 8614 synchronized (this) { 8615 TaskRecord tr = recentTaskForIdLocked(taskId); 8616 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8617 } 8618 } finally { 8619 Binder.restoreCallingIdentity(ident); 8620 } 8621 } 8622 8623 @Override 8624 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8625 synchronized(this) { 8626 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8627 } 8628 } 8629 8630 private boolean isLockTaskAuthorized(String pkg) { 8631 final DevicePolicyManager dpm = (DevicePolicyManager) 8632 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8633 try { 8634 int uid = mContext.getPackageManager().getPackageUid(pkg, 8635 Binder.getCallingUserHandle().getIdentifier()); 8636 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8637 } catch (NameNotFoundException e) { 8638 return false; 8639 } 8640 } 8641 8642 void startLockTaskMode(TaskRecord task) { 8643 final String pkg; 8644 synchronized (this) { 8645 pkg = task.intent.getComponent().getPackageName(); 8646 } 8647 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8648 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8649 final TaskRecord taskRecord = task; 8650 mHandler.post(new Runnable() { 8651 @Override 8652 public void run() { 8653 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8654 } 8655 }); 8656 return; 8657 } 8658 long ident = Binder.clearCallingIdentity(); 8659 try { 8660 synchronized (this) { 8661 // Since we lost lock on task, make sure it is still there. 8662 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8663 if (task != null) { 8664 if (!isSystemInitiated 8665 && ((mStackSupervisor.getFocusedStack() == null) 8666 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8667 throw new IllegalArgumentException("Invalid task, not in foreground"); 8668 } 8669 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8670 } 8671 } 8672 } finally { 8673 Binder.restoreCallingIdentity(ident); 8674 } 8675 } 8676 8677 @Override 8678 public void startLockTaskMode(int taskId) { 8679 final TaskRecord task; 8680 long ident = Binder.clearCallingIdentity(); 8681 try { 8682 synchronized (this) { 8683 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8684 } 8685 } finally { 8686 Binder.restoreCallingIdentity(ident); 8687 } 8688 if (task != null) { 8689 startLockTaskMode(task); 8690 } 8691 } 8692 8693 @Override 8694 public void startLockTaskMode(IBinder token) { 8695 final TaskRecord task; 8696 long ident = Binder.clearCallingIdentity(); 8697 try { 8698 synchronized (this) { 8699 final ActivityRecord r = ActivityRecord.forToken(token); 8700 if (r == null) { 8701 return; 8702 } 8703 task = r.task; 8704 } 8705 } finally { 8706 Binder.restoreCallingIdentity(ident); 8707 } 8708 if (task != null) { 8709 startLockTaskMode(task); 8710 } 8711 } 8712 8713 @Override 8714 public void startLockTaskModeOnCurrent() throws RemoteException { 8715 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8716 "startLockTaskModeOnCurrent"); 8717 ActivityRecord r = null; 8718 synchronized (this) { 8719 r = mStackSupervisor.topRunningActivityLocked(); 8720 } 8721 startLockTaskMode(r.task); 8722 } 8723 8724 @Override 8725 public void stopLockTaskMode() { 8726 // Verify that the user matches the package of the intent for the TaskRecord 8727 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8728 // and stopLockTaskMode. 8729 final int callingUid = Binder.getCallingUid(); 8730 if (callingUid != Process.SYSTEM_UID) { 8731 try { 8732 String pkg = 8733 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8734 int uid = mContext.getPackageManager().getPackageUid(pkg, 8735 Binder.getCallingUserHandle().getIdentifier()); 8736 if (uid != callingUid) { 8737 throw new SecurityException("Invalid uid, expected " + uid); 8738 } 8739 } catch (NameNotFoundException e) { 8740 Log.d(TAG, "stopLockTaskMode " + e); 8741 return; 8742 } 8743 } 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 Log.d(TAG, "stopLockTaskMode"); 8747 // Stop lock task 8748 synchronized (this) { 8749 mStackSupervisor.setLockTaskModeLocked(null, false); 8750 } 8751 } finally { 8752 Binder.restoreCallingIdentity(ident); 8753 } 8754 } 8755 8756 @Override 8757 public void stopLockTaskModeOnCurrent() throws RemoteException { 8758 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8759 "stopLockTaskModeOnCurrent"); 8760 long ident = Binder.clearCallingIdentity(); 8761 try { 8762 stopLockTaskMode(); 8763 } finally { 8764 Binder.restoreCallingIdentity(ident); 8765 } 8766 } 8767 8768 @Override 8769 public boolean isInLockTaskMode() { 8770 synchronized (this) { 8771 return mStackSupervisor.isInLockTaskMode(); 8772 } 8773 } 8774 8775 // ========================================================= 8776 // CONTENT PROVIDERS 8777 // ========================================================= 8778 8779 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8780 List<ProviderInfo> providers = null; 8781 try { 8782 providers = AppGlobals.getPackageManager(). 8783 queryContentProviders(app.processName, app.uid, 8784 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8785 } catch (RemoteException ex) { 8786 } 8787 if (DEBUG_MU) 8788 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8789 int userId = app.userId; 8790 if (providers != null) { 8791 int N = providers.size(); 8792 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8793 for (int i=0; i<N; i++) { 8794 ProviderInfo cpi = 8795 (ProviderInfo)providers.get(i); 8796 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8797 cpi.name, cpi.flags); 8798 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8799 // This is a singleton provider, but a user besides the 8800 // default user is asking to initialize a process it runs 8801 // in... well, no, it doesn't actually run in this process, 8802 // it runs in the process of the default user. Get rid of it. 8803 providers.remove(i); 8804 N--; 8805 i--; 8806 continue; 8807 } 8808 8809 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8810 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8811 if (cpr == null) { 8812 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8813 mProviderMap.putProviderByClass(comp, cpr); 8814 } 8815 if (DEBUG_MU) 8816 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8817 app.pubProviders.put(cpi.name, cpr); 8818 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8819 // Don't add this if it is a platform component that is marked 8820 // to run in multiple processes, because this is actually 8821 // part of the framework so doesn't make sense to track as a 8822 // separate apk in the process. 8823 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8824 mProcessStats); 8825 } 8826 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8827 } 8828 } 8829 return providers; 8830 } 8831 8832 /** 8833 * Check if {@link ProcessRecord} has a possible chance at accessing the 8834 * given {@link ProviderInfo}. Final permission checking is always done 8835 * in {@link ContentProvider}. 8836 */ 8837 private final String checkContentProviderPermissionLocked( 8838 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8839 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8840 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8841 boolean checkedGrants = false; 8842 if (checkUser) { 8843 // Looking for cross-user grants before enforcing the typical cross-users permissions 8844 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8845 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8846 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8847 return null; 8848 } 8849 checkedGrants = true; 8850 } 8851 userId = handleIncomingUser(callingPid, callingUid, userId, 8852 false, ALLOW_NON_FULL, 8853 "checkContentProviderPermissionLocked " + cpi.authority, null); 8854 if (userId != tmpTargetUserId) { 8855 // When we actually went to determine the final targer user ID, this ended 8856 // up different than our initial check for the authority. This is because 8857 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8858 // SELF. So we need to re-check the grants again. 8859 checkedGrants = false; 8860 } 8861 } 8862 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8863 cpi.applicationInfo.uid, cpi.exported) 8864 == PackageManager.PERMISSION_GRANTED) { 8865 return null; 8866 } 8867 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8868 cpi.applicationInfo.uid, cpi.exported) 8869 == PackageManager.PERMISSION_GRANTED) { 8870 return null; 8871 } 8872 8873 PathPermission[] pps = cpi.pathPermissions; 8874 if (pps != null) { 8875 int i = pps.length; 8876 while (i > 0) { 8877 i--; 8878 PathPermission pp = pps[i]; 8879 String pprperm = pp.getReadPermission(); 8880 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8881 cpi.applicationInfo.uid, cpi.exported) 8882 == PackageManager.PERMISSION_GRANTED) { 8883 return null; 8884 } 8885 String ppwperm = pp.getWritePermission(); 8886 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8887 cpi.applicationInfo.uid, cpi.exported) 8888 == PackageManager.PERMISSION_GRANTED) { 8889 return null; 8890 } 8891 } 8892 } 8893 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8894 return null; 8895 } 8896 8897 String msg; 8898 if (!cpi.exported) { 8899 msg = "Permission Denial: opening provider " + cpi.name 8900 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8901 + ", uid=" + callingUid + ") that is not exported from uid " 8902 + cpi.applicationInfo.uid; 8903 } else { 8904 msg = "Permission Denial: opening provider " + cpi.name 8905 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8906 + ", uid=" + callingUid + ") requires " 8907 + cpi.readPermission + " or " + cpi.writePermission; 8908 } 8909 Slog.w(TAG, msg); 8910 return msg; 8911 } 8912 8913 /** 8914 * Returns if the ContentProvider has granted a uri to callingUid 8915 */ 8916 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8917 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8918 if (perms != null) { 8919 for (int i=perms.size()-1; i>=0; i--) { 8920 GrantUri grantUri = perms.keyAt(i); 8921 if (grantUri.sourceUserId == userId || !checkUser) { 8922 if (matchesProvider(grantUri.uri, cpi)) { 8923 return true; 8924 } 8925 } 8926 } 8927 } 8928 return false; 8929 } 8930 8931 /** 8932 * Returns true if the uri authority is one of the authorities specified in the provider. 8933 */ 8934 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8935 String uriAuth = uri.getAuthority(); 8936 String cpiAuth = cpi.authority; 8937 if (cpiAuth.indexOf(';') == -1) { 8938 return cpiAuth.equals(uriAuth); 8939 } 8940 String[] cpiAuths = cpiAuth.split(";"); 8941 int length = cpiAuths.length; 8942 for (int i = 0; i < length; i++) { 8943 if (cpiAuths[i].equals(uriAuth)) return true; 8944 } 8945 return false; 8946 } 8947 8948 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8949 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8950 if (r != null) { 8951 for (int i=0; i<r.conProviders.size(); i++) { 8952 ContentProviderConnection conn = r.conProviders.get(i); 8953 if (conn.provider == cpr) { 8954 if (DEBUG_PROVIDER) Slog.v(TAG, 8955 "Adding provider requested by " 8956 + r.processName + " from process " 8957 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8958 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8959 if (stable) { 8960 conn.stableCount++; 8961 conn.numStableIncs++; 8962 } else { 8963 conn.unstableCount++; 8964 conn.numUnstableIncs++; 8965 } 8966 return conn; 8967 } 8968 } 8969 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8970 if (stable) { 8971 conn.stableCount = 1; 8972 conn.numStableIncs = 1; 8973 } else { 8974 conn.unstableCount = 1; 8975 conn.numUnstableIncs = 1; 8976 } 8977 cpr.connections.add(conn); 8978 r.conProviders.add(conn); 8979 return conn; 8980 } 8981 cpr.addExternalProcessHandleLocked(externalProcessToken); 8982 return null; 8983 } 8984 8985 boolean decProviderCountLocked(ContentProviderConnection conn, 8986 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8987 if (conn != null) { 8988 cpr = conn.provider; 8989 if (DEBUG_PROVIDER) Slog.v(TAG, 8990 "Removing provider requested by " 8991 + conn.client.processName + " from process " 8992 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8993 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8994 if (stable) { 8995 conn.stableCount--; 8996 } else { 8997 conn.unstableCount--; 8998 } 8999 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9000 cpr.connections.remove(conn); 9001 conn.client.conProviders.remove(conn); 9002 return true; 9003 } 9004 return false; 9005 } 9006 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9007 return false; 9008 } 9009 9010 private void checkTime(long startTime, String where) { 9011 long now = SystemClock.elapsedRealtime(); 9012 if ((now-startTime) > 1000) { 9013 // If we are taking more than a second, log about it. 9014 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9015 } 9016 } 9017 9018 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9019 String name, IBinder token, boolean stable, int userId) { 9020 ContentProviderRecord cpr; 9021 ContentProviderConnection conn = null; 9022 ProviderInfo cpi = null; 9023 9024 synchronized(this) { 9025 long startTime = SystemClock.elapsedRealtime(); 9026 9027 ProcessRecord r = null; 9028 if (caller != null) { 9029 r = getRecordForAppLocked(caller); 9030 if (r == null) { 9031 throw new SecurityException( 9032 "Unable to find app for caller " + caller 9033 + " (pid=" + Binder.getCallingPid() 9034 + ") when getting content provider " + name); 9035 } 9036 } 9037 9038 boolean checkCrossUser = true; 9039 9040 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9041 9042 // First check if this content provider has been published... 9043 cpr = mProviderMap.getProviderByName(name, userId); 9044 // If that didn't work, check if it exists for user 0 and then 9045 // verify that it's a singleton provider before using it. 9046 if (cpr == null && userId != UserHandle.USER_OWNER) { 9047 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9048 if (cpr != null) { 9049 cpi = cpr.info; 9050 if (isSingleton(cpi.processName, cpi.applicationInfo, 9051 cpi.name, cpi.flags) 9052 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9053 userId = UserHandle.USER_OWNER; 9054 checkCrossUser = false; 9055 } else { 9056 cpr = null; 9057 cpi = null; 9058 } 9059 } 9060 } 9061 9062 boolean providerRunning = cpr != null; 9063 if (providerRunning) { 9064 cpi = cpr.info; 9065 String msg; 9066 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9067 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9068 != null) { 9069 throw new SecurityException(msg); 9070 } 9071 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9072 9073 if (r != null && cpr.canRunHere(r)) { 9074 // This provider has been published or is in the process 9075 // of being published... but it is also allowed to run 9076 // in the caller's process, so don't make a connection 9077 // and just let the caller instantiate its own instance. 9078 ContentProviderHolder holder = cpr.newHolder(null); 9079 // don't give caller the provider object, it needs 9080 // to make its own. 9081 holder.provider = null; 9082 return holder; 9083 } 9084 9085 final long origId = Binder.clearCallingIdentity(); 9086 9087 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9088 9089 // In this case the provider instance already exists, so we can 9090 // return it right away. 9091 conn = incProviderCountLocked(r, cpr, token, stable); 9092 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9093 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9094 // If this is a perceptible app accessing the provider, 9095 // make sure to count it as being accessed and thus 9096 // back up on the LRU list. This is good because 9097 // content providers are often expensive to start. 9098 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9099 updateLruProcessLocked(cpr.proc, false, null); 9100 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9101 } 9102 } 9103 9104 if (cpr.proc != null) { 9105 if (false) { 9106 if (cpr.name.flattenToShortString().equals( 9107 "com.android.providers.calendar/.CalendarProvider2")) { 9108 Slog.v(TAG, "****************** KILLING " 9109 + cpr.name.flattenToShortString()); 9110 Process.killProcess(cpr.proc.pid); 9111 } 9112 } 9113 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9114 boolean success = updateOomAdjLocked(cpr.proc); 9115 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9116 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9117 // NOTE: there is still a race here where a signal could be 9118 // pending on the process even though we managed to update its 9119 // adj level. Not sure what to do about this, but at least 9120 // the race is now smaller. 9121 if (!success) { 9122 // Uh oh... it looks like the provider's process 9123 // has been killed on us. We need to wait for a new 9124 // process to be started, and make sure its death 9125 // doesn't kill our process. 9126 Slog.i(TAG, 9127 "Existing provider " + cpr.name.flattenToShortString() 9128 + " is crashing; detaching " + r); 9129 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9130 checkTime(startTime, "getContentProviderImpl: before appDied"); 9131 appDiedLocked(cpr.proc); 9132 checkTime(startTime, "getContentProviderImpl: after appDied"); 9133 if (!lastRef) { 9134 // This wasn't the last ref our process had on 9135 // the provider... we have now been killed, bail. 9136 return null; 9137 } 9138 providerRunning = false; 9139 conn = null; 9140 } 9141 } 9142 9143 Binder.restoreCallingIdentity(origId); 9144 } 9145 9146 boolean singleton; 9147 if (!providerRunning) { 9148 try { 9149 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9150 cpi = AppGlobals.getPackageManager(). 9151 resolveContentProvider(name, 9152 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9153 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9154 } catch (RemoteException ex) { 9155 } 9156 if (cpi == null) { 9157 return null; 9158 } 9159 // If the provider is a singleton AND 9160 // (it's a call within the same user || the provider is a 9161 // privileged app) 9162 // Then allow connecting to the singleton provider 9163 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9164 cpi.name, cpi.flags) 9165 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9166 if (singleton) { 9167 userId = UserHandle.USER_OWNER; 9168 } 9169 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9170 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9171 9172 String msg; 9173 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9174 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9175 != null) { 9176 throw new SecurityException(msg); 9177 } 9178 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9179 9180 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9181 && !cpi.processName.equals("system")) { 9182 // If this content provider does not run in the system 9183 // process, and the system is not yet ready to run other 9184 // processes, then fail fast instead of hanging. 9185 throw new IllegalArgumentException( 9186 "Attempt to launch content provider before system ready"); 9187 } 9188 9189 // Make sure that the user who owns this provider is started. If not, 9190 // we don't want to allow it to run. 9191 if (mStartedUsers.get(userId) == null) { 9192 Slog.w(TAG, "Unable to launch app " 9193 + cpi.applicationInfo.packageName + "/" 9194 + cpi.applicationInfo.uid + " for provider " 9195 + name + ": user " + userId + " is stopped"); 9196 return null; 9197 } 9198 9199 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9200 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9201 cpr = mProviderMap.getProviderByClass(comp, userId); 9202 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9203 final boolean firstClass = cpr == null; 9204 if (firstClass) { 9205 final long ident = Binder.clearCallingIdentity(); 9206 try { 9207 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9208 ApplicationInfo ai = 9209 AppGlobals.getPackageManager(). 9210 getApplicationInfo( 9211 cpi.applicationInfo.packageName, 9212 STOCK_PM_FLAGS, userId); 9213 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9214 if (ai == null) { 9215 Slog.w(TAG, "No package info for content provider " 9216 + cpi.name); 9217 return null; 9218 } 9219 ai = getAppInfoForUser(ai, userId); 9220 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9221 } catch (RemoteException ex) { 9222 // pm is in same process, this will never happen. 9223 } finally { 9224 Binder.restoreCallingIdentity(ident); 9225 } 9226 } 9227 9228 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9229 9230 if (r != null && cpr.canRunHere(r)) { 9231 // If this is a multiprocess provider, then just return its 9232 // info and allow the caller to instantiate it. Only do 9233 // this if the provider is the same user as the caller's 9234 // process, or can run as root (so can be in any process). 9235 return cpr.newHolder(null); 9236 } 9237 9238 if (DEBUG_PROVIDER) { 9239 RuntimeException e = new RuntimeException("here"); 9240 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9241 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9242 } 9243 9244 // This is single process, and our app is now connecting to it. 9245 // See if we are already in the process of launching this 9246 // provider. 9247 final int N = mLaunchingProviders.size(); 9248 int i; 9249 for (i=0; i<N; i++) { 9250 if (mLaunchingProviders.get(i) == cpr) { 9251 break; 9252 } 9253 } 9254 9255 // If the provider is not already being launched, then get it 9256 // started. 9257 if (i >= N) { 9258 final long origId = Binder.clearCallingIdentity(); 9259 9260 try { 9261 // Content provider is now in use, its package can't be stopped. 9262 try { 9263 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9264 AppGlobals.getPackageManager().setPackageStoppedState( 9265 cpr.appInfo.packageName, false, userId); 9266 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9267 } catch (RemoteException e) { 9268 } catch (IllegalArgumentException e) { 9269 Slog.w(TAG, "Failed trying to unstop package " 9270 + cpr.appInfo.packageName + ": " + e); 9271 } 9272 9273 // Use existing process if already started 9274 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9275 ProcessRecord proc = getProcessRecordLocked( 9276 cpi.processName, cpr.appInfo.uid, false); 9277 if (proc != null && proc.thread != null) { 9278 if (DEBUG_PROVIDER) { 9279 Slog.d(TAG, "Installing in existing process " + proc); 9280 } 9281 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9282 proc.pubProviders.put(cpi.name, cpr); 9283 try { 9284 proc.thread.scheduleInstallProvider(cpi); 9285 } catch (RemoteException e) { 9286 } 9287 } else { 9288 checkTime(startTime, "getContentProviderImpl: before start process"); 9289 proc = startProcessLocked(cpi.processName, 9290 cpr.appInfo, false, 0, "content provider", 9291 new ComponentName(cpi.applicationInfo.packageName, 9292 cpi.name), false, false, false); 9293 checkTime(startTime, "getContentProviderImpl: after start process"); 9294 if (proc == null) { 9295 Slog.w(TAG, "Unable to launch app " 9296 + cpi.applicationInfo.packageName + "/" 9297 + cpi.applicationInfo.uid + " for provider " 9298 + name + ": process is bad"); 9299 return null; 9300 } 9301 } 9302 cpr.launchingApp = proc; 9303 mLaunchingProviders.add(cpr); 9304 } finally { 9305 Binder.restoreCallingIdentity(origId); 9306 } 9307 } 9308 9309 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9310 9311 // Make sure the provider is published (the same provider class 9312 // may be published under multiple names). 9313 if (firstClass) { 9314 mProviderMap.putProviderByClass(comp, cpr); 9315 } 9316 9317 mProviderMap.putProviderByName(name, cpr); 9318 conn = incProviderCountLocked(r, cpr, token, stable); 9319 if (conn != null) { 9320 conn.waiting = true; 9321 } 9322 } 9323 checkTime(startTime, "getContentProviderImpl: done!"); 9324 } 9325 9326 // Wait for the provider to be published... 9327 synchronized (cpr) { 9328 while (cpr.provider == null) { 9329 if (cpr.launchingApp == null) { 9330 Slog.w(TAG, "Unable to launch app " 9331 + cpi.applicationInfo.packageName + "/" 9332 + cpi.applicationInfo.uid + " for provider " 9333 + name + ": launching app became null"); 9334 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9335 UserHandle.getUserId(cpi.applicationInfo.uid), 9336 cpi.applicationInfo.packageName, 9337 cpi.applicationInfo.uid, name); 9338 return null; 9339 } 9340 try { 9341 if (DEBUG_MU) { 9342 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9343 + cpr.launchingApp); 9344 } 9345 if (conn != null) { 9346 conn.waiting = true; 9347 } 9348 cpr.wait(); 9349 } catch (InterruptedException ex) { 9350 } finally { 9351 if (conn != null) { 9352 conn.waiting = false; 9353 } 9354 } 9355 } 9356 } 9357 return cpr != null ? cpr.newHolder(conn) : null; 9358 } 9359 9360 @Override 9361 public final ContentProviderHolder getContentProvider( 9362 IApplicationThread caller, String name, int userId, boolean stable) { 9363 enforceNotIsolatedCaller("getContentProvider"); 9364 if (caller == null) { 9365 String msg = "null IApplicationThread when getting content provider " 9366 + name; 9367 Slog.w(TAG, msg); 9368 throw new SecurityException(msg); 9369 } 9370 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9371 // with cross-user grant. 9372 return getContentProviderImpl(caller, name, null, stable, userId); 9373 } 9374 9375 public ContentProviderHolder getContentProviderExternal( 9376 String name, int userId, IBinder token) { 9377 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9378 "Do not have permission in call getContentProviderExternal()"); 9379 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9380 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9381 return getContentProviderExternalUnchecked(name, token, userId); 9382 } 9383 9384 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9385 IBinder token, int userId) { 9386 return getContentProviderImpl(null, name, token, true, userId); 9387 } 9388 9389 /** 9390 * Drop a content provider from a ProcessRecord's bookkeeping 9391 */ 9392 public void removeContentProvider(IBinder connection, boolean stable) { 9393 enforceNotIsolatedCaller("removeContentProvider"); 9394 long ident = Binder.clearCallingIdentity(); 9395 try { 9396 synchronized (this) { 9397 ContentProviderConnection conn; 9398 try { 9399 conn = (ContentProviderConnection)connection; 9400 } catch (ClassCastException e) { 9401 String msg ="removeContentProvider: " + connection 9402 + " not a ContentProviderConnection"; 9403 Slog.w(TAG, msg); 9404 throw new IllegalArgumentException(msg); 9405 } 9406 if (conn == null) { 9407 throw new NullPointerException("connection is null"); 9408 } 9409 if (decProviderCountLocked(conn, null, null, stable)) { 9410 updateOomAdjLocked(); 9411 } 9412 } 9413 } finally { 9414 Binder.restoreCallingIdentity(ident); 9415 } 9416 } 9417 9418 public void removeContentProviderExternal(String name, IBinder token) { 9419 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9420 "Do not have permission in call removeContentProviderExternal()"); 9421 int userId = UserHandle.getCallingUserId(); 9422 long ident = Binder.clearCallingIdentity(); 9423 try { 9424 removeContentProviderExternalUnchecked(name, token, userId); 9425 } finally { 9426 Binder.restoreCallingIdentity(ident); 9427 } 9428 } 9429 9430 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9431 synchronized (this) { 9432 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9433 if(cpr == null) { 9434 //remove from mProvidersByClass 9435 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9436 return; 9437 } 9438 9439 //update content provider record entry info 9440 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9441 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9442 if (localCpr.hasExternalProcessHandles()) { 9443 if (localCpr.removeExternalProcessHandleLocked(token)) { 9444 updateOomAdjLocked(); 9445 } else { 9446 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9447 + " with no external reference for token: " 9448 + token + "."); 9449 } 9450 } else { 9451 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9452 + " with no external references."); 9453 } 9454 } 9455 } 9456 9457 public final void publishContentProviders(IApplicationThread caller, 9458 List<ContentProviderHolder> providers) { 9459 if (providers == null) { 9460 return; 9461 } 9462 9463 enforceNotIsolatedCaller("publishContentProviders"); 9464 synchronized (this) { 9465 final ProcessRecord r = getRecordForAppLocked(caller); 9466 if (DEBUG_MU) 9467 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9468 if (r == null) { 9469 throw new SecurityException( 9470 "Unable to find app for caller " + caller 9471 + " (pid=" + Binder.getCallingPid() 9472 + ") when publishing content providers"); 9473 } 9474 9475 final long origId = Binder.clearCallingIdentity(); 9476 9477 final int N = providers.size(); 9478 for (int i=0; i<N; i++) { 9479 ContentProviderHolder src = providers.get(i); 9480 if (src == null || src.info == null || src.provider == null) { 9481 continue; 9482 } 9483 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9484 if (DEBUG_MU) 9485 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9486 if (dst != null) { 9487 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9488 mProviderMap.putProviderByClass(comp, dst); 9489 String names[] = dst.info.authority.split(";"); 9490 for (int j = 0; j < names.length; j++) { 9491 mProviderMap.putProviderByName(names[j], dst); 9492 } 9493 9494 int NL = mLaunchingProviders.size(); 9495 int j; 9496 for (j=0; j<NL; j++) { 9497 if (mLaunchingProviders.get(j) == dst) { 9498 mLaunchingProviders.remove(j); 9499 j--; 9500 NL--; 9501 } 9502 } 9503 synchronized (dst) { 9504 dst.provider = src.provider; 9505 dst.proc = r; 9506 dst.notifyAll(); 9507 } 9508 updateOomAdjLocked(r); 9509 } 9510 } 9511 9512 Binder.restoreCallingIdentity(origId); 9513 } 9514 } 9515 9516 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9517 ContentProviderConnection conn; 9518 try { 9519 conn = (ContentProviderConnection)connection; 9520 } catch (ClassCastException e) { 9521 String msg ="refContentProvider: " + connection 9522 + " not a ContentProviderConnection"; 9523 Slog.w(TAG, msg); 9524 throw new IllegalArgumentException(msg); 9525 } 9526 if (conn == null) { 9527 throw new NullPointerException("connection is null"); 9528 } 9529 9530 synchronized (this) { 9531 if (stable > 0) { 9532 conn.numStableIncs += stable; 9533 } 9534 stable = conn.stableCount + stable; 9535 if (stable < 0) { 9536 throw new IllegalStateException("stableCount < 0: " + stable); 9537 } 9538 9539 if (unstable > 0) { 9540 conn.numUnstableIncs += unstable; 9541 } 9542 unstable = conn.unstableCount + unstable; 9543 if (unstable < 0) { 9544 throw new IllegalStateException("unstableCount < 0: " + unstable); 9545 } 9546 9547 if ((stable+unstable) <= 0) { 9548 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9549 + stable + " unstable=" + unstable); 9550 } 9551 conn.stableCount = stable; 9552 conn.unstableCount = unstable; 9553 return !conn.dead; 9554 } 9555 } 9556 9557 public void unstableProviderDied(IBinder connection) { 9558 ContentProviderConnection conn; 9559 try { 9560 conn = (ContentProviderConnection)connection; 9561 } catch (ClassCastException e) { 9562 String msg ="refContentProvider: " + connection 9563 + " not a ContentProviderConnection"; 9564 Slog.w(TAG, msg); 9565 throw new IllegalArgumentException(msg); 9566 } 9567 if (conn == null) { 9568 throw new NullPointerException("connection is null"); 9569 } 9570 9571 // Safely retrieve the content provider associated with the connection. 9572 IContentProvider provider; 9573 synchronized (this) { 9574 provider = conn.provider.provider; 9575 } 9576 9577 if (provider == null) { 9578 // Um, yeah, we're way ahead of you. 9579 return; 9580 } 9581 9582 // Make sure the caller is being honest with us. 9583 if (provider.asBinder().pingBinder()) { 9584 // Er, no, still looks good to us. 9585 synchronized (this) { 9586 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9587 + " says " + conn + " died, but we don't agree"); 9588 return; 9589 } 9590 } 9591 9592 // Well look at that! It's dead! 9593 synchronized (this) { 9594 if (conn.provider.provider != provider) { 9595 // But something changed... good enough. 9596 return; 9597 } 9598 9599 ProcessRecord proc = conn.provider.proc; 9600 if (proc == null || proc.thread == null) { 9601 // Seems like the process is already cleaned up. 9602 return; 9603 } 9604 9605 // As far as we're concerned, this is just like receiving a 9606 // death notification... just a bit prematurely. 9607 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9608 + ") early provider death"); 9609 final long ident = Binder.clearCallingIdentity(); 9610 try { 9611 appDiedLocked(proc); 9612 } finally { 9613 Binder.restoreCallingIdentity(ident); 9614 } 9615 } 9616 } 9617 9618 @Override 9619 public void appNotRespondingViaProvider(IBinder connection) { 9620 enforceCallingPermission( 9621 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9622 9623 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9624 if (conn == null) { 9625 Slog.w(TAG, "ContentProviderConnection is null"); 9626 return; 9627 } 9628 9629 final ProcessRecord host = conn.provider.proc; 9630 if (host == null) { 9631 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9632 return; 9633 } 9634 9635 final long token = Binder.clearCallingIdentity(); 9636 try { 9637 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9638 } finally { 9639 Binder.restoreCallingIdentity(token); 9640 } 9641 } 9642 9643 public final void installSystemProviders() { 9644 List<ProviderInfo> providers; 9645 synchronized (this) { 9646 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9647 providers = generateApplicationProvidersLocked(app); 9648 if (providers != null) { 9649 for (int i=providers.size()-1; i>=0; i--) { 9650 ProviderInfo pi = (ProviderInfo)providers.get(i); 9651 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9652 Slog.w(TAG, "Not installing system proc provider " + pi.name 9653 + ": not system .apk"); 9654 providers.remove(i); 9655 } 9656 } 9657 } 9658 } 9659 if (providers != null) { 9660 mSystemThread.installSystemProviders(providers); 9661 } 9662 9663 mCoreSettingsObserver = new CoreSettingsObserver(this); 9664 9665 //mUsageStatsService.monitorPackages(); 9666 } 9667 9668 /** 9669 * Allows apps to retrieve the MIME type of a URI. 9670 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9671 * users, then it does not need permission to access the ContentProvider. 9672 * Either, it needs cross-user uri grants. 9673 * 9674 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9675 * 9676 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9677 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9678 */ 9679 public String getProviderMimeType(Uri uri, int userId) { 9680 enforceNotIsolatedCaller("getProviderMimeType"); 9681 final String name = uri.getAuthority(); 9682 int callingUid = Binder.getCallingUid(); 9683 int callingPid = Binder.getCallingPid(); 9684 long ident = 0; 9685 boolean clearedIdentity = false; 9686 userId = unsafeConvertIncomingUser(userId); 9687 if (canClearIdentity(callingPid, callingUid, userId)) { 9688 clearedIdentity = true; 9689 ident = Binder.clearCallingIdentity(); 9690 } 9691 ContentProviderHolder holder = null; 9692 try { 9693 holder = getContentProviderExternalUnchecked(name, null, userId); 9694 if (holder != null) { 9695 return holder.provider.getType(uri); 9696 } 9697 } catch (RemoteException e) { 9698 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9699 return null; 9700 } finally { 9701 // We need to clear the identity to call removeContentProviderExternalUnchecked 9702 if (!clearedIdentity) { 9703 ident = Binder.clearCallingIdentity(); 9704 } 9705 try { 9706 if (holder != null) { 9707 removeContentProviderExternalUnchecked(name, null, userId); 9708 } 9709 } finally { 9710 Binder.restoreCallingIdentity(ident); 9711 } 9712 } 9713 9714 return null; 9715 } 9716 9717 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9718 if (UserHandle.getUserId(callingUid) == userId) { 9719 return true; 9720 } 9721 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9722 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9723 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9724 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9725 return true; 9726 } 9727 return false; 9728 } 9729 9730 // ========================================================= 9731 // GLOBAL MANAGEMENT 9732 // ========================================================= 9733 9734 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9735 boolean isolated, int isolatedUid) { 9736 String proc = customProcess != null ? customProcess : info.processName; 9737 BatteryStatsImpl.Uid.Proc ps = null; 9738 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9739 int uid = info.uid; 9740 if (isolated) { 9741 if (isolatedUid == 0) { 9742 int userId = UserHandle.getUserId(uid); 9743 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9744 while (true) { 9745 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9746 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9747 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9748 } 9749 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9750 mNextIsolatedProcessUid++; 9751 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9752 // No process for this uid, use it. 9753 break; 9754 } 9755 stepsLeft--; 9756 if (stepsLeft <= 0) { 9757 return null; 9758 } 9759 } 9760 } else { 9761 // Special case for startIsolatedProcess (internal only), where 9762 // the uid of the isolated process is specified by the caller. 9763 uid = isolatedUid; 9764 } 9765 } 9766 return new ProcessRecord(stats, info, proc, uid); 9767 } 9768 9769 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9770 String abiOverride) { 9771 ProcessRecord app; 9772 if (!isolated) { 9773 app = getProcessRecordLocked(info.processName, info.uid, true); 9774 } else { 9775 app = null; 9776 } 9777 9778 if (app == null) { 9779 app = newProcessRecordLocked(info, null, isolated, 0); 9780 mProcessNames.put(info.processName, app.uid, app); 9781 if (isolated) { 9782 mIsolatedProcesses.put(app.uid, app); 9783 } 9784 updateLruProcessLocked(app, false, null); 9785 updateOomAdjLocked(); 9786 } 9787 9788 // This package really, really can not be stopped. 9789 try { 9790 AppGlobals.getPackageManager().setPackageStoppedState( 9791 info.packageName, false, UserHandle.getUserId(app.uid)); 9792 } catch (RemoteException e) { 9793 } catch (IllegalArgumentException e) { 9794 Slog.w(TAG, "Failed trying to unstop package " 9795 + info.packageName + ": " + e); 9796 } 9797 9798 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9799 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9800 app.persistent = true; 9801 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9802 } 9803 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9804 mPersistentStartingProcesses.add(app); 9805 startProcessLocked(app, "added application", app.processName, abiOverride, 9806 null /* entryPoint */, null /* entryPointArgs */); 9807 } 9808 9809 return app; 9810 } 9811 9812 public void unhandledBack() { 9813 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9814 "unhandledBack()"); 9815 9816 synchronized(this) { 9817 final long origId = Binder.clearCallingIdentity(); 9818 try { 9819 getFocusedStack().unhandledBackLocked(); 9820 } finally { 9821 Binder.restoreCallingIdentity(origId); 9822 } 9823 } 9824 } 9825 9826 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9827 enforceNotIsolatedCaller("openContentUri"); 9828 final int userId = UserHandle.getCallingUserId(); 9829 String name = uri.getAuthority(); 9830 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9831 ParcelFileDescriptor pfd = null; 9832 if (cph != null) { 9833 // We record the binder invoker's uid in thread-local storage before 9834 // going to the content provider to open the file. Later, in the code 9835 // that handles all permissions checks, we look for this uid and use 9836 // that rather than the Activity Manager's own uid. The effect is that 9837 // we do the check against the caller's permissions even though it looks 9838 // to the content provider like the Activity Manager itself is making 9839 // the request. 9840 sCallerIdentity.set(new Identity( 9841 Binder.getCallingPid(), Binder.getCallingUid())); 9842 try { 9843 pfd = cph.provider.openFile(null, uri, "r", null); 9844 } catch (FileNotFoundException e) { 9845 // do nothing; pfd will be returned null 9846 } finally { 9847 // Ensure that whatever happens, we clean up the identity state 9848 sCallerIdentity.remove(); 9849 } 9850 9851 // We've got the fd now, so we're done with the provider. 9852 removeContentProviderExternalUnchecked(name, null, userId); 9853 } else { 9854 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9855 } 9856 return pfd; 9857 } 9858 9859 // Actually is sleeping or shutting down or whatever else in the future 9860 // is an inactive state. 9861 public boolean isSleepingOrShuttingDown() { 9862 return isSleeping() || mShuttingDown; 9863 } 9864 9865 public boolean isSleeping() { 9866 return mSleeping; 9867 } 9868 9869 void goingToSleep() { 9870 synchronized(this) { 9871 mWentToSleep = true; 9872 goToSleepIfNeededLocked(); 9873 } 9874 } 9875 9876 void finishRunningVoiceLocked() { 9877 if (mRunningVoice) { 9878 mRunningVoice = false; 9879 goToSleepIfNeededLocked(); 9880 } 9881 } 9882 9883 void goToSleepIfNeededLocked() { 9884 if (mWentToSleep && !mRunningVoice) { 9885 if (!mSleeping) { 9886 mSleeping = true; 9887 mStackSupervisor.goingToSleepLocked(); 9888 9889 // Initialize the wake times of all processes. 9890 checkExcessivePowerUsageLocked(false); 9891 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9892 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9893 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9894 } 9895 } 9896 } 9897 9898 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9899 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9900 // Never persist the home stack. 9901 return; 9902 } 9903 mTaskPersister.wakeup(task, flush); 9904 } 9905 9906 @Override 9907 public boolean shutdown(int timeout) { 9908 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9909 != PackageManager.PERMISSION_GRANTED) { 9910 throw new SecurityException("Requires permission " 9911 + android.Manifest.permission.SHUTDOWN); 9912 } 9913 9914 boolean timedout = false; 9915 9916 synchronized(this) { 9917 mShuttingDown = true; 9918 updateEventDispatchingLocked(); 9919 timedout = mStackSupervisor.shutdownLocked(timeout); 9920 } 9921 9922 mAppOpsService.shutdown(); 9923 if (mUsageStatsService != null) { 9924 mUsageStatsService.prepareShutdown(); 9925 } 9926 mBatteryStatsService.shutdown(); 9927 synchronized (this) { 9928 mProcessStats.shutdownLocked(); 9929 } 9930 notifyTaskPersisterLocked(null, true); 9931 9932 return timedout; 9933 } 9934 9935 public final void activitySlept(IBinder token) { 9936 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9937 9938 final long origId = Binder.clearCallingIdentity(); 9939 9940 synchronized (this) { 9941 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9942 if (r != null) { 9943 mStackSupervisor.activitySleptLocked(r); 9944 } 9945 } 9946 9947 Binder.restoreCallingIdentity(origId); 9948 } 9949 9950 void logLockScreen(String msg) { 9951 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9952 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9953 mWentToSleep + " mSleeping=" + mSleeping); 9954 } 9955 9956 private void comeOutOfSleepIfNeededLocked() { 9957 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9958 if (mSleeping) { 9959 mSleeping = false; 9960 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9961 } 9962 } 9963 } 9964 9965 void wakingUp() { 9966 synchronized(this) { 9967 mWentToSleep = false; 9968 comeOutOfSleepIfNeededLocked(); 9969 } 9970 } 9971 9972 void startRunningVoiceLocked() { 9973 if (!mRunningVoice) { 9974 mRunningVoice = true; 9975 comeOutOfSleepIfNeededLocked(); 9976 } 9977 } 9978 9979 private void updateEventDispatchingLocked() { 9980 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9981 } 9982 9983 public void setLockScreenShown(boolean shown) { 9984 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9985 != PackageManager.PERMISSION_GRANTED) { 9986 throw new SecurityException("Requires permission " 9987 + android.Manifest.permission.DEVICE_POWER); 9988 } 9989 9990 synchronized(this) { 9991 long ident = Binder.clearCallingIdentity(); 9992 try { 9993 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9994 mLockScreenShown = shown; 9995 comeOutOfSleepIfNeededLocked(); 9996 } finally { 9997 Binder.restoreCallingIdentity(ident); 9998 } 9999 } 10000 } 10001 10002 @Override 10003 public void stopAppSwitches() { 10004 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10005 != PackageManager.PERMISSION_GRANTED) { 10006 throw new SecurityException("Requires permission " 10007 + android.Manifest.permission.STOP_APP_SWITCHES); 10008 } 10009 10010 synchronized(this) { 10011 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10012 + APP_SWITCH_DELAY_TIME; 10013 mDidAppSwitch = false; 10014 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10015 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10016 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10017 } 10018 } 10019 10020 public void resumeAppSwitches() { 10021 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10022 != PackageManager.PERMISSION_GRANTED) { 10023 throw new SecurityException("Requires permission " 10024 + android.Manifest.permission.STOP_APP_SWITCHES); 10025 } 10026 10027 synchronized(this) { 10028 // Note that we don't execute any pending app switches... we will 10029 // let those wait until either the timeout, or the next start 10030 // activity request. 10031 mAppSwitchesAllowedTime = 0; 10032 } 10033 } 10034 10035 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10036 int callingPid, int callingUid, String name) { 10037 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10038 return true; 10039 } 10040 10041 int perm = checkComponentPermission( 10042 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10043 sourceUid, -1, true); 10044 if (perm == PackageManager.PERMISSION_GRANTED) { 10045 return true; 10046 } 10047 10048 // If the actual IPC caller is different from the logical source, then 10049 // also see if they are allowed to control app switches. 10050 if (callingUid != -1 && callingUid != sourceUid) { 10051 perm = checkComponentPermission( 10052 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10053 callingUid, -1, true); 10054 if (perm == PackageManager.PERMISSION_GRANTED) { 10055 return true; 10056 } 10057 } 10058 10059 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10060 return false; 10061 } 10062 10063 public void setDebugApp(String packageName, boolean waitForDebugger, 10064 boolean persistent) { 10065 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10066 "setDebugApp()"); 10067 10068 long ident = Binder.clearCallingIdentity(); 10069 try { 10070 // Note that this is not really thread safe if there are multiple 10071 // callers into it at the same time, but that's not a situation we 10072 // care about. 10073 if (persistent) { 10074 final ContentResolver resolver = mContext.getContentResolver(); 10075 Settings.Global.putString( 10076 resolver, Settings.Global.DEBUG_APP, 10077 packageName); 10078 Settings.Global.putInt( 10079 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10080 waitForDebugger ? 1 : 0); 10081 } 10082 10083 synchronized (this) { 10084 if (!persistent) { 10085 mOrigDebugApp = mDebugApp; 10086 mOrigWaitForDebugger = mWaitForDebugger; 10087 } 10088 mDebugApp = packageName; 10089 mWaitForDebugger = waitForDebugger; 10090 mDebugTransient = !persistent; 10091 if (packageName != null) { 10092 forceStopPackageLocked(packageName, -1, false, false, true, true, 10093 false, UserHandle.USER_ALL, "set debug app"); 10094 } 10095 } 10096 } finally { 10097 Binder.restoreCallingIdentity(ident); 10098 } 10099 } 10100 10101 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10102 synchronized (this) { 10103 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10104 if (!isDebuggable) { 10105 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10106 throw new SecurityException("Process not debuggable: " + app.packageName); 10107 } 10108 } 10109 10110 mOpenGlTraceApp = processName; 10111 } 10112 } 10113 10114 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10115 synchronized (this) { 10116 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10117 if (!isDebuggable) { 10118 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10119 throw new SecurityException("Process not debuggable: " + app.packageName); 10120 } 10121 } 10122 mProfileApp = processName; 10123 mProfileFile = profilerInfo.profileFile; 10124 if (mProfileFd != null) { 10125 try { 10126 mProfileFd.close(); 10127 } catch (IOException e) { 10128 } 10129 mProfileFd = null; 10130 } 10131 mProfileFd = profilerInfo.profileFd; 10132 mSamplingInterval = profilerInfo.samplingInterval; 10133 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10134 mProfileType = 0; 10135 } 10136 } 10137 10138 @Override 10139 public void setAlwaysFinish(boolean enabled) { 10140 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10141 "setAlwaysFinish()"); 10142 10143 Settings.Global.putInt( 10144 mContext.getContentResolver(), 10145 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10146 10147 synchronized (this) { 10148 mAlwaysFinishActivities = enabled; 10149 } 10150 } 10151 10152 @Override 10153 public void setActivityController(IActivityController controller) { 10154 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10155 "setActivityController()"); 10156 synchronized (this) { 10157 mController = controller; 10158 Watchdog.getInstance().setActivityController(controller); 10159 } 10160 } 10161 10162 @Override 10163 public void setUserIsMonkey(boolean userIsMonkey) { 10164 synchronized (this) { 10165 synchronized (mPidsSelfLocked) { 10166 final int callingPid = Binder.getCallingPid(); 10167 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10168 if (precessRecord == null) { 10169 throw new SecurityException("Unknown process: " + callingPid); 10170 } 10171 if (precessRecord.instrumentationUiAutomationConnection == null) { 10172 throw new SecurityException("Only an instrumentation process " 10173 + "with a UiAutomation can call setUserIsMonkey"); 10174 } 10175 } 10176 mUserIsMonkey = userIsMonkey; 10177 } 10178 } 10179 10180 @Override 10181 public boolean isUserAMonkey() { 10182 synchronized (this) { 10183 // If there is a controller also implies the user is a monkey. 10184 return (mUserIsMonkey || mController != null); 10185 } 10186 } 10187 10188 public void requestBugReport() { 10189 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10190 SystemProperties.set("ctl.start", "bugreport"); 10191 } 10192 10193 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10194 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10195 } 10196 10197 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10198 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10199 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10200 } 10201 return KEY_DISPATCHING_TIMEOUT; 10202 } 10203 10204 @Override 10205 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10206 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10207 != PackageManager.PERMISSION_GRANTED) { 10208 throw new SecurityException("Requires permission " 10209 + android.Manifest.permission.FILTER_EVENTS); 10210 } 10211 ProcessRecord proc; 10212 long timeout; 10213 synchronized (this) { 10214 synchronized (mPidsSelfLocked) { 10215 proc = mPidsSelfLocked.get(pid); 10216 } 10217 timeout = getInputDispatchingTimeoutLocked(proc); 10218 } 10219 10220 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10221 return -1; 10222 } 10223 10224 return timeout; 10225 } 10226 10227 /** 10228 * Handle input dispatching timeouts. 10229 * Returns whether input dispatching should be aborted or not. 10230 */ 10231 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10232 final ActivityRecord activity, final ActivityRecord parent, 10233 final boolean aboveSystem, String reason) { 10234 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10235 != PackageManager.PERMISSION_GRANTED) { 10236 throw new SecurityException("Requires permission " 10237 + android.Manifest.permission.FILTER_EVENTS); 10238 } 10239 10240 final String annotation; 10241 if (reason == null) { 10242 annotation = "Input dispatching timed out"; 10243 } else { 10244 annotation = "Input dispatching timed out (" + reason + ")"; 10245 } 10246 10247 if (proc != null) { 10248 synchronized (this) { 10249 if (proc.debugging) { 10250 return false; 10251 } 10252 10253 if (mDidDexOpt) { 10254 // Give more time since we were dexopting. 10255 mDidDexOpt = false; 10256 return false; 10257 } 10258 10259 if (proc.instrumentationClass != null) { 10260 Bundle info = new Bundle(); 10261 info.putString("shortMsg", "keyDispatchingTimedOut"); 10262 info.putString("longMsg", annotation); 10263 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10264 return true; 10265 } 10266 } 10267 mHandler.post(new Runnable() { 10268 @Override 10269 public void run() { 10270 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10271 } 10272 }); 10273 } 10274 10275 return true; 10276 } 10277 10278 public Bundle getAssistContextExtras(int requestType) { 10279 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10280 UserHandle.getCallingUserId()); 10281 if (pae == null) { 10282 return null; 10283 } 10284 synchronized (pae) { 10285 while (!pae.haveResult) { 10286 try { 10287 pae.wait(); 10288 } catch (InterruptedException e) { 10289 } 10290 } 10291 if (pae.result != null) { 10292 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10293 } 10294 } 10295 synchronized (this) { 10296 mPendingAssistExtras.remove(pae); 10297 mHandler.removeCallbacks(pae); 10298 } 10299 return pae.extras; 10300 } 10301 10302 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10303 int userHandle) { 10304 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10305 "getAssistContextExtras()"); 10306 PendingAssistExtras pae; 10307 Bundle extras = new Bundle(); 10308 synchronized (this) { 10309 ActivityRecord activity = getFocusedStack().mResumedActivity; 10310 if (activity == null) { 10311 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10312 return null; 10313 } 10314 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10315 if (activity.app == null || activity.app.thread == null) { 10316 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10317 return null; 10318 } 10319 if (activity.app.pid == Binder.getCallingPid()) { 10320 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10321 return null; 10322 } 10323 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10324 try { 10325 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10326 requestType); 10327 mPendingAssistExtras.add(pae); 10328 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10329 } catch (RemoteException e) { 10330 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10331 return null; 10332 } 10333 return pae; 10334 } 10335 } 10336 10337 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10338 PendingAssistExtras pae = (PendingAssistExtras)token; 10339 synchronized (pae) { 10340 pae.result = extras; 10341 pae.haveResult = true; 10342 pae.notifyAll(); 10343 if (pae.intent == null) { 10344 // Caller is just waiting for the result. 10345 return; 10346 } 10347 } 10348 10349 // We are now ready to launch the assist activity. 10350 synchronized (this) { 10351 boolean exists = mPendingAssistExtras.remove(pae); 10352 mHandler.removeCallbacks(pae); 10353 if (!exists) { 10354 // Timed out. 10355 return; 10356 } 10357 } 10358 pae.intent.replaceExtras(extras); 10359 if (pae.hint != null) { 10360 pae.intent.putExtra(pae.hint, true); 10361 } 10362 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10363 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10364 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10365 closeSystemDialogs("assist"); 10366 try { 10367 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10368 } catch (ActivityNotFoundException e) { 10369 Slog.w(TAG, "No activity to handle assist action.", e); 10370 } 10371 } 10372 10373 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10374 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10375 } 10376 10377 public void registerProcessObserver(IProcessObserver observer) { 10378 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10379 "registerProcessObserver()"); 10380 synchronized (this) { 10381 mProcessObservers.register(observer); 10382 } 10383 } 10384 10385 @Override 10386 public void unregisterProcessObserver(IProcessObserver observer) { 10387 synchronized (this) { 10388 mProcessObservers.unregister(observer); 10389 } 10390 } 10391 10392 @Override 10393 public boolean convertFromTranslucent(IBinder token) { 10394 final long origId = Binder.clearCallingIdentity(); 10395 try { 10396 synchronized (this) { 10397 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10398 if (r == null) { 10399 return false; 10400 } 10401 final boolean translucentChanged = r.changeWindowTranslucency(true); 10402 if (translucentChanged) { 10403 r.task.stack.releaseBackgroundResources(); 10404 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10405 } 10406 mWindowManager.setAppFullscreen(token, true); 10407 return translucentChanged; 10408 } 10409 } finally { 10410 Binder.restoreCallingIdentity(origId); 10411 } 10412 } 10413 10414 @Override 10415 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10416 final long origId = Binder.clearCallingIdentity(); 10417 try { 10418 synchronized (this) { 10419 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10420 if (r == null) { 10421 return false; 10422 } 10423 int index = r.task.mActivities.lastIndexOf(r); 10424 if (index > 0) { 10425 ActivityRecord under = r.task.mActivities.get(index - 1); 10426 under.returningOptions = options; 10427 } 10428 final boolean translucentChanged = r.changeWindowTranslucency(false); 10429 if (translucentChanged) { 10430 r.task.stack.convertToTranslucent(r); 10431 } 10432 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10433 mWindowManager.setAppFullscreen(token, false); 10434 return translucentChanged; 10435 } 10436 } finally { 10437 Binder.restoreCallingIdentity(origId); 10438 } 10439 } 10440 10441 @Override 10442 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10443 final long origId = Binder.clearCallingIdentity(); 10444 try { 10445 synchronized (this) { 10446 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10447 if (r != null) { 10448 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10449 } 10450 } 10451 return false; 10452 } finally { 10453 Binder.restoreCallingIdentity(origId); 10454 } 10455 } 10456 10457 @Override 10458 public boolean isBackgroundVisibleBehind(IBinder token) { 10459 final long origId = Binder.clearCallingIdentity(); 10460 try { 10461 synchronized (this) { 10462 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10463 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10464 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10465 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10466 return visible; 10467 } 10468 } finally { 10469 Binder.restoreCallingIdentity(origId); 10470 } 10471 } 10472 10473 @Override 10474 public ActivityOptions getActivityOptions(IBinder token) { 10475 final long origId = Binder.clearCallingIdentity(); 10476 try { 10477 synchronized (this) { 10478 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10479 if (r != null) { 10480 final ActivityOptions activityOptions = r.pendingOptions; 10481 r.pendingOptions = null; 10482 return activityOptions; 10483 } 10484 return null; 10485 } 10486 } finally { 10487 Binder.restoreCallingIdentity(origId); 10488 } 10489 } 10490 10491 @Override 10492 public void setImmersive(IBinder token, boolean immersive) { 10493 synchronized(this) { 10494 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10495 if (r == null) { 10496 throw new IllegalArgumentException(); 10497 } 10498 r.immersive = immersive; 10499 10500 // update associated state if we're frontmost 10501 if (r == mFocusedActivity) { 10502 if (DEBUG_IMMERSIVE) { 10503 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10504 } 10505 applyUpdateLockStateLocked(r); 10506 } 10507 } 10508 } 10509 10510 @Override 10511 public boolean isImmersive(IBinder token) { 10512 synchronized (this) { 10513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10514 if (r == null) { 10515 throw new IllegalArgumentException(); 10516 } 10517 return r.immersive; 10518 } 10519 } 10520 10521 public boolean isTopActivityImmersive() { 10522 enforceNotIsolatedCaller("startActivity"); 10523 synchronized (this) { 10524 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10525 return (r != null) ? r.immersive : false; 10526 } 10527 } 10528 10529 @Override 10530 public boolean isTopOfTask(IBinder token) { 10531 synchronized (this) { 10532 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10533 if (r == null) { 10534 throw new IllegalArgumentException(); 10535 } 10536 return r.task.getTopActivity() == r; 10537 } 10538 } 10539 10540 public final void enterSafeMode() { 10541 synchronized(this) { 10542 // It only makes sense to do this before the system is ready 10543 // and started launching other packages. 10544 if (!mSystemReady) { 10545 try { 10546 AppGlobals.getPackageManager().enterSafeMode(); 10547 } catch (RemoteException e) { 10548 } 10549 } 10550 10551 mSafeMode = true; 10552 } 10553 } 10554 10555 public final void showSafeModeOverlay() { 10556 View v = LayoutInflater.from(mContext).inflate( 10557 com.android.internal.R.layout.safe_mode, null); 10558 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10559 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10560 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10561 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10562 lp.gravity = Gravity.BOTTOM | Gravity.START; 10563 lp.format = v.getBackground().getOpacity(); 10564 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10565 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10566 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10567 ((WindowManager)mContext.getSystemService( 10568 Context.WINDOW_SERVICE)).addView(v, lp); 10569 } 10570 10571 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10572 if (!(sender instanceof PendingIntentRecord)) { 10573 return; 10574 } 10575 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10576 synchronized (stats) { 10577 if (mBatteryStatsService.isOnBattery()) { 10578 mBatteryStatsService.enforceCallingPermission(); 10579 PendingIntentRecord rec = (PendingIntentRecord)sender; 10580 int MY_UID = Binder.getCallingUid(); 10581 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10582 BatteryStatsImpl.Uid.Pkg pkg = 10583 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10584 sourcePkg != null ? sourcePkg : rec.key.packageName); 10585 pkg.incWakeupsLocked(); 10586 } 10587 } 10588 } 10589 10590 public boolean killPids(int[] pids, String pReason, boolean secure) { 10591 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10592 throw new SecurityException("killPids only available to the system"); 10593 } 10594 String reason = (pReason == null) ? "Unknown" : pReason; 10595 // XXX Note: don't acquire main activity lock here, because the window 10596 // manager calls in with its locks held. 10597 10598 boolean killed = false; 10599 synchronized (mPidsSelfLocked) { 10600 int[] types = new int[pids.length]; 10601 int worstType = 0; 10602 for (int i=0; i<pids.length; i++) { 10603 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10604 if (proc != null) { 10605 int type = proc.setAdj; 10606 types[i] = type; 10607 if (type > worstType) { 10608 worstType = type; 10609 } 10610 } 10611 } 10612 10613 // If the worst oom_adj is somewhere in the cached proc LRU range, 10614 // then constrain it so we will kill all cached procs. 10615 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10616 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10617 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10618 } 10619 10620 // If this is not a secure call, don't let it kill processes that 10621 // are important. 10622 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10623 worstType = ProcessList.SERVICE_ADJ; 10624 } 10625 10626 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10627 for (int i=0; i<pids.length; i++) { 10628 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10629 if (proc == null) { 10630 continue; 10631 } 10632 int adj = proc.setAdj; 10633 if (adj >= worstType && !proc.killedByAm) { 10634 proc.kill(reason, true); 10635 killed = true; 10636 } 10637 } 10638 } 10639 return killed; 10640 } 10641 10642 @Override 10643 public void killUid(int uid, String reason) { 10644 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10645 throw new SecurityException("killUid only available to the system"); 10646 } 10647 synchronized (this) { 10648 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10649 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10650 reason != null ? reason : "kill uid"); 10651 } 10652 } 10653 10654 @Override 10655 public boolean killProcessesBelowForeground(String reason) { 10656 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10657 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10658 } 10659 10660 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10661 } 10662 10663 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10664 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10665 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10666 } 10667 10668 boolean killed = false; 10669 synchronized (mPidsSelfLocked) { 10670 final int size = mPidsSelfLocked.size(); 10671 for (int i = 0; i < size; i++) { 10672 final int pid = mPidsSelfLocked.keyAt(i); 10673 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10674 if (proc == null) continue; 10675 10676 final int adj = proc.setAdj; 10677 if (adj > belowAdj && !proc.killedByAm) { 10678 proc.kill(reason, true); 10679 killed = true; 10680 } 10681 } 10682 } 10683 return killed; 10684 } 10685 10686 @Override 10687 public void hang(final IBinder who, boolean allowRestart) { 10688 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10689 != PackageManager.PERMISSION_GRANTED) { 10690 throw new SecurityException("Requires permission " 10691 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10692 } 10693 10694 final IBinder.DeathRecipient death = new DeathRecipient() { 10695 @Override 10696 public void binderDied() { 10697 synchronized (this) { 10698 notifyAll(); 10699 } 10700 } 10701 }; 10702 10703 try { 10704 who.linkToDeath(death, 0); 10705 } catch (RemoteException e) { 10706 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10707 return; 10708 } 10709 10710 synchronized (this) { 10711 Watchdog.getInstance().setAllowRestart(allowRestart); 10712 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10713 synchronized (death) { 10714 while (who.isBinderAlive()) { 10715 try { 10716 death.wait(); 10717 } catch (InterruptedException e) { 10718 } 10719 } 10720 } 10721 Watchdog.getInstance().setAllowRestart(true); 10722 } 10723 } 10724 10725 @Override 10726 public void restart() { 10727 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10728 != PackageManager.PERMISSION_GRANTED) { 10729 throw new SecurityException("Requires permission " 10730 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10731 } 10732 10733 Log.i(TAG, "Sending shutdown broadcast..."); 10734 10735 BroadcastReceiver br = new BroadcastReceiver() { 10736 @Override public void onReceive(Context context, Intent intent) { 10737 // Now the broadcast is done, finish up the low-level shutdown. 10738 Log.i(TAG, "Shutting down activity manager..."); 10739 shutdown(10000); 10740 Log.i(TAG, "Shutdown complete, restarting!"); 10741 Process.killProcess(Process.myPid()); 10742 System.exit(10); 10743 } 10744 }; 10745 10746 // First send the high-level shut down broadcast. 10747 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10748 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10749 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10750 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10751 mContext.sendOrderedBroadcastAsUser(intent, 10752 UserHandle.ALL, null, br, mHandler, 0, null, null); 10753 */ 10754 br.onReceive(mContext, intent); 10755 } 10756 10757 private long getLowRamTimeSinceIdle(long now) { 10758 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10759 } 10760 10761 @Override 10762 public void performIdleMaintenance() { 10763 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10764 != PackageManager.PERMISSION_GRANTED) { 10765 throw new SecurityException("Requires permission " 10766 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10767 } 10768 10769 synchronized (this) { 10770 final long now = SystemClock.uptimeMillis(); 10771 final long timeSinceLastIdle = now - mLastIdleTime; 10772 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10773 mLastIdleTime = now; 10774 mLowRamTimeSinceLastIdle = 0; 10775 if (mLowRamStartTime != 0) { 10776 mLowRamStartTime = now; 10777 } 10778 10779 StringBuilder sb = new StringBuilder(128); 10780 sb.append("Idle maintenance over "); 10781 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10782 sb.append(" low RAM for "); 10783 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10784 Slog.i(TAG, sb.toString()); 10785 10786 // If at least 1/3 of our time since the last idle period has been spent 10787 // with RAM low, then we want to kill processes. 10788 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10789 10790 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10791 ProcessRecord proc = mLruProcesses.get(i); 10792 if (proc.notCachedSinceIdle) { 10793 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10794 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10795 if (doKilling && proc.initialIdlePss != 0 10796 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10797 proc.kill("idle maint (pss " + proc.lastPss 10798 + " from " + proc.initialIdlePss + ")", true); 10799 } 10800 } 10801 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10802 proc.notCachedSinceIdle = true; 10803 proc.initialIdlePss = 0; 10804 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10805 isSleeping(), now); 10806 } 10807 } 10808 10809 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10810 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10811 } 10812 } 10813 10814 private void retrieveSettings() { 10815 final ContentResolver resolver = mContext.getContentResolver(); 10816 String debugApp = Settings.Global.getString( 10817 resolver, Settings.Global.DEBUG_APP); 10818 boolean waitForDebugger = Settings.Global.getInt( 10819 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10820 boolean alwaysFinishActivities = Settings.Global.getInt( 10821 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10822 boolean forceRtl = Settings.Global.getInt( 10823 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10824 // Transfer any global setting for forcing RTL layout, into a System Property 10825 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10826 10827 Configuration configuration = new Configuration(); 10828 Settings.System.getConfiguration(resolver, configuration); 10829 if (forceRtl) { 10830 // This will take care of setting the correct layout direction flags 10831 configuration.setLayoutDirection(configuration.locale); 10832 } 10833 10834 synchronized (this) { 10835 mDebugApp = mOrigDebugApp = debugApp; 10836 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10837 mAlwaysFinishActivities = alwaysFinishActivities; 10838 // This happens before any activities are started, so we can 10839 // change mConfiguration in-place. 10840 updateConfigurationLocked(configuration, null, false, true); 10841 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10842 } 10843 } 10844 10845 /** Loads resources after the current configuration has been set. */ 10846 private void loadResourcesOnSystemReady() { 10847 final Resources res = mContext.getResources(); 10848 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10849 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10850 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10851 } 10852 10853 public boolean testIsSystemReady() { 10854 // no need to synchronize(this) just to read & return the value 10855 return mSystemReady; 10856 } 10857 10858 private static File getCalledPreBootReceiversFile() { 10859 File dataDir = Environment.getDataDirectory(); 10860 File systemDir = new File(dataDir, "system"); 10861 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10862 return fname; 10863 } 10864 10865 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10866 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10867 File file = getCalledPreBootReceiversFile(); 10868 FileInputStream fis = null; 10869 try { 10870 fis = new FileInputStream(file); 10871 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10872 int fvers = dis.readInt(); 10873 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10874 String vers = dis.readUTF(); 10875 String codename = dis.readUTF(); 10876 String build = dis.readUTF(); 10877 if (android.os.Build.VERSION.RELEASE.equals(vers) 10878 && android.os.Build.VERSION.CODENAME.equals(codename) 10879 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10880 int num = dis.readInt(); 10881 while (num > 0) { 10882 num--; 10883 String pkg = dis.readUTF(); 10884 String cls = dis.readUTF(); 10885 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10886 } 10887 } 10888 } 10889 } catch (FileNotFoundException e) { 10890 } catch (IOException e) { 10891 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10892 } finally { 10893 if (fis != null) { 10894 try { 10895 fis.close(); 10896 } catch (IOException e) { 10897 } 10898 } 10899 } 10900 return lastDoneReceivers; 10901 } 10902 10903 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10904 File file = getCalledPreBootReceiversFile(); 10905 FileOutputStream fos = null; 10906 DataOutputStream dos = null; 10907 try { 10908 fos = new FileOutputStream(file); 10909 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10910 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10911 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10912 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10913 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10914 dos.writeInt(list.size()); 10915 for (int i=0; i<list.size(); i++) { 10916 dos.writeUTF(list.get(i).getPackageName()); 10917 dos.writeUTF(list.get(i).getClassName()); 10918 } 10919 } catch (IOException e) { 10920 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10921 file.delete(); 10922 } finally { 10923 FileUtils.sync(fos); 10924 if (dos != null) { 10925 try { 10926 dos.close(); 10927 } catch (IOException e) { 10928 // TODO Auto-generated catch block 10929 e.printStackTrace(); 10930 } 10931 } 10932 } 10933 } 10934 10935 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10936 ArrayList<ComponentName> doneReceivers, int userId) { 10937 boolean waitingUpdate = false; 10938 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10939 List<ResolveInfo> ris = null; 10940 try { 10941 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10942 intent, null, 0, userId); 10943 } catch (RemoteException e) { 10944 } 10945 if (ris != null) { 10946 for (int i=ris.size()-1; i>=0; i--) { 10947 if ((ris.get(i).activityInfo.applicationInfo.flags 10948 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10949 ris.remove(i); 10950 } 10951 } 10952 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10953 10954 // For User 0, load the version number. When delivering to a new user, deliver 10955 // to all receivers. 10956 if (userId == UserHandle.USER_OWNER) { 10957 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10958 for (int i=0; i<ris.size(); i++) { 10959 ActivityInfo ai = ris.get(i).activityInfo; 10960 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10961 if (lastDoneReceivers.contains(comp)) { 10962 // We already did the pre boot receiver for this app with the current 10963 // platform version, so don't do it again... 10964 ris.remove(i); 10965 i--; 10966 // ...however, do keep it as one that has been done, so we don't 10967 // forget about it when rewriting the file of last done receivers. 10968 doneReceivers.add(comp); 10969 } 10970 } 10971 } 10972 10973 // If primary user, send broadcast to all available users, else just to userId 10974 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10975 : new int[] { userId }; 10976 for (int i = 0; i < ris.size(); i++) { 10977 ActivityInfo ai = ris.get(i).activityInfo; 10978 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10979 doneReceivers.add(comp); 10980 intent.setComponent(comp); 10981 for (int j=0; j<users.length; j++) { 10982 IIntentReceiver finisher = null; 10983 // On last receiver and user, set up a completion callback 10984 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10985 finisher = new IIntentReceiver.Stub() { 10986 public void performReceive(Intent intent, int resultCode, 10987 String data, Bundle extras, boolean ordered, 10988 boolean sticky, int sendingUser) { 10989 // The raw IIntentReceiver interface is called 10990 // with the AM lock held, so redispatch to 10991 // execute our code without the lock. 10992 mHandler.post(onFinishCallback); 10993 } 10994 }; 10995 } 10996 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10997 + " for user " + users[j]); 10998 broadcastIntentLocked(null, null, intent, null, finisher, 10999 0, null, null, null, AppOpsManager.OP_NONE, 11000 true, false, MY_PID, Process.SYSTEM_UID, 11001 users[j]); 11002 if (finisher != null) { 11003 waitingUpdate = true; 11004 } 11005 } 11006 } 11007 } 11008 11009 return waitingUpdate; 11010 } 11011 11012 public void systemReady(final Runnable goingCallback) { 11013 synchronized(this) { 11014 if (mSystemReady) { 11015 // If we're done calling all the receivers, run the next "boot phase" passed in 11016 // by the SystemServer 11017 if (goingCallback != null) { 11018 goingCallback.run(); 11019 } 11020 return; 11021 } 11022 11023 // Make sure we have the current profile info, since it is needed for 11024 // security checks. 11025 updateCurrentProfileIdsLocked(); 11026 11027 if (mRecentTasks == null) { 11028 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11029 if (!mRecentTasks.isEmpty()) { 11030 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11031 } 11032 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11033 mTaskPersister.startPersisting(); 11034 } 11035 11036 // Check to see if there are any update receivers to run. 11037 if (!mDidUpdate) { 11038 if (mWaitingUpdate) { 11039 return; 11040 } 11041 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11042 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11043 public void run() { 11044 synchronized (ActivityManagerService.this) { 11045 mDidUpdate = true; 11046 } 11047 writeLastDonePreBootReceivers(doneReceivers); 11048 showBootMessage(mContext.getText( 11049 R.string.android_upgrading_complete), 11050 false); 11051 systemReady(goingCallback); 11052 } 11053 }, doneReceivers, UserHandle.USER_OWNER); 11054 11055 if (mWaitingUpdate) { 11056 return; 11057 } 11058 mDidUpdate = true; 11059 } 11060 11061 mAppOpsService.systemReady(); 11062 mSystemReady = true; 11063 } 11064 11065 ArrayList<ProcessRecord> procsToKill = null; 11066 synchronized(mPidsSelfLocked) { 11067 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11068 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11069 if (!isAllowedWhileBooting(proc.info)){ 11070 if (procsToKill == null) { 11071 procsToKill = new ArrayList<ProcessRecord>(); 11072 } 11073 procsToKill.add(proc); 11074 } 11075 } 11076 } 11077 11078 synchronized(this) { 11079 if (procsToKill != null) { 11080 for (int i=procsToKill.size()-1; i>=0; i--) { 11081 ProcessRecord proc = procsToKill.get(i); 11082 Slog.i(TAG, "Removing system update proc: " + proc); 11083 removeProcessLocked(proc, true, false, "system update done"); 11084 } 11085 } 11086 11087 // Now that we have cleaned up any update processes, we 11088 // are ready to start launching real processes and know that 11089 // we won't trample on them any more. 11090 mProcessesReady = true; 11091 } 11092 11093 Slog.i(TAG, "System now ready"); 11094 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11095 SystemClock.uptimeMillis()); 11096 11097 synchronized(this) { 11098 // Make sure we have no pre-ready processes sitting around. 11099 11100 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11101 ResolveInfo ri = mContext.getPackageManager() 11102 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11103 STOCK_PM_FLAGS); 11104 CharSequence errorMsg = null; 11105 if (ri != null) { 11106 ActivityInfo ai = ri.activityInfo; 11107 ApplicationInfo app = ai.applicationInfo; 11108 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11109 mTopAction = Intent.ACTION_FACTORY_TEST; 11110 mTopData = null; 11111 mTopComponent = new ComponentName(app.packageName, 11112 ai.name); 11113 } else { 11114 errorMsg = mContext.getResources().getText( 11115 com.android.internal.R.string.factorytest_not_system); 11116 } 11117 } else { 11118 errorMsg = mContext.getResources().getText( 11119 com.android.internal.R.string.factorytest_no_action); 11120 } 11121 if (errorMsg != null) { 11122 mTopAction = null; 11123 mTopData = null; 11124 mTopComponent = null; 11125 Message msg = Message.obtain(); 11126 msg.what = SHOW_FACTORY_ERROR_MSG; 11127 msg.getData().putCharSequence("msg", errorMsg); 11128 mHandler.sendMessage(msg); 11129 } 11130 } 11131 } 11132 11133 retrieveSettings(); 11134 loadResourcesOnSystemReady(); 11135 11136 synchronized (this) { 11137 readGrantedUriPermissionsLocked(); 11138 } 11139 11140 if (goingCallback != null) goingCallback.run(); 11141 11142 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11143 Integer.toString(mCurrentUserId), mCurrentUserId); 11144 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11145 Integer.toString(mCurrentUserId), mCurrentUserId); 11146 mSystemServiceManager.startUser(mCurrentUserId); 11147 11148 synchronized (this) { 11149 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11150 try { 11151 List apps = AppGlobals.getPackageManager(). 11152 getPersistentApplications(STOCK_PM_FLAGS); 11153 if (apps != null) { 11154 int N = apps.size(); 11155 int i; 11156 for (i=0; i<N; i++) { 11157 ApplicationInfo info 11158 = (ApplicationInfo)apps.get(i); 11159 if (info != null && 11160 !info.packageName.equals("android")) { 11161 addAppLocked(info, false, null /* ABI override */); 11162 } 11163 } 11164 } 11165 } catch (RemoteException ex) { 11166 // pm is in same process, this will never happen. 11167 } 11168 } 11169 11170 // Start up initial activity. 11171 mBooting = true; 11172 startHomeActivityLocked(mCurrentUserId); 11173 11174 try { 11175 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11176 Message msg = Message.obtain(); 11177 msg.what = SHOW_UID_ERROR_MSG; 11178 mHandler.sendMessage(msg); 11179 } 11180 } catch (RemoteException e) { 11181 } 11182 11183 long ident = Binder.clearCallingIdentity(); 11184 try { 11185 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11186 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11187 | Intent.FLAG_RECEIVER_FOREGROUND); 11188 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11189 broadcastIntentLocked(null, null, intent, 11190 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11191 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11192 intent = new Intent(Intent.ACTION_USER_STARTING); 11193 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11194 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11195 broadcastIntentLocked(null, null, intent, 11196 null, new IIntentReceiver.Stub() { 11197 @Override 11198 public void performReceive(Intent intent, int resultCode, String data, 11199 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11200 throws RemoteException { 11201 } 11202 }, 0, null, null, 11203 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11204 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11205 } catch (Throwable t) { 11206 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11207 } finally { 11208 Binder.restoreCallingIdentity(ident); 11209 } 11210 mStackSupervisor.resumeTopActivitiesLocked(); 11211 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11212 } 11213 } 11214 11215 private boolean makeAppCrashingLocked(ProcessRecord app, 11216 String shortMsg, String longMsg, String stackTrace) { 11217 app.crashing = true; 11218 app.crashingReport = generateProcessError(app, 11219 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11220 startAppProblemLocked(app); 11221 app.stopFreezingAllLocked(); 11222 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11223 } 11224 11225 private void makeAppNotRespondingLocked(ProcessRecord app, 11226 String activity, String shortMsg, String longMsg) { 11227 app.notResponding = true; 11228 app.notRespondingReport = generateProcessError(app, 11229 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11230 activity, shortMsg, longMsg, null); 11231 startAppProblemLocked(app); 11232 app.stopFreezingAllLocked(); 11233 } 11234 11235 /** 11236 * Generate a process error record, suitable for attachment to a ProcessRecord. 11237 * 11238 * @param app The ProcessRecord in which the error occurred. 11239 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11240 * ActivityManager.AppErrorStateInfo 11241 * @param activity The activity associated with the crash, if known. 11242 * @param shortMsg Short message describing the crash. 11243 * @param longMsg Long message describing the crash. 11244 * @param stackTrace Full crash stack trace, may be null. 11245 * 11246 * @return Returns a fully-formed AppErrorStateInfo record. 11247 */ 11248 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11249 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11250 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11251 11252 report.condition = condition; 11253 report.processName = app.processName; 11254 report.pid = app.pid; 11255 report.uid = app.info.uid; 11256 report.tag = activity; 11257 report.shortMsg = shortMsg; 11258 report.longMsg = longMsg; 11259 report.stackTrace = stackTrace; 11260 11261 return report; 11262 } 11263 11264 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11265 synchronized (this) { 11266 app.crashing = false; 11267 app.crashingReport = null; 11268 app.notResponding = false; 11269 app.notRespondingReport = null; 11270 if (app.anrDialog == fromDialog) { 11271 app.anrDialog = null; 11272 } 11273 if (app.waitDialog == fromDialog) { 11274 app.waitDialog = null; 11275 } 11276 if (app.pid > 0 && app.pid != MY_PID) { 11277 handleAppCrashLocked(app, null, null, null); 11278 app.kill("user request after error", true); 11279 } 11280 } 11281 } 11282 11283 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11284 String stackTrace) { 11285 long now = SystemClock.uptimeMillis(); 11286 11287 Long crashTime; 11288 if (!app.isolated) { 11289 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11290 } else { 11291 crashTime = null; 11292 } 11293 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11294 // This process loses! 11295 Slog.w(TAG, "Process " + app.info.processName 11296 + " has crashed too many times: killing!"); 11297 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11298 app.userId, app.info.processName, app.uid); 11299 mStackSupervisor.handleAppCrashLocked(app); 11300 if (!app.persistent) { 11301 // We don't want to start this process again until the user 11302 // explicitly does so... but for persistent process, we really 11303 // need to keep it running. If a persistent process is actually 11304 // repeatedly crashing, then badness for everyone. 11305 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11306 app.info.processName); 11307 if (!app.isolated) { 11308 // XXX We don't have a way to mark isolated processes 11309 // as bad, since they don't have a peristent identity. 11310 mBadProcesses.put(app.info.processName, app.uid, 11311 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11312 mProcessCrashTimes.remove(app.info.processName, app.uid); 11313 } 11314 app.bad = true; 11315 app.removed = true; 11316 // Don't let services in this process be restarted and potentially 11317 // annoy the user repeatedly. Unless it is persistent, since those 11318 // processes run critical code. 11319 removeProcessLocked(app, false, false, "crash"); 11320 mStackSupervisor.resumeTopActivitiesLocked(); 11321 return false; 11322 } 11323 mStackSupervisor.resumeTopActivitiesLocked(); 11324 } else { 11325 mStackSupervisor.finishTopRunningActivityLocked(app); 11326 } 11327 11328 // Bump up the crash count of any services currently running in the proc. 11329 for (int i=app.services.size()-1; i>=0; i--) { 11330 // Any services running in the application need to be placed 11331 // back in the pending list. 11332 ServiceRecord sr = app.services.valueAt(i); 11333 sr.crashCount++; 11334 } 11335 11336 // If the crashing process is what we consider to be the "home process" and it has been 11337 // replaced by a third-party app, clear the package preferred activities from packages 11338 // with a home activity running in the process to prevent a repeatedly crashing app 11339 // from blocking the user to manually clear the list. 11340 final ArrayList<ActivityRecord> activities = app.activities; 11341 if (app == mHomeProcess && activities.size() > 0 11342 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11343 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11344 final ActivityRecord r = activities.get(activityNdx); 11345 if (r.isHomeActivity()) { 11346 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11347 try { 11348 ActivityThread.getPackageManager() 11349 .clearPackagePreferredActivities(r.packageName); 11350 } catch (RemoteException c) { 11351 // pm is in same process, this will never happen. 11352 } 11353 } 11354 } 11355 } 11356 11357 if (!app.isolated) { 11358 // XXX Can't keep track of crash times for isolated processes, 11359 // because they don't have a perisistent identity. 11360 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11361 } 11362 11363 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11364 return true; 11365 } 11366 11367 void startAppProblemLocked(ProcessRecord app) { 11368 // If this app is not running under the current user, then we 11369 // can't give it a report button because that would require 11370 // launching the report UI under a different user. 11371 app.errorReportReceiver = null; 11372 11373 for (int userId : mCurrentProfileIds) { 11374 if (app.userId == userId) { 11375 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11376 mContext, app.info.packageName, app.info.flags); 11377 } 11378 } 11379 skipCurrentReceiverLocked(app); 11380 } 11381 11382 void skipCurrentReceiverLocked(ProcessRecord app) { 11383 for (BroadcastQueue queue : mBroadcastQueues) { 11384 queue.skipCurrentReceiverLocked(app); 11385 } 11386 } 11387 11388 /** 11389 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11390 * The application process will exit immediately after this call returns. 11391 * @param app object of the crashing app, null for the system server 11392 * @param crashInfo describing the exception 11393 */ 11394 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11395 ProcessRecord r = findAppProcess(app, "Crash"); 11396 final String processName = app == null ? "system_server" 11397 : (r == null ? "unknown" : r.processName); 11398 11399 handleApplicationCrashInner("crash", r, processName, crashInfo); 11400 } 11401 11402 /* Native crash reporting uses this inner version because it needs to be somewhat 11403 * decoupled from the AM-managed cleanup lifecycle 11404 */ 11405 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11406 ApplicationErrorReport.CrashInfo crashInfo) { 11407 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11408 UserHandle.getUserId(Binder.getCallingUid()), processName, 11409 r == null ? -1 : r.info.flags, 11410 crashInfo.exceptionClassName, 11411 crashInfo.exceptionMessage, 11412 crashInfo.throwFileName, 11413 crashInfo.throwLineNumber); 11414 11415 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11416 11417 crashApplication(r, crashInfo); 11418 } 11419 11420 public void handleApplicationStrictModeViolation( 11421 IBinder app, 11422 int violationMask, 11423 StrictMode.ViolationInfo info) { 11424 ProcessRecord r = findAppProcess(app, "StrictMode"); 11425 if (r == null) { 11426 return; 11427 } 11428 11429 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11430 Integer stackFingerprint = info.hashCode(); 11431 boolean logIt = true; 11432 synchronized (mAlreadyLoggedViolatedStacks) { 11433 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11434 logIt = false; 11435 // TODO: sub-sample into EventLog for these, with 11436 // the info.durationMillis? Then we'd get 11437 // the relative pain numbers, without logging all 11438 // the stack traces repeatedly. We'd want to do 11439 // likewise in the client code, which also does 11440 // dup suppression, before the Binder call. 11441 } else { 11442 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11443 mAlreadyLoggedViolatedStacks.clear(); 11444 } 11445 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11446 } 11447 } 11448 if (logIt) { 11449 logStrictModeViolationToDropBox(r, info); 11450 } 11451 } 11452 11453 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11454 AppErrorResult result = new AppErrorResult(); 11455 synchronized (this) { 11456 final long origId = Binder.clearCallingIdentity(); 11457 11458 Message msg = Message.obtain(); 11459 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11460 HashMap<String, Object> data = new HashMap<String, Object>(); 11461 data.put("result", result); 11462 data.put("app", r); 11463 data.put("violationMask", violationMask); 11464 data.put("info", info); 11465 msg.obj = data; 11466 mHandler.sendMessage(msg); 11467 11468 Binder.restoreCallingIdentity(origId); 11469 } 11470 int res = result.get(); 11471 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11472 } 11473 } 11474 11475 // Depending on the policy in effect, there could be a bunch of 11476 // these in quick succession so we try to batch these together to 11477 // minimize disk writes, number of dropbox entries, and maximize 11478 // compression, by having more fewer, larger records. 11479 private void logStrictModeViolationToDropBox( 11480 ProcessRecord process, 11481 StrictMode.ViolationInfo info) { 11482 if (info == null) { 11483 return; 11484 } 11485 final boolean isSystemApp = process == null || 11486 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11487 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11488 final String processName = process == null ? "unknown" : process.processName; 11489 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11490 final DropBoxManager dbox = (DropBoxManager) 11491 mContext.getSystemService(Context.DROPBOX_SERVICE); 11492 11493 // Exit early if the dropbox isn't configured to accept this report type. 11494 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11495 11496 boolean bufferWasEmpty; 11497 boolean needsFlush; 11498 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11499 synchronized (sb) { 11500 bufferWasEmpty = sb.length() == 0; 11501 appendDropBoxProcessHeaders(process, processName, sb); 11502 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11503 sb.append("System-App: ").append(isSystemApp).append("\n"); 11504 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11505 if (info.violationNumThisLoop != 0) { 11506 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11507 } 11508 if (info.numAnimationsRunning != 0) { 11509 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11510 } 11511 if (info.broadcastIntentAction != null) { 11512 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11513 } 11514 if (info.durationMillis != -1) { 11515 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11516 } 11517 if (info.numInstances != -1) { 11518 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11519 } 11520 if (info.tags != null) { 11521 for (String tag : info.tags) { 11522 sb.append("Span-Tag: ").append(tag).append("\n"); 11523 } 11524 } 11525 sb.append("\n"); 11526 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11527 sb.append(info.crashInfo.stackTrace); 11528 } 11529 sb.append("\n"); 11530 11531 // Only buffer up to ~64k. Various logging bits truncate 11532 // things at 128k. 11533 needsFlush = (sb.length() > 64 * 1024); 11534 } 11535 11536 // Flush immediately if the buffer's grown too large, or this 11537 // is a non-system app. Non-system apps are isolated with a 11538 // different tag & policy and not batched. 11539 // 11540 // Batching is useful during internal testing with 11541 // StrictMode settings turned up high. Without batching, 11542 // thousands of separate files could be created on boot. 11543 if (!isSystemApp || needsFlush) { 11544 new Thread("Error dump: " + dropboxTag) { 11545 @Override 11546 public void run() { 11547 String report; 11548 synchronized (sb) { 11549 report = sb.toString(); 11550 sb.delete(0, sb.length()); 11551 sb.trimToSize(); 11552 } 11553 if (report.length() != 0) { 11554 dbox.addText(dropboxTag, report); 11555 } 11556 } 11557 }.start(); 11558 return; 11559 } 11560 11561 // System app batching: 11562 if (!bufferWasEmpty) { 11563 // An existing dropbox-writing thread is outstanding, so 11564 // we don't need to start it up. The existing thread will 11565 // catch the buffer appends we just did. 11566 return; 11567 } 11568 11569 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11570 // (After this point, we shouldn't access AMS internal data structures.) 11571 new Thread("Error dump: " + dropboxTag) { 11572 @Override 11573 public void run() { 11574 // 5 second sleep to let stacks arrive and be batched together 11575 try { 11576 Thread.sleep(5000); // 5 seconds 11577 } catch (InterruptedException e) {} 11578 11579 String errorReport; 11580 synchronized (mStrictModeBuffer) { 11581 errorReport = mStrictModeBuffer.toString(); 11582 if (errorReport.length() == 0) { 11583 return; 11584 } 11585 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11586 mStrictModeBuffer.trimToSize(); 11587 } 11588 dbox.addText(dropboxTag, errorReport); 11589 } 11590 }.start(); 11591 } 11592 11593 /** 11594 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11595 * @param app object of the crashing app, null for the system server 11596 * @param tag reported by the caller 11597 * @param system whether this wtf is coming from the system 11598 * @param crashInfo describing the context of the error 11599 * @return true if the process should exit immediately (WTF is fatal) 11600 */ 11601 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11602 final ApplicationErrorReport.CrashInfo crashInfo) { 11603 final int callingUid = Binder.getCallingUid(); 11604 final int callingPid = Binder.getCallingPid(); 11605 11606 if (system) { 11607 // If this is coming from the system, we could very well have low-level 11608 // system locks held, so we want to do this all asynchronously. And we 11609 // never want this to become fatal, so there is that too. 11610 mHandler.post(new Runnable() { 11611 @Override public void run() { 11612 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11613 } 11614 }); 11615 return false; 11616 } 11617 11618 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11619 crashInfo); 11620 11621 if (r != null && r.pid != Process.myPid() && 11622 Settings.Global.getInt(mContext.getContentResolver(), 11623 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11624 crashApplication(r, crashInfo); 11625 return true; 11626 } else { 11627 return false; 11628 } 11629 } 11630 11631 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11632 final ApplicationErrorReport.CrashInfo crashInfo) { 11633 final ProcessRecord r = findAppProcess(app, "WTF"); 11634 final String processName = app == null ? "system_server" 11635 : (r == null ? "unknown" : r.processName); 11636 11637 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11638 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11639 11640 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11641 11642 return r; 11643 } 11644 11645 /** 11646 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11647 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11648 */ 11649 private ProcessRecord findAppProcess(IBinder app, String reason) { 11650 if (app == null) { 11651 return null; 11652 } 11653 11654 synchronized (this) { 11655 final int NP = mProcessNames.getMap().size(); 11656 for (int ip=0; ip<NP; ip++) { 11657 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11658 final int NA = apps.size(); 11659 for (int ia=0; ia<NA; ia++) { 11660 ProcessRecord p = apps.valueAt(ia); 11661 if (p.thread != null && p.thread.asBinder() == app) { 11662 return p; 11663 } 11664 } 11665 } 11666 11667 Slog.w(TAG, "Can't find mystery application for " + reason 11668 + " from pid=" + Binder.getCallingPid() 11669 + " uid=" + Binder.getCallingUid() + ": " + app); 11670 return null; 11671 } 11672 } 11673 11674 /** 11675 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11676 * to append various headers to the dropbox log text. 11677 */ 11678 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11679 StringBuilder sb) { 11680 // Watchdog thread ends up invoking this function (with 11681 // a null ProcessRecord) to add the stack file to dropbox. 11682 // Do not acquire a lock on this (am) in such cases, as it 11683 // could cause a potential deadlock, if and when watchdog 11684 // is invoked due to unavailability of lock on am and it 11685 // would prevent watchdog from killing system_server. 11686 if (process == null) { 11687 sb.append("Process: ").append(processName).append("\n"); 11688 return; 11689 } 11690 // Note: ProcessRecord 'process' is guarded by the service 11691 // instance. (notably process.pkgList, which could otherwise change 11692 // concurrently during execution of this method) 11693 synchronized (this) { 11694 sb.append("Process: ").append(processName).append("\n"); 11695 int flags = process.info.flags; 11696 IPackageManager pm = AppGlobals.getPackageManager(); 11697 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11698 for (int ip=0; ip<process.pkgList.size(); ip++) { 11699 String pkg = process.pkgList.keyAt(ip); 11700 sb.append("Package: ").append(pkg); 11701 try { 11702 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11703 if (pi != null) { 11704 sb.append(" v").append(pi.versionCode); 11705 if (pi.versionName != null) { 11706 sb.append(" (").append(pi.versionName).append(")"); 11707 } 11708 } 11709 } catch (RemoteException e) { 11710 Slog.e(TAG, "Error getting package info: " + pkg, e); 11711 } 11712 sb.append("\n"); 11713 } 11714 } 11715 } 11716 11717 private static String processClass(ProcessRecord process) { 11718 if (process == null || process.pid == MY_PID) { 11719 return "system_server"; 11720 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11721 return "system_app"; 11722 } else { 11723 return "data_app"; 11724 } 11725 } 11726 11727 /** 11728 * Write a description of an error (crash, WTF, ANR) to the drop box. 11729 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11730 * @param process which caused the error, null means the system server 11731 * @param activity which triggered the error, null if unknown 11732 * @param parent activity related to the error, null if unknown 11733 * @param subject line related to the error, null if absent 11734 * @param report in long form describing the error, null if absent 11735 * @param logFile to include in the report, null if none 11736 * @param crashInfo giving an application stack trace, null if absent 11737 */ 11738 public void addErrorToDropBox(String eventType, 11739 ProcessRecord process, String processName, ActivityRecord activity, 11740 ActivityRecord parent, String subject, 11741 final String report, final File logFile, 11742 final ApplicationErrorReport.CrashInfo crashInfo) { 11743 // NOTE -- this must never acquire the ActivityManagerService lock, 11744 // otherwise the watchdog may be prevented from resetting the system. 11745 11746 final String dropboxTag = processClass(process) + "_" + eventType; 11747 final DropBoxManager dbox = (DropBoxManager) 11748 mContext.getSystemService(Context.DROPBOX_SERVICE); 11749 11750 // Exit early if the dropbox isn't configured to accept this report type. 11751 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11752 11753 final StringBuilder sb = new StringBuilder(1024); 11754 appendDropBoxProcessHeaders(process, processName, sb); 11755 if (activity != null) { 11756 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11757 } 11758 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11759 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11760 } 11761 if (parent != null && parent != activity) { 11762 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11763 } 11764 if (subject != null) { 11765 sb.append("Subject: ").append(subject).append("\n"); 11766 } 11767 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11768 if (Debug.isDebuggerConnected()) { 11769 sb.append("Debugger: Connected\n"); 11770 } 11771 sb.append("\n"); 11772 11773 // Do the rest in a worker thread to avoid blocking the caller on I/O 11774 // (After this point, we shouldn't access AMS internal data structures.) 11775 Thread worker = new Thread("Error dump: " + dropboxTag) { 11776 @Override 11777 public void run() { 11778 if (report != null) { 11779 sb.append(report); 11780 } 11781 if (logFile != null) { 11782 try { 11783 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11784 "\n\n[[TRUNCATED]]")); 11785 } catch (IOException e) { 11786 Slog.e(TAG, "Error reading " + logFile, e); 11787 } 11788 } 11789 if (crashInfo != null && crashInfo.stackTrace != null) { 11790 sb.append(crashInfo.stackTrace); 11791 } 11792 11793 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11794 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11795 if (lines > 0) { 11796 sb.append("\n"); 11797 11798 // Merge several logcat streams, and take the last N lines 11799 InputStreamReader input = null; 11800 try { 11801 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11802 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11803 "-b", "crash", 11804 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11805 11806 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11807 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11808 input = new InputStreamReader(logcat.getInputStream()); 11809 11810 int num; 11811 char[] buf = new char[8192]; 11812 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11813 } catch (IOException e) { 11814 Slog.e(TAG, "Error running logcat", e); 11815 } finally { 11816 if (input != null) try { input.close(); } catch (IOException e) {} 11817 } 11818 } 11819 11820 dbox.addText(dropboxTag, sb.toString()); 11821 } 11822 }; 11823 11824 if (process == null) { 11825 // If process is null, we are being called from some internal code 11826 // and may be about to die -- run this synchronously. 11827 worker.run(); 11828 } else { 11829 worker.start(); 11830 } 11831 } 11832 11833 /** 11834 * Bring up the "unexpected error" dialog box for a crashing app. 11835 * Deal with edge cases (intercepts from instrumented applications, 11836 * ActivityController, error intent receivers, that sort of thing). 11837 * @param r the application crashing 11838 * @param crashInfo describing the failure 11839 */ 11840 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11841 long timeMillis = System.currentTimeMillis(); 11842 String shortMsg = crashInfo.exceptionClassName; 11843 String longMsg = crashInfo.exceptionMessage; 11844 String stackTrace = crashInfo.stackTrace; 11845 if (shortMsg != null && longMsg != null) { 11846 longMsg = shortMsg + ": " + longMsg; 11847 } else if (shortMsg != null) { 11848 longMsg = shortMsg; 11849 } 11850 11851 AppErrorResult result = new AppErrorResult(); 11852 synchronized (this) { 11853 if (mController != null) { 11854 try { 11855 String name = r != null ? r.processName : null; 11856 int pid = r != null ? r.pid : Binder.getCallingPid(); 11857 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11858 if (!mController.appCrashed(name, pid, 11859 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11860 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11861 && "Native crash".equals(crashInfo.exceptionClassName)) { 11862 Slog.w(TAG, "Skip killing native crashed app " + name 11863 + "(" + pid + ") during testing"); 11864 } else { 11865 Slog.w(TAG, "Force-killing crashed app " + name 11866 + " at watcher's request"); 11867 if (r != null) { 11868 r.kill("crash", true); 11869 } else { 11870 // Huh. 11871 Process.killProcess(pid); 11872 Process.killProcessGroup(uid, pid); 11873 } 11874 } 11875 return; 11876 } 11877 } catch (RemoteException e) { 11878 mController = null; 11879 Watchdog.getInstance().setActivityController(null); 11880 } 11881 } 11882 11883 final long origId = Binder.clearCallingIdentity(); 11884 11885 // If this process is running instrumentation, finish it. 11886 if (r != null && r.instrumentationClass != null) { 11887 Slog.w(TAG, "Error in app " + r.processName 11888 + " running instrumentation " + r.instrumentationClass + ":"); 11889 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11890 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11891 Bundle info = new Bundle(); 11892 info.putString("shortMsg", shortMsg); 11893 info.putString("longMsg", longMsg); 11894 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11895 Binder.restoreCallingIdentity(origId); 11896 return; 11897 } 11898 11899 // If we can't identify the process or it's already exceeded its crash quota, 11900 // quit right away without showing a crash dialog. 11901 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11902 Binder.restoreCallingIdentity(origId); 11903 return; 11904 } 11905 11906 Message msg = Message.obtain(); 11907 msg.what = SHOW_ERROR_MSG; 11908 HashMap data = new HashMap(); 11909 data.put("result", result); 11910 data.put("app", r); 11911 msg.obj = data; 11912 mHandler.sendMessage(msg); 11913 11914 Binder.restoreCallingIdentity(origId); 11915 } 11916 11917 int res = result.get(); 11918 11919 Intent appErrorIntent = null; 11920 synchronized (this) { 11921 if (r != null && !r.isolated) { 11922 // XXX Can't keep track of crash time for isolated processes, 11923 // since they don't have a persistent identity. 11924 mProcessCrashTimes.put(r.info.processName, r.uid, 11925 SystemClock.uptimeMillis()); 11926 } 11927 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11928 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11929 } 11930 } 11931 11932 if (appErrorIntent != null) { 11933 try { 11934 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11935 } catch (ActivityNotFoundException e) { 11936 Slog.w(TAG, "bug report receiver dissappeared", e); 11937 } 11938 } 11939 } 11940 11941 Intent createAppErrorIntentLocked(ProcessRecord r, 11942 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11943 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11944 if (report == null) { 11945 return null; 11946 } 11947 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11948 result.setComponent(r.errorReportReceiver); 11949 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11950 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11951 return result; 11952 } 11953 11954 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11955 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11956 if (r.errorReportReceiver == null) { 11957 return null; 11958 } 11959 11960 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11961 return null; 11962 } 11963 11964 ApplicationErrorReport report = new ApplicationErrorReport(); 11965 report.packageName = r.info.packageName; 11966 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11967 report.processName = r.processName; 11968 report.time = timeMillis; 11969 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11970 11971 if (r.crashing || r.forceCrashReport) { 11972 report.type = ApplicationErrorReport.TYPE_CRASH; 11973 report.crashInfo = crashInfo; 11974 } else if (r.notResponding) { 11975 report.type = ApplicationErrorReport.TYPE_ANR; 11976 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11977 11978 report.anrInfo.activity = r.notRespondingReport.tag; 11979 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11980 report.anrInfo.info = r.notRespondingReport.longMsg; 11981 } 11982 11983 return report; 11984 } 11985 11986 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11987 enforceNotIsolatedCaller("getProcessesInErrorState"); 11988 // assume our apps are happy - lazy create the list 11989 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11990 11991 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11992 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11993 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11994 11995 synchronized (this) { 11996 11997 // iterate across all processes 11998 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11999 ProcessRecord app = mLruProcesses.get(i); 12000 if (!allUsers && app.userId != userId) { 12001 continue; 12002 } 12003 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12004 // This one's in trouble, so we'll generate a report for it 12005 // crashes are higher priority (in case there's a crash *and* an anr) 12006 ActivityManager.ProcessErrorStateInfo report = null; 12007 if (app.crashing) { 12008 report = app.crashingReport; 12009 } else if (app.notResponding) { 12010 report = app.notRespondingReport; 12011 } 12012 12013 if (report != null) { 12014 if (errList == null) { 12015 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12016 } 12017 errList.add(report); 12018 } else { 12019 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12020 " crashing = " + app.crashing + 12021 " notResponding = " + app.notResponding); 12022 } 12023 } 12024 } 12025 } 12026 12027 return errList; 12028 } 12029 12030 static int procStateToImportance(int procState, int memAdj, 12031 ActivityManager.RunningAppProcessInfo currApp) { 12032 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12033 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12034 currApp.lru = memAdj; 12035 } else { 12036 currApp.lru = 0; 12037 } 12038 return imp; 12039 } 12040 12041 private void fillInProcMemInfo(ProcessRecord app, 12042 ActivityManager.RunningAppProcessInfo outInfo) { 12043 outInfo.pid = app.pid; 12044 outInfo.uid = app.info.uid; 12045 if (mHeavyWeightProcess == app) { 12046 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12047 } 12048 if (app.persistent) { 12049 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12050 } 12051 if (app.activities.size() > 0) { 12052 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12053 } 12054 outInfo.lastTrimLevel = app.trimMemoryLevel; 12055 int adj = app.curAdj; 12056 int procState = app.curProcState; 12057 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12058 outInfo.importanceReasonCode = app.adjTypeCode; 12059 outInfo.processState = app.curProcState; 12060 } 12061 12062 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12063 enforceNotIsolatedCaller("getRunningAppProcesses"); 12064 // Lazy instantiation of list 12065 List<ActivityManager.RunningAppProcessInfo> runList = null; 12066 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12067 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12068 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12069 synchronized (this) { 12070 // Iterate across all processes 12071 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12072 ProcessRecord app = mLruProcesses.get(i); 12073 if (!allUsers && app.userId != userId) { 12074 continue; 12075 } 12076 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12077 // Generate process state info for running application 12078 ActivityManager.RunningAppProcessInfo currApp = 12079 new ActivityManager.RunningAppProcessInfo(app.processName, 12080 app.pid, app.getPackageList()); 12081 fillInProcMemInfo(app, currApp); 12082 if (app.adjSource instanceof ProcessRecord) { 12083 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12084 currApp.importanceReasonImportance = 12085 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12086 app.adjSourceProcState); 12087 } else if (app.adjSource instanceof ActivityRecord) { 12088 ActivityRecord r = (ActivityRecord)app.adjSource; 12089 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12090 } 12091 if (app.adjTarget instanceof ComponentName) { 12092 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12093 } 12094 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12095 // + " lru=" + currApp.lru); 12096 if (runList == null) { 12097 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12098 } 12099 runList.add(currApp); 12100 } 12101 } 12102 } 12103 return runList; 12104 } 12105 12106 public List<ApplicationInfo> getRunningExternalApplications() { 12107 enforceNotIsolatedCaller("getRunningExternalApplications"); 12108 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12109 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12110 if (runningApps != null && runningApps.size() > 0) { 12111 Set<String> extList = new HashSet<String>(); 12112 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12113 if (app.pkgList != null) { 12114 for (String pkg : app.pkgList) { 12115 extList.add(pkg); 12116 } 12117 } 12118 } 12119 IPackageManager pm = AppGlobals.getPackageManager(); 12120 for (String pkg : extList) { 12121 try { 12122 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12123 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12124 retList.add(info); 12125 } 12126 } catch (RemoteException e) { 12127 } 12128 } 12129 } 12130 return retList; 12131 } 12132 12133 @Override 12134 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12135 enforceNotIsolatedCaller("getMyMemoryState"); 12136 synchronized (this) { 12137 ProcessRecord proc; 12138 synchronized (mPidsSelfLocked) { 12139 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12140 } 12141 fillInProcMemInfo(proc, outInfo); 12142 } 12143 } 12144 12145 @Override 12146 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12147 if (checkCallingPermission(android.Manifest.permission.DUMP) 12148 != PackageManager.PERMISSION_GRANTED) { 12149 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12150 + Binder.getCallingPid() 12151 + ", uid=" + Binder.getCallingUid() 12152 + " without permission " 12153 + android.Manifest.permission.DUMP); 12154 return; 12155 } 12156 12157 boolean dumpAll = false; 12158 boolean dumpClient = false; 12159 String dumpPackage = null; 12160 12161 int opti = 0; 12162 while (opti < args.length) { 12163 String opt = args[opti]; 12164 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12165 break; 12166 } 12167 opti++; 12168 if ("-a".equals(opt)) { 12169 dumpAll = true; 12170 } else if ("-c".equals(opt)) { 12171 dumpClient = true; 12172 } else if ("-h".equals(opt)) { 12173 pw.println("Activity manager dump options:"); 12174 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12175 pw.println(" cmd may be one of:"); 12176 pw.println(" a[ctivities]: activity stack state"); 12177 pw.println(" r[recents]: recent activities state"); 12178 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12179 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12180 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12181 pw.println(" o[om]: out of memory management"); 12182 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12183 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12184 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12185 pw.println(" service [COMP_SPEC]: service client-side state"); 12186 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12187 pw.println(" all: dump all activities"); 12188 pw.println(" top: dump the top activity"); 12189 pw.println(" write: write all pending state to storage"); 12190 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12191 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12192 pw.println(" a partial substring in a component name, a"); 12193 pw.println(" hex object identifier."); 12194 pw.println(" -a: include all available server state."); 12195 pw.println(" -c: include client state."); 12196 return; 12197 } else { 12198 pw.println("Unknown argument: " + opt + "; use -h for help"); 12199 } 12200 } 12201 12202 long origId = Binder.clearCallingIdentity(); 12203 boolean more = false; 12204 // Is the caller requesting to dump a particular piece of data? 12205 if (opti < args.length) { 12206 String cmd = args[opti]; 12207 opti++; 12208 if ("activities".equals(cmd) || "a".equals(cmd)) { 12209 synchronized (this) { 12210 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12211 } 12212 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12213 synchronized (this) { 12214 dumpRecentsLocked(fd, pw, args, opti, true, null); 12215 } 12216 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12217 String[] newArgs; 12218 String name; 12219 if (opti >= args.length) { 12220 name = null; 12221 newArgs = EMPTY_STRING_ARRAY; 12222 } else { 12223 name = args[opti]; 12224 opti++; 12225 newArgs = new String[args.length - opti]; 12226 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12227 args.length - opti); 12228 } 12229 synchronized (this) { 12230 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12231 } 12232 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12233 String[] newArgs; 12234 String name; 12235 if (opti >= args.length) { 12236 name = null; 12237 newArgs = EMPTY_STRING_ARRAY; 12238 } else { 12239 name = args[opti]; 12240 opti++; 12241 newArgs = new String[args.length - opti]; 12242 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12243 args.length - opti); 12244 } 12245 synchronized (this) { 12246 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12247 } 12248 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12249 String[] newArgs; 12250 String name; 12251 if (opti >= args.length) { 12252 name = null; 12253 newArgs = EMPTY_STRING_ARRAY; 12254 } else { 12255 name = args[opti]; 12256 opti++; 12257 newArgs = new String[args.length - opti]; 12258 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12259 args.length - opti); 12260 } 12261 synchronized (this) { 12262 dumpProcessesLocked(fd, pw, args, opti, true, name); 12263 } 12264 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12265 synchronized (this) { 12266 dumpOomLocked(fd, pw, args, opti, true); 12267 } 12268 } else if ("provider".equals(cmd)) { 12269 String[] newArgs; 12270 String name; 12271 if (opti >= args.length) { 12272 name = null; 12273 newArgs = EMPTY_STRING_ARRAY; 12274 } else { 12275 name = args[opti]; 12276 opti++; 12277 newArgs = new String[args.length - opti]; 12278 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12279 } 12280 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12281 pw.println("No providers match: " + name); 12282 pw.println("Use -h for help."); 12283 } 12284 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12285 synchronized (this) { 12286 dumpProvidersLocked(fd, pw, args, opti, true, null); 12287 } 12288 } else if ("service".equals(cmd)) { 12289 String[] newArgs; 12290 String name; 12291 if (opti >= args.length) { 12292 name = null; 12293 newArgs = EMPTY_STRING_ARRAY; 12294 } else { 12295 name = args[opti]; 12296 opti++; 12297 newArgs = new String[args.length - opti]; 12298 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12299 args.length - opti); 12300 } 12301 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12302 pw.println("No services match: " + name); 12303 pw.println("Use -h for help."); 12304 } 12305 } else if ("package".equals(cmd)) { 12306 String[] newArgs; 12307 if (opti >= args.length) { 12308 pw.println("package: no package name specified"); 12309 pw.println("Use -h for help."); 12310 } else { 12311 dumpPackage = args[opti]; 12312 opti++; 12313 newArgs = new String[args.length - opti]; 12314 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12315 args.length - opti); 12316 args = newArgs; 12317 opti = 0; 12318 more = true; 12319 } 12320 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12321 synchronized (this) { 12322 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12323 } 12324 } else if ("write".equals(cmd)) { 12325 mTaskPersister.flush(); 12326 pw.println("All tasks persisted."); 12327 return; 12328 } else { 12329 // Dumping a single activity? 12330 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12331 pw.println("Bad activity command, or no activities match: " + cmd); 12332 pw.println("Use -h for help."); 12333 } 12334 } 12335 if (!more) { 12336 Binder.restoreCallingIdentity(origId); 12337 return; 12338 } 12339 } 12340 12341 // No piece of data specified, dump everything. 12342 synchronized (this) { 12343 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12344 pw.println(); 12345 if (dumpAll) { 12346 pw.println("-------------------------------------------------------------------------------"); 12347 } 12348 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12349 pw.println(); 12350 if (dumpAll) { 12351 pw.println("-------------------------------------------------------------------------------"); 12352 } 12353 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12354 pw.println(); 12355 if (dumpAll) { 12356 pw.println("-------------------------------------------------------------------------------"); 12357 } 12358 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12359 pw.println(); 12360 if (dumpAll) { 12361 pw.println("-------------------------------------------------------------------------------"); 12362 } 12363 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12364 pw.println(); 12365 if (dumpAll) { 12366 pw.println("-------------------------------------------------------------------------------"); 12367 } 12368 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12369 pw.println(); 12370 if (dumpAll) { 12371 pw.println("-------------------------------------------------------------------------------"); 12372 } 12373 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12374 } 12375 Binder.restoreCallingIdentity(origId); 12376 } 12377 12378 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12379 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12380 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12381 12382 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12383 dumpPackage); 12384 boolean needSep = printedAnything; 12385 12386 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12387 dumpPackage, needSep, " mFocusedActivity: "); 12388 if (printed) { 12389 printedAnything = true; 12390 needSep = false; 12391 } 12392 12393 if (dumpPackage == null) { 12394 if (needSep) { 12395 pw.println(); 12396 } 12397 needSep = true; 12398 printedAnything = true; 12399 mStackSupervisor.dump(pw, " "); 12400 } 12401 12402 if (!printedAnything) { 12403 pw.println(" (nothing)"); 12404 } 12405 } 12406 12407 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12408 int opti, boolean dumpAll, String dumpPackage) { 12409 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12410 12411 boolean printedAnything = false; 12412 12413 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12414 boolean printedHeader = false; 12415 12416 final int N = mRecentTasks.size(); 12417 for (int i=0; i<N; i++) { 12418 TaskRecord tr = mRecentTasks.get(i); 12419 if (dumpPackage != null) { 12420 if (tr.realActivity == null || 12421 !dumpPackage.equals(tr.realActivity)) { 12422 continue; 12423 } 12424 } 12425 if (!printedHeader) { 12426 pw.println(" Recent tasks:"); 12427 printedHeader = true; 12428 printedAnything = true; 12429 } 12430 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12431 pw.println(tr); 12432 if (dumpAll) { 12433 mRecentTasks.get(i).dump(pw, " "); 12434 } 12435 } 12436 } 12437 12438 if (!printedAnything) { 12439 pw.println(" (nothing)"); 12440 } 12441 } 12442 12443 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12444 int opti, boolean dumpAll, String dumpPackage) { 12445 boolean needSep = false; 12446 boolean printedAnything = false; 12447 int numPers = 0; 12448 12449 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12450 12451 if (dumpAll) { 12452 final int NP = mProcessNames.getMap().size(); 12453 for (int ip=0; ip<NP; ip++) { 12454 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12455 final int NA = procs.size(); 12456 for (int ia=0; ia<NA; ia++) { 12457 ProcessRecord r = procs.valueAt(ia); 12458 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12459 continue; 12460 } 12461 if (!needSep) { 12462 pw.println(" All known processes:"); 12463 needSep = true; 12464 printedAnything = true; 12465 } 12466 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12467 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12468 pw.print(" "); pw.println(r); 12469 r.dump(pw, " "); 12470 if (r.persistent) { 12471 numPers++; 12472 } 12473 } 12474 } 12475 } 12476 12477 if (mIsolatedProcesses.size() > 0) { 12478 boolean printed = false; 12479 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12480 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12481 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12482 continue; 12483 } 12484 if (!printed) { 12485 if (needSep) { 12486 pw.println(); 12487 } 12488 pw.println(" Isolated process list (sorted by uid):"); 12489 printedAnything = true; 12490 printed = true; 12491 needSep = true; 12492 } 12493 pw.println(String.format("%sIsolated #%2d: %s", 12494 " ", i, r.toString())); 12495 } 12496 } 12497 12498 if (mLruProcesses.size() > 0) { 12499 if (needSep) { 12500 pw.println(); 12501 } 12502 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12503 pw.print(" total, non-act at "); 12504 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12505 pw.print(", non-svc at "); 12506 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12507 pw.println("):"); 12508 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12509 needSep = true; 12510 printedAnything = true; 12511 } 12512 12513 if (dumpAll || dumpPackage != null) { 12514 synchronized (mPidsSelfLocked) { 12515 boolean printed = false; 12516 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12517 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12518 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12519 continue; 12520 } 12521 if (!printed) { 12522 if (needSep) pw.println(); 12523 needSep = true; 12524 pw.println(" PID mappings:"); 12525 printed = true; 12526 printedAnything = true; 12527 } 12528 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12529 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12530 } 12531 } 12532 } 12533 12534 if (mForegroundProcesses.size() > 0) { 12535 synchronized (mPidsSelfLocked) { 12536 boolean printed = false; 12537 for (int i=0; i<mForegroundProcesses.size(); i++) { 12538 ProcessRecord r = mPidsSelfLocked.get( 12539 mForegroundProcesses.valueAt(i).pid); 12540 if (dumpPackage != null && (r == null 12541 || !r.pkgList.containsKey(dumpPackage))) { 12542 continue; 12543 } 12544 if (!printed) { 12545 if (needSep) pw.println(); 12546 needSep = true; 12547 pw.println(" Foreground Processes:"); 12548 printed = true; 12549 printedAnything = true; 12550 } 12551 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12552 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12553 } 12554 } 12555 } 12556 12557 if (mPersistentStartingProcesses.size() > 0) { 12558 if (needSep) pw.println(); 12559 needSep = true; 12560 printedAnything = true; 12561 pw.println(" Persisent processes that are starting:"); 12562 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12563 "Starting Norm", "Restarting PERS", dumpPackage); 12564 } 12565 12566 if (mRemovedProcesses.size() > 0) { 12567 if (needSep) pw.println(); 12568 needSep = true; 12569 printedAnything = true; 12570 pw.println(" Processes that are being removed:"); 12571 dumpProcessList(pw, this, mRemovedProcesses, " ", 12572 "Removed Norm", "Removed PERS", dumpPackage); 12573 } 12574 12575 if (mProcessesOnHold.size() > 0) { 12576 if (needSep) pw.println(); 12577 needSep = true; 12578 printedAnything = true; 12579 pw.println(" Processes that are on old until the system is ready:"); 12580 dumpProcessList(pw, this, mProcessesOnHold, " ", 12581 "OnHold Norm", "OnHold PERS", dumpPackage); 12582 } 12583 12584 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12585 12586 if (mProcessCrashTimes.getMap().size() > 0) { 12587 boolean printed = false; 12588 long now = SystemClock.uptimeMillis(); 12589 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12590 final int NP = pmap.size(); 12591 for (int ip=0; ip<NP; ip++) { 12592 String pname = pmap.keyAt(ip); 12593 SparseArray<Long> uids = pmap.valueAt(ip); 12594 final int N = uids.size(); 12595 for (int i=0; i<N; i++) { 12596 int puid = uids.keyAt(i); 12597 ProcessRecord r = mProcessNames.get(pname, puid); 12598 if (dumpPackage != null && (r == null 12599 || !r.pkgList.containsKey(dumpPackage))) { 12600 continue; 12601 } 12602 if (!printed) { 12603 if (needSep) pw.println(); 12604 needSep = true; 12605 pw.println(" Time since processes crashed:"); 12606 printed = true; 12607 printedAnything = true; 12608 } 12609 pw.print(" Process "); pw.print(pname); 12610 pw.print(" uid "); pw.print(puid); 12611 pw.print(": last crashed "); 12612 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12613 pw.println(" ago"); 12614 } 12615 } 12616 } 12617 12618 if (mBadProcesses.getMap().size() > 0) { 12619 boolean printed = false; 12620 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12621 final int NP = pmap.size(); 12622 for (int ip=0; ip<NP; ip++) { 12623 String pname = pmap.keyAt(ip); 12624 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12625 final int N = uids.size(); 12626 for (int i=0; i<N; i++) { 12627 int puid = uids.keyAt(i); 12628 ProcessRecord r = mProcessNames.get(pname, puid); 12629 if (dumpPackage != null && (r == null 12630 || !r.pkgList.containsKey(dumpPackage))) { 12631 continue; 12632 } 12633 if (!printed) { 12634 if (needSep) pw.println(); 12635 needSep = true; 12636 pw.println(" Bad processes:"); 12637 printedAnything = true; 12638 } 12639 BadProcessInfo info = uids.valueAt(i); 12640 pw.print(" Bad process "); pw.print(pname); 12641 pw.print(" uid "); pw.print(puid); 12642 pw.print(": crashed at time "); pw.println(info.time); 12643 if (info.shortMsg != null) { 12644 pw.print(" Short msg: "); pw.println(info.shortMsg); 12645 } 12646 if (info.longMsg != null) { 12647 pw.print(" Long msg: "); pw.println(info.longMsg); 12648 } 12649 if (info.stack != null) { 12650 pw.println(" Stack:"); 12651 int lastPos = 0; 12652 for (int pos=0; pos<info.stack.length(); pos++) { 12653 if (info.stack.charAt(pos) == '\n') { 12654 pw.print(" "); 12655 pw.write(info.stack, lastPos, pos-lastPos); 12656 pw.println(); 12657 lastPos = pos+1; 12658 } 12659 } 12660 if (lastPos < info.stack.length()) { 12661 pw.print(" "); 12662 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12663 pw.println(); 12664 } 12665 } 12666 } 12667 } 12668 } 12669 12670 if (dumpPackage == null) { 12671 pw.println(); 12672 needSep = false; 12673 pw.println(" mStartedUsers:"); 12674 for (int i=0; i<mStartedUsers.size(); i++) { 12675 UserStartedState uss = mStartedUsers.valueAt(i); 12676 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12677 pw.print(": "); uss.dump("", pw); 12678 } 12679 pw.print(" mStartedUserArray: ["); 12680 for (int i=0; i<mStartedUserArray.length; i++) { 12681 if (i > 0) pw.print(", "); 12682 pw.print(mStartedUserArray[i]); 12683 } 12684 pw.println("]"); 12685 pw.print(" mUserLru: ["); 12686 for (int i=0; i<mUserLru.size(); i++) { 12687 if (i > 0) pw.print(", "); 12688 pw.print(mUserLru.get(i)); 12689 } 12690 pw.println("]"); 12691 if (dumpAll) { 12692 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12693 } 12694 synchronized (mUserProfileGroupIdsSelfLocked) { 12695 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12696 pw.println(" mUserProfileGroupIds:"); 12697 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12698 pw.print(" User #"); 12699 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12700 pw.print(" -> profile #"); 12701 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12702 } 12703 } 12704 } 12705 } 12706 if (mHomeProcess != null && (dumpPackage == null 12707 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12708 if (needSep) { 12709 pw.println(); 12710 needSep = false; 12711 } 12712 pw.println(" mHomeProcess: " + mHomeProcess); 12713 } 12714 if (mPreviousProcess != null && (dumpPackage == null 12715 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12716 if (needSep) { 12717 pw.println(); 12718 needSep = false; 12719 } 12720 pw.println(" mPreviousProcess: " + mPreviousProcess); 12721 } 12722 if (dumpAll) { 12723 StringBuilder sb = new StringBuilder(128); 12724 sb.append(" mPreviousProcessVisibleTime: "); 12725 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12726 pw.println(sb); 12727 } 12728 if (mHeavyWeightProcess != null && (dumpPackage == null 12729 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12730 if (needSep) { 12731 pw.println(); 12732 needSep = false; 12733 } 12734 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12735 } 12736 if (dumpPackage == null) { 12737 pw.println(" mConfiguration: " + mConfiguration); 12738 } 12739 if (dumpAll) { 12740 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12741 if (mCompatModePackages.getPackages().size() > 0) { 12742 boolean printed = false; 12743 for (Map.Entry<String, Integer> entry 12744 : mCompatModePackages.getPackages().entrySet()) { 12745 String pkg = entry.getKey(); 12746 int mode = entry.getValue(); 12747 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12748 continue; 12749 } 12750 if (!printed) { 12751 pw.println(" mScreenCompatPackages:"); 12752 printed = true; 12753 } 12754 pw.print(" "); pw.print(pkg); pw.print(": "); 12755 pw.print(mode); pw.println(); 12756 } 12757 } 12758 } 12759 if (dumpPackage == null) { 12760 if (mSleeping || mWentToSleep || mLockScreenShown) { 12761 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12762 + " mLockScreenShown " + mLockScreenShown); 12763 } 12764 if (mShuttingDown || mRunningVoice) { 12765 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12766 } 12767 } 12768 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12769 || mOrigWaitForDebugger) { 12770 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12771 || dumpPackage.equals(mOrigDebugApp)) { 12772 if (needSep) { 12773 pw.println(); 12774 needSep = false; 12775 } 12776 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12777 + " mDebugTransient=" + mDebugTransient 12778 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12779 } 12780 } 12781 if (mOpenGlTraceApp != null) { 12782 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12783 if (needSep) { 12784 pw.println(); 12785 needSep = false; 12786 } 12787 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12788 } 12789 } 12790 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12791 || mProfileFd != null) { 12792 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12793 if (needSep) { 12794 pw.println(); 12795 needSep = false; 12796 } 12797 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12798 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12799 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12800 + mAutoStopProfiler); 12801 pw.println(" mProfileType=" + mProfileType); 12802 } 12803 } 12804 if (dumpPackage == null) { 12805 if (mAlwaysFinishActivities || mController != null) { 12806 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12807 + " mController=" + mController); 12808 } 12809 if (dumpAll) { 12810 pw.println(" Total persistent processes: " + numPers); 12811 pw.println(" mProcessesReady=" + mProcessesReady 12812 + " mSystemReady=" + mSystemReady 12813 + " mBooted=" + mBooted 12814 + " mFactoryTest=" + mFactoryTest); 12815 pw.println(" mBooting=" + mBooting 12816 + " mCallFinishBooting=" + mCallFinishBooting 12817 + " mBootAnimationComplete=" + mBootAnimationComplete); 12818 pw.print(" mLastPowerCheckRealtime="); 12819 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12820 pw.println(""); 12821 pw.print(" mLastPowerCheckUptime="); 12822 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12823 pw.println(""); 12824 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12825 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12826 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12827 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12828 + " (" + mLruProcesses.size() + " total)" 12829 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12830 + " mNumServiceProcs=" + mNumServiceProcs 12831 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12832 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12833 + " mLastMemoryLevel" + mLastMemoryLevel 12834 + " mLastNumProcesses" + mLastNumProcesses); 12835 long now = SystemClock.uptimeMillis(); 12836 pw.print(" mLastIdleTime="); 12837 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12838 pw.print(" mLowRamSinceLastIdle="); 12839 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12840 pw.println(); 12841 } 12842 } 12843 12844 if (!printedAnything) { 12845 pw.println(" (nothing)"); 12846 } 12847 } 12848 12849 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12850 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12851 if (mProcessesToGc.size() > 0) { 12852 boolean printed = false; 12853 long now = SystemClock.uptimeMillis(); 12854 for (int i=0; i<mProcessesToGc.size(); i++) { 12855 ProcessRecord proc = mProcessesToGc.get(i); 12856 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12857 continue; 12858 } 12859 if (!printed) { 12860 if (needSep) pw.println(); 12861 needSep = true; 12862 pw.println(" Processes that are waiting to GC:"); 12863 printed = true; 12864 } 12865 pw.print(" Process "); pw.println(proc); 12866 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12867 pw.print(", last gced="); 12868 pw.print(now-proc.lastRequestedGc); 12869 pw.print(" ms ago, last lowMem="); 12870 pw.print(now-proc.lastLowMemory); 12871 pw.println(" ms ago"); 12872 12873 } 12874 } 12875 return needSep; 12876 } 12877 12878 void printOomLevel(PrintWriter pw, String name, int adj) { 12879 pw.print(" "); 12880 if (adj >= 0) { 12881 pw.print(' '); 12882 if (adj < 10) pw.print(' '); 12883 } else { 12884 if (adj > -10) pw.print(' '); 12885 } 12886 pw.print(adj); 12887 pw.print(": "); 12888 pw.print(name); 12889 pw.print(" ("); 12890 pw.print(mProcessList.getMemLevel(adj)/1024); 12891 pw.println(" kB)"); 12892 } 12893 12894 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12895 int opti, boolean dumpAll) { 12896 boolean needSep = false; 12897 12898 if (mLruProcesses.size() > 0) { 12899 if (needSep) pw.println(); 12900 needSep = true; 12901 pw.println(" OOM levels:"); 12902 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12903 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12904 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12905 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12906 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12907 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12908 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12909 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12910 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12911 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12912 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12913 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12914 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12915 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12916 12917 if (needSep) pw.println(); 12918 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12919 pw.print(" total, non-act at "); 12920 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12921 pw.print(", non-svc at "); 12922 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12923 pw.println("):"); 12924 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12925 needSep = true; 12926 } 12927 12928 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12929 12930 pw.println(); 12931 pw.println(" mHomeProcess: " + mHomeProcess); 12932 pw.println(" mPreviousProcess: " + mPreviousProcess); 12933 if (mHeavyWeightProcess != null) { 12934 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12935 } 12936 12937 return true; 12938 } 12939 12940 /** 12941 * There are three ways to call this: 12942 * - no provider specified: dump all the providers 12943 * - a flattened component name that matched an existing provider was specified as the 12944 * first arg: dump that one provider 12945 * - the first arg isn't the flattened component name of an existing provider: 12946 * dump all providers whose component contains the first arg as a substring 12947 */ 12948 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12949 int opti, boolean dumpAll) { 12950 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12951 } 12952 12953 static class ItemMatcher { 12954 ArrayList<ComponentName> components; 12955 ArrayList<String> strings; 12956 ArrayList<Integer> objects; 12957 boolean all; 12958 12959 ItemMatcher() { 12960 all = true; 12961 } 12962 12963 void build(String name) { 12964 ComponentName componentName = ComponentName.unflattenFromString(name); 12965 if (componentName != null) { 12966 if (components == null) { 12967 components = new ArrayList<ComponentName>(); 12968 } 12969 components.add(componentName); 12970 all = false; 12971 } else { 12972 int objectId = 0; 12973 // Not a '/' separated full component name; maybe an object ID? 12974 try { 12975 objectId = Integer.parseInt(name, 16); 12976 if (objects == null) { 12977 objects = new ArrayList<Integer>(); 12978 } 12979 objects.add(objectId); 12980 all = false; 12981 } catch (RuntimeException e) { 12982 // Not an integer; just do string match. 12983 if (strings == null) { 12984 strings = new ArrayList<String>(); 12985 } 12986 strings.add(name); 12987 all = false; 12988 } 12989 } 12990 } 12991 12992 int build(String[] args, int opti) { 12993 for (; opti<args.length; opti++) { 12994 String name = args[opti]; 12995 if ("--".equals(name)) { 12996 return opti+1; 12997 } 12998 build(name); 12999 } 13000 return opti; 13001 } 13002 13003 boolean match(Object object, ComponentName comp) { 13004 if (all) { 13005 return true; 13006 } 13007 if (components != null) { 13008 for (int i=0; i<components.size(); i++) { 13009 if (components.get(i).equals(comp)) { 13010 return true; 13011 } 13012 } 13013 } 13014 if (objects != null) { 13015 for (int i=0; i<objects.size(); i++) { 13016 if (System.identityHashCode(object) == objects.get(i)) { 13017 return true; 13018 } 13019 } 13020 } 13021 if (strings != null) { 13022 String flat = comp.flattenToString(); 13023 for (int i=0; i<strings.size(); i++) { 13024 if (flat.contains(strings.get(i))) { 13025 return true; 13026 } 13027 } 13028 } 13029 return false; 13030 } 13031 } 13032 13033 /** 13034 * There are three things that cmd can be: 13035 * - a flattened component name that matches an existing activity 13036 * - the cmd arg isn't the flattened component name of an existing activity: 13037 * dump all activity whose component contains the cmd as a substring 13038 * - A hex number of the ActivityRecord object instance. 13039 */ 13040 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13041 int opti, boolean dumpAll) { 13042 ArrayList<ActivityRecord> activities; 13043 13044 synchronized (this) { 13045 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13046 } 13047 13048 if (activities.size() <= 0) { 13049 return false; 13050 } 13051 13052 String[] newArgs = new String[args.length - opti]; 13053 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13054 13055 TaskRecord lastTask = null; 13056 boolean needSep = false; 13057 for (int i=activities.size()-1; i>=0; i--) { 13058 ActivityRecord r = activities.get(i); 13059 if (needSep) { 13060 pw.println(); 13061 } 13062 needSep = true; 13063 synchronized (this) { 13064 if (lastTask != r.task) { 13065 lastTask = r.task; 13066 pw.print("TASK "); pw.print(lastTask.affinity); 13067 pw.print(" id="); pw.println(lastTask.taskId); 13068 if (dumpAll) { 13069 lastTask.dump(pw, " "); 13070 } 13071 } 13072 } 13073 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13074 } 13075 return true; 13076 } 13077 13078 /** 13079 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13080 * there is a thread associated with the activity. 13081 */ 13082 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13083 final ActivityRecord r, String[] args, boolean dumpAll) { 13084 String innerPrefix = prefix + " "; 13085 synchronized (this) { 13086 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13087 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13088 pw.print(" pid="); 13089 if (r.app != null) pw.println(r.app.pid); 13090 else pw.println("(not running)"); 13091 if (dumpAll) { 13092 r.dump(pw, innerPrefix); 13093 } 13094 } 13095 if (r.app != null && r.app.thread != null) { 13096 // flush anything that is already in the PrintWriter since the thread is going 13097 // to write to the file descriptor directly 13098 pw.flush(); 13099 try { 13100 TransferPipe tp = new TransferPipe(); 13101 try { 13102 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13103 r.appToken, innerPrefix, args); 13104 tp.go(fd); 13105 } finally { 13106 tp.kill(); 13107 } 13108 } catch (IOException e) { 13109 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13110 } catch (RemoteException e) { 13111 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13112 } 13113 } 13114 } 13115 13116 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13117 int opti, boolean dumpAll, String dumpPackage) { 13118 boolean needSep = false; 13119 boolean onlyHistory = false; 13120 boolean printedAnything = false; 13121 13122 if ("history".equals(dumpPackage)) { 13123 if (opti < args.length && "-s".equals(args[opti])) { 13124 dumpAll = false; 13125 } 13126 onlyHistory = true; 13127 dumpPackage = null; 13128 } 13129 13130 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13131 if (!onlyHistory && dumpAll) { 13132 if (mRegisteredReceivers.size() > 0) { 13133 boolean printed = false; 13134 Iterator it = mRegisteredReceivers.values().iterator(); 13135 while (it.hasNext()) { 13136 ReceiverList r = (ReceiverList)it.next(); 13137 if (dumpPackage != null && (r.app == null || 13138 !dumpPackage.equals(r.app.info.packageName))) { 13139 continue; 13140 } 13141 if (!printed) { 13142 pw.println(" Registered Receivers:"); 13143 needSep = true; 13144 printed = true; 13145 printedAnything = true; 13146 } 13147 pw.print(" * "); pw.println(r); 13148 r.dump(pw, " "); 13149 } 13150 } 13151 13152 if (mReceiverResolver.dump(pw, needSep ? 13153 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13154 " ", dumpPackage, false)) { 13155 needSep = true; 13156 printedAnything = true; 13157 } 13158 } 13159 13160 for (BroadcastQueue q : mBroadcastQueues) { 13161 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13162 printedAnything |= needSep; 13163 } 13164 13165 needSep = true; 13166 13167 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13168 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13169 if (needSep) { 13170 pw.println(); 13171 } 13172 needSep = true; 13173 printedAnything = true; 13174 pw.print(" Sticky broadcasts for user "); 13175 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13176 StringBuilder sb = new StringBuilder(128); 13177 for (Map.Entry<String, ArrayList<Intent>> ent 13178 : mStickyBroadcasts.valueAt(user).entrySet()) { 13179 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13180 if (dumpAll) { 13181 pw.println(":"); 13182 ArrayList<Intent> intents = ent.getValue(); 13183 final int N = intents.size(); 13184 for (int i=0; i<N; i++) { 13185 sb.setLength(0); 13186 sb.append(" Intent: "); 13187 intents.get(i).toShortString(sb, false, true, false, false); 13188 pw.println(sb.toString()); 13189 Bundle bundle = intents.get(i).getExtras(); 13190 if (bundle != null) { 13191 pw.print(" "); 13192 pw.println(bundle.toString()); 13193 } 13194 } 13195 } else { 13196 pw.println(""); 13197 } 13198 } 13199 } 13200 } 13201 13202 if (!onlyHistory && dumpAll) { 13203 pw.println(); 13204 for (BroadcastQueue queue : mBroadcastQueues) { 13205 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13206 + queue.mBroadcastsScheduled); 13207 } 13208 pw.println(" mHandler:"); 13209 mHandler.dump(new PrintWriterPrinter(pw), " "); 13210 needSep = true; 13211 printedAnything = true; 13212 } 13213 13214 if (!printedAnything) { 13215 pw.println(" (nothing)"); 13216 } 13217 } 13218 13219 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13220 int opti, boolean dumpAll, String dumpPackage) { 13221 boolean needSep; 13222 boolean printedAnything = false; 13223 13224 ItemMatcher matcher = new ItemMatcher(); 13225 matcher.build(args, opti); 13226 13227 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13228 13229 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13230 printedAnything |= needSep; 13231 13232 if (mLaunchingProviders.size() > 0) { 13233 boolean printed = false; 13234 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13235 ContentProviderRecord r = mLaunchingProviders.get(i); 13236 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13237 continue; 13238 } 13239 if (!printed) { 13240 if (needSep) pw.println(); 13241 needSep = true; 13242 pw.println(" Launching content providers:"); 13243 printed = true; 13244 printedAnything = true; 13245 } 13246 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13247 pw.println(r); 13248 } 13249 } 13250 13251 if (mGrantedUriPermissions.size() > 0) { 13252 boolean printed = false; 13253 int dumpUid = -2; 13254 if (dumpPackage != null) { 13255 try { 13256 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13257 } catch (NameNotFoundException e) { 13258 dumpUid = -1; 13259 } 13260 } 13261 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13262 int uid = mGrantedUriPermissions.keyAt(i); 13263 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13264 continue; 13265 } 13266 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13267 if (!printed) { 13268 if (needSep) pw.println(); 13269 needSep = true; 13270 pw.println(" Granted Uri Permissions:"); 13271 printed = true; 13272 printedAnything = true; 13273 } 13274 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13275 for (UriPermission perm : perms.values()) { 13276 pw.print(" "); pw.println(perm); 13277 if (dumpAll) { 13278 perm.dump(pw, " "); 13279 } 13280 } 13281 } 13282 } 13283 13284 if (!printedAnything) { 13285 pw.println(" (nothing)"); 13286 } 13287 } 13288 13289 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13290 int opti, boolean dumpAll, String dumpPackage) { 13291 boolean printed = false; 13292 13293 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13294 13295 if (mIntentSenderRecords.size() > 0) { 13296 Iterator<WeakReference<PendingIntentRecord>> it 13297 = mIntentSenderRecords.values().iterator(); 13298 while (it.hasNext()) { 13299 WeakReference<PendingIntentRecord> ref = it.next(); 13300 PendingIntentRecord rec = ref != null ? ref.get(): null; 13301 if (dumpPackage != null && (rec == null 13302 || !dumpPackage.equals(rec.key.packageName))) { 13303 continue; 13304 } 13305 printed = true; 13306 if (rec != null) { 13307 pw.print(" * "); pw.println(rec); 13308 if (dumpAll) { 13309 rec.dump(pw, " "); 13310 } 13311 } else { 13312 pw.print(" * "); pw.println(ref); 13313 } 13314 } 13315 } 13316 13317 if (!printed) { 13318 pw.println(" (nothing)"); 13319 } 13320 } 13321 13322 private static final int dumpProcessList(PrintWriter pw, 13323 ActivityManagerService service, List list, 13324 String prefix, String normalLabel, String persistentLabel, 13325 String dumpPackage) { 13326 int numPers = 0; 13327 final int N = list.size()-1; 13328 for (int i=N; i>=0; i--) { 13329 ProcessRecord r = (ProcessRecord)list.get(i); 13330 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13331 continue; 13332 } 13333 pw.println(String.format("%s%s #%2d: %s", 13334 prefix, (r.persistent ? persistentLabel : normalLabel), 13335 i, r.toString())); 13336 if (r.persistent) { 13337 numPers++; 13338 } 13339 } 13340 return numPers; 13341 } 13342 13343 private static final boolean dumpProcessOomList(PrintWriter pw, 13344 ActivityManagerService service, List<ProcessRecord> origList, 13345 String prefix, String normalLabel, String persistentLabel, 13346 boolean inclDetails, String dumpPackage) { 13347 13348 ArrayList<Pair<ProcessRecord, Integer>> list 13349 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13350 for (int i=0; i<origList.size(); i++) { 13351 ProcessRecord r = origList.get(i); 13352 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13353 continue; 13354 } 13355 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13356 } 13357 13358 if (list.size() <= 0) { 13359 return false; 13360 } 13361 13362 Comparator<Pair<ProcessRecord, Integer>> comparator 13363 = new Comparator<Pair<ProcessRecord, Integer>>() { 13364 @Override 13365 public int compare(Pair<ProcessRecord, Integer> object1, 13366 Pair<ProcessRecord, Integer> object2) { 13367 if (object1.first.setAdj != object2.first.setAdj) { 13368 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13369 } 13370 if (object1.second.intValue() != object2.second.intValue()) { 13371 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13372 } 13373 return 0; 13374 } 13375 }; 13376 13377 Collections.sort(list, comparator); 13378 13379 final long curRealtime = SystemClock.elapsedRealtime(); 13380 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13381 final long curUptime = SystemClock.uptimeMillis(); 13382 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13383 13384 for (int i=list.size()-1; i>=0; i--) { 13385 ProcessRecord r = list.get(i).first; 13386 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13387 char schedGroup; 13388 switch (r.setSchedGroup) { 13389 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13390 schedGroup = 'B'; 13391 break; 13392 case Process.THREAD_GROUP_DEFAULT: 13393 schedGroup = 'F'; 13394 break; 13395 default: 13396 schedGroup = '?'; 13397 break; 13398 } 13399 char foreground; 13400 if (r.foregroundActivities) { 13401 foreground = 'A'; 13402 } else if (r.foregroundServices) { 13403 foreground = 'S'; 13404 } else { 13405 foreground = ' '; 13406 } 13407 String procState = ProcessList.makeProcStateString(r.curProcState); 13408 pw.print(prefix); 13409 pw.print(r.persistent ? persistentLabel : normalLabel); 13410 pw.print(" #"); 13411 int num = (origList.size()-1)-list.get(i).second; 13412 if (num < 10) pw.print(' '); 13413 pw.print(num); 13414 pw.print(": "); 13415 pw.print(oomAdj); 13416 pw.print(' '); 13417 pw.print(schedGroup); 13418 pw.print('/'); 13419 pw.print(foreground); 13420 pw.print('/'); 13421 pw.print(procState); 13422 pw.print(" trm:"); 13423 if (r.trimMemoryLevel < 10) pw.print(' '); 13424 pw.print(r.trimMemoryLevel); 13425 pw.print(' '); 13426 pw.print(r.toShortString()); 13427 pw.print(" ("); 13428 pw.print(r.adjType); 13429 pw.println(')'); 13430 if (r.adjSource != null || r.adjTarget != null) { 13431 pw.print(prefix); 13432 pw.print(" "); 13433 if (r.adjTarget instanceof ComponentName) { 13434 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13435 } else if (r.adjTarget != null) { 13436 pw.print(r.adjTarget.toString()); 13437 } else { 13438 pw.print("{null}"); 13439 } 13440 pw.print("<="); 13441 if (r.adjSource instanceof ProcessRecord) { 13442 pw.print("Proc{"); 13443 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13444 pw.println("}"); 13445 } else if (r.adjSource != null) { 13446 pw.println(r.adjSource.toString()); 13447 } else { 13448 pw.println("{null}"); 13449 } 13450 } 13451 if (inclDetails) { 13452 pw.print(prefix); 13453 pw.print(" "); 13454 pw.print("oom: max="); pw.print(r.maxAdj); 13455 pw.print(" curRaw="); pw.print(r.curRawAdj); 13456 pw.print(" setRaw="); pw.print(r.setRawAdj); 13457 pw.print(" cur="); pw.print(r.curAdj); 13458 pw.print(" set="); pw.println(r.setAdj); 13459 pw.print(prefix); 13460 pw.print(" "); 13461 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13462 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13463 pw.print(" lastPss="); pw.print(r.lastPss); 13464 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13465 pw.print(prefix); 13466 pw.print(" "); 13467 pw.print("cached="); pw.print(r.cached); 13468 pw.print(" empty="); pw.print(r.empty); 13469 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13470 13471 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13472 if (r.lastWakeTime != 0) { 13473 long wtime; 13474 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13475 synchronized (stats) { 13476 wtime = stats.getProcessWakeTime(r.info.uid, 13477 r.pid, curRealtime); 13478 } 13479 long timeUsed = wtime - r.lastWakeTime; 13480 pw.print(prefix); 13481 pw.print(" "); 13482 pw.print("keep awake over "); 13483 TimeUtils.formatDuration(realtimeSince, pw); 13484 pw.print(" used "); 13485 TimeUtils.formatDuration(timeUsed, pw); 13486 pw.print(" ("); 13487 pw.print((timeUsed*100)/realtimeSince); 13488 pw.println("%)"); 13489 } 13490 if (r.lastCpuTime != 0) { 13491 long timeUsed = r.curCpuTime - r.lastCpuTime; 13492 pw.print(prefix); 13493 pw.print(" "); 13494 pw.print("run cpu over "); 13495 TimeUtils.formatDuration(uptimeSince, pw); 13496 pw.print(" used "); 13497 TimeUtils.formatDuration(timeUsed, pw); 13498 pw.print(" ("); 13499 pw.print((timeUsed*100)/uptimeSince); 13500 pw.println("%)"); 13501 } 13502 } 13503 } 13504 } 13505 return true; 13506 } 13507 13508 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13509 String[] args) { 13510 ArrayList<ProcessRecord> procs; 13511 synchronized (this) { 13512 if (args != null && args.length > start 13513 && args[start].charAt(0) != '-') { 13514 procs = new ArrayList<ProcessRecord>(); 13515 int pid = -1; 13516 try { 13517 pid = Integer.parseInt(args[start]); 13518 } catch (NumberFormatException e) { 13519 } 13520 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13521 ProcessRecord proc = mLruProcesses.get(i); 13522 if (proc.pid == pid) { 13523 procs.add(proc); 13524 } else if (allPkgs && proc.pkgList != null 13525 && proc.pkgList.containsKey(args[start])) { 13526 procs.add(proc); 13527 } else if (proc.processName.equals(args[start])) { 13528 procs.add(proc); 13529 } 13530 } 13531 if (procs.size() <= 0) { 13532 return null; 13533 } 13534 } else { 13535 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13536 } 13537 } 13538 return procs; 13539 } 13540 13541 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13542 PrintWriter pw, String[] args) { 13543 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13544 if (procs == null) { 13545 pw.println("No process found for: " + args[0]); 13546 return; 13547 } 13548 13549 long uptime = SystemClock.uptimeMillis(); 13550 long realtime = SystemClock.elapsedRealtime(); 13551 pw.println("Applications Graphics Acceleration Info:"); 13552 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13553 13554 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13555 ProcessRecord r = procs.get(i); 13556 if (r.thread != null) { 13557 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13558 pw.flush(); 13559 try { 13560 TransferPipe tp = new TransferPipe(); 13561 try { 13562 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13563 tp.go(fd); 13564 } finally { 13565 tp.kill(); 13566 } 13567 } catch (IOException e) { 13568 pw.println("Failure while dumping the app: " + r); 13569 pw.flush(); 13570 } catch (RemoteException e) { 13571 pw.println("Got a RemoteException while dumping the app " + r); 13572 pw.flush(); 13573 } 13574 } 13575 } 13576 } 13577 13578 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13579 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13580 if (procs == null) { 13581 pw.println("No process found for: " + args[0]); 13582 return; 13583 } 13584 13585 pw.println("Applications Database Info:"); 13586 13587 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13588 ProcessRecord r = procs.get(i); 13589 if (r.thread != null) { 13590 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13591 pw.flush(); 13592 try { 13593 TransferPipe tp = new TransferPipe(); 13594 try { 13595 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13596 tp.go(fd); 13597 } finally { 13598 tp.kill(); 13599 } 13600 } catch (IOException e) { 13601 pw.println("Failure while dumping the app: " + r); 13602 pw.flush(); 13603 } catch (RemoteException e) { 13604 pw.println("Got a RemoteException while dumping the app " + r); 13605 pw.flush(); 13606 } 13607 } 13608 } 13609 } 13610 13611 final static class MemItem { 13612 final boolean isProc; 13613 final String label; 13614 final String shortLabel; 13615 final long pss; 13616 final int id; 13617 final boolean hasActivities; 13618 ArrayList<MemItem> subitems; 13619 13620 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13621 boolean _hasActivities) { 13622 isProc = true; 13623 label = _label; 13624 shortLabel = _shortLabel; 13625 pss = _pss; 13626 id = _id; 13627 hasActivities = _hasActivities; 13628 } 13629 13630 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13631 isProc = false; 13632 label = _label; 13633 shortLabel = _shortLabel; 13634 pss = _pss; 13635 id = _id; 13636 hasActivities = false; 13637 } 13638 } 13639 13640 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13641 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13642 if (sort && !isCompact) { 13643 Collections.sort(items, new Comparator<MemItem>() { 13644 @Override 13645 public int compare(MemItem lhs, MemItem rhs) { 13646 if (lhs.pss < rhs.pss) { 13647 return 1; 13648 } else if (lhs.pss > rhs.pss) { 13649 return -1; 13650 } 13651 return 0; 13652 } 13653 }); 13654 } 13655 13656 for (int i=0; i<items.size(); i++) { 13657 MemItem mi = items.get(i); 13658 if (!isCompact) { 13659 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13660 } else if (mi.isProc) { 13661 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13662 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13663 pw.println(mi.hasActivities ? ",a" : ",e"); 13664 } else { 13665 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13666 pw.println(mi.pss); 13667 } 13668 if (mi.subitems != null) { 13669 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13670 true, isCompact); 13671 } 13672 } 13673 } 13674 13675 // These are in KB. 13676 static final long[] DUMP_MEM_BUCKETS = new long[] { 13677 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13678 120*1024, 160*1024, 200*1024, 13679 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13680 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13681 }; 13682 13683 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13684 boolean stackLike) { 13685 int start = label.lastIndexOf('.'); 13686 if (start >= 0) start++; 13687 else start = 0; 13688 int end = label.length(); 13689 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13690 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13691 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13692 out.append(bucket); 13693 out.append(stackLike ? "MB." : "MB "); 13694 out.append(label, start, end); 13695 return; 13696 } 13697 } 13698 out.append(memKB/1024); 13699 out.append(stackLike ? "MB." : "MB "); 13700 out.append(label, start, end); 13701 } 13702 13703 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13704 ProcessList.NATIVE_ADJ, 13705 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13706 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13707 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13708 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13709 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13710 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13711 }; 13712 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13713 "Native", 13714 "System", "Persistent", "Persistent Service", "Foreground", 13715 "Visible", "Perceptible", 13716 "Heavy Weight", "Backup", 13717 "A Services", "Home", 13718 "Previous", "B Services", "Cached" 13719 }; 13720 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13721 "native", 13722 "sys", "pers", "persvc", "fore", 13723 "vis", "percept", 13724 "heavy", "backup", 13725 "servicea", "home", 13726 "prev", "serviceb", "cached" 13727 }; 13728 13729 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13730 long realtime, boolean isCheckinRequest, boolean isCompact) { 13731 if (isCheckinRequest || isCompact) { 13732 // short checkin version 13733 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13734 } else { 13735 pw.println("Applications Memory Usage (kB):"); 13736 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13737 } 13738 } 13739 13740 private static final int KSM_SHARED = 0; 13741 private static final int KSM_SHARING = 1; 13742 private static final int KSM_UNSHARED = 2; 13743 private static final int KSM_VOLATILE = 3; 13744 13745 private final long[] getKsmInfo() { 13746 long[] longOut = new long[4]; 13747 final int[] SINGLE_LONG_FORMAT = new int[] { 13748 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13749 }; 13750 long[] longTmp = new long[1]; 13751 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13752 SINGLE_LONG_FORMAT, null, longTmp, null); 13753 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13754 longTmp[0] = 0; 13755 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13756 SINGLE_LONG_FORMAT, null, longTmp, null); 13757 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13758 longTmp[0] = 0; 13759 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13760 SINGLE_LONG_FORMAT, null, longTmp, null); 13761 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13762 longTmp[0] = 0; 13763 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13764 SINGLE_LONG_FORMAT, null, longTmp, null); 13765 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13766 return longOut; 13767 } 13768 13769 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13770 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13771 boolean dumpDetails = false; 13772 boolean dumpFullDetails = false; 13773 boolean dumpDalvik = false; 13774 boolean oomOnly = false; 13775 boolean isCompact = false; 13776 boolean localOnly = false; 13777 boolean packages = false; 13778 13779 int opti = 0; 13780 while (opti < args.length) { 13781 String opt = args[opti]; 13782 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13783 break; 13784 } 13785 opti++; 13786 if ("-a".equals(opt)) { 13787 dumpDetails = true; 13788 dumpFullDetails = true; 13789 dumpDalvik = true; 13790 } else if ("-d".equals(opt)) { 13791 dumpDalvik = true; 13792 } else if ("-c".equals(opt)) { 13793 isCompact = true; 13794 } else if ("--oom".equals(opt)) { 13795 oomOnly = true; 13796 } else if ("--local".equals(opt)) { 13797 localOnly = true; 13798 } else if ("--package".equals(opt)) { 13799 packages = true; 13800 } else if ("-h".equals(opt)) { 13801 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13802 pw.println(" -a: include all available information for each process."); 13803 pw.println(" -d: include dalvik details when dumping process details."); 13804 pw.println(" -c: dump in a compact machine-parseable representation."); 13805 pw.println(" --oom: only show processes organized by oom adj."); 13806 pw.println(" --local: only collect details locally, don't call process."); 13807 pw.println(" --package: interpret process arg as package, dumping all"); 13808 pw.println(" processes that have loaded that package."); 13809 pw.println("If [process] is specified it can be the name or "); 13810 pw.println("pid of a specific process to dump."); 13811 return; 13812 } else { 13813 pw.println("Unknown argument: " + opt + "; use -h for help"); 13814 } 13815 } 13816 13817 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13818 long uptime = SystemClock.uptimeMillis(); 13819 long realtime = SystemClock.elapsedRealtime(); 13820 final long[] tmpLong = new long[1]; 13821 13822 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13823 if (procs == null) { 13824 // No Java processes. Maybe they want to print a native process. 13825 if (args != null && args.length > opti 13826 && args[opti].charAt(0) != '-') { 13827 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13828 = new ArrayList<ProcessCpuTracker.Stats>(); 13829 updateCpuStatsNow(); 13830 int findPid = -1; 13831 try { 13832 findPid = Integer.parseInt(args[opti]); 13833 } catch (NumberFormatException e) { 13834 } 13835 synchronized (mProcessCpuTracker) { 13836 final int N = mProcessCpuTracker.countStats(); 13837 for (int i=0; i<N; i++) { 13838 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13839 if (st.pid == findPid || (st.baseName != null 13840 && st.baseName.equals(args[opti]))) { 13841 nativeProcs.add(st); 13842 } 13843 } 13844 } 13845 if (nativeProcs.size() > 0) { 13846 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13847 isCompact); 13848 Debug.MemoryInfo mi = null; 13849 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13850 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13851 final int pid = r.pid; 13852 if (!isCheckinRequest && dumpDetails) { 13853 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13854 } 13855 if (mi == null) { 13856 mi = new Debug.MemoryInfo(); 13857 } 13858 if (dumpDetails || (!brief && !oomOnly)) { 13859 Debug.getMemoryInfo(pid, mi); 13860 } else { 13861 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13862 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13863 } 13864 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13865 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13866 if (isCheckinRequest) { 13867 pw.println(); 13868 } 13869 } 13870 return; 13871 } 13872 } 13873 pw.println("No process found for: " + args[opti]); 13874 return; 13875 } 13876 13877 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13878 dumpDetails = true; 13879 } 13880 13881 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13882 13883 String[] innerArgs = new String[args.length-opti]; 13884 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13885 13886 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13887 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13888 long nativePss=0, dalvikPss=0, otherPss=0; 13889 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13890 13891 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13892 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13893 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13894 13895 long totalPss = 0; 13896 long cachedPss = 0; 13897 13898 Debug.MemoryInfo mi = null; 13899 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13900 final ProcessRecord r = procs.get(i); 13901 final IApplicationThread thread; 13902 final int pid; 13903 final int oomAdj; 13904 final boolean hasActivities; 13905 synchronized (this) { 13906 thread = r.thread; 13907 pid = r.pid; 13908 oomAdj = r.getSetAdjWithServices(); 13909 hasActivities = r.activities.size() > 0; 13910 } 13911 if (thread != null) { 13912 if (!isCheckinRequest && dumpDetails) { 13913 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13914 } 13915 if (mi == null) { 13916 mi = new Debug.MemoryInfo(); 13917 } 13918 if (dumpDetails || (!brief && !oomOnly)) { 13919 Debug.getMemoryInfo(pid, mi); 13920 } else { 13921 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13922 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13923 } 13924 if (dumpDetails) { 13925 if (localOnly) { 13926 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13927 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13928 if (isCheckinRequest) { 13929 pw.println(); 13930 } 13931 } else { 13932 try { 13933 pw.flush(); 13934 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13935 dumpDalvik, innerArgs); 13936 } catch (RemoteException e) { 13937 if (!isCheckinRequest) { 13938 pw.println("Got RemoteException!"); 13939 pw.flush(); 13940 } 13941 } 13942 } 13943 } 13944 13945 final long myTotalPss = mi.getTotalPss(); 13946 final long myTotalUss = mi.getTotalUss(); 13947 13948 synchronized (this) { 13949 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13950 // Record this for posterity if the process has been stable. 13951 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13952 } 13953 } 13954 13955 if (!isCheckinRequest && mi != null) { 13956 totalPss += myTotalPss; 13957 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13958 (hasActivities ? " / activities)" : ")"), 13959 r.processName, myTotalPss, pid, hasActivities); 13960 procMems.add(pssItem); 13961 procMemsMap.put(pid, pssItem); 13962 13963 nativePss += mi.nativePss; 13964 dalvikPss += mi.dalvikPss; 13965 otherPss += mi.otherPss; 13966 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13967 long mem = mi.getOtherPss(j); 13968 miscPss[j] += mem; 13969 otherPss -= mem; 13970 } 13971 13972 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13973 cachedPss += myTotalPss; 13974 } 13975 13976 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13977 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13978 || oomIndex == (oomPss.length-1)) { 13979 oomPss[oomIndex] += myTotalPss; 13980 if (oomProcs[oomIndex] == null) { 13981 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13982 } 13983 oomProcs[oomIndex].add(pssItem); 13984 break; 13985 } 13986 } 13987 } 13988 } 13989 } 13990 13991 long nativeProcTotalPss = 0; 13992 13993 if (!isCheckinRequest && procs.size() > 1 && !packages) { 13994 // If we are showing aggregations, also look for native processes to 13995 // include so that our aggregations are more accurate. 13996 updateCpuStatsNow(); 13997 synchronized (mProcessCpuTracker) { 13998 final int N = mProcessCpuTracker.countStats(); 13999 for (int i=0; i<N; i++) { 14000 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14001 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14002 if (mi == null) { 14003 mi = new Debug.MemoryInfo(); 14004 } 14005 if (!brief && !oomOnly) { 14006 Debug.getMemoryInfo(st.pid, mi); 14007 } else { 14008 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14009 mi.nativePrivateDirty = (int)tmpLong[0]; 14010 } 14011 14012 final long myTotalPss = mi.getTotalPss(); 14013 totalPss += myTotalPss; 14014 nativeProcTotalPss += myTotalPss; 14015 14016 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14017 st.name, myTotalPss, st.pid, false); 14018 procMems.add(pssItem); 14019 14020 nativePss += mi.nativePss; 14021 dalvikPss += mi.dalvikPss; 14022 otherPss += mi.otherPss; 14023 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14024 long mem = mi.getOtherPss(j); 14025 miscPss[j] += mem; 14026 otherPss -= mem; 14027 } 14028 oomPss[0] += myTotalPss; 14029 if (oomProcs[0] == null) { 14030 oomProcs[0] = new ArrayList<MemItem>(); 14031 } 14032 oomProcs[0].add(pssItem); 14033 } 14034 } 14035 } 14036 14037 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14038 14039 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14040 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14041 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14042 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14043 String label = Debug.MemoryInfo.getOtherLabel(j); 14044 catMems.add(new MemItem(label, label, miscPss[j], j)); 14045 } 14046 14047 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14048 for (int j=0; j<oomPss.length; j++) { 14049 if (oomPss[j] != 0) { 14050 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14051 : DUMP_MEM_OOM_LABEL[j]; 14052 MemItem item = new MemItem(label, label, oomPss[j], 14053 DUMP_MEM_OOM_ADJ[j]); 14054 item.subitems = oomProcs[j]; 14055 oomMems.add(item); 14056 } 14057 } 14058 14059 if (!brief && !oomOnly && !isCompact) { 14060 pw.println(); 14061 pw.println("Total PSS by process:"); 14062 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14063 pw.println(); 14064 } 14065 if (!isCompact) { 14066 pw.println("Total PSS by OOM adjustment:"); 14067 } 14068 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14069 if (!brief && !oomOnly) { 14070 PrintWriter out = categoryPw != null ? categoryPw : pw; 14071 if (!isCompact) { 14072 out.println(); 14073 out.println("Total PSS by category:"); 14074 } 14075 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14076 } 14077 if (!isCompact) { 14078 pw.println(); 14079 } 14080 MemInfoReader memInfo = new MemInfoReader(); 14081 memInfo.readMemInfo(); 14082 if (nativeProcTotalPss > 0) { 14083 synchronized (this) { 14084 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14085 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14086 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14087 } 14088 } 14089 if (!brief) { 14090 if (!isCompact) { 14091 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14092 pw.print(" kB (status "); 14093 switch (mLastMemoryLevel) { 14094 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14095 pw.println("normal)"); 14096 break; 14097 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14098 pw.println("moderate)"); 14099 break; 14100 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14101 pw.println("low)"); 14102 break; 14103 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14104 pw.println("critical)"); 14105 break; 14106 default: 14107 pw.print(mLastMemoryLevel); 14108 pw.println(")"); 14109 break; 14110 } 14111 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14112 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14113 pw.print(cachedPss); pw.print(" cached pss + "); 14114 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14115 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14116 } else { 14117 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14118 pw.print(cachedPss + memInfo.getCachedSizeKb() 14119 + memInfo.getFreeSizeKb()); pw.print(","); 14120 pw.println(totalPss - cachedPss); 14121 } 14122 } 14123 if (!isCompact) { 14124 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14125 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14126 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14127 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14128 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14129 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14130 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14131 } 14132 if (!brief) { 14133 if (memInfo.getZramTotalSizeKb() != 0) { 14134 if (!isCompact) { 14135 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14136 pw.print(" kB physical used for "); 14137 pw.print(memInfo.getSwapTotalSizeKb() 14138 - memInfo.getSwapFreeSizeKb()); 14139 pw.print(" kB in swap ("); 14140 pw.print(memInfo.getSwapTotalSizeKb()); 14141 pw.println(" kB total swap)"); 14142 } else { 14143 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14144 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14145 pw.println(memInfo.getSwapFreeSizeKb()); 14146 } 14147 } 14148 final long[] ksm = getKsmInfo(); 14149 if (!isCompact) { 14150 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14151 || ksm[KSM_VOLATILE] != 0) { 14152 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14153 pw.print(" kB saved from shared "); 14154 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14155 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14156 pw.print(" kB unshared; "); 14157 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14158 } 14159 pw.print(" Tuning: "); 14160 pw.print(ActivityManager.staticGetMemoryClass()); 14161 pw.print(" (large "); 14162 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14163 pw.print("), oom "); 14164 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14165 pw.print(" kB"); 14166 pw.print(", restore limit "); 14167 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14168 pw.print(" kB"); 14169 if (ActivityManager.isLowRamDeviceStatic()) { 14170 pw.print(" (low-ram)"); 14171 } 14172 if (ActivityManager.isHighEndGfx()) { 14173 pw.print(" (high-end-gfx)"); 14174 } 14175 pw.println(); 14176 } else { 14177 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14178 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14179 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14180 pw.print("tuning,"); 14181 pw.print(ActivityManager.staticGetMemoryClass()); 14182 pw.print(','); 14183 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14184 pw.print(','); 14185 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14186 if (ActivityManager.isLowRamDeviceStatic()) { 14187 pw.print(",low-ram"); 14188 } 14189 if (ActivityManager.isHighEndGfx()) { 14190 pw.print(",high-end-gfx"); 14191 } 14192 pw.println(); 14193 } 14194 } 14195 } 14196 } 14197 14198 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14199 String name) { 14200 sb.append(" "); 14201 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14202 sb.append(' '); 14203 sb.append(ProcessList.makeProcStateString(procState)); 14204 sb.append(' '); 14205 ProcessList.appendRamKb(sb, pss); 14206 sb.append(" kB: "); 14207 sb.append(name); 14208 } 14209 14210 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14211 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14212 sb.append(" ("); 14213 sb.append(mi.pid); 14214 sb.append(") "); 14215 sb.append(mi.adjType); 14216 sb.append('\n'); 14217 if (mi.adjReason != null) { 14218 sb.append(" "); 14219 sb.append(mi.adjReason); 14220 sb.append('\n'); 14221 } 14222 } 14223 14224 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14225 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14226 for (int i=0, N=memInfos.size(); i<N; i++) { 14227 ProcessMemInfo mi = memInfos.get(i); 14228 infoMap.put(mi.pid, mi); 14229 } 14230 updateCpuStatsNow(); 14231 synchronized (mProcessCpuTracker) { 14232 final int N = mProcessCpuTracker.countStats(); 14233 for (int i=0; i<N; i++) { 14234 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14235 if (st.vsize > 0) { 14236 long pss = Debug.getPss(st.pid, null); 14237 if (pss > 0) { 14238 if (infoMap.indexOfKey(st.pid) < 0) { 14239 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14240 ProcessList.NATIVE_ADJ, -1, "native", null); 14241 mi.pss = pss; 14242 memInfos.add(mi); 14243 } 14244 } 14245 } 14246 } 14247 } 14248 14249 long totalPss = 0; 14250 for (int i=0, N=memInfos.size(); i<N; i++) { 14251 ProcessMemInfo mi = memInfos.get(i); 14252 if (mi.pss == 0) { 14253 mi.pss = Debug.getPss(mi.pid, null); 14254 } 14255 totalPss += mi.pss; 14256 } 14257 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14258 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14259 if (lhs.oomAdj != rhs.oomAdj) { 14260 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14261 } 14262 if (lhs.pss != rhs.pss) { 14263 return lhs.pss < rhs.pss ? 1 : -1; 14264 } 14265 return 0; 14266 } 14267 }); 14268 14269 StringBuilder tag = new StringBuilder(128); 14270 StringBuilder stack = new StringBuilder(128); 14271 tag.append("Low on memory -- "); 14272 appendMemBucket(tag, totalPss, "total", false); 14273 appendMemBucket(stack, totalPss, "total", true); 14274 14275 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14276 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14277 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14278 14279 boolean firstLine = true; 14280 int lastOomAdj = Integer.MIN_VALUE; 14281 long extraNativeRam = 0; 14282 long cachedPss = 0; 14283 for (int i=0, N=memInfos.size(); i<N; i++) { 14284 ProcessMemInfo mi = memInfos.get(i); 14285 14286 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14287 cachedPss += mi.pss; 14288 } 14289 14290 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14291 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14292 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14293 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14294 if (lastOomAdj != mi.oomAdj) { 14295 lastOomAdj = mi.oomAdj; 14296 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14297 tag.append(" / "); 14298 } 14299 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14300 if (firstLine) { 14301 stack.append(":"); 14302 firstLine = false; 14303 } 14304 stack.append("\n\t at "); 14305 } else { 14306 stack.append("$"); 14307 } 14308 } else { 14309 tag.append(" "); 14310 stack.append("$"); 14311 } 14312 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14313 appendMemBucket(tag, mi.pss, mi.name, false); 14314 } 14315 appendMemBucket(stack, mi.pss, mi.name, true); 14316 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14317 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14318 stack.append("("); 14319 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14320 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14321 stack.append(DUMP_MEM_OOM_LABEL[k]); 14322 stack.append(":"); 14323 stack.append(DUMP_MEM_OOM_ADJ[k]); 14324 } 14325 } 14326 stack.append(")"); 14327 } 14328 } 14329 14330 appendMemInfo(fullNativeBuilder, mi); 14331 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14332 // The short form only has native processes that are >= 1MB. 14333 if (mi.pss >= 1000) { 14334 appendMemInfo(shortNativeBuilder, mi); 14335 } else { 14336 extraNativeRam += mi.pss; 14337 } 14338 } else { 14339 // Short form has all other details, but if we have collected RAM 14340 // from smaller native processes let's dump a summary of that. 14341 if (extraNativeRam > 0) { 14342 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14343 -1, extraNativeRam, "(Other native)"); 14344 shortNativeBuilder.append('\n'); 14345 extraNativeRam = 0; 14346 } 14347 appendMemInfo(fullJavaBuilder, mi); 14348 } 14349 } 14350 14351 fullJavaBuilder.append(" "); 14352 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14353 fullJavaBuilder.append(" kB: TOTAL\n"); 14354 14355 MemInfoReader memInfo = new MemInfoReader(); 14356 memInfo.readMemInfo(); 14357 final long[] infos = memInfo.getRawInfo(); 14358 14359 StringBuilder memInfoBuilder = new StringBuilder(1024); 14360 Debug.getMemInfo(infos); 14361 memInfoBuilder.append(" MemInfo: "); 14362 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14363 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14364 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14365 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14366 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14367 memInfoBuilder.append(" "); 14368 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14369 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14370 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14371 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14372 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14373 memInfoBuilder.append(" ZRAM: "); 14374 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14375 memInfoBuilder.append(" kB RAM, "); 14376 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14377 memInfoBuilder.append(" kB swap total, "); 14378 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14379 memInfoBuilder.append(" kB swap free\n"); 14380 } 14381 final long[] ksm = getKsmInfo(); 14382 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14383 || ksm[KSM_VOLATILE] != 0) { 14384 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14385 memInfoBuilder.append(" kB saved from shared "); 14386 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14387 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14388 memInfoBuilder.append(" kB unshared; "); 14389 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14390 } 14391 memInfoBuilder.append(" Free RAM: "); 14392 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14393 + memInfo.getFreeSizeKb()); 14394 memInfoBuilder.append(" kB\n"); 14395 memInfoBuilder.append(" Used RAM: "); 14396 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14397 memInfoBuilder.append(" kB\n"); 14398 memInfoBuilder.append(" Lost RAM: "); 14399 memInfoBuilder.append(memInfo.getTotalSizeKb() 14400 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14401 - memInfo.getKernelUsedSizeKb()); 14402 memInfoBuilder.append(" kB\n"); 14403 Slog.i(TAG, "Low on memory:"); 14404 Slog.i(TAG, shortNativeBuilder.toString()); 14405 Slog.i(TAG, fullJavaBuilder.toString()); 14406 Slog.i(TAG, memInfoBuilder.toString()); 14407 14408 StringBuilder dropBuilder = new StringBuilder(1024); 14409 /* 14410 StringWriter oomSw = new StringWriter(); 14411 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14412 StringWriter catSw = new StringWriter(); 14413 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14414 String[] emptyArgs = new String[] { }; 14415 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14416 oomPw.flush(); 14417 String oomString = oomSw.toString(); 14418 */ 14419 dropBuilder.append("Low on memory:"); 14420 dropBuilder.append(stack); 14421 dropBuilder.append('\n'); 14422 dropBuilder.append(fullNativeBuilder); 14423 dropBuilder.append(fullJavaBuilder); 14424 dropBuilder.append('\n'); 14425 dropBuilder.append(memInfoBuilder); 14426 dropBuilder.append('\n'); 14427 /* 14428 dropBuilder.append(oomString); 14429 dropBuilder.append('\n'); 14430 */ 14431 StringWriter catSw = new StringWriter(); 14432 synchronized (ActivityManagerService.this) { 14433 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14434 String[] emptyArgs = new String[] { }; 14435 catPw.println(); 14436 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14437 catPw.println(); 14438 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14439 false, false, null); 14440 catPw.println(); 14441 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14442 catPw.flush(); 14443 } 14444 dropBuilder.append(catSw.toString()); 14445 addErrorToDropBox("lowmem", null, "system_server", null, 14446 null, tag.toString(), dropBuilder.toString(), null, null); 14447 //Slog.i(TAG, "Sent to dropbox:"); 14448 //Slog.i(TAG, dropBuilder.toString()); 14449 synchronized (ActivityManagerService.this) { 14450 long now = SystemClock.uptimeMillis(); 14451 if (mLastMemUsageReportTime < now) { 14452 mLastMemUsageReportTime = now; 14453 } 14454 } 14455 } 14456 14457 /** 14458 * Searches array of arguments for the specified string 14459 * @param args array of argument strings 14460 * @param value value to search for 14461 * @return true if the value is contained in the array 14462 */ 14463 private static boolean scanArgs(String[] args, String value) { 14464 if (args != null) { 14465 for (String arg : args) { 14466 if (value.equals(arg)) { 14467 return true; 14468 } 14469 } 14470 } 14471 return false; 14472 } 14473 14474 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14475 ContentProviderRecord cpr, boolean always) { 14476 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14477 14478 if (!inLaunching || always) { 14479 synchronized (cpr) { 14480 cpr.launchingApp = null; 14481 cpr.notifyAll(); 14482 } 14483 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14484 String names[] = cpr.info.authority.split(";"); 14485 for (int j = 0; j < names.length; j++) { 14486 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14487 } 14488 } 14489 14490 for (int i=0; i<cpr.connections.size(); i++) { 14491 ContentProviderConnection conn = cpr.connections.get(i); 14492 if (conn.waiting) { 14493 // If this connection is waiting for the provider, then we don't 14494 // need to mess with its process unless we are always removing 14495 // or for some reason the provider is not currently launching. 14496 if (inLaunching && !always) { 14497 continue; 14498 } 14499 } 14500 ProcessRecord capp = conn.client; 14501 conn.dead = true; 14502 if (conn.stableCount > 0) { 14503 if (!capp.persistent && capp.thread != null 14504 && capp.pid != 0 14505 && capp.pid != MY_PID) { 14506 capp.kill("depends on provider " 14507 + cpr.name.flattenToShortString() 14508 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14509 } 14510 } else if (capp.thread != null && conn.provider.provider != null) { 14511 try { 14512 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14513 } catch (RemoteException e) { 14514 } 14515 // In the protocol here, we don't expect the client to correctly 14516 // clean up this connection, we'll just remove it. 14517 cpr.connections.remove(i); 14518 conn.client.conProviders.remove(conn); 14519 } 14520 } 14521 14522 if (inLaunching && always) { 14523 mLaunchingProviders.remove(cpr); 14524 } 14525 return inLaunching; 14526 } 14527 14528 /** 14529 * Main code for cleaning up a process when it has gone away. This is 14530 * called both as a result of the process dying, or directly when stopping 14531 * a process when running in single process mode. 14532 * 14533 * @return Returns true if the given process has been restarted, so the 14534 * app that was passed in must remain on the process lists. 14535 */ 14536 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14537 boolean restarting, boolean allowRestart, int index) { 14538 if (index >= 0) { 14539 removeLruProcessLocked(app); 14540 ProcessList.remove(app.pid); 14541 } 14542 14543 mProcessesToGc.remove(app); 14544 mPendingPssProcesses.remove(app); 14545 14546 // Dismiss any open dialogs. 14547 if (app.crashDialog != null && !app.forceCrashReport) { 14548 app.crashDialog.dismiss(); 14549 app.crashDialog = null; 14550 } 14551 if (app.anrDialog != null) { 14552 app.anrDialog.dismiss(); 14553 app.anrDialog = null; 14554 } 14555 if (app.waitDialog != null) { 14556 app.waitDialog.dismiss(); 14557 app.waitDialog = null; 14558 } 14559 14560 app.crashing = false; 14561 app.notResponding = false; 14562 14563 app.resetPackageList(mProcessStats); 14564 app.unlinkDeathRecipient(); 14565 app.makeInactive(mProcessStats); 14566 app.waitingToKill = null; 14567 app.forcingToForeground = null; 14568 updateProcessForegroundLocked(app, false, false); 14569 app.foregroundActivities = false; 14570 app.hasShownUi = false; 14571 app.treatLikeActivity = false; 14572 app.hasAboveClient = false; 14573 app.hasClientActivities = false; 14574 14575 mServices.killServicesLocked(app, allowRestart); 14576 14577 boolean restart = false; 14578 14579 // Remove published content providers. 14580 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14581 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14582 final boolean always = app.bad || !allowRestart; 14583 if (removeDyingProviderLocked(app, cpr, always) || always) { 14584 // We left the provider in the launching list, need to 14585 // restart it. 14586 restart = true; 14587 } 14588 14589 cpr.provider = null; 14590 cpr.proc = null; 14591 } 14592 app.pubProviders.clear(); 14593 14594 // Take care of any launching providers waiting for this process. 14595 if (checkAppInLaunchingProvidersLocked(app, false)) { 14596 restart = true; 14597 } 14598 14599 // Unregister from connected content providers. 14600 if (!app.conProviders.isEmpty()) { 14601 for (int i=0; i<app.conProviders.size(); i++) { 14602 ContentProviderConnection conn = app.conProviders.get(i); 14603 conn.provider.connections.remove(conn); 14604 } 14605 app.conProviders.clear(); 14606 } 14607 14608 // At this point there may be remaining entries in mLaunchingProviders 14609 // where we were the only one waiting, so they are no longer of use. 14610 // Look for these and clean up if found. 14611 // XXX Commented out for now. Trying to figure out a way to reproduce 14612 // the actual situation to identify what is actually going on. 14613 if (false) { 14614 for (int i=0; i<mLaunchingProviders.size(); i++) { 14615 ContentProviderRecord cpr = (ContentProviderRecord) 14616 mLaunchingProviders.get(i); 14617 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14618 synchronized (cpr) { 14619 cpr.launchingApp = null; 14620 cpr.notifyAll(); 14621 } 14622 } 14623 } 14624 } 14625 14626 skipCurrentReceiverLocked(app); 14627 14628 // Unregister any receivers. 14629 for (int i=app.receivers.size()-1; i>=0; i--) { 14630 removeReceiverLocked(app.receivers.valueAt(i)); 14631 } 14632 app.receivers.clear(); 14633 14634 // If the app is undergoing backup, tell the backup manager about it 14635 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14636 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14637 + mBackupTarget.appInfo + " died during backup"); 14638 try { 14639 IBackupManager bm = IBackupManager.Stub.asInterface( 14640 ServiceManager.getService(Context.BACKUP_SERVICE)); 14641 bm.agentDisconnected(app.info.packageName); 14642 } catch (RemoteException e) { 14643 // can't happen; backup manager is local 14644 } 14645 } 14646 14647 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14648 ProcessChangeItem item = mPendingProcessChanges.get(i); 14649 if (item.pid == app.pid) { 14650 mPendingProcessChanges.remove(i); 14651 mAvailProcessChanges.add(item); 14652 } 14653 } 14654 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14655 14656 // If the caller is restarting this app, then leave it in its 14657 // current lists and let the caller take care of it. 14658 if (restarting) { 14659 return false; 14660 } 14661 14662 if (!app.persistent || app.isolated) { 14663 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14664 "Removing non-persistent process during cleanup: " + app); 14665 mProcessNames.remove(app.processName, app.uid); 14666 mIsolatedProcesses.remove(app.uid); 14667 if (mHeavyWeightProcess == app) { 14668 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14669 mHeavyWeightProcess.userId, 0)); 14670 mHeavyWeightProcess = null; 14671 } 14672 } else if (!app.removed) { 14673 // This app is persistent, so we need to keep its record around. 14674 // If it is not already on the pending app list, add it there 14675 // and start a new process for it. 14676 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14677 mPersistentStartingProcesses.add(app); 14678 restart = true; 14679 } 14680 } 14681 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14682 "Clean-up removing on hold: " + app); 14683 mProcessesOnHold.remove(app); 14684 14685 if (app == mHomeProcess) { 14686 mHomeProcess = null; 14687 } 14688 if (app == mPreviousProcess) { 14689 mPreviousProcess = null; 14690 } 14691 14692 if (restart && !app.isolated) { 14693 // We have components that still need to be running in the 14694 // process, so re-launch it. 14695 if (index < 0) { 14696 ProcessList.remove(app.pid); 14697 } 14698 mProcessNames.put(app.processName, app.uid, app); 14699 startProcessLocked(app, "restart", app.processName); 14700 return true; 14701 } else if (app.pid > 0 && app.pid != MY_PID) { 14702 // Goodbye! 14703 boolean removed; 14704 synchronized (mPidsSelfLocked) { 14705 mPidsSelfLocked.remove(app.pid); 14706 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14707 } 14708 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14709 if (app.isolated) { 14710 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14711 } 14712 app.setPid(0); 14713 } 14714 return false; 14715 } 14716 14717 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14718 // Look through the content providers we are waiting to have launched, 14719 // and if any run in this process then either schedule a restart of 14720 // the process or kill the client waiting for it if this process has 14721 // gone bad. 14722 int NL = mLaunchingProviders.size(); 14723 boolean restart = false; 14724 for (int i=0; i<NL; i++) { 14725 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14726 if (cpr.launchingApp == app) { 14727 if (!alwaysBad && !app.bad) { 14728 restart = true; 14729 } else { 14730 removeDyingProviderLocked(app, cpr, true); 14731 // cpr should have been removed from mLaunchingProviders 14732 NL = mLaunchingProviders.size(); 14733 i--; 14734 } 14735 } 14736 } 14737 return restart; 14738 } 14739 14740 // ========================================================= 14741 // SERVICES 14742 // ========================================================= 14743 14744 @Override 14745 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14746 int flags) { 14747 enforceNotIsolatedCaller("getServices"); 14748 synchronized (this) { 14749 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14750 } 14751 } 14752 14753 @Override 14754 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14755 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14756 synchronized (this) { 14757 return mServices.getRunningServiceControlPanelLocked(name); 14758 } 14759 } 14760 14761 @Override 14762 public ComponentName startService(IApplicationThread caller, Intent service, 14763 String resolvedType, int userId) { 14764 enforceNotIsolatedCaller("startService"); 14765 // Refuse possible leaked file descriptors 14766 if (service != null && service.hasFileDescriptors() == true) { 14767 throw new IllegalArgumentException("File descriptors passed in Intent"); 14768 } 14769 14770 if (DEBUG_SERVICE) 14771 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14772 synchronized(this) { 14773 final int callingPid = Binder.getCallingPid(); 14774 final int callingUid = Binder.getCallingUid(); 14775 final long origId = Binder.clearCallingIdentity(); 14776 ComponentName res = mServices.startServiceLocked(caller, service, 14777 resolvedType, callingPid, callingUid, userId); 14778 Binder.restoreCallingIdentity(origId); 14779 return res; 14780 } 14781 } 14782 14783 ComponentName startServiceInPackage(int uid, 14784 Intent service, String resolvedType, int userId) { 14785 synchronized(this) { 14786 if (DEBUG_SERVICE) 14787 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14788 final long origId = Binder.clearCallingIdentity(); 14789 ComponentName res = mServices.startServiceLocked(null, service, 14790 resolvedType, -1, uid, userId); 14791 Binder.restoreCallingIdentity(origId); 14792 return res; 14793 } 14794 } 14795 14796 @Override 14797 public int stopService(IApplicationThread caller, Intent service, 14798 String resolvedType, int userId) { 14799 enforceNotIsolatedCaller("stopService"); 14800 // Refuse possible leaked file descriptors 14801 if (service != null && service.hasFileDescriptors() == true) { 14802 throw new IllegalArgumentException("File descriptors passed in Intent"); 14803 } 14804 14805 synchronized(this) { 14806 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14807 } 14808 } 14809 14810 @Override 14811 public IBinder peekService(Intent service, String resolvedType) { 14812 enforceNotIsolatedCaller("peekService"); 14813 // Refuse possible leaked file descriptors 14814 if (service != null && service.hasFileDescriptors() == true) { 14815 throw new IllegalArgumentException("File descriptors passed in Intent"); 14816 } 14817 synchronized(this) { 14818 return mServices.peekServiceLocked(service, resolvedType); 14819 } 14820 } 14821 14822 @Override 14823 public boolean stopServiceToken(ComponentName className, IBinder token, 14824 int startId) { 14825 synchronized(this) { 14826 return mServices.stopServiceTokenLocked(className, token, startId); 14827 } 14828 } 14829 14830 @Override 14831 public void setServiceForeground(ComponentName className, IBinder token, 14832 int id, Notification notification, boolean removeNotification) { 14833 synchronized(this) { 14834 mServices.setServiceForegroundLocked(className, token, id, notification, 14835 removeNotification); 14836 } 14837 } 14838 14839 @Override 14840 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14841 boolean requireFull, String name, String callerPackage) { 14842 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14843 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14844 } 14845 14846 int unsafeConvertIncomingUser(int userId) { 14847 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14848 ? mCurrentUserId : userId; 14849 } 14850 14851 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14852 int allowMode, String name, String callerPackage) { 14853 final int callingUserId = UserHandle.getUserId(callingUid); 14854 if (callingUserId == userId) { 14855 return userId; 14856 } 14857 14858 // Note that we may be accessing mCurrentUserId outside of a lock... 14859 // shouldn't be a big deal, if this is being called outside 14860 // of a locked context there is intrinsically a race with 14861 // the value the caller will receive and someone else changing it. 14862 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14863 // we will switch to the calling user if access to the current user fails. 14864 int targetUserId = unsafeConvertIncomingUser(userId); 14865 14866 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14867 final boolean allow; 14868 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14869 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14870 // If the caller has this permission, they always pass go. And collect $200. 14871 allow = true; 14872 } else if (allowMode == ALLOW_FULL_ONLY) { 14873 // We require full access, sucks to be you. 14874 allow = false; 14875 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14876 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14877 // If the caller does not have either permission, they are always doomed. 14878 allow = false; 14879 } else if (allowMode == ALLOW_NON_FULL) { 14880 // We are blanket allowing non-full access, you lucky caller! 14881 allow = true; 14882 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14883 // We may or may not allow this depending on whether the two users are 14884 // in the same profile. 14885 synchronized (mUserProfileGroupIdsSelfLocked) { 14886 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14887 UserInfo.NO_PROFILE_GROUP_ID); 14888 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14889 UserInfo.NO_PROFILE_GROUP_ID); 14890 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14891 && callingProfile == targetProfile; 14892 } 14893 } else { 14894 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14895 } 14896 if (!allow) { 14897 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14898 // In this case, they would like to just execute as their 14899 // owner user instead of failing. 14900 targetUserId = callingUserId; 14901 } else { 14902 StringBuilder builder = new StringBuilder(128); 14903 builder.append("Permission Denial: "); 14904 builder.append(name); 14905 if (callerPackage != null) { 14906 builder.append(" from "); 14907 builder.append(callerPackage); 14908 } 14909 builder.append(" asks to run as user "); 14910 builder.append(userId); 14911 builder.append(" but is calling from user "); 14912 builder.append(UserHandle.getUserId(callingUid)); 14913 builder.append("; this requires "); 14914 builder.append(INTERACT_ACROSS_USERS_FULL); 14915 if (allowMode != ALLOW_FULL_ONLY) { 14916 builder.append(" or "); 14917 builder.append(INTERACT_ACROSS_USERS); 14918 } 14919 String msg = builder.toString(); 14920 Slog.w(TAG, msg); 14921 throw new SecurityException(msg); 14922 } 14923 } 14924 } 14925 if (!allowAll && targetUserId < 0) { 14926 throw new IllegalArgumentException( 14927 "Call does not support special user #" + targetUserId); 14928 } 14929 // Check shell permission 14930 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14931 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14932 targetUserId)) { 14933 throw new SecurityException("Shell does not have permission to access user " 14934 + targetUserId + "\n " + Debug.getCallers(3)); 14935 } 14936 } 14937 return targetUserId; 14938 } 14939 14940 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14941 String className, int flags) { 14942 boolean result = false; 14943 // For apps that don't have pre-defined UIDs, check for permission 14944 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14945 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14946 if (ActivityManager.checkUidPermission( 14947 INTERACT_ACROSS_USERS, 14948 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14949 ComponentName comp = new ComponentName(aInfo.packageName, className); 14950 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14951 + " requests FLAG_SINGLE_USER, but app does not hold " 14952 + INTERACT_ACROSS_USERS; 14953 Slog.w(TAG, msg); 14954 throw new SecurityException(msg); 14955 } 14956 // Permission passed 14957 result = true; 14958 } 14959 } else if ("system".equals(componentProcessName)) { 14960 result = true; 14961 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14962 // Phone app and persistent apps are allowed to export singleuser providers. 14963 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14964 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14965 } 14966 if (DEBUG_MU) { 14967 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14968 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14969 } 14970 return result; 14971 } 14972 14973 /** 14974 * Checks to see if the caller is in the same app as the singleton 14975 * component, or the component is in a special app. It allows special apps 14976 * to export singleton components but prevents exporting singleton 14977 * components for regular apps. 14978 */ 14979 boolean isValidSingletonCall(int callingUid, int componentUid) { 14980 int componentAppId = UserHandle.getAppId(componentUid); 14981 return UserHandle.isSameApp(callingUid, componentUid) 14982 || componentAppId == Process.SYSTEM_UID 14983 || componentAppId == Process.PHONE_UID 14984 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14985 == PackageManager.PERMISSION_GRANTED; 14986 } 14987 14988 public int bindService(IApplicationThread caller, IBinder token, 14989 Intent service, String resolvedType, 14990 IServiceConnection connection, int flags, int userId) { 14991 enforceNotIsolatedCaller("bindService"); 14992 14993 // Refuse possible leaked file descriptors 14994 if (service != null && service.hasFileDescriptors() == true) { 14995 throw new IllegalArgumentException("File descriptors passed in Intent"); 14996 } 14997 14998 synchronized(this) { 14999 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15000 connection, flags, userId); 15001 } 15002 } 15003 15004 public boolean unbindService(IServiceConnection connection) { 15005 synchronized (this) { 15006 return mServices.unbindServiceLocked(connection); 15007 } 15008 } 15009 15010 public void publishService(IBinder token, Intent intent, IBinder service) { 15011 // Refuse possible leaked file descriptors 15012 if (intent != null && intent.hasFileDescriptors() == true) { 15013 throw new IllegalArgumentException("File descriptors passed in Intent"); 15014 } 15015 15016 synchronized(this) { 15017 if (!(token instanceof ServiceRecord)) { 15018 throw new IllegalArgumentException("Invalid service token"); 15019 } 15020 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15021 } 15022 } 15023 15024 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15025 // Refuse possible leaked file descriptors 15026 if (intent != null && intent.hasFileDescriptors() == true) { 15027 throw new IllegalArgumentException("File descriptors passed in Intent"); 15028 } 15029 15030 synchronized(this) { 15031 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15032 } 15033 } 15034 15035 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15036 synchronized(this) { 15037 if (!(token instanceof ServiceRecord)) { 15038 throw new IllegalArgumentException("Invalid service token"); 15039 } 15040 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15041 } 15042 } 15043 15044 // ========================================================= 15045 // BACKUP AND RESTORE 15046 // ========================================================= 15047 15048 // Cause the target app to be launched if necessary and its backup agent 15049 // instantiated. The backup agent will invoke backupAgentCreated() on the 15050 // activity manager to announce its creation. 15051 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15052 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15053 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15054 15055 synchronized(this) { 15056 // !!! TODO: currently no check here that we're already bound 15057 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15058 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15059 synchronized (stats) { 15060 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15061 } 15062 15063 // Backup agent is now in use, its package can't be stopped. 15064 try { 15065 AppGlobals.getPackageManager().setPackageStoppedState( 15066 app.packageName, false, UserHandle.getUserId(app.uid)); 15067 } catch (RemoteException e) { 15068 } catch (IllegalArgumentException e) { 15069 Slog.w(TAG, "Failed trying to unstop package " 15070 + app.packageName + ": " + e); 15071 } 15072 15073 BackupRecord r = new BackupRecord(ss, app, backupMode); 15074 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15075 ? new ComponentName(app.packageName, app.backupAgentName) 15076 : new ComponentName("android", "FullBackupAgent"); 15077 // startProcessLocked() returns existing proc's record if it's already running 15078 ProcessRecord proc = startProcessLocked(app.processName, app, 15079 false, 0, "backup", hostingName, false, false, false); 15080 if (proc == null) { 15081 Slog.e(TAG, "Unable to start backup agent process " + r); 15082 return false; 15083 } 15084 15085 r.app = proc; 15086 mBackupTarget = r; 15087 mBackupAppName = app.packageName; 15088 15089 // Try not to kill the process during backup 15090 updateOomAdjLocked(proc); 15091 15092 // If the process is already attached, schedule the creation of the backup agent now. 15093 // If it is not yet live, this will be done when it attaches to the framework. 15094 if (proc.thread != null) { 15095 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15096 try { 15097 proc.thread.scheduleCreateBackupAgent(app, 15098 compatibilityInfoForPackageLocked(app), backupMode); 15099 } catch (RemoteException e) { 15100 // Will time out on the backup manager side 15101 } 15102 } else { 15103 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15104 } 15105 // Invariants: at this point, the target app process exists and the application 15106 // is either already running or in the process of coming up. mBackupTarget and 15107 // mBackupAppName describe the app, so that when it binds back to the AM we 15108 // know that it's scheduled for a backup-agent operation. 15109 } 15110 15111 return true; 15112 } 15113 15114 @Override 15115 public void clearPendingBackup() { 15116 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15117 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15118 15119 synchronized (this) { 15120 mBackupTarget = null; 15121 mBackupAppName = null; 15122 } 15123 } 15124 15125 // A backup agent has just come up 15126 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15127 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15128 + " = " + agent); 15129 15130 synchronized(this) { 15131 if (!agentPackageName.equals(mBackupAppName)) { 15132 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15133 return; 15134 } 15135 } 15136 15137 long oldIdent = Binder.clearCallingIdentity(); 15138 try { 15139 IBackupManager bm = IBackupManager.Stub.asInterface( 15140 ServiceManager.getService(Context.BACKUP_SERVICE)); 15141 bm.agentConnected(agentPackageName, agent); 15142 } catch (RemoteException e) { 15143 // can't happen; the backup manager service is local 15144 } catch (Exception e) { 15145 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15146 e.printStackTrace(); 15147 } finally { 15148 Binder.restoreCallingIdentity(oldIdent); 15149 } 15150 } 15151 15152 // done with this agent 15153 public void unbindBackupAgent(ApplicationInfo appInfo) { 15154 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15155 if (appInfo == null) { 15156 Slog.w(TAG, "unbind backup agent for null app"); 15157 return; 15158 } 15159 15160 synchronized(this) { 15161 try { 15162 if (mBackupAppName == null) { 15163 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15164 return; 15165 } 15166 15167 if (!mBackupAppName.equals(appInfo.packageName)) { 15168 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15169 return; 15170 } 15171 15172 // Not backing this app up any more; reset its OOM adjustment 15173 final ProcessRecord proc = mBackupTarget.app; 15174 updateOomAdjLocked(proc); 15175 15176 // If the app crashed during backup, 'thread' will be null here 15177 if (proc.thread != null) { 15178 try { 15179 proc.thread.scheduleDestroyBackupAgent(appInfo, 15180 compatibilityInfoForPackageLocked(appInfo)); 15181 } catch (Exception e) { 15182 Slog.e(TAG, "Exception when unbinding backup agent:"); 15183 e.printStackTrace(); 15184 } 15185 } 15186 } finally { 15187 mBackupTarget = null; 15188 mBackupAppName = null; 15189 } 15190 } 15191 } 15192 // ========================================================= 15193 // BROADCASTS 15194 // ========================================================= 15195 15196 private final List getStickiesLocked(String action, IntentFilter filter, 15197 List cur, int userId) { 15198 final ContentResolver resolver = mContext.getContentResolver(); 15199 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15200 if (stickies == null) { 15201 return cur; 15202 } 15203 final ArrayList<Intent> list = stickies.get(action); 15204 if (list == null) { 15205 return cur; 15206 } 15207 int N = list.size(); 15208 for (int i=0; i<N; i++) { 15209 Intent intent = list.get(i); 15210 if (filter.match(resolver, intent, true, TAG) >= 0) { 15211 if (cur == null) { 15212 cur = new ArrayList<Intent>(); 15213 } 15214 cur.add(intent); 15215 } 15216 } 15217 return cur; 15218 } 15219 15220 boolean isPendingBroadcastProcessLocked(int pid) { 15221 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15222 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15223 } 15224 15225 void skipPendingBroadcastLocked(int pid) { 15226 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15227 for (BroadcastQueue queue : mBroadcastQueues) { 15228 queue.skipPendingBroadcastLocked(pid); 15229 } 15230 } 15231 15232 // The app just attached; send any pending broadcasts that it should receive 15233 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15234 boolean didSomething = false; 15235 for (BroadcastQueue queue : mBroadcastQueues) { 15236 didSomething |= queue.sendPendingBroadcastsLocked(app); 15237 } 15238 return didSomething; 15239 } 15240 15241 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15242 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15243 enforceNotIsolatedCaller("registerReceiver"); 15244 int callingUid; 15245 int callingPid; 15246 synchronized(this) { 15247 ProcessRecord callerApp = null; 15248 if (caller != null) { 15249 callerApp = getRecordForAppLocked(caller); 15250 if (callerApp == null) { 15251 throw new SecurityException( 15252 "Unable to find app for caller " + caller 15253 + " (pid=" + Binder.getCallingPid() 15254 + ") when registering receiver " + receiver); 15255 } 15256 if (callerApp.info.uid != Process.SYSTEM_UID && 15257 !callerApp.pkgList.containsKey(callerPackage) && 15258 !"android".equals(callerPackage)) { 15259 throw new SecurityException("Given caller package " + callerPackage 15260 + " is not running in process " + callerApp); 15261 } 15262 callingUid = callerApp.info.uid; 15263 callingPid = callerApp.pid; 15264 } else { 15265 callerPackage = null; 15266 callingUid = Binder.getCallingUid(); 15267 callingPid = Binder.getCallingPid(); 15268 } 15269 15270 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15271 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15272 15273 List allSticky = null; 15274 15275 // Look for any matching sticky broadcasts... 15276 Iterator actions = filter.actionsIterator(); 15277 if (actions != null) { 15278 while (actions.hasNext()) { 15279 String action = (String)actions.next(); 15280 allSticky = getStickiesLocked(action, filter, allSticky, 15281 UserHandle.USER_ALL); 15282 allSticky = getStickiesLocked(action, filter, allSticky, 15283 UserHandle.getUserId(callingUid)); 15284 } 15285 } else { 15286 allSticky = getStickiesLocked(null, filter, allSticky, 15287 UserHandle.USER_ALL); 15288 allSticky = getStickiesLocked(null, filter, allSticky, 15289 UserHandle.getUserId(callingUid)); 15290 } 15291 15292 // The first sticky in the list is returned directly back to 15293 // the client. 15294 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15295 15296 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15297 + ": " + sticky); 15298 15299 if (receiver == null) { 15300 return sticky; 15301 } 15302 15303 ReceiverList rl 15304 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15305 if (rl == null) { 15306 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15307 userId, receiver); 15308 if (rl.app != null) { 15309 rl.app.receivers.add(rl); 15310 } else { 15311 try { 15312 receiver.asBinder().linkToDeath(rl, 0); 15313 } catch (RemoteException e) { 15314 return sticky; 15315 } 15316 rl.linkedToDeath = true; 15317 } 15318 mRegisteredReceivers.put(receiver.asBinder(), rl); 15319 } else if (rl.uid != callingUid) { 15320 throw new IllegalArgumentException( 15321 "Receiver requested to register for uid " + callingUid 15322 + " was previously registered for uid " + rl.uid); 15323 } else if (rl.pid != callingPid) { 15324 throw new IllegalArgumentException( 15325 "Receiver requested to register for pid " + callingPid 15326 + " was previously registered for pid " + rl.pid); 15327 } else if (rl.userId != userId) { 15328 throw new IllegalArgumentException( 15329 "Receiver requested to register for user " + userId 15330 + " was previously registered for user " + rl.userId); 15331 } 15332 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15333 permission, callingUid, userId); 15334 rl.add(bf); 15335 if (!bf.debugCheck()) { 15336 Slog.w(TAG, "==> For Dynamic broadast"); 15337 } 15338 mReceiverResolver.addFilter(bf); 15339 15340 // Enqueue broadcasts for all existing stickies that match 15341 // this filter. 15342 if (allSticky != null) { 15343 ArrayList receivers = new ArrayList(); 15344 receivers.add(bf); 15345 15346 int N = allSticky.size(); 15347 for (int i=0; i<N; i++) { 15348 Intent intent = (Intent)allSticky.get(i); 15349 BroadcastQueue queue = broadcastQueueForIntent(intent); 15350 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15351 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15352 null, null, false, true, true, -1); 15353 queue.enqueueParallelBroadcastLocked(r); 15354 queue.scheduleBroadcastsLocked(); 15355 } 15356 } 15357 15358 return sticky; 15359 } 15360 } 15361 15362 public void unregisterReceiver(IIntentReceiver receiver) { 15363 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15364 15365 final long origId = Binder.clearCallingIdentity(); 15366 try { 15367 boolean doTrim = false; 15368 15369 synchronized(this) { 15370 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15371 if (rl != null) { 15372 if (rl.curBroadcast != null) { 15373 BroadcastRecord r = rl.curBroadcast; 15374 final boolean doNext = finishReceiverLocked( 15375 receiver.asBinder(), r.resultCode, r.resultData, 15376 r.resultExtras, r.resultAbort); 15377 if (doNext) { 15378 doTrim = true; 15379 r.queue.processNextBroadcast(false); 15380 } 15381 } 15382 15383 if (rl.app != null) { 15384 rl.app.receivers.remove(rl); 15385 } 15386 removeReceiverLocked(rl); 15387 if (rl.linkedToDeath) { 15388 rl.linkedToDeath = false; 15389 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15390 } 15391 } 15392 } 15393 15394 // If we actually concluded any broadcasts, we might now be able 15395 // to trim the recipients' apps from our working set 15396 if (doTrim) { 15397 trimApplications(); 15398 return; 15399 } 15400 15401 } finally { 15402 Binder.restoreCallingIdentity(origId); 15403 } 15404 } 15405 15406 void removeReceiverLocked(ReceiverList rl) { 15407 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15408 int N = rl.size(); 15409 for (int i=0; i<N; i++) { 15410 mReceiverResolver.removeFilter(rl.get(i)); 15411 } 15412 } 15413 15414 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15415 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15416 ProcessRecord r = mLruProcesses.get(i); 15417 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15418 try { 15419 r.thread.dispatchPackageBroadcast(cmd, packages); 15420 } catch (RemoteException ex) { 15421 } 15422 } 15423 } 15424 } 15425 15426 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15427 int callingUid, int[] users) { 15428 List<ResolveInfo> receivers = null; 15429 try { 15430 HashSet<ComponentName> singleUserReceivers = null; 15431 boolean scannedFirstReceivers = false; 15432 for (int user : users) { 15433 // Skip users that have Shell restrictions 15434 if (callingUid == Process.SHELL_UID 15435 && getUserManagerLocked().hasUserRestriction( 15436 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15437 continue; 15438 } 15439 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15440 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15441 if (user != 0 && newReceivers != null) { 15442 // If this is not the primary user, we need to check for 15443 // any receivers that should be filtered out. 15444 for (int i=0; i<newReceivers.size(); i++) { 15445 ResolveInfo ri = newReceivers.get(i); 15446 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15447 newReceivers.remove(i); 15448 i--; 15449 } 15450 } 15451 } 15452 if (newReceivers != null && newReceivers.size() == 0) { 15453 newReceivers = null; 15454 } 15455 if (receivers == null) { 15456 receivers = newReceivers; 15457 } else if (newReceivers != null) { 15458 // We need to concatenate the additional receivers 15459 // found with what we have do far. This would be easy, 15460 // but we also need to de-dup any receivers that are 15461 // singleUser. 15462 if (!scannedFirstReceivers) { 15463 // Collect any single user receivers we had already retrieved. 15464 scannedFirstReceivers = true; 15465 for (int i=0; i<receivers.size(); i++) { 15466 ResolveInfo ri = receivers.get(i); 15467 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15468 ComponentName cn = new ComponentName( 15469 ri.activityInfo.packageName, ri.activityInfo.name); 15470 if (singleUserReceivers == null) { 15471 singleUserReceivers = new HashSet<ComponentName>(); 15472 } 15473 singleUserReceivers.add(cn); 15474 } 15475 } 15476 } 15477 // Add the new results to the existing results, tracking 15478 // and de-dupping single user receivers. 15479 for (int i=0; i<newReceivers.size(); i++) { 15480 ResolveInfo ri = newReceivers.get(i); 15481 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15482 ComponentName cn = new ComponentName( 15483 ri.activityInfo.packageName, ri.activityInfo.name); 15484 if (singleUserReceivers == null) { 15485 singleUserReceivers = new HashSet<ComponentName>(); 15486 } 15487 if (!singleUserReceivers.contains(cn)) { 15488 singleUserReceivers.add(cn); 15489 receivers.add(ri); 15490 } 15491 } else { 15492 receivers.add(ri); 15493 } 15494 } 15495 } 15496 } 15497 } catch (RemoteException ex) { 15498 // pm is in same process, this will never happen. 15499 } 15500 return receivers; 15501 } 15502 15503 private final int broadcastIntentLocked(ProcessRecord callerApp, 15504 String callerPackage, Intent intent, String resolvedType, 15505 IIntentReceiver resultTo, int resultCode, String resultData, 15506 Bundle map, String requiredPermission, int appOp, 15507 boolean ordered, boolean sticky, int callingPid, int callingUid, 15508 int userId) { 15509 intent = new Intent(intent); 15510 15511 // By default broadcasts do not go to stopped apps. 15512 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15513 15514 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15515 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15516 + " ordered=" + ordered + " userid=" + userId); 15517 if ((resultTo != null) && !ordered) { 15518 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15519 } 15520 15521 userId = handleIncomingUser(callingPid, callingUid, userId, 15522 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15523 15524 // Make sure that the user who is receiving this broadcast is started. 15525 // If not, we will just skip it. 15526 15527 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15528 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15529 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15530 Slog.w(TAG, "Skipping broadcast of " + intent 15531 + ": user " + userId + " is stopped"); 15532 return ActivityManager.BROADCAST_SUCCESS; 15533 } 15534 } 15535 15536 /* 15537 * Prevent non-system code (defined here to be non-persistent 15538 * processes) from sending protected broadcasts. 15539 */ 15540 int callingAppId = UserHandle.getAppId(callingUid); 15541 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15542 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15543 || callingAppId == Process.NFC_UID || callingUid == 0) { 15544 // Always okay. 15545 } else if (callerApp == null || !callerApp.persistent) { 15546 try { 15547 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15548 intent.getAction())) { 15549 String msg = "Permission Denial: not allowed to send broadcast " 15550 + intent.getAction() + " from pid=" 15551 + callingPid + ", uid=" + callingUid; 15552 Slog.w(TAG, msg); 15553 throw new SecurityException(msg); 15554 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15555 // Special case for compatibility: we don't want apps to send this, 15556 // but historically it has not been protected and apps may be using it 15557 // to poke their own app widget. So, instead of making it protected, 15558 // just limit it to the caller. 15559 if (callerApp == null) { 15560 String msg = "Permission Denial: not allowed to send broadcast " 15561 + intent.getAction() + " from unknown caller."; 15562 Slog.w(TAG, msg); 15563 throw new SecurityException(msg); 15564 } else if (intent.getComponent() != null) { 15565 // They are good enough to send to an explicit component... verify 15566 // it is being sent to the calling app. 15567 if (!intent.getComponent().getPackageName().equals( 15568 callerApp.info.packageName)) { 15569 String msg = "Permission Denial: not allowed to send broadcast " 15570 + intent.getAction() + " to " 15571 + intent.getComponent().getPackageName() + " from " 15572 + callerApp.info.packageName; 15573 Slog.w(TAG, msg); 15574 throw new SecurityException(msg); 15575 } 15576 } else { 15577 // Limit broadcast to their own package. 15578 intent.setPackage(callerApp.info.packageName); 15579 } 15580 } 15581 } catch (RemoteException e) { 15582 Slog.w(TAG, "Remote exception", e); 15583 return ActivityManager.BROADCAST_SUCCESS; 15584 } 15585 } 15586 15587 // Handle special intents: if this broadcast is from the package 15588 // manager about a package being removed, we need to remove all of 15589 // its activities from the history stack. 15590 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15591 intent.getAction()); 15592 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15593 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15594 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15595 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15596 || uidRemoved) { 15597 if (checkComponentPermission( 15598 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15599 callingPid, callingUid, -1, true) 15600 == PackageManager.PERMISSION_GRANTED) { 15601 if (uidRemoved) { 15602 final Bundle intentExtras = intent.getExtras(); 15603 final int uid = intentExtras != null 15604 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15605 if (uid >= 0) { 15606 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15607 synchronized (bs) { 15608 bs.removeUidStatsLocked(uid); 15609 } 15610 mAppOpsService.uidRemoved(uid); 15611 } 15612 } else { 15613 // If resources are unavailable just force stop all 15614 // those packages and flush the attribute cache as well. 15615 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15616 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15617 if (list != null && (list.length > 0)) { 15618 for (String pkg : list) { 15619 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15620 "storage unmount"); 15621 } 15622 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15623 sendPackageBroadcastLocked( 15624 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15625 } 15626 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15627 intent.getAction())) { 15628 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15629 } else { 15630 Uri data = intent.getData(); 15631 String ssp; 15632 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15633 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15634 intent.getAction()); 15635 boolean fullUninstall = removed && 15636 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15637 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15638 forceStopPackageLocked(ssp, UserHandle.getAppId( 15639 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15640 false, fullUninstall, userId, 15641 removed ? "pkg removed" : "pkg changed"); 15642 } 15643 if (removed) { 15644 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15645 new String[] {ssp}, userId); 15646 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15647 mAppOpsService.packageRemoved( 15648 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15649 15650 // Remove all permissions granted from/to this package 15651 removeUriPermissionsForPackageLocked(ssp, userId, true); 15652 } 15653 } 15654 } 15655 } 15656 } 15657 } else { 15658 String msg = "Permission Denial: " + intent.getAction() 15659 + " broadcast from " + callerPackage + " (pid=" + callingPid 15660 + ", uid=" + callingUid + ")" 15661 + " requires " 15662 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15663 Slog.w(TAG, msg); 15664 throw new SecurityException(msg); 15665 } 15666 15667 // Special case for adding a package: by default turn on compatibility 15668 // mode. 15669 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15670 Uri data = intent.getData(); 15671 String ssp; 15672 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15673 mCompatModePackages.handlePackageAddedLocked(ssp, 15674 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15675 } 15676 } 15677 15678 /* 15679 * If this is the time zone changed action, queue up a message that will reset the timezone 15680 * of all currently running processes. This message will get queued up before the broadcast 15681 * happens. 15682 */ 15683 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15684 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15685 } 15686 15687 /* 15688 * If the user set the time, let all running processes know. 15689 */ 15690 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15691 final int is24Hour = intent.getBooleanExtra( 15692 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15693 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15695 synchronized (stats) { 15696 stats.noteCurrentTimeChangedLocked(); 15697 } 15698 } 15699 15700 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15701 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15702 } 15703 15704 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15705 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15706 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15707 } 15708 15709 // Add to the sticky list if requested. 15710 if (sticky) { 15711 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15712 callingPid, callingUid) 15713 != PackageManager.PERMISSION_GRANTED) { 15714 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15715 + callingPid + ", uid=" + callingUid 15716 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15717 Slog.w(TAG, msg); 15718 throw new SecurityException(msg); 15719 } 15720 if (requiredPermission != null) { 15721 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15722 + " and enforce permission " + requiredPermission); 15723 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15724 } 15725 if (intent.getComponent() != null) { 15726 throw new SecurityException( 15727 "Sticky broadcasts can't target a specific component"); 15728 } 15729 // We use userId directly here, since the "all" target is maintained 15730 // as a separate set of sticky broadcasts. 15731 if (userId != UserHandle.USER_ALL) { 15732 // But first, if this is not a broadcast to all users, then 15733 // make sure it doesn't conflict with an existing broadcast to 15734 // all users. 15735 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15736 UserHandle.USER_ALL); 15737 if (stickies != null) { 15738 ArrayList<Intent> list = stickies.get(intent.getAction()); 15739 if (list != null) { 15740 int N = list.size(); 15741 int i; 15742 for (i=0; i<N; i++) { 15743 if (intent.filterEquals(list.get(i))) { 15744 throw new IllegalArgumentException( 15745 "Sticky broadcast " + intent + " for user " 15746 + userId + " conflicts with existing global broadcast"); 15747 } 15748 } 15749 } 15750 } 15751 } 15752 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15753 if (stickies == null) { 15754 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15755 mStickyBroadcasts.put(userId, stickies); 15756 } 15757 ArrayList<Intent> list = stickies.get(intent.getAction()); 15758 if (list == null) { 15759 list = new ArrayList<Intent>(); 15760 stickies.put(intent.getAction(), list); 15761 } 15762 int N = list.size(); 15763 int i; 15764 for (i=0; i<N; i++) { 15765 if (intent.filterEquals(list.get(i))) { 15766 // This sticky already exists, replace it. 15767 list.set(i, new Intent(intent)); 15768 break; 15769 } 15770 } 15771 if (i >= N) { 15772 list.add(new Intent(intent)); 15773 } 15774 } 15775 15776 int[] users; 15777 if (userId == UserHandle.USER_ALL) { 15778 // Caller wants broadcast to go to all started users. 15779 users = mStartedUserArray; 15780 } else { 15781 // Caller wants broadcast to go to one specific user. 15782 users = new int[] {userId}; 15783 } 15784 15785 // Figure out who all will receive this broadcast. 15786 List receivers = null; 15787 List<BroadcastFilter> registeredReceivers = null; 15788 // Need to resolve the intent to interested receivers... 15789 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15790 == 0) { 15791 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15792 } 15793 if (intent.getComponent() == null) { 15794 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15795 // Query one target user at a time, excluding shell-restricted users 15796 UserManagerService ums = getUserManagerLocked(); 15797 for (int i = 0; i < users.length; i++) { 15798 if (ums.hasUserRestriction( 15799 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15800 continue; 15801 } 15802 List<BroadcastFilter> registeredReceiversForUser = 15803 mReceiverResolver.queryIntent(intent, 15804 resolvedType, false, users[i]); 15805 if (registeredReceivers == null) { 15806 registeredReceivers = registeredReceiversForUser; 15807 } else if (registeredReceiversForUser != null) { 15808 registeredReceivers.addAll(registeredReceiversForUser); 15809 } 15810 } 15811 } else { 15812 registeredReceivers = mReceiverResolver.queryIntent(intent, 15813 resolvedType, false, userId); 15814 } 15815 } 15816 15817 final boolean replacePending = 15818 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15819 15820 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15821 + " replacePending=" + replacePending); 15822 15823 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15824 if (!ordered && NR > 0) { 15825 // If we are not serializing this broadcast, then send the 15826 // registered receivers separately so they don't wait for the 15827 // components to be launched. 15828 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15829 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15830 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15831 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15832 ordered, sticky, false, userId); 15833 if (DEBUG_BROADCAST) Slog.v( 15834 TAG, "Enqueueing parallel broadcast " + r); 15835 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15836 if (!replaced) { 15837 queue.enqueueParallelBroadcastLocked(r); 15838 queue.scheduleBroadcastsLocked(); 15839 } 15840 registeredReceivers = null; 15841 NR = 0; 15842 } 15843 15844 // Merge into one list. 15845 int ir = 0; 15846 if (receivers != null) { 15847 // A special case for PACKAGE_ADDED: do not allow the package 15848 // being added to see this broadcast. This prevents them from 15849 // using this as a back door to get run as soon as they are 15850 // installed. Maybe in the future we want to have a special install 15851 // broadcast or such for apps, but we'd like to deliberately make 15852 // this decision. 15853 String skipPackages[] = null; 15854 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15855 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15856 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15857 Uri data = intent.getData(); 15858 if (data != null) { 15859 String pkgName = data.getSchemeSpecificPart(); 15860 if (pkgName != null) { 15861 skipPackages = new String[] { pkgName }; 15862 } 15863 } 15864 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15865 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15866 } 15867 if (skipPackages != null && (skipPackages.length > 0)) { 15868 for (String skipPackage : skipPackages) { 15869 if (skipPackage != null) { 15870 int NT = receivers.size(); 15871 for (int it=0; it<NT; it++) { 15872 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15873 if (curt.activityInfo.packageName.equals(skipPackage)) { 15874 receivers.remove(it); 15875 it--; 15876 NT--; 15877 } 15878 } 15879 } 15880 } 15881 } 15882 15883 int NT = receivers != null ? receivers.size() : 0; 15884 int it = 0; 15885 ResolveInfo curt = null; 15886 BroadcastFilter curr = null; 15887 while (it < NT && ir < NR) { 15888 if (curt == null) { 15889 curt = (ResolveInfo)receivers.get(it); 15890 } 15891 if (curr == null) { 15892 curr = registeredReceivers.get(ir); 15893 } 15894 if (curr.getPriority() >= curt.priority) { 15895 // Insert this broadcast record into the final list. 15896 receivers.add(it, curr); 15897 ir++; 15898 curr = null; 15899 it++; 15900 NT++; 15901 } else { 15902 // Skip to the next ResolveInfo in the final list. 15903 it++; 15904 curt = null; 15905 } 15906 } 15907 } 15908 while (ir < NR) { 15909 if (receivers == null) { 15910 receivers = new ArrayList(); 15911 } 15912 receivers.add(registeredReceivers.get(ir)); 15913 ir++; 15914 } 15915 15916 if ((receivers != null && receivers.size() > 0) 15917 || resultTo != null) { 15918 BroadcastQueue queue = broadcastQueueForIntent(intent); 15919 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15920 callerPackage, callingPid, callingUid, resolvedType, 15921 requiredPermission, appOp, receivers, resultTo, resultCode, 15922 resultData, map, ordered, sticky, false, userId); 15923 if (DEBUG_BROADCAST) Slog.v( 15924 TAG, "Enqueueing ordered broadcast " + r 15925 + ": prev had " + queue.mOrderedBroadcasts.size()); 15926 if (DEBUG_BROADCAST) { 15927 int seq = r.intent.getIntExtra("seq", -1); 15928 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15929 } 15930 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15931 if (!replaced) { 15932 queue.enqueueOrderedBroadcastLocked(r); 15933 queue.scheduleBroadcastsLocked(); 15934 } 15935 } 15936 15937 return ActivityManager.BROADCAST_SUCCESS; 15938 } 15939 15940 final Intent verifyBroadcastLocked(Intent intent) { 15941 // Refuse possible leaked file descriptors 15942 if (intent != null && intent.hasFileDescriptors() == true) { 15943 throw new IllegalArgumentException("File descriptors passed in Intent"); 15944 } 15945 15946 int flags = intent.getFlags(); 15947 15948 if (!mProcessesReady) { 15949 // if the caller really truly claims to know what they're doing, go 15950 // ahead and allow the broadcast without launching any receivers 15951 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15952 intent = new Intent(intent); 15953 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15954 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15955 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15956 + " before boot completion"); 15957 throw new IllegalStateException("Cannot broadcast before boot completed"); 15958 } 15959 } 15960 15961 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15962 throw new IllegalArgumentException( 15963 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15964 } 15965 15966 return intent; 15967 } 15968 15969 public final int broadcastIntent(IApplicationThread caller, 15970 Intent intent, String resolvedType, IIntentReceiver resultTo, 15971 int resultCode, String resultData, Bundle map, 15972 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15973 enforceNotIsolatedCaller("broadcastIntent"); 15974 synchronized(this) { 15975 intent = verifyBroadcastLocked(intent); 15976 15977 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15978 final int callingPid = Binder.getCallingPid(); 15979 final int callingUid = Binder.getCallingUid(); 15980 final long origId = Binder.clearCallingIdentity(); 15981 int res = broadcastIntentLocked(callerApp, 15982 callerApp != null ? callerApp.info.packageName : null, 15983 intent, resolvedType, resultTo, 15984 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15985 callingPid, callingUid, userId); 15986 Binder.restoreCallingIdentity(origId); 15987 return res; 15988 } 15989 } 15990 15991 int broadcastIntentInPackage(String packageName, int uid, 15992 Intent intent, String resolvedType, IIntentReceiver resultTo, 15993 int resultCode, String resultData, Bundle map, 15994 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15995 synchronized(this) { 15996 intent = verifyBroadcastLocked(intent); 15997 15998 final long origId = Binder.clearCallingIdentity(); 15999 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16000 resultTo, resultCode, resultData, map, requiredPermission, 16001 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16002 Binder.restoreCallingIdentity(origId); 16003 return res; 16004 } 16005 } 16006 16007 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16008 // Refuse possible leaked file descriptors 16009 if (intent != null && intent.hasFileDescriptors() == true) { 16010 throw new IllegalArgumentException("File descriptors passed in Intent"); 16011 } 16012 16013 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16014 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16015 16016 synchronized(this) { 16017 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16018 != PackageManager.PERMISSION_GRANTED) { 16019 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16020 + Binder.getCallingPid() 16021 + ", uid=" + Binder.getCallingUid() 16022 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16023 Slog.w(TAG, msg); 16024 throw new SecurityException(msg); 16025 } 16026 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16027 if (stickies != null) { 16028 ArrayList<Intent> list = stickies.get(intent.getAction()); 16029 if (list != null) { 16030 int N = list.size(); 16031 int i; 16032 for (i=0; i<N; i++) { 16033 if (intent.filterEquals(list.get(i))) { 16034 list.remove(i); 16035 break; 16036 } 16037 } 16038 if (list.size() <= 0) { 16039 stickies.remove(intent.getAction()); 16040 } 16041 } 16042 if (stickies.size() <= 0) { 16043 mStickyBroadcasts.remove(userId); 16044 } 16045 } 16046 } 16047 } 16048 16049 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16050 String resultData, Bundle resultExtras, boolean resultAbort) { 16051 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16052 if (r == null) { 16053 Slog.w(TAG, "finishReceiver called but not found on queue"); 16054 return false; 16055 } 16056 16057 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16058 } 16059 16060 void backgroundServicesFinishedLocked(int userId) { 16061 for (BroadcastQueue queue : mBroadcastQueues) { 16062 queue.backgroundServicesFinishedLocked(userId); 16063 } 16064 } 16065 16066 public void finishReceiver(IBinder who, int resultCode, String resultData, 16067 Bundle resultExtras, boolean resultAbort) { 16068 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16069 16070 // Refuse possible leaked file descriptors 16071 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16072 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16073 } 16074 16075 final long origId = Binder.clearCallingIdentity(); 16076 try { 16077 boolean doNext = false; 16078 BroadcastRecord r; 16079 16080 synchronized(this) { 16081 r = broadcastRecordForReceiverLocked(who); 16082 if (r != null) { 16083 doNext = r.queue.finishReceiverLocked(r, resultCode, 16084 resultData, resultExtras, resultAbort, true); 16085 } 16086 } 16087 16088 if (doNext) { 16089 r.queue.processNextBroadcast(false); 16090 } 16091 trimApplications(); 16092 } finally { 16093 Binder.restoreCallingIdentity(origId); 16094 } 16095 } 16096 16097 // ========================================================= 16098 // INSTRUMENTATION 16099 // ========================================================= 16100 16101 public boolean startInstrumentation(ComponentName className, 16102 String profileFile, int flags, Bundle arguments, 16103 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16104 int userId, String abiOverride) { 16105 enforceNotIsolatedCaller("startInstrumentation"); 16106 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16107 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16108 // Refuse possible leaked file descriptors 16109 if (arguments != null && arguments.hasFileDescriptors()) { 16110 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16111 } 16112 16113 synchronized(this) { 16114 InstrumentationInfo ii = null; 16115 ApplicationInfo ai = null; 16116 try { 16117 ii = mContext.getPackageManager().getInstrumentationInfo( 16118 className, STOCK_PM_FLAGS); 16119 ai = AppGlobals.getPackageManager().getApplicationInfo( 16120 ii.targetPackage, STOCK_PM_FLAGS, userId); 16121 } catch (PackageManager.NameNotFoundException e) { 16122 } catch (RemoteException e) { 16123 } 16124 if (ii == null) { 16125 reportStartInstrumentationFailure(watcher, className, 16126 "Unable to find instrumentation info for: " + className); 16127 return false; 16128 } 16129 if (ai == null) { 16130 reportStartInstrumentationFailure(watcher, className, 16131 "Unable to find instrumentation target package: " + ii.targetPackage); 16132 return false; 16133 } 16134 16135 int match = mContext.getPackageManager().checkSignatures( 16136 ii.targetPackage, ii.packageName); 16137 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16138 String msg = "Permission Denial: starting instrumentation " 16139 + className + " from pid=" 16140 + Binder.getCallingPid() 16141 + ", uid=" + Binder.getCallingPid() 16142 + " not allowed because package " + ii.packageName 16143 + " does not have a signature matching the target " 16144 + ii.targetPackage; 16145 reportStartInstrumentationFailure(watcher, className, msg); 16146 throw new SecurityException(msg); 16147 } 16148 16149 final long origId = Binder.clearCallingIdentity(); 16150 // Instrumentation can kill and relaunch even persistent processes 16151 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16152 "start instr"); 16153 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16154 app.instrumentationClass = className; 16155 app.instrumentationInfo = ai; 16156 app.instrumentationProfileFile = profileFile; 16157 app.instrumentationArguments = arguments; 16158 app.instrumentationWatcher = watcher; 16159 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16160 app.instrumentationResultClass = className; 16161 Binder.restoreCallingIdentity(origId); 16162 } 16163 16164 return true; 16165 } 16166 16167 /** 16168 * Report errors that occur while attempting to start Instrumentation. Always writes the 16169 * error to the logs, but if somebody is watching, send the report there too. This enables 16170 * the "am" command to report errors with more information. 16171 * 16172 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16173 * @param cn The component name of the instrumentation. 16174 * @param report The error report. 16175 */ 16176 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16177 ComponentName cn, String report) { 16178 Slog.w(TAG, report); 16179 try { 16180 if (watcher != null) { 16181 Bundle results = new Bundle(); 16182 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16183 results.putString("Error", report); 16184 watcher.instrumentationStatus(cn, -1, results); 16185 } 16186 } catch (RemoteException e) { 16187 Slog.w(TAG, e); 16188 } 16189 } 16190 16191 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16192 if (app.instrumentationWatcher != null) { 16193 try { 16194 // NOTE: IInstrumentationWatcher *must* be oneway here 16195 app.instrumentationWatcher.instrumentationFinished( 16196 app.instrumentationClass, 16197 resultCode, 16198 results); 16199 } catch (RemoteException e) { 16200 } 16201 } 16202 if (app.instrumentationUiAutomationConnection != null) { 16203 try { 16204 app.instrumentationUiAutomationConnection.shutdown(); 16205 } catch (RemoteException re) { 16206 /* ignore */ 16207 } 16208 // Only a UiAutomation can set this flag and now that 16209 // it is finished we make sure it is reset to its default. 16210 mUserIsMonkey = false; 16211 } 16212 app.instrumentationWatcher = null; 16213 app.instrumentationUiAutomationConnection = null; 16214 app.instrumentationClass = null; 16215 app.instrumentationInfo = null; 16216 app.instrumentationProfileFile = null; 16217 app.instrumentationArguments = null; 16218 16219 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16220 "finished inst"); 16221 } 16222 16223 public void finishInstrumentation(IApplicationThread target, 16224 int resultCode, Bundle results) { 16225 int userId = UserHandle.getCallingUserId(); 16226 // Refuse possible leaked file descriptors 16227 if (results != null && results.hasFileDescriptors()) { 16228 throw new IllegalArgumentException("File descriptors passed in Intent"); 16229 } 16230 16231 synchronized(this) { 16232 ProcessRecord app = getRecordForAppLocked(target); 16233 if (app == null) { 16234 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16235 return; 16236 } 16237 final long origId = Binder.clearCallingIdentity(); 16238 finishInstrumentationLocked(app, resultCode, results); 16239 Binder.restoreCallingIdentity(origId); 16240 } 16241 } 16242 16243 // ========================================================= 16244 // CONFIGURATION 16245 // ========================================================= 16246 16247 public ConfigurationInfo getDeviceConfigurationInfo() { 16248 ConfigurationInfo config = new ConfigurationInfo(); 16249 synchronized (this) { 16250 config.reqTouchScreen = mConfiguration.touchscreen; 16251 config.reqKeyboardType = mConfiguration.keyboard; 16252 config.reqNavigation = mConfiguration.navigation; 16253 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16254 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16255 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16256 } 16257 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16258 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16259 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16260 } 16261 config.reqGlEsVersion = GL_ES_VERSION; 16262 } 16263 return config; 16264 } 16265 16266 ActivityStack getFocusedStack() { 16267 return mStackSupervisor.getFocusedStack(); 16268 } 16269 16270 public Configuration getConfiguration() { 16271 Configuration ci; 16272 synchronized(this) { 16273 ci = new Configuration(mConfiguration); 16274 } 16275 return ci; 16276 } 16277 16278 public void updatePersistentConfiguration(Configuration values) { 16279 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16280 "updateConfiguration()"); 16281 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16282 "updateConfiguration()"); 16283 if (values == null) { 16284 throw new NullPointerException("Configuration must not be null"); 16285 } 16286 16287 synchronized(this) { 16288 final long origId = Binder.clearCallingIdentity(); 16289 updateConfigurationLocked(values, null, true, false); 16290 Binder.restoreCallingIdentity(origId); 16291 } 16292 } 16293 16294 public void updateConfiguration(Configuration values) { 16295 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16296 "updateConfiguration()"); 16297 16298 synchronized(this) { 16299 if (values == null && mWindowManager != null) { 16300 // sentinel: fetch the current configuration from the window manager 16301 values = mWindowManager.computeNewConfiguration(); 16302 } 16303 16304 if (mWindowManager != null) { 16305 mProcessList.applyDisplaySize(mWindowManager); 16306 } 16307 16308 final long origId = Binder.clearCallingIdentity(); 16309 if (values != null) { 16310 Settings.System.clearConfiguration(values); 16311 } 16312 updateConfigurationLocked(values, null, false, false); 16313 Binder.restoreCallingIdentity(origId); 16314 } 16315 } 16316 16317 /** 16318 * Do either or both things: (1) change the current configuration, and (2) 16319 * make sure the given activity is running with the (now) current 16320 * configuration. Returns true if the activity has been left running, or 16321 * false if <var>starting</var> is being destroyed to match the new 16322 * configuration. 16323 * @param persistent TODO 16324 */ 16325 boolean updateConfigurationLocked(Configuration values, 16326 ActivityRecord starting, boolean persistent, boolean initLocale) { 16327 int changes = 0; 16328 16329 if (values != null) { 16330 Configuration newConfig = new Configuration(mConfiguration); 16331 changes = newConfig.updateFrom(values); 16332 if (changes != 0) { 16333 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16334 Slog.i(TAG, "Updating configuration to: " + values); 16335 } 16336 16337 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16338 16339 if (values.locale != null && !initLocale) { 16340 saveLocaleLocked(values.locale, 16341 !values.locale.equals(mConfiguration.locale), 16342 values.userSetLocale); 16343 } 16344 16345 mConfigurationSeq++; 16346 if (mConfigurationSeq <= 0) { 16347 mConfigurationSeq = 1; 16348 } 16349 newConfig.seq = mConfigurationSeq; 16350 mConfiguration = newConfig; 16351 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16352 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16353 //mUsageStatsService.noteStartConfig(newConfig); 16354 16355 final Configuration configCopy = new Configuration(mConfiguration); 16356 16357 // TODO: If our config changes, should we auto dismiss any currently 16358 // showing dialogs? 16359 mShowDialogs = shouldShowDialogs(newConfig); 16360 16361 AttributeCache ac = AttributeCache.instance(); 16362 if (ac != null) { 16363 ac.updateConfiguration(configCopy); 16364 } 16365 16366 // Make sure all resources in our process are updated 16367 // right now, so that anyone who is going to retrieve 16368 // resource values after we return will be sure to get 16369 // the new ones. This is especially important during 16370 // boot, where the first config change needs to guarantee 16371 // all resources have that config before following boot 16372 // code is executed. 16373 mSystemThread.applyConfigurationToResources(configCopy); 16374 16375 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16376 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16377 msg.obj = new Configuration(configCopy); 16378 mHandler.sendMessage(msg); 16379 } 16380 16381 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16382 ProcessRecord app = mLruProcesses.get(i); 16383 try { 16384 if (app.thread != null) { 16385 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16386 + app.processName + " new config " + mConfiguration); 16387 app.thread.scheduleConfigurationChanged(configCopy); 16388 } 16389 } catch (Exception e) { 16390 } 16391 } 16392 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16393 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16394 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16395 | Intent.FLAG_RECEIVER_FOREGROUND); 16396 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16397 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16398 Process.SYSTEM_UID, UserHandle.USER_ALL); 16399 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16400 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16401 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16402 broadcastIntentLocked(null, null, intent, 16403 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16404 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16405 } 16406 } 16407 } 16408 16409 boolean kept = true; 16410 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16411 // mainStack is null during startup. 16412 if (mainStack != null) { 16413 if (changes != 0 && starting == null) { 16414 // If the configuration changed, and the caller is not already 16415 // in the process of starting an activity, then find the top 16416 // activity to check if its configuration needs to change. 16417 starting = mainStack.topRunningActivityLocked(null); 16418 } 16419 16420 if (starting != null) { 16421 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16422 // And we need to make sure at this point that all other activities 16423 // are made visible with the correct configuration. 16424 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16425 } 16426 } 16427 16428 if (values != null && mWindowManager != null) { 16429 mWindowManager.setNewConfiguration(mConfiguration); 16430 } 16431 16432 return kept; 16433 } 16434 16435 /** 16436 * Decide based on the configuration whether we should shouw the ANR, 16437 * crash, etc dialogs. The idea is that if there is no affordnace to 16438 * press the on-screen buttons, we shouldn't show the dialog. 16439 * 16440 * A thought: SystemUI might also want to get told about this, the Power 16441 * dialog / global actions also might want different behaviors. 16442 */ 16443 private static final boolean shouldShowDialogs(Configuration config) { 16444 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16445 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16446 } 16447 16448 /** 16449 * Save the locale. You must be inside a synchronized (this) block. 16450 */ 16451 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16452 if(isDiff) { 16453 SystemProperties.set("user.language", l.getLanguage()); 16454 SystemProperties.set("user.region", l.getCountry()); 16455 } 16456 16457 if(isPersist) { 16458 SystemProperties.set("persist.sys.language", l.getLanguage()); 16459 SystemProperties.set("persist.sys.country", l.getCountry()); 16460 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16461 16462 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16463 } 16464 } 16465 16466 @Override 16467 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16468 synchronized (this) { 16469 ActivityRecord srec = ActivityRecord.forToken(token); 16470 if (srec.task != null && srec.task.stack != null) { 16471 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16472 } 16473 } 16474 return false; 16475 } 16476 16477 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16478 Intent resultData) { 16479 16480 synchronized (this) { 16481 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16482 if (stack != null) { 16483 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16484 } 16485 return false; 16486 } 16487 } 16488 16489 public int getLaunchedFromUid(IBinder activityToken) { 16490 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16491 if (srec == null) { 16492 return -1; 16493 } 16494 return srec.launchedFromUid; 16495 } 16496 16497 public String getLaunchedFromPackage(IBinder activityToken) { 16498 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16499 if (srec == null) { 16500 return null; 16501 } 16502 return srec.launchedFromPackage; 16503 } 16504 16505 // ========================================================= 16506 // LIFETIME MANAGEMENT 16507 // ========================================================= 16508 16509 // Returns which broadcast queue the app is the current [or imminent] receiver 16510 // on, or 'null' if the app is not an active broadcast recipient. 16511 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16512 BroadcastRecord r = app.curReceiver; 16513 if (r != null) { 16514 return r.queue; 16515 } 16516 16517 // It's not the current receiver, but it might be starting up to become one 16518 synchronized (this) { 16519 for (BroadcastQueue queue : mBroadcastQueues) { 16520 r = queue.mPendingBroadcast; 16521 if (r != null && r.curApp == app) { 16522 // found it; report which queue it's in 16523 return queue; 16524 } 16525 } 16526 } 16527 16528 return null; 16529 } 16530 16531 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16532 boolean doingAll, long now) { 16533 if (mAdjSeq == app.adjSeq) { 16534 // This adjustment has already been computed. 16535 return app.curRawAdj; 16536 } 16537 16538 if (app.thread == null) { 16539 app.adjSeq = mAdjSeq; 16540 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16541 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16542 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16543 } 16544 16545 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16546 app.adjSource = null; 16547 app.adjTarget = null; 16548 app.empty = false; 16549 app.cached = false; 16550 16551 final int activitiesSize = app.activities.size(); 16552 16553 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16554 // The max adjustment doesn't allow this app to be anything 16555 // below foreground, so it is not worth doing work for it. 16556 app.adjType = "fixed"; 16557 app.adjSeq = mAdjSeq; 16558 app.curRawAdj = app.maxAdj; 16559 app.foregroundActivities = false; 16560 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16561 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16562 // System processes can do UI, and when they do we want to have 16563 // them trim their memory after the user leaves the UI. To 16564 // facilitate this, here we need to determine whether or not it 16565 // is currently showing UI. 16566 app.systemNoUi = true; 16567 if (app == TOP_APP) { 16568 app.systemNoUi = false; 16569 } else if (activitiesSize > 0) { 16570 for (int j = 0; j < activitiesSize; j++) { 16571 final ActivityRecord r = app.activities.get(j); 16572 if (r.visible) { 16573 app.systemNoUi = false; 16574 } 16575 } 16576 } 16577 if (!app.systemNoUi) { 16578 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16579 } 16580 return (app.curAdj=app.maxAdj); 16581 } 16582 16583 app.systemNoUi = false; 16584 16585 // Determine the importance of the process, starting with most 16586 // important to least, and assign an appropriate OOM adjustment. 16587 int adj; 16588 int schedGroup; 16589 int procState; 16590 boolean foregroundActivities = false; 16591 BroadcastQueue queue; 16592 if (app == TOP_APP) { 16593 // The last app on the list is the foreground app. 16594 adj = ProcessList.FOREGROUND_APP_ADJ; 16595 schedGroup = Process.THREAD_GROUP_DEFAULT; 16596 app.adjType = "top-activity"; 16597 foregroundActivities = true; 16598 procState = ActivityManager.PROCESS_STATE_TOP; 16599 } else if (app.instrumentationClass != null) { 16600 // Don't want to kill running instrumentation. 16601 adj = ProcessList.FOREGROUND_APP_ADJ; 16602 schedGroup = Process.THREAD_GROUP_DEFAULT; 16603 app.adjType = "instrumentation"; 16604 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16605 } else if ((queue = isReceivingBroadcast(app)) != null) { 16606 // An app that is currently receiving a broadcast also 16607 // counts as being in the foreground for OOM killer purposes. 16608 // It's placed in a sched group based on the nature of the 16609 // broadcast as reflected by which queue it's active in. 16610 adj = ProcessList.FOREGROUND_APP_ADJ; 16611 schedGroup = (queue == mFgBroadcastQueue) 16612 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16613 app.adjType = "broadcast"; 16614 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16615 } else if (app.executingServices.size() > 0) { 16616 // An app that is currently executing a service callback also 16617 // counts as being in the foreground. 16618 adj = ProcessList.FOREGROUND_APP_ADJ; 16619 schedGroup = app.execServicesFg ? 16620 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16621 app.adjType = "exec-service"; 16622 procState = ActivityManager.PROCESS_STATE_SERVICE; 16623 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16624 } else { 16625 // As far as we know the process is empty. We may change our mind later. 16626 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16627 // At this point we don't actually know the adjustment. Use the cached adj 16628 // value that the caller wants us to. 16629 adj = cachedAdj; 16630 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16631 app.cached = true; 16632 app.empty = true; 16633 app.adjType = "cch-empty"; 16634 } 16635 16636 // Examine all activities if not already foreground. 16637 if (!foregroundActivities && activitiesSize > 0) { 16638 for (int j = 0; j < activitiesSize; j++) { 16639 final ActivityRecord r = app.activities.get(j); 16640 if (r.app != app) { 16641 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16642 + app + "?!?"); 16643 continue; 16644 } 16645 if (r.visible) { 16646 // App has a visible activity; only upgrade adjustment. 16647 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16648 adj = ProcessList.VISIBLE_APP_ADJ; 16649 app.adjType = "visible"; 16650 } 16651 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16652 procState = ActivityManager.PROCESS_STATE_TOP; 16653 } 16654 schedGroup = Process.THREAD_GROUP_DEFAULT; 16655 app.cached = false; 16656 app.empty = false; 16657 foregroundActivities = true; 16658 break; 16659 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16660 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16661 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16662 app.adjType = "pausing"; 16663 } 16664 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16665 procState = ActivityManager.PROCESS_STATE_TOP; 16666 } 16667 schedGroup = Process.THREAD_GROUP_DEFAULT; 16668 app.cached = false; 16669 app.empty = false; 16670 foregroundActivities = true; 16671 } else if (r.state == ActivityState.STOPPING) { 16672 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16673 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16674 app.adjType = "stopping"; 16675 } 16676 // For the process state, we will at this point consider the 16677 // process to be cached. It will be cached either as an activity 16678 // or empty depending on whether the activity is finishing. We do 16679 // this so that we can treat the process as cached for purposes of 16680 // memory trimming (determing current memory level, trim command to 16681 // send to process) since there can be an arbitrary number of stopping 16682 // processes and they should soon all go into the cached state. 16683 if (!r.finishing) { 16684 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16685 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16686 } 16687 } 16688 app.cached = false; 16689 app.empty = false; 16690 foregroundActivities = true; 16691 } else { 16692 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16693 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16694 app.adjType = "cch-act"; 16695 } 16696 } 16697 } 16698 } 16699 16700 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16701 if (app.foregroundServices) { 16702 // The user is aware of this app, so make it visible. 16703 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16704 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16705 app.cached = false; 16706 app.adjType = "fg-service"; 16707 schedGroup = Process.THREAD_GROUP_DEFAULT; 16708 } else if (app.forcingToForeground != null) { 16709 // The user is aware of this app, so make it visible. 16710 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16711 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16712 app.cached = false; 16713 app.adjType = "force-fg"; 16714 app.adjSource = app.forcingToForeground; 16715 schedGroup = Process.THREAD_GROUP_DEFAULT; 16716 } 16717 } 16718 16719 if (app == mHeavyWeightProcess) { 16720 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16721 // We don't want to kill the current heavy-weight process. 16722 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16723 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16724 app.cached = false; 16725 app.adjType = "heavy"; 16726 } 16727 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16728 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16729 } 16730 } 16731 16732 if (app == mHomeProcess) { 16733 if (adj > ProcessList.HOME_APP_ADJ) { 16734 // This process is hosting what we currently consider to be the 16735 // home app, so we don't want to let it go into the background. 16736 adj = ProcessList.HOME_APP_ADJ; 16737 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16738 app.cached = false; 16739 app.adjType = "home"; 16740 } 16741 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16742 procState = ActivityManager.PROCESS_STATE_HOME; 16743 } 16744 } 16745 16746 if (app == mPreviousProcess && app.activities.size() > 0) { 16747 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16748 // This was the previous process that showed UI to the user. 16749 // We want to try to keep it around more aggressively, to give 16750 // a good experience around switching between two apps. 16751 adj = ProcessList.PREVIOUS_APP_ADJ; 16752 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16753 app.cached = false; 16754 app.adjType = "previous"; 16755 } 16756 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16757 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16758 } 16759 } 16760 16761 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16762 + " reason=" + app.adjType); 16763 16764 // By default, we use the computed adjustment. It may be changed if 16765 // there are applications dependent on our services or providers, but 16766 // this gives us a baseline and makes sure we don't get into an 16767 // infinite recursion. 16768 app.adjSeq = mAdjSeq; 16769 app.curRawAdj = adj; 16770 app.hasStartedServices = false; 16771 16772 if (mBackupTarget != null && app == mBackupTarget.app) { 16773 // If possible we want to avoid killing apps while they're being backed up 16774 if (adj > ProcessList.BACKUP_APP_ADJ) { 16775 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16776 adj = ProcessList.BACKUP_APP_ADJ; 16777 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16778 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16779 } 16780 app.adjType = "backup"; 16781 app.cached = false; 16782 } 16783 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16784 procState = ActivityManager.PROCESS_STATE_BACKUP; 16785 } 16786 } 16787 16788 boolean mayBeTop = false; 16789 16790 for (int is = app.services.size()-1; 16791 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16792 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16793 || procState > ActivityManager.PROCESS_STATE_TOP); 16794 is--) { 16795 ServiceRecord s = app.services.valueAt(is); 16796 if (s.startRequested) { 16797 app.hasStartedServices = true; 16798 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16799 procState = ActivityManager.PROCESS_STATE_SERVICE; 16800 } 16801 if (app.hasShownUi && app != mHomeProcess) { 16802 // If this process has shown some UI, let it immediately 16803 // go to the LRU list because it may be pretty heavy with 16804 // UI stuff. We'll tag it with a label just to help 16805 // debug and understand what is going on. 16806 if (adj > ProcessList.SERVICE_ADJ) { 16807 app.adjType = "cch-started-ui-services"; 16808 } 16809 } else { 16810 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16811 // This service has seen some activity within 16812 // recent memory, so we will keep its process ahead 16813 // of the background processes. 16814 if (adj > ProcessList.SERVICE_ADJ) { 16815 adj = ProcessList.SERVICE_ADJ; 16816 app.adjType = "started-services"; 16817 app.cached = false; 16818 } 16819 } 16820 // If we have let the service slide into the background 16821 // state, still have some text describing what it is doing 16822 // even though the service no longer has an impact. 16823 if (adj > ProcessList.SERVICE_ADJ) { 16824 app.adjType = "cch-started-services"; 16825 } 16826 } 16827 } 16828 for (int conni = s.connections.size()-1; 16829 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16830 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16831 || procState > ActivityManager.PROCESS_STATE_TOP); 16832 conni--) { 16833 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16834 for (int i = 0; 16835 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16836 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16837 || procState > ActivityManager.PROCESS_STATE_TOP); 16838 i++) { 16839 // XXX should compute this based on the max of 16840 // all connected clients. 16841 ConnectionRecord cr = clist.get(i); 16842 if (cr.binding.client == app) { 16843 // Binding to ourself is not interesting. 16844 continue; 16845 } 16846 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16847 ProcessRecord client = cr.binding.client; 16848 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16849 TOP_APP, doingAll, now); 16850 int clientProcState = client.curProcState; 16851 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16852 // If the other app is cached for any reason, for purposes here 16853 // we are going to consider it empty. The specific cached state 16854 // doesn't propagate except under certain conditions. 16855 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16856 } 16857 String adjType = null; 16858 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16859 // Not doing bind OOM management, so treat 16860 // this guy more like a started service. 16861 if (app.hasShownUi && app != mHomeProcess) { 16862 // If this process has shown some UI, let it immediately 16863 // go to the LRU list because it may be pretty heavy with 16864 // UI stuff. We'll tag it with a label just to help 16865 // debug and understand what is going on. 16866 if (adj > clientAdj) { 16867 adjType = "cch-bound-ui-services"; 16868 } 16869 app.cached = false; 16870 clientAdj = adj; 16871 clientProcState = procState; 16872 } else { 16873 if (now >= (s.lastActivity 16874 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16875 // This service has not seen activity within 16876 // recent memory, so allow it to drop to the 16877 // LRU list if there is no other reason to keep 16878 // it around. We'll also tag it with a label just 16879 // to help debug and undertand what is going on. 16880 if (adj > clientAdj) { 16881 adjType = "cch-bound-services"; 16882 } 16883 clientAdj = adj; 16884 } 16885 } 16886 } 16887 if (adj > clientAdj) { 16888 // If this process has recently shown UI, and 16889 // the process that is binding to it is less 16890 // important than being visible, then we don't 16891 // care about the binding as much as we care 16892 // about letting this process get into the LRU 16893 // list to be killed and restarted if needed for 16894 // memory. 16895 if (app.hasShownUi && app != mHomeProcess 16896 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16897 adjType = "cch-bound-ui-services"; 16898 } else { 16899 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16900 |Context.BIND_IMPORTANT)) != 0) { 16901 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16902 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16903 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16904 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16905 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16906 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16907 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16908 adj = clientAdj; 16909 } else { 16910 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16911 adj = ProcessList.VISIBLE_APP_ADJ; 16912 } 16913 } 16914 if (!client.cached) { 16915 app.cached = false; 16916 } 16917 adjType = "service"; 16918 } 16919 } 16920 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16921 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16922 schedGroup = Process.THREAD_GROUP_DEFAULT; 16923 } 16924 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16925 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16926 // Special handling of clients who are in the top state. 16927 // We *may* want to consider this process to be in the 16928 // top state as well, but only if there is not another 16929 // reason for it to be running. Being on the top is a 16930 // special state, meaning you are specifically running 16931 // for the current top app. If the process is already 16932 // running in the background for some other reason, it 16933 // is more important to continue considering it to be 16934 // in the background state. 16935 mayBeTop = true; 16936 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16937 } else { 16938 // Special handling for above-top states (persistent 16939 // processes). These should not bring the current process 16940 // into the top state, since they are not on top. Instead 16941 // give them the best state after that. 16942 clientProcState = 16943 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16944 } 16945 } 16946 } else { 16947 if (clientProcState < 16948 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16949 clientProcState = 16950 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16951 } 16952 } 16953 if (procState > clientProcState) { 16954 procState = clientProcState; 16955 } 16956 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16957 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16958 app.pendingUiClean = true; 16959 } 16960 if (adjType != null) { 16961 app.adjType = adjType; 16962 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16963 .REASON_SERVICE_IN_USE; 16964 app.adjSource = cr.binding.client; 16965 app.adjSourceProcState = clientProcState; 16966 app.adjTarget = s.name; 16967 } 16968 } 16969 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16970 app.treatLikeActivity = true; 16971 } 16972 final ActivityRecord a = cr.activity; 16973 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16974 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16975 (a.visible || a.state == ActivityState.RESUMED 16976 || a.state == ActivityState.PAUSING)) { 16977 adj = ProcessList.FOREGROUND_APP_ADJ; 16978 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16979 schedGroup = Process.THREAD_GROUP_DEFAULT; 16980 } 16981 app.cached = false; 16982 app.adjType = "service"; 16983 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16984 .REASON_SERVICE_IN_USE; 16985 app.adjSource = a; 16986 app.adjSourceProcState = procState; 16987 app.adjTarget = s.name; 16988 } 16989 } 16990 } 16991 } 16992 } 16993 16994 for (int provi = app.pubProviders.size()-1; 16995 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16996 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16997 || procState > ActivityManager.PROCESS_STATE_TOP); 16998 provi--) { 16999 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17000 for (int i = cpr.connections.size()-1; 17001 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17002 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17003 || procState > ActivityManager.PROCESS_STATE_TOP); 17004 i--) { 17005 ContentProviderConnection conn = cpr.connections.get(i); 17006 ProcessRecord client = conn.client; 17007 if (client == app) { 17008 // Being our own client is not interesting. 17009 continue; 17010 } 17011 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17012 int clientProcState = client.curProcState; 17013 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17014 // If the other app is cached for any reason, for purposes here 17015 // we are going to consider it empty. 17016 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17017 } 17018 if (adj > clientAdj) { 17019 if (app.hasShownUi && app != mHomeProcess 17020 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17021 app.adjType = "cch-ui-provider"; 17022 } else { 17023 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17024 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17025 app.adjType = "provider"; 17026 } 17027 app.cached &= client.cached; 17028 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17029 .REASON_PROVIDER_IN_USE; 17030 app.adjSource = client; 17031 app.adjSourceProcState = clientProcState; 17032 app.adjTarget = cpr.name; 17033 } 17034 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17035 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17036 // Special handling of clients who are in the top state. 17037 // We *may* want to consider this process to be in the 17038 // top state as well, but only if there is not another 17039 // reason for it to be running. Being on the top is a 17040 // special state, meaning you are specifically running 17041 // for the current top app. If the process is already 17042 // running in the background for some other reason, it 17043 // is more important to continue considering it to be 17044 // in the background state. 17045 mayBeTop = true; 17046 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17047 } else { 17048 // Special handling for above-top states (persistent 17049 // processes). These should not bring the current process 17050 // into the top state, since they are not on top. Instead 17051 // give them the best state after that. 17052 clientProcState = 17053 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17054 } 17055 } 17056 if (procState > clientProcState) { 17057 procState = clientProcState; 17058 } 17059 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17060 schedGroup = Process.THREAD_GROUP_DEFAULT; 17061 } 17062 } 17063 // If the provider has external (non-framework) process 17064 // dependencies, ensure that its adjustment is at least 17065 // FOREGROUND_APP_ADJ. 17066 if (cpr.hasExternalProcessHandles()) { 17067 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17068 adj = ProcessList.FOREGROUND_APP_ADJ; 17069 schedGroup = Process.THREAD_GROUP_DEFAULT; 17070 app.cached = false; 17071 app.adjType = "provider"; 17072 app.adjTarget = cpr.name; 17073 } 17074 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17075 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17076 } 17077 } 17078 } 17079 17080 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17081 // A client of one of our services or providers is in the top state. We 17082 // *may* want to be in the top state, but not if we are already running in 17083 // the background for some other reason. For the decision here, we are going 17084 // to pick out a few specific states that we want to remain in when a client 17085 // is top (states that tend to be longer-term) and otherwise allow it to go 17086 // to the top state. 17087 switch (procState) { 17088 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17089 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17090 case ActivityManager.PROCESS_STATE_SERVICE: 17091 // These all are longer-term states, so pull them up to the top 17092 // of the background states, but not all the way to the top state. 17093 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17094 break; 17095 default: 17096 // Otherwise, top is a better choice, so take it. 17097 procState = ActivityManager.PROCESS_STATE_TOP; 17098 break; 17099 } 17100 } 17101 17102 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17103 if (app.hasClientActivities) { 17104 // This is a cached process, but with client activities. Mark it so. 17105 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17106 app.adjType = "cch-client-act"; 17107 } else if (app.treatLikeActivity) { 17108 // This is a cached process, but somebody wants us to treat it like it has 17109 // an activity, okay! 17110 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17111 app.adjType = "cch-as-act"; 17112 } 17113 } 17114 17115 if (adj == ProcessList.SERVICE_ADJ) { 17116 if (doingAll) { 17117 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17118 mNewNumServiceProcs++; 17119 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17120 if (!app.serviceb) { 17121 // This service isn't far enough down on the LRU list to 17122 // normally be a B service, but if we are low on RAM and it 17123 // is large we want to force it down since we would prefer to 17124 // keep launcher over it. 17125 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17126 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17127 app.serviceHighRam = true; 17128 app.serviceb = true; 17129 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17130 } else { 17131 mNewNumAServiceProcs++; 17132 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17133 } 17134 } else { 17135 app.serviceHighRam = false; 17136 } 17137 } 17138 if (app.serviceb) { 17139 adj = ProcessList.SERVICE_B_ADJ; 17140 } 17141 } 17142 17143 app.curRawAdj = adj; 17144 17145 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17146 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17147 if (adj > app.maxAdj) { 17148 adj = app.maxAdj; 17149 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17150 schedGroup = Process.THREAD_GROUP_DEFAULT; 17151 } 17152 } 17153 17154 // Do final modification to adj. Everything we do between here and applying 17155 // the final setAdj must be done in this function, because we will also use 17156 // it when computing the final cached adj later. Note that we don't need to 17157 // worry about this for max adj above, since max adj will always be used to 17158 // keep it out of the cached vaues. 17159 app.curAdj = app.modifyRawOomAdj(adj); 17160 app.curSchedGroup = schedGroup; 17161 app.curProcState = procState; 17162 app.foregroundActivities = foregroundActivities; 17163 17164 return app.curRawAdj; 17165 } 17166 17167 /** 17168 * Schedule PSS collection of a process. 17169 */ 17170 void requestPssLocked(ProcessRecord proc, int procState) { 17171 if (mPendingPssProcesses.contains(proc)) { 17172 return; 17173 } 17174 if (mPendingPssProcesses.size() == 0) { 17175 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17176 } 17177 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17178 proc.pssProcState = procState; 17179 mPendingPssProcesses.add(proc); 17180 } 17181 17182 /** 17183 * Schedule PSS collection of all processes. 17184 */ 17185 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17186 if (!always) { 17187 if (now < (mLastFullPssTime + 17188 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17189 return; 17190 } 17191 } 17192 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17193 mLastFullPssTime = now; 17194 mFullPssPending = true; 17195 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17196 mPendingPssProcesses.clear(); 17197 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17198 ProcessRecord app = mLruProcesses.get(i); 17199 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17200 app.pssProcState = app.setProcState; 17201 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17202 isSleeping(), now); 17203 mPendingPssProcesses.add(app); 17204 } 17205 } 17206 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17207 } 17208 17209 /** 17210 * Ask a given process to GC right now. 17211 */ 17212 final void performAppGcLocked(ProcessRecord app) { 17213 try { 17214 app.lastRequestedGc = SystemClock.uptimeMillis(); 17215 if (app.thread != null) { 17216 if (app.reportLowMemory) { 17217 app.reportLowMemory = false; 17218 app.thread.scheduleLowMemory(); 17219 } else { 17220 app.thread.processInBackground(); 17221 } 17222 } 17223 } catch (Exception e) { 17224 // whatever. 17225 } 17226 } 17227 17228 /** 17229 * Returns true if things are idle enough to perform GCs. 17230 */ 17231 private final boolean canGcNowLocked() { 17232 boolean processingBroadcasts = false; 17233 for (BroadcastQueue q : mBroadcastQueues) { 17234 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17235 processingBroadcasts = true; 17236 } 17237 } 17238 return !processingBroadcasts 17239 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17240 } 17241 17242 /** 17243 * Perform GCs on all processes that are waiting for it, but only 17244 * if things are idle. 17245 */ 17246 final void performAppGcsLocked() { 17247 final int N = mProcessesToGc.size(); 17248 if (N <= 0) { 17249 return; 17250 } 17251 if (canGcNowLocked()) { 17252 while (mProcessesToGc.size() > 0) { 17253 ProcessRecord proc = mProcessesToGc.remove(0); 17254 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17255 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17256 <= SystemClock.uptimeMillis()) { 17257 // To avoid spamming the system, we will GC processes one 17258 // at a time, waiting a few seconds between each. 17259 performAppGcLocked(proc); 17260 scheduleAppGcsLocked(); 17261 return; 17262 } else { 17263 // It hasn't been long enough since we last GCed this 17264 // process... put it in the list to wait for its time. 17265 addProcessToGcListLocked(proc); 17266 break; 17267 } 17268 } 17269 } 17270 17271 scheduleAppGcsLocked(); 17272 } 17273 } 17274 17275 /** 17276 * If all looks good, perform GCs on all processes waiting for them. 17277 */ 17278 final void performAppGcsIfAppropriateLocked() { 17279 if (canGcNowLocked()) { 17280 performAppGcsLocked(); 17281 return; 17282 } 17283 // Still not idle, wait some more. 17284 scheduleAppGcsLocked(); 17285 } 17286 17287 /** 17288 * Schedule the execution of all pending app GCs. 17289 */ 17290 final void scheduleAppGcsLocked() { 17291 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17292 17293 if (mProcessesToGc.size() > 0) { 17294 // Schedule a GC for the time to the next process. 17295 ProcessRecord proc = mProcessesToGc.get(0); 17296 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17297 17298 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17299 long now = SystemClock.uptimeMillis(); 17300 if (when < (now+GC_TIMEOUT)) { 17301 when = now + GC_TIMEOUT; 17302 } 17303 mHandler.sendMessageAtTime(msg, when); 17304 } 17305 } 17306 17307 /** 17308 * Add a process to the array of processes waiting to be GCed. Keeps the 17309 * list in sorted order by the last GC time. The process can't already be 17310 * on the list. 17311 */ 17312 final void addProcessToGcListLocked(ProcessRecord proc) { 17313 boolean added = false; 17314 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17315 if (mProcessesToGc.get(i).lastRequestedGc < 17316 proc.lastRequestedGc) { 17317 added = true; 17318 mProcessesToGc.add(i+1, proc); 17319 break; 17320 } 17321 } 17322 if (!added) { 17323 mProcessesToGc.add(0, proc); 17324 } 17325 } 17326 17327 /** 17328 * Set up to ask a process to GC itself. This will either do it 17329 * immediately, or put it on the list of processes to gc the next 17330 * time things are idle. 17331 */ 17332 final void scheduleAppGcLocked(ProcessRecord app) { 17333 long now = SystemClock.uptimeMillis(); 17334 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17335 return; 17336 } 17337 if (!mProcessesToGc.contains(app)) { 17338 addProcessToGcListLocked(app); 17339 scheduleAppGcsLocked(); 17340 } 17341 } 17342 17343 final void checkExcessivePowerUsageLocked(boolean doKills) { 17344 updateCpuStatsNow(); 17345 17346 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17347 boolean doWakeKills = doKills; 17348 boolean doCpuKills = doKills; 17349 if (mLastPowerCheckRealtime == 0) { 17350 doWakeKills = false; 17351 } 17352 if (mLastPowerCheckUptime == 0) { 17353 doCpuKills = false; 17354 } 17355 if (stats.isScreenOn()) { 17356 doWakeKills = false; 17357 } 17358 final long curRealtime = SystemClock.elapsedRealtime(); 17359 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17360 final long curUptime = SystemClock.uptimeMillis(); 17361 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17362 mLastPowerCheckRealtime = curRealtime; 17363 mLastPowerCheckUptime = curUptime; 17364 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17365 doWakeKills = false; 17366 } 17367 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17368 doCpuKills = false; 17369 } 17370 int i = mLruProcesses.size(); 17371 while (i > 0) { 17372 i--; 17373 ProcessRecord app = mLruProcesses.get(i); 17374 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17375 long wtime; 17376 synchronized (stats) { 17377 wtime = stats.getProcessWakeTime(app.info.uid, 17378 app.pid, curRealtime); 17379 } 17380 long wtimeUsed = wtime - app.lastWakeTime; 17381 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17382 if (DEBUG_POWER) { 17383 StringBuilder sb = new StringBuilder(128); 17384 sb.append("Wake for "); 17385 app.toShortString(sb); 17386 sb.append(": over "); 17387 TimeUtils.formatDuration(realtimeSince, sb); 17388 sb.append(" used "); 17389 TimeUtils.formatDuration(wtimeUsed, sb); 17390 sb.append(" ("); 17391 sb.append((wtimeUsed*100)/realtimeSince); 17392 sb.append("%)"); 17393 Slog.i(TAG, sb.toString()); 17394 sb.setLength(0); 17395 sb.append("CPU for "); 17396 app.toShortString(sb); 17397 sb.append(": over "); 17398 TimeUtils.formatDuration(uptimeSince, sb); 17399 sb.append(" used "); 17400 TimeUtils.formatDuration(cputimeUsed, sb); 17401 sb.append(" ("); 17402 sb.append((cputimeUsed*100)/uptimeSince); 17403 sb.append("%)"); 17404 Slog.i(TAG, sb.toString()); 17405 } 17406 // If a process has held a wake lock for more 17407 // than 50% of the time during this period, 17408 // that sounds bad. Kill! 17409 if (doWakeKills && realtimeSince > 0 17410 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17411 synchronized (stats) { 17412 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17413 realtimeSince, wtimeUsed); 17414 } 17415 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17416 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17417 } else if (doCpuKills && uptimeSince > 0 17418 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17419 synchronized (stats) { 17420 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17421 uptimeSince, cputimeUsed); 17422 } 17423 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17424 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17425 } else { 17426 app.lastWakeTime = wtime; 17427 app.lastCpuTime = app.curCpuTime; 17428 } 17429 } 17430 } 17431 } 17432 17433 private final boolean applyOomAdjLocked(ProcessRecord app, 17434 ProcessRecord TOP_APP, boolean doingAll, long now) { 17435 boolean success = true; 17436 17437 if (app.curRawAdj != app.setRawAdj) { 17438 app.setRawAdj = app.curRawAdj; 17439 } 17440 17441 int changes = 0; 17442 17443 if (app.curAdj != app.setAdj) { 17444 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17445 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17446 TAG, "Set " + app.pid + " " + app.processName + 17447 " adj " + app.curAdj + ": " + app.adjType); 17448 app.setAdj = app.curAdj; 17449 } 17450 17451 if (app.setSchedGroup != app.curSchedGroup) { 17452 app.setSchedGroup = app.curSchedGroup; 17453 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17454 "Setting process group of " + app.processName 17455 + " to " + app.curSchedGroup); 17456 if (app.waitingToKill != null && 17457 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17458 app.kill(app.waitingToKill, true); 17459 success = false; 17460 } else { 17461 if (true) { 17462 long oldId = Binder.clearCallingIdentity(); 17463 try { 17464 Process.setProcessGroup(app.pid, app.curSchedGroup); 17465 } catch (Exception e) { 17466 Slog.w(TAG, "Failed setting process group of " + app.pid 17467 + " to " + app.curSchedGroup); 17468 e.printStackTrace(); 17469 } finally { 17470 Binder.restoreCallingIdentity(oldId); 17471 } 17472 } else { 17473 if (app.thread != null) { 17474 try { 17475 app.thread.setSchedulingGroup(app.curSchedGroup); 17476 } catch (RemoteException e) { 17477 } 17478 } 17479 } 17480 Process.setSwappiness(app.pid, 17481 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17482 } 17483 } 17484 if (app.repForegroundActivities != app.foregroundActivities) { 17485 app.repForegroundActivities = app.foregroundActivities; 17486 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17487 } 17488 if (app.repProcState != app.curProcState) { 17489 app.repProcState = app.curProcState; 17490 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17491 if (app.thread != null) { 17492 try { 17493 if (false) { 17494 //RuntimeException h = new RuntimeException("here"); 17495 Slog.i(TAG, "Sending new process state " + app.repProcState 17496 + " to " + app /*, h*/); 17497 } 17498 app.thread.setProcessState(app.repProcState); 17499 } catch (RemoteException e) { 17500 } 17501 } 17502 } 17503 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17504 app.setProcState)) { 17505 app.lastStateTime = now; 17506 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17507 isSleeping(), now); 17508 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17509 + ProcessList.makeProcStateString(app.setProcState) + " to " 17510 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17511 + (app.nextPssTime-now) + ": " + app); 17512 } else { 17513 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17514 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17515 requestPssLocked(app, app.setProcState); 17516 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17517 isSleeping(), now); 17518 } else if (false && DEBUG_PSS) { 17519 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17520 } 17521 } 17522 if (app.setProcState != app.curProcState) { 17523 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17524 "Proc state change of " + app.processName 17525 + " to " + app.curProcState); 17526 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17527 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17528 if (setImportant && !curImportant) { 17529 // This app is no longer something we consider important enough to allow to 17530 // use arbitrary amounts of battery power. Note 17531 // its current wake lock time to later know to kill it if 17532 // it is not behaving well. 17533 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17534 synchronized (stats) { 17535 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17536 app.pid, SystemClock.elapsedRealtime()); 17537 } 17538 app.lastCpuTime = app.curCpuTime; 17539 17540 } 17541 app.setProcState = app.curProcState; 17542 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17543 app.notCachedSinceIdle = false; 17544 } 17545 if (!doingAll) { 17546 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17547 } else { 17548 app.procStateChanged = true; 17549 } 17550 } 17551 17552 if (changes != 0) { 17553 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17554 int i = mPendingProcessChanges.size()-1; 17555 ProcessChangeItem item = null; 17556 while (i >= 0) { 17557 item = mPendingProcessChanges.get(i); 17558 if (item.pid == app.pid) { 17559 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17560 break; 17561 } 17562 i--; 17563 } 17564 if (i < 0) { 17565 // No existing item in pending changes; need a new one. 17566 final int NA = mAvailProcessChanges.size(); 17567 if (NA > 0) { 17568 item = mAvailProcessChanges.remove(NA-1); 17569 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17570 } else { 17571 item = new ProcessChangeItem(); 17572 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17573 } 17574 item.changes = 0; 17575 item.pid = app.pid; 17576 item.uid = app.info.uid; 17577 if (mPendingProcessChanges.size() == 0) { 17578 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17579 "*** Enqueueing dispatch processes changed!"); 17580 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17581 } 17582 mPendingProcessChanges.add(item); 17583 } 17584 item.changes |= changes; 17585 item.processState = app.repProcState; 17586 item.foregroundActivities = app.repForegroundActivities; 17587 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17588 + Integer.toHexString(System.identityHashCode(item)) 17589 + " " + app.toShortString() + ": changes=" + item.changes 17590 + " procState=" + item.processState 17591 + " foreground=" + item.foregroundActivities 17592 + " type=" + app.adjType + " source=" + app.adjSource 17593 + " target=" + app.adjTarget); 17594 } 17595 17596 return success; 17597 } 17598 17599 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17600 if (proc.thread != null) { 17601 if (proc.baseProcessTracker != null) { 17602 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17603 } 17604 if (proc.repProcState >= 0) { 17605 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17606 proc.repProcState); 17607 } 17608 } 17609 } 17610 17611 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17612 ProcessRecord TOP_APP, boolean doingAll, long now) { 17613 if (app.thread == null) { 17614 return false; 17615 } 17616 17617 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17618 17619 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17620 } 17621 17622 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17623 boolean oomAdj) { 17624 if (isForeground != proc.foregroundServices) { 17625 proc.foregroundServices = isForeground; 17626 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17627 proc.info.uid); 17628 if (isForeground) { 17629 if (curProcs == null) { 17630 curProcs = new ArrayList<ProcessRecord>(); 17631 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17632 } 17633 if (!curProcs.contains(proc)) { 17634 curProcs.add(proc); 17635 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17636 proc.info.packageName, proc.info.uid); 17637 } 17638 } else { 17639 if (curProcs != null) { 17640 if (curProcs.remove(proc)) { 17641 mBatteryStatsService.noteEvent( 17642 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17643 proc.info.packageName, proc.info.uid); 17644 if (curProcs.size() <= 0) { 17645 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17646 } 17647 } 17648 } 17649 } 17650 if (oomAdj) { 17651 updateOomAdjLocked(); 17652 } 17653 } 17654 } 17655 17656 private final ActivityRecord resumedAppLocked() { 17657 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17658 String pkg; 17659 int uid; 17660 if (act != null) { 17661 pkg = act.packageName; 17662 uid = act.info.applicationInfo.uid; 17663 } else { 17664 pkg = null; 17665 uid = -1; 17666 } 17667 // Has the UID or resumed package name changed? 17668 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17669 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17670 if (mCurResumedPackage != null) { 17671 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17672 mCurResumedPackage, mCurResumedUid); 17673 } 17674 mCurResumedPackage = pkg; 17675 mCurResumedUid = uid; 17676 if (mCurResumedPackage != null) { 17677 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17678 mCurResumedPackage, mCurResumedUid); 17679 } 17680 } 17681 return act; 17682 } 17683 17684 final boolean updateOomAdjLocked(ProcessRecord app) { 17685 final ActivityRecord TOP_ACT = resumedAppLocked(); 17686 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17687 final boolean wasCached = app.cached; 17688 17689 mAdjSeq++; 17690 17691 // This is the desired cached adjusment we want to tell it to use. 17692 // If our app is currently cached, we know it, and that is it. Otherwise, 17693 // we don't know it yet, and it needs to now be cached we will then 17694 // need to do a complete oom adj. 17695 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17696 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17697 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17698 SystemClock.uptimeMillis()); 17699 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17700 // Changed to/from cached state, so apps after it in the LRU 17701 // list may also be changed. 17702 updateOomAdjLocked(); 17703 } 17704 return success; 17705 } 17706 17707 final void updateOomAdjLocked() { 17708 final ActivityRecord TOP_ACT = resumedAppLocked(); 17709 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17710 final long now = SystemClock.uptimeMillis(); 17711 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17712 final int N = mLruProcesses.size(); 17713 17714 if (false) { 17715 RuntimeException e = new RuntimeException(); 17716 e.fillInStackTrace(); 17717 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17718 } 17719 17720 mAdjSeq++; 17721 mNewNumServiceProcs = 0; 17722 mNewNumAServiceProcs = 0; 17723 17724 final int emptyProcessLimit; 17725 final int cachedProcessLimit; 17726 if (mProcessLimit <= 0) { 17727 emptyProcessLimit = cachedProcessLimit = 0; 17728 } else if (mProcessLimit == 1) { 17729 emptyProcessLimit = 1; 17730 cachedProcessLimit = 0; 17731 } else { 17732 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17733 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17734 } 17735 17736 // Let's determine how many processes we have running vs. 17737 // how many slots we have for background processes; we may want 17738 // to put multiple processes in a slot of there are enough of 17739 // them. 17740 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17741 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17742 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17743 if (numEmptyProcs > cachedProcessLimit) { 17744 // If there are more empty processes than our limit on cached 17745 // processes, then use the cached process limit for the factor. 17746 // This ensures that the really old empty processes get pushed 17747 // down to the bottom, so if we are running low on memory we will 17748 // have a better chance at keeping around more cached processes 17749 // instead of a gazillion empty processes. 17750 numEmptyProcs = cachedProcessLimit; 17751 } 17752 int emptyFactor = numEmptyProcs/numSlots; 17753 if (emptyFactor < 1) emptyFactor = 1; 17754 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17755 if (cachedFactor < 1) cachedFactor = 1; 17756 int stepCached = 0; 17757 int stepEmpty = 0; 17758 int numCached = 0; 17759 int numEmpty = 0; 17760 int numTrimming = 0; 17761 17762 mNumNonCachedProcs = 0; 17763 mNumCachedHiddenProcs = 0; 17764 17765 // First update the OOM adjustment for each of the 17766 // application processes based on their current state. 17767 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17768 int nextCachedAdj = curCachedAdj+1; 17769 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17770 int nextEmptyAdj = curEmptyAdj+2; 17771 for (int i=N-1; i>=0; i--) { 17772 ProcessRecord app = mLruProcesses.get(i); 17773 if (!app.killedByAm && app.thread != null) { 17774 app.procStateChanged = false; 17775 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17776 17777 // If we haven't yet assigned the final cached adj 17778 // to the process, do that now. 17779 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17780 switch (app.curProcState) { 17781 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17782 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17783 // This process is a cached process holding activities... 17784 // assign it the next cached value for that type, and then 17785 // step that cached level. 17786 app.curRawAdj = curCachedAdj; 17787 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17788 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17789 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17790 + ")"); 17791 if (curCachedAdj != nextCachedAdj) { 17792 stepCached++; 17793 if (stepCached >= cachedFactor) { 17794 stepCached = 0; 17795 curCachedAdj = nextCachedAdj; 17796 nextCachedAdj += 2; 17797 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17798 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17799 } 17800 } 17801 } 17802 break; 17803 default: 17804 // For everything else, assign next empty cached process 17805 // level and bump that up. Note that this means that 17806 // long-running services that have dropped down to the 17807 // cached level will be treated as empty (since their process 17808 // state is still as a service), which is what we want. 17809 app.curRawAdj = curEmptyAdj; 17810 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17811 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17812 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17813 + ")"); 17814 if (curEmptyAdj != nextEmptyAdj) { 17815 stepEmpty++; 17816 if (stepEmpty >= emptyFactor) { 17817 stepEmpty = 0; 17818 curEmptyAdj = nextEmptyAdj; 17819 nextEmptyAdj += 2; 17820 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17821 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17822 } 17823 } 17824 } 17825 break; 17826 } 17827 } 17828 17829 applyOomAdjLocked(app, TOP_APP, true, now); 17830 17831 // Count the number of process types. 17832 switch (app.curProcState) { 17833 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17834 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17835 mNumCachedHiddenProcs++; 17836 numCached++; 17837 if (numCached > cachedProcessLimit) { 17838 app.kill("cached #" + numCached, true); 17839 } 17840 break; 17841 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17842 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17843 && app.lastActivityTime < oldTime) { 17844 app.kill("empty for " 17845 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17846 / 1000) + "s", true); 17847 } else { 17848 numEmpty++; 17849 if (numEmpty > emptyProcessLimit) { 17850 app.kill("empty #" + numEmpty, true); 17851 } 17852 } 17853 break; 17854 default: 17855 mNumNonCachedProcs++; 17856 break; 17857 } 17858 17859 if (app.isolated && app.services.size() <= 0) { 17860 // If this is an isolated process, and there are no 17861 // services running in it, then the process is no longer 17862 // needed. We agressively kill these because we can by 17863 // definition not re-use the same process again, and it is 17864 // good to avoid having whatever code was running in them 17865 // left sitting around after no longer needed. 17866 app.kill("isolated not needed", true); 17867 } 17868 17869 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17870 && !app.killedByAm) { 17871 numTrimming++; 17872 } 17873 } 17874 } 17875 17876 mNumServiceProcs = mNewNumServiceProcs; 17877 17878 // Now determine the memory trimming level of background processes. 17879 // Unfortunately we need to start at the back of the list to do this 17880 // properly. We only do this if the number of background apps we 17881 // are managing to keep around is less than half the maximum we desire; 17882 // if we are keeping a good number around, we'll let them use whatever 17883 // memory they want. 17884 final int numCachedAndEmpty = numCached + numEmpty; 17885 int memFactor; 17886 if (numCached <= ProcessList.TRIM_CACHED_APPS 17887 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17888 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17889 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17890 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17891 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17892 } else { 17893 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17894 } 17895 } else { 17896 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17897 } 17898 // We always allow the memory level to go up (better). We only allow it to go 17899 // down if we are in a state where that is allowed, *and* the total number of processes 17900 // has gone down since last time. 17901 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17902 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17903 + " last=" + mLastNumProcesses); 17904 if (memFactor > mLastMemoryLevel) { 17905 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17906 memFactor = mLastMemoryLevel; 17907 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17908 } 17909 } 17910 mLastMemoryLevel = memFactor; 17911 mLastNumProcesses = mLruProcesses.size(); 17912 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17913 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17914 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17915 if (mLowRamStartTime == 0) { 17916 mLowRamStartTime = now; 17917 } 17918 int step = 0; 17919 int fgTrimLevel; 17920 switch (memFactor) { 17921 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17922 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17923 break; 17924 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17925 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17926 break; 17927 default: 17928 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17929 break; 17930 } 17931 int factor = numTrimming/3; 17932 int minFactor = 2; 17933 if (mHomeProcess != null) minFactor++; 17934 if (mPreviousProcess != null) minFactor++; 17935 if (factor < minFactor) factor = minFactor; 17936 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17937 for (int i=N-1; i>=0; i--) { 17938 ProcessRecord app = mLruProcesses.get(i); 17939 if (allChanged || app.procStateChanged) { 17940 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17941 app.procStateChanged = false; 17942 } 17943 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17944 && !app.killedByAm) { 17945 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17946 try { 17947 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17948 "Trimming memory of " + app.processName 17949 + " to " + curLevel); 17950 app.thread.scheduleTrimMemory(curLevel); 17951 } catch (RemoteException e) { 17952 } 17953 if (false) { 17954 // For now we won't do this; our memory trimming seems 17955 // to be good enough at this point that destroying 17956 // activities causes more harm than good. 17957 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17958 && app != mHomeProcess && app != mPreviousProcess) { 17959 // Need to do this on its own message because the stack may not 17960 // be in a consistent state at this point. 17961 // For these apps we will also finish their activities 17962 // to help them free memory. 17963 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17964 } 17965 } 17966 } 17967 app.trimMemoryLevel = curLevel; 17968 step++; 17969 if (step >= factor) { 17970 step = 0; 17971 switch (curLevel) { 17972 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17973 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17974 break; 17975 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17976 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17977 break; 17978 } 17979 } 17980 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17981 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17982 && app.thread != null) { 17983 try { 17984 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17985 "Trimming memory of heavy-weight " + app.processName 17986 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17987 app.thread.scheduleTrimMemory( 17988 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17989 } catch (RemoteException e) { 17990 } 17991 } 17992 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17993 } else { 17994 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17995 || app.systemNoUi) && app.pendingUiClean) { 17996 // If this application is now in the background and it 17997 // had done UI, then give it the special trim level to 17998 // have it free UI resources. 17999 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18000 if (app.trimMemoryLevel < level && app.thread != null) { 18001 try { 18002 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18003 "Trimming memory of bg-ui " + app.processName 18004 + " to " + level); 18005 app.thread.scheduleTrimMemory(level); 18006 } catch (RemoteException e) { 18007 } 18008 } 18009 app.pendingUiClean = false; 18010 } 18011 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18012 try { 18013 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18014 "Trimming memory of fg " + app.processName 18015 + " to " + fgTrimLevel); 18016 app.thread.scheduleTrimMemory(fgTrimLevel); 18017 } catch (RemoteException e) { 18018 } 18019 } 18020 app.trimMemoryLevel = fgTrimLevel; 18021 } 18022 } 18023 } else { 18024 if (mLowRamStartTime != 0) { 18025 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18026 mLowRamStartTime = 0; 18027 } 18028 for (int i=N-1; i>=0; i--) { 18029 ProcessRecord app = mLruProcesses.get(i); 18030 if (allChanged || app.procStateChanged) { 18031 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18032 app.procStateChanged = false; 18033 } 18034 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18035 || app.systemNoUi) && app.pendingUiClean) { 18036 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18037 && app.thread != null) { 18038 try { 18039 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18040 "Trimming memory of ui hidden " + app.processName 18041 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18042 app.thread.scheduleTrimMemory( 18043 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18044 } catch (RemoteException e) { 18045 } 18046 } 18047 app.pendingUiClean = false; 18048 } 18049 app.trimMemoryLevel = 0; 18050 } 18051 } 18052 18053 if (mAlwaysFinishActivities) { 18054 // Need to do this on its own message because the stack may not 18055 // be in a consistent state at this point. 18056 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18057 } 18058 18059 if (allChanged) { 18060 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18061 } 18062 18063 if (mProcessStats.shouldWriteNowLocked(now)) { 18064 mHandler.post(new Runnable() { 18065 @Override public void run() { 18066 synchronized (ActivityManagerService.this) { 18067 mProcessStats.writeStateAsyncLocked(); 18068 } 18069 } 18070 }); 18071 } 18072 18073 if (DEBUG_OOM_ADJ) { 18074 if (false) { 18075 RuntimeException here = new RuntimeException("here"); 18076 here.fillInStackTrace(); 18077 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18078 } else { 18079 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18080 } 18081 } 18082 } 18083 18084 final void trimApplications() { 18085 synchronized (this) { 18086 int i; 18087 18088 // First remove any unused application processes whose package 18089 // has been removed. 18090 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18091 final ProcessRecord app = mRemovedProcesses.get(i); 18092 if (app.activities.size() == 0 18093 && app.curReceiver == null && app.services.size() == 0) { 18094 Slog.i( 18095 TAG, "Exiting empty application process " 18096 + app.processName + " (" 18097 + (app.thread != null ? app.thread.asBinder() : null) 18098 + ")\n"); 18099 if (app.pid > 0 && app.pid != MY_PID) { 18100 app.kill("empty", false); 18101 } else { 18102 try { 18103 app.thread.scheduleExit(); 18104 } catch (Exception e) { 18105 // Ignore exceptions. 18106 } 18107 } 18108 cleanUpApplicationRecordLocked(app, false, true, -1); 18109 mRemovedProcesses.remove(i); 18110 18111 if (app.persistent) { 18112 addAppLocked(app.info, false, null /* ABI override */); 18113 } 18114 } 18115 } 18116 18117 // Now update the oom adj for all processes. 18118 updateOomAdjLocked(); 18119 } 18120 } 18121 18122 /** This method sends the specified signal to each of the persistent apps */ 18123 public void signalPersistentProcesses(int sig) throws RemoteException { 18124 if (sig != Process.SIGNAL_USR1) { 18125 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18126 } 18127 18128 synchronized (this) { 18129 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18130 != PackageManager.PERMISSION_GRANTED) { 18131 throw new SecurityException("Requires permission " 18132 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18133 } 18134 18135 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18136 ProcessRecord r = mLruProcesses.get(i); 18137 if (r.thread != null && r.persistent) { 18138 Process.sendSignal(r.pid, sig); 18139 } 18140 } 18141 } 18142 } 18143 18144 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18145 if (proc == null || proc == mProfileProc) { 18146 proc = mProfileProc; 18147 profileType = mProfileType; 18148 clearProfilerLocked(); 18149 } 18150 if (proc == null) { 18151 return; 18152 } 18153 try { 18154 proc.thread.profilerControl(false, null, profileType); 18155 } catch (RemoteException e) { 18156 throw new IllegalStateException("Process disappeared"); 18157 } 18158 } 18159 18160 private void clearProfilerLocked() { 18161 if (mProfileFd != null) { 18162 try { 18163 mProfileFd.close(); 18164 } catch (IOException e) { 18165 } 18166 } 18167 mProfileApp = null; 18168 mProfileProc = null; 18169 mProfileFile = null; 18170 mProfileType = 0; 18171 mAutoStopProfiler = false; 18172 mSamplingInterval = 0; 18173 } 18174 18175 public boolean profileControl(String process, int userId, boolean start, 18176 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18177 18178 try { 18179 synchronized (this) { 18180 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18181 // its own permission. 18182 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18183 != PackageManager.PERMISSION_GRANTED) { 18184 throw new SecurityException("Requires permission " 18185 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18186 } 18187 18188 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18189 throw new IllegalArgumentException("null profile info or fd"); 18190 } 18191 18192 ProcessRecord proc = null; 18193 if (process != null) { 18194 proc = findProcessLocked(process, userId, "profileControl"); 18195 } 18196 18197 if (start && (proc == null || proc.thread == null)) { 18198 throw new IllegalArgumentException("Unknown process: " + process); 18199 } 18200 18201 if (start) { 18202 stopProfilerLocked(null, 0); 18203 setProfileApp(proc.info, proc.processName, profilerInfo); 18204 mProfileProc = proc; 18205 mProfileType = profileType; 18206 ParcelFileDescriptor fd = profilerInfo.profileFd; 18207 try { 18208 fd = fd.dup(); 18209 } catch (IOException e) { 18210 fd = null; 18211 } 18212 profilerInfo.profileFd = fd; 18213 proc.thread.profilerControl(start, profilerInfo, profileType); 18214 fd = null; 18215 mProfileFd = null; 18216 } else { 18217 stopProfilerLocked(proc, profileType); 18218 if (profilerInfo != null && profilerInfo.profileFd != null) { 18219 try { 18220 profilerInfo.profileFd.close(); 18221 } catch (IOException e) { 18222 } 18223 } 18224 } 18225 18226 return true; 18227 } 18228 } catch (RemoteException e) { 18229 throw new IllegalStateException("Process disappeared"); 18230 } finally { 18231 if (profilerInfo != null && profilerInfo.profileFd != null) { 18232 try { 18233 profilerInfo.profileFd.close(); 18234 } catch (IOException e) { 18235 } 18236 } 18237 } 18238 } 18239 18240 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18241 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18242 userId, true, ALLOW_FULL_ONLY, callName, null); 18243 ProcessRecord proc = null; 18244 try { 18245 int pid = Integer.parseInt(process); 18246 synchronized (mPidsSelfLocked) { 18247 proc = mPidsSelfLocked.get(pid); 18248 } 18249 } catch (NumberFormatException e) { 18250 } 18251 18252 if (proc == null) { 18253 ArrayMap<String, SparseArray<ProcessRecord>> all 18254 = mProcessNames.getMap(); 18255 SparseArray<ProcessRecord> procs = all.get(process); 18256 if (procs != null && procs.size() > 0) { 18257 proc = procs.valueAt(0); 18258 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18259 for (int i=1; i<procs.size(); i++) { 18260 ProcessRecord thisProc = procs.valueAt(i); 18261 if (thisProc.userId == userId) { 18262 proc = thisProc; 18263 break; 18264 } 18265 } 18266 } 18267 } 18268 } 18269 18270 return proc; 18271 } 18272 18273 public boolean dumpHeap(String process, int userId, boolean managed, 18274 String path, ParcelFileDescriptor fd) throws RemoteException { 18275 18276 try { 18277 synchronized (this) { 18278 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18279 // its own permission (same as profileControl). 18280 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18281 != PackageManager.PERMISSION_GRANTED) { 18282 throw new SecurityException("Requires permission " 18283 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18284 } 18285 18286 if (fd == null) { 18287 throw new IllegalArgumentException("null fd"); 18288 } 18289 18290 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18291 if (proc == null || proc.thread == null) { 18292 throw new IllegalArgumentException("Unknown process: " + process); 18293 } 18294 18295 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18296 if (!isDebuggable) { 18297 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18298 throw new SecurityException("Process not debuggable: " + proc); 18299 } 18300 } 18301 18302 proc.thread.dumpHeap(managed, path, fd); 18303 fd = null; 18304 return true; 18305 } 18306 } catch (RemoteException e) { 18307 throw new IllegalStateException("Process disappeared"); 18308 } finally { 18309 if (fd != null) { 18310 try { 18311 fd.close(); 18312 } catch (IOException e) { 18313 } 18314 } 18315 } 18316 } 18317 18318 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18319 public void monitor() { 18320 synchronized (this) { } 18321 } 18322 18323 void onCoreSettingsChange(Bundle settings) { 18324 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18325 ProcessRecord processRecord = mLruProcesses.get(i); 18326 try { 18327 if (processRecord.thread != null) { 18328 processRecord.thread.setCoreSettings(settings); 18329 } 18330 } catch (RemoteException re) { 18331 /* ignore */ 18332 } 18333 } 18334 } 18335 18336 // Multi-user methods 18337 18338 /** 18339 * Start user, if its not already running, but don't bring it to foreground. 18340 */ 18341 @Override 18342 public boolean startUserInBackground(final int userId) { 18343 return startUser(userId, /* foreground */ false); 18344 } 18345 18346 /** 18347 * Start user, if its not already running, and bring it to foreground. 18348 */ 18349 boolean startUserInForeground(final int userId, Dialog dlg) { 18350 boolean result = startUser(userId, /* foreground */ true); 18351 dlg.dismiss(); 18352 return result; 18353 } 18354 18355 /** 18356 * Refreshes the list of users related to the current user when either a 18357 * user switch happens or when a new related user is started in the 18358 * background. 18359 */ 18360 private void updateCurrentProfileIdsLocked() { 18361 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18362 mCurrentUserId, false /* enabledOnly */); 18363 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18364 for (int i = 0; i < currentProfileIds.length; i++) { 18365 currentProfileIds[i] = profiles.get(i).id; 18366 } 18367 mCurrentProfileIds = currentProfileIds; 18368 18369 synchronized (mUserProfileGroupIdsSelfLocked) { 18370 mUserProfileGroupIdsSelfLocked.clear(); 18371 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18372 for (int i = 0; i < users.size(); i++) { 18373 UserInfo user = users.get(i); 18374 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18375 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18376 } 18377 } 18378 } 18379 } 18380 18381 private Set getProfileIdsLocked(int userId) { 18382 Set userIds = new HashSet<Integer>(); 18383 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18384 userId, false /* enabledOnly */); 18385 for (UserInfo user : profiles) { 18386 userIds.add(Integer.valueOf(user.id)); 18387 } 18388 return userIds; 18389 } 18390 18391 @Override 18392 public boolean switchUser(final int userId) { 18393 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18394 String userName; 18395 synchronized (this) { 18396 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18397 if (userInfo == null) { 18398 Slog.w(TAG, "No user info for user #" + userId); 18399 return false; 18400 } 18401 if (userInfo.isManagedProfile()) { 18402 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18403 return false; 18404 } 18405 userName = userInfo.name; 18406 mTargetUserId = userId; 18407 } 18408 mHandler.removeMessages(START_USER_SWITCH_MSG); 18409 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18410 return true; 18411 } 18412 18413 private void showUserSwitchDialog(int userId, String userName) { 18414 // The dialog will show and then initiate the user switch by calling startUserInForeground 18415 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18416 true /* above system */); 18417 d.show(); 18418 } 18419 18420 private boolean startUser(final int userId, final boolean foreground) { 18421 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18422 != PackageManager.PERMISSION_GRANTED) { 18423 String msg = "Permission Denial: switchUser() from pid=" 18424 + Binder.getCallingPid() 18425 + ", uid=" + Binder.getCallingUid() 18426 + " requires " + INTERACT_ACROSS_USERS_FULL; 18427 Slog.w(TAG, msg); 18428 throw new SecurityException(msg); 18429 } 18430 18431 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18432 18433 final long ident = Binder.clearCallingIdentity(); 18434 try { 18435 synchronized (this) { 18436 final int oldUserId = mCurrentUserId; 18437 if (oldUserId == userId) { 18438 return true; 18439 } 18440 18441 mStackSupervisor.setLockTaskModeLocked(null, false); 18442 18443 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18444 if (userInfo == null) { 18445 Slog.w(TAG, "No user info for user #" + userId); 18446 return false; 18447 } 18448 if (foreground && userInfo.isManagedProfile()) { 18449 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18450 return false; 18451 } 18452 18453 if (foreground) { 18454 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18455 R.anim.screen_user_enter); 18456 } 18457 18458 boolean needStart = false; 18459 18460 // If the user we are switching to is not currently started, then 18461 // we need to start it now. 18462 if (mStartedUsers.get(userId) == null) { 18463 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18464 updateStartedUserArrayLocked(); 18465 needStart = true; 18466 } 18467 18468 final Integer userIdInt = Integer.valueOf(userId); 18469 mUserLru.remove(userIdInt); 18470 mUserLru.add(userIdInt); 18471 18472 if (foreground) { 18473 mCurrentUserId = userId; 18474 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18475 updateCurrentProfileIdsLocked(); 18476 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18477 // Once the internal notion of the active user has switched, we lock the device 18478 // with the option to show the user switcher on the keyguard. 18479 mWindowManager.lockNow(null); 18480 } else { 18481 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18482 updateCurrentProfileIdsLocked(); 18483 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18484 mUserLru.remove(currentUserIdInt); 18485 mUserLru.add(currentUserIdInt); 18486 } 18487 18488 final UserStartedState uss = mStartedUsers.get(userId); 18489 18490 // Make sure user is in the started state. If it is currently 18491 // stopping, we need to knock that off. 18492 if (uss.mState == UserStartedState.STATE_STOPPING) { 18493 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18494 // so we can just fairly silently bring the user back from 18495 // the almost-dead. 18496 uss.mState = UserStartedState.STATE_RUNNING; 18497 updateStartedUserArrayLocked(); 18498 needStart = true; 18499 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18500 // This means ACTION_SHUTDOWN has been sent, so we will 18501 // need to treat this as a new boot of the user. 18502 uss.mState = UserStartedState.STATE_BOOTING; 18503 updateStartedUserArrayLocked(); 18504 needStart = true; 18505 } 18506 18507 if (uss.mState == UserStartedState.STATE_BOOTING) { 18508 // Booting up a new user, need to tell system services about it. 18509 // Note that this is on the same handler as scheduling of broadcasts, 18510 // which is important because it needs to go first. 18511 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18512 } 18513 18514 if (foreground) { 18515 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18516 oldUserId)); 18517 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18518 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18519 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18520 oldUserId, userId, uss)); 18521 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18522 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18523 } 18524 18525 if (needStart) { 18526 // Send USER_STARTED broadcast 18527 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18528 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18529 | Intent.FLAG_RECEIVER_FOREGROUND); 18530 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18531 broadcastIntentLocked(null, null, intent, 18532 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18533 false, false, MY_PID, Process.SYSTEM_UID, userId); 18534 } 18535 18536 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18537 if (userId != UserHandle.USER_OWNER) { 18538 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18539 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18540 broadcastIntentLocked(null, null, intent, null, 18541 new IIntentReceiver.Stub() { 18542 public void performReceive(Intent intent, int resultCode, 18543 String data, Bundle extras, boolean ordered, 18544 boolean sticky, int sendingUser) { 18545 onUserInitialized(uss, foreground, oldUserId, userId); 18546 } 18547 }, 0, null, null, null, AppOpsManager.OP_NONE, 18548 true, false, MY_PID, Process.SYSTEM_UID, 18549 userId); 18550 uss.initializing = true; 18551 } else { 18552 getUserManagerLocked().makeInitialized(userInfo.id); 18553 } 18554 } 18555 18556 if (foreground) { 18557 if (!uss.initializing) { 18558 moveUserToForeground(uss, oldUserId, userId); 18559 } 18560 } else { 18561 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18562 } 18563 18564 if (needStart) { 18565 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18567 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18568 broadcastIntentLocked(null, null, intent, 18569 null, new IIntentReceiver.Stub() { 18570 @Override 18571 public void performReceive(Intent intent, int resultCode, String data, 18572 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18573 throws RemoteException { 18574 } 18575 }, 0, null, null, 18576 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18577 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18578 } 18579 } 18580 } finally { 18581 Binder.restoreCallingIdentity(ident); 18582 } 18583 18584 return true; 18585 } 18586 18587 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18588 long ident = Binder.clearCallingIdentity(); 18589 try { 18590 Intent intent; 18591 if (oldUserId >= 0) { 18592 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18593 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18594 int count = profiles.size(); 18595 for (int i = 0; i < count; i++) { 18596 int profileUserId = profiles.get(i).id; 18597 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18598 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18599 | Intent.FLAG_RECEIVER_FOREGROUND); 18600 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18601 broadcastIntentLocked(null, null, intent, 18602 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18603 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18604 } 18605 } 18606 if (newUserId >= 0) { 18607 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18608 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18609 int count = profiles.size(); 18610 for (int i = 0; i < count; i++) { 18611 int profileUserId = profiles.get(i).id; 18612 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18614 | Intent.FLAG_RECEIVER_FOREGROUND); 18615 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18616 broadcastIntentLocked(null, null, intent, 18617 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18618 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18619 } 18620 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18621 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18622 | Intent.FLAG_RECEIVER_FOREGROUND); 18623 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18624 broadcastIntentLocked(null, null, intent, 18625 null, null, 0, null, null, 18626 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18627 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18628 } 18629 } finally { 18630 Binder.restoreCallingIdentity(ident); 18631 } 18632 } 18633 18634 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18635 final int newUserId) { 18636 final int N = mUserSwitchObservers.beginBroadcast(); 18637 if (N > 0) { 18638 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18639 int mCount = 0; 18640 @Override 18641 public void sendResult(Bundle data) throws RemoteException { 18642 synchronized (ActivityManagerService.this) { 18643 if (mCurUserSwitchCallback == this) { 18644 mCount++; 18645 if (mCount == N) { 18646 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18647 } 18648 } 18649 } 18650 } 18651 }; 18652 synchronized (this) { 18653 uss.switching = true; 18654 mCurUserSwitchCallback = callback; 18655 } 18656 for (int i=0; i<N; i++) { 18657 try { 18658 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18659 newUserId, callback); 18660 } catch (RemoteException e) { 18661 } 18662 } 18663 } else { 18664 synchronized (this) { 18665 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18666 } 18667 } 18668 mUserSwitchObservers.finishBroadcast(); 18669 } 18670 18671 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18672 synchronized (this) { 18673 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18674 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18675 } 18676 } 18677 18678 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18679 mCurUserSwitchCallback = null; 18680 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18681 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18682 oldUserId, newUserId, uss)); 18683 } 18684 18685 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18686 synchronized (this) { 18687 if (foreground) { 18688 moveUserToForeground(uss, oldUserId, newUserId); 18689 } 18690 } 18691 18692 completeSwitchAndInitalize(uss, newUserId, true, false); 18693 } 18694 18695 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18696 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18697 if (homeInFront) { 18698 startHomeActivityLocked(newUserId); 18699 } else { 18700 mStackSupervisor.resumeTopActivitiesLocked(); 18701 } 18702 EventLogTags.writeAmSwitchUser(newUserId); 18703 getUserManagerLocked().userForeground(newUserId); 18704 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18705 } 18706 18707 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18708 completeSwitchAndInitalize(uss, newUserId, false, true); 18709 } 18710 18711 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18712 boolean clearInitializing, boolean clearSwitching) { 18713 boolean unfrozen = false; 18714 synchronized (this) { 18715 if (clearInitializing) { 18716 uss.initializing = false; 18717 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18718 } 18719 if (clearSwitching) { 18720 uss.switching = false; 18721 } 18722 if (!uss.switching && !uss.initializing) { 18723 mWindowManager.stopFreezingScreen(); 18724 unfrozen = true; 18725 } 18726 } 18727 if (unfrozen) { 18728 final int N = mUserSwitchObservers.beginBroadcast(); 18729 for (int i=0; i<N; i++) { 18730 try { 18731 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18732 } catch (RemoteException e) { 18733 } 18734 } 18735 mUserSwitchObservers.finishBroadcast(); 18736 } 18737 } 18738 18739 void scheduleStartProfilesLocked() { 18740 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18741 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18742 DateUtils.SECOND_IN_MILLIS); 18743 } 18744 } 18745 18746 void startProfilesLocked() { 18747 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18748 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18749 mCurrentUserId, false /* enabledOnly */); 18750 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18751 for (UserInfo user : profiles) { 18752 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18753 && user.id != mCurrentUserId) { 18754 toStart.add(user); 18755 } 18756 } 18757 final int n = toStart.size(); 18758 int i = 0; 18759 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18760 startUserInBackground(toStart.get(i).id); 18761 } 18762 if (i < n) { 18763 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18764 } 18765 } 18766 18767 void finishUserBoot(UserStartedState uss) { 18768 synchronized (this) { 18769 if (uss.mState == UserStartedState.STATE_BOOTING 18770 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18771 uss.mState = UserStartedState.STATE_RUNNING; 18772 final int userId = uss.mHandle.getIdentifier(); 18773 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18774 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18775 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18776 broadcastIntentLocked(null, null, intent, 18777 null, null, 0, null, null, 18778 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18779 true, false, MY_PID, Process.SYSTEM_UID, userId); 18780 } 18781 } 18782 } 18783 18784 void finishUserSwitch(UserStartedState uss) { 18785 synchronized (this) { 18786 finishUserBoot(uss); 18787 18788 startProfilesLocked(); 18789 18790 int num = mUserLru.size(); 18791 int i = 0; 18792 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18793 Integer oldUserId = mUserLru.get(i); 18794 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18795 if (oldUss == null) { 18796 // Shouldn't happen, but be sane if it does. 18797 mUserLru.remove(i); 18798 num--; 18799 continue; 18800 } 18801 if (oldUss.mState == UserStartedState.STATE_STOPPING 18802 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18803 // This user is already stopping, doesn't count. 18804 num--; 18805 i++; 18806 continue; 18807 } 18808 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18809 // Owner and current can't be stopped, but count as running. 18810 i++; 18811 continue; 18812 } 18813 // This is a user to be stopped. 18814 stopUserLocked(oldUserId, null); 18815 num--; 18816 i++; 18817 } 18818 } 18819 } 18820 18821 @Override 18822 public int stopUser(final int userId, final IStopUserCallback callback) { 18823 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18824 != PackageManager.PERMISSION_GRANTED) { 18825 String msg = "Permission Denial: switchUser() from pid=" 18826 + Binder.getCallingPid() 18827 + ", uid=" + Binder.getCallingUid() 18828 + " requires " + INTERACT_ACROSS_USERS_FULL; 18829 Slog.w(TAG, msg); 18830 throw new SecurityException(msg); 18831 } 18832 if (userId <= 0) { 18833 throw new IllegalArgumentException("Can't stop primary user " + userId); 18834 } 18835 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18836 synchronized (this) { 18837 return stopUserLocked(userId, callback); 18838 } 18839 } 18840 18841 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18842 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18843 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18844 return ActivityManager.USER_OP_IS_CURRENT; 18845 } 18846 18847 final UserStartedState uss = mStartedUsers.get(userId); 18848 if (uss == null) { 18849 // User is not started, nothing to do... but we do need to 18850 // callback if requested. 18851 if (callback != null) { 18852 mHandler.post(new Runnable() { 18853 @Override 18854 public void run() { 18855 try { 18856 callback.userStopped(userId); 18857 } catch (RemoteException e) { 18858 } 18859 } 18860 }); 18861 } 18862 return ActivityManager.USER_OP_SUCCESS; 18863 } 18864 18865 if (callback != null) { 18866 uss.mStopCallbacks.add(callback); 18867 } 18868 18869 if (uss.mState != UserStartedState.STATE_STOPPING 18870 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18871 uss.mState = UserStartedState.STATE_STOPPING; 18872 updateStartedUserArrayLocked(); 18873 18874 long ident = Binder.clearCallingIdentity(); 18875 try { 18876 // We are going to broadcast ACTION_USER_STOPPING and then 18877 // once that is done send a final ACTION_SHUTDOWN and then 18878 // stop the user. 18879 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18880 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18881 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18882 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18883 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18884 // This is the result receiver for the final shutdown broadcast. 18885 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18886 @Override 18887 public void performReceive(Intent intent, int resultCode, String data, 18888 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18889 finishUserStop(uss); 18890 } 18891 }; 18892 // This is the result receiver for the initial stopping broadcast. 18893 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18894 @Override 18895 public void performReceive(Intent intent, int resultCode, String data, 18896 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18897 // On to the next. 18898 synchronized (ActivityManagerService.this) { 18899 if (uss.mState != UserStartedState.STATE_STOPPING) { 18900 // Whoops, we are being started back up. Abort, abort! 18901 return; 18902 } 18903 uss.mState = UserStartedState.STATE_SHUTDOWN; 18904 } 18905 mBatteryStatsService.noteEvent( 18906 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18907 Integer.toString(userId), userId); 18908 mSystemServiceManager.stopUser(userId); 18909 broadcastIntentLocked(null, null, shutdownIntent, 18910 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18911 true, false, MY_PID, Process.SYSTEM_UID, userId); 18912 } 18913 }; 18914 // Kick things off. 18915 broadcastIntentLocked(null, null, stoppingIntent, 18916 null, stoppingReceiver, 0, null, null, 18917 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18918 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18919 } finally { 18920 Binder.restoreCallingIdentity(ident); 18921 } 18922 } 18923 18924 return ActivityManager.USER_OP_SUCCESS; 18925 } 18926 18927 void finishUserStop(UserStartedState uss) { 18928 final int userId = uss.mHandle.getIdentifier(); 18929 boolean stopped; 18930 ArrayList<IStopUserCallback> callbacks; 18931 synchronized (this) { 18932 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18933 if (mStartedUsers.get(userId) != uss) { 18934 stopped = false; 18935 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18936 stopped = false; 18937 } else { 18938 stopped = true; 18939 // User can no longer run. 18940 mStartedUsers.remove(userId); 18941 mUserLru.remove(Integer.valueOf(userId)); 18942 updateStartedUserArrayLocked(); 18943 18944 // Clean up all state and processes associated with the user. 18945 // Kill all the processes for the user. 18946 forceStopUserLocked(userId, "finish user"); 18947 } 18948 18949 // Explicitly remove the old information in mRecentTasks. 18950 removeRecentTasksForUserLocked(userId); 18951 } 18952 18953 for (int i=0; i<callbacks.size(); i++) { 18954 try { 18955 if (stopped) callbacks.get(i).userStopped(userId); 18956 else callbacks.get(i).userStopAborted(userId); 18957 } catch (RemoteException e) { 18958 } 18959 } 18960 18961 if (stopped) { 18962 mSystemServiceManager.cleanupUser(userId); 18963 synchronized (this) { 18964 mStackSupervisor.removeUserLocked(userId); 18965 } 18966 } 18967 } 18968 18969 @Override 18970 public UserInfo getCurrentUser() { 18971 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18972 != PackageManager.PERMISSION_GRANTED) && ( 18973 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18974 != PackageManager.PERMISSION_GRANTED)) { 18975 String msg = "Permission Denial: getCurrentUser() from pid=" 18976 + Binder.getCallingPid() 18977 + ", uid=" + Binder.getCallingUid() 18978 + " requires " + INTERACT_ACROSS_USERS; 18979 Slog.w(TAG, msg); 18980 throw new SecurityException(msg); 18981 } 18982 synchronized (this) { 18983 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18984 return getUserManagerLocked().getUserInfo(userId); 18985 } 18986 } 18987 18988 int getCurrentUserIdLocked() { 18989 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18990 } 18991 18992 @Override 18993 public boolean isUserRunning(int userId, boolean orStopped) { 18994 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18995 != PackageManager.PERMISSION_GRANTED) { 18996 String msg = "Permission Denial: isUserRunning() from pid=" 18997 + Binder.getCallingPid() 18998 + ", uid=" + Binder.getCallingUid() 18999 + " requires " + INTERACT_ACROSS_USERS; 19000 Slog.w(TAG, msg); 19001 throw new SecurityException(msg); 19002 } 19003 synchronized (this) { 19004 return isUserRunningLocked(userId, orStopped); 19005 } 19006 } 19007 19008 boolean isUserRunningLocked(int userId, boolean orStopped) { 19009 UserStartedState state = mStartedUsers.get(userId); 19010 if (state == null) { 19011 return false; 19012 } 19013 if (orStopped) { 19014 return true; 19015 } 19016 return state.mState != UserStartedState.STATE_STOPPING 19017 && state.mState != UserStartedState.STATE_SHUTDOWN; 19018 } 19019 19020 @Override 19021 public int[] getRunningUserIds() { 19022 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19023 != PackageManager.PERMISSION_GRANTED) { 19024 String msg = "Permission Denial: isUserRunning() from pid=" 19025 + Binder.getCallingPid() 19026 + ", uid=" + Binder.getCallingUid() 19027 + " requires " + INTERACT_ACROSS_USERS; 19028 Slog.w(TAG, msg); 19029 throw new SecurityException(msg); 19030 } 19031 synchronized (this) { 19032 return mStartedUserArray; 19033 } 19034 } 19035 19036 private void updateStartedUserArrayLocked() { 19037 int num = 0; 19038 for (int i=0; i<mStartedUsers.size(); i++) { 19039 UserStartedState uss = mStartedUsers.valueAt(i); 19040 // This list does not include stopping users. 19041 if (uss.mState != UserStartedState.STATE_STOPPING 19042 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19043 num++; 19044 } 19045 } 19046 mStartedUserArray = new int[num]; 19047 num = 0; 19048 for (int i=0; i<mStartedUsers.size(); i++) { 19049 UserStartedState uss = mStartedUsers.valueAt(i); 19050 if (uss.mState != UserStartedState.STATE_STOPPING 19051 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19052 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19053 num++; 19054 } 19055 } 19056 } 19057 19058 @Override 19059 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19060 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19061 != PackageManager.PERMISSION_GRANTED) { 19062 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19063 + Binder.getCallingPid() 19064 + ", uid=" + Binder.getCallingUid() 19065 + " requires " + INTERACT_ACROSS_USERS_FULL; 19066 Slog.w(TAG, msg); 19067 throw new SecurityException(msg); 19068 } 19069 19070 mUserSwitchObservers.register(observer); 19071 } 19072 19073 @Override 19074 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19075 mUserSwitchObservers.unregister(observer); 19076 } 19077 19078 private boolean userExists(int userId) { 19079 if (userId == 0) { 19080 return true; 19081 } 19082 UserManagerService ums = getUserManagerLocked(); 19083 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19084 } 19085 19086 int[] getUsersLocked() { 19087 UserManagerService ums = getUserManagerLocked(); 19088 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19089 } 19090 19091 UserManagerService getUserManagerLocked() { 19092 if (mUserManager == null) { 19093 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19094 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19095 } 19096 return mUserManager; 19097 } 19098 19099 private int applyUserId(int uid, int userId) { 19100 return UserHandle.getUid(userId, uid); 19101 } 19102 19103 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19104 if (info == null) return null; 19105 ApplicationInfo newInfo = new ApplicationInfo(info); 19106 newInfo.uid = applyUserId(info.uid, userId); 19107 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19108 + info.packageName; 19109 return newInfo; 19110 } 19111 19112 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19113 if (aInfo == null 19114 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19115 return aInfo; 19116 } 19117 19118 ActivityInfo info = new ActivityInfo(aInfo); 19119 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19120 return info; 19121 } 19122 19123 private final class LocalService extends ActivityManagerInternal { 19124 @Override 19125 public void goingToSleep() { 19126 ActivityManagerService.this.goingToSleep(); 19127 } 19128 19129 @Override 19130 public void wakingUp() { 19131 ActivityManagerService.this.wakingUp(); 19132 } 19133 19134 @Override 19135 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19136 String processName, String abiOverride, int uid, Runnable crashHandler) { 19137 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19138 processName, abiOverride, uid, crashHandler); 19139 } 19140 } 19141 19142 /** 19143 * An implementation of IAppTask, that allows an app to manage its own tasks via 19144 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19145 * only the process that calls getAppTasks() can call the AppTask methods. 19146 */ 19147 class AppTaskImpl extends IAppTask.Stub { 19148 private int mTaskId; 19149 private int mCallingUid; 19150 19151 public AppTaskImpl(int taskId, int callingUid) { 19152 mTaskId = taskId; 19153 mCallingUid = callingUid; 19154 } 19155 19156 private void checkCaller() { 19157 if (mCallingUid != Binder.getCallingUid()) { 19158 throw new SecurityException("Caller " + mCallingUid 19159 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19160 } 19161 } 19162 19163 @Override 19164 public void finishAndRemoveTask() { 19165 checkCaller(); 19166 19167 synchronized (ActivityManagerService.this) { 19168 long origId = Binder.clearCallingIdentity(); 19169 try { 19170 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19171 if (tr == null) { 19172 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19173 } 19174 // Only kill the process if we are not a new document 19175 int flags = tr.getBaseIntent().getFlags(); 19176 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19177 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19178 removeTaskByIdLocked(mTaskId, 19179 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19180 } finally { 19181 Binder.restoreCallingIdentity(origId); 19182 } 19183 } 19184 } 19185 19186 @Override 19187 public ActivityManager.RecentTaskInfo getTaskInfo() { 19188 checkCaller(); 19189 19190 synchronized (ActivityManagerService.this) { 19191 long origId = Binder.clearCallingIdentity(); 19192 try { 19193 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19194 if (tr == null) { 19195 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19196 } 19197 return createRecentTaskInfoFromTaskRecord(tr); 19198 } finally { 19199 Binder.restoreCallingIdentity(origId); 19200 } 19201 } 19202 } 19203 19204 @Override 19205 public void moveToFront() { 19206 checkCaller(); 19207 19208 final TaskRecord tr; 19209 synchronized (ActivityManagerService.this) { 19210 tr = recentTaskForIdLocked(mTaskId); 19211 if (tr == null) { 19212 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19213 } 19214 if (tr.getRootActivity() != null) { 19215 moveTaskToFrontLocked(tr.taskId, 0, null); 19216 return; 19217 } 19218 } 19219 19220 startActivityFromRecentsInner(tr.taskId, null); 19221 } 19222 19223 @Override 19224 public int startActivity(IBinder whoThread, String callingPackage, 19225 Intent intent, String resolvedType, Bundle options) { 19226 checkCaller(); 19227 19228 int callingUser = UserHandle.getCallingUserId(); 19229 TaskRecord tr; 19230 IApplicationThread appThread; 19231 synchronized (ActivityManagerService.this) { 19232 tr = recentTaskForIdLocked(mTaskId); 19233 if (tr == null) { 19234 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19235 } 19236 appThread = ApplicationThreadNative.asInterface(whoThread); 19237 if (appThread == null) { 19238 throw new IllegalArgumentException("Bad app thread " + appThread); 19239 } 19240 } 19241 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19242 resolvedType, null, null, null, null, 0, 0, null, null, 19243 null, options, callingUser, null, tr); 19244 } 19245 19246 @Override 19247 public void setExcludeFromRecents(boolean exclude) { 19248 checkCaller(); 19249 19250 synchronized (ActivityManagerService.this) { 19251 long origId = Binder.clearCallingIdentity(); 19252 try { 19253 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19254 if (tr == null) { 19255 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19256 } 19257 Intent intent = tr.getBaseIntent(); 19258 if (exclude) { 19259 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19260 } else { 19261 intent.setFlags(intent.getFlags() 19262 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19263 } 19264 } finally { 19265 Binder.restoreCallingIdentity(origId); 19266 } 19267 } 19268 } 19269 } 19270} 19271