ActivityManagerService.java revision 6b0ed64fb868e64684031558cbdeedcd94d40713
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.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199import dalvik.system.VMRuntime; 200 201import java.io.BufferedInputStream; 202import java.io.BufferedOutputStream; 203import java.io.DataInputStream; 204import java.io.DataOutputStream; 205import java.io.File; 206import java.io.FileDescriptor; 207import java.io.FileInputStream; 208import java.io.FileNotFoundException; 209import java.io.FileOutputStream; 210import java.io.IOException; 211import java.io.InputStreamReader; 212import java.io.PrintWriter; 213import java.io.StringWriter; 214import java.lang.ref.WeakReference; 215import java.util.ArrayList; 216import java.util.Arrays; 217import java.util.Collections; 218import java.util.Comparator; 219import java.util.HashMap; 220import java.util.HashSet; 221import java.util.Iterator; 222import java.util.List; 223import java.util.Locale; 224import java.util.Map; 225import java.util.Set; 226import java.util.concurrent.atomic.AtomicBoolean; 227import java.util.concurrent.atomic.AtomicLong; 228 229public final class ActivityManagerService extends ActivityManagerNative 230 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 231 232 private static final String USER_DATA_DIR = "/data/user/"; 233 // File that stores last updated system version and called preboot receivers 234 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 235 236 static final String TAG = "ActivityManager"; 237 static final String TAG_MU = "ActivityManagerServiceMU"; 238 static final boolean DEBUG = false; 239 static final boolean localLOGV = DEBUG; 240 static final boolean DEBUG_BACKUP = localLOGV || false; 241 static final boolean DEBUG_BROADCAST = localLOGV || false; 242 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_CLEANUP = localLOGV || false; 245 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 246 static final boolean DEBUG_FOCUS = false; 247 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 248 static final boolean DEBUG_MU = localLOGV || false; 249 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 250 static final boolean DEBUG_LRU = localLOGV || false; 251 static final boolean DEBUG_PAUSE = localLOGV || false; 252 static final boolean DEBUG_POWER = localLOGV || false; 253 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 254 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 255 static final boolean DEBUG_PROCESSES = localLOGV || false; 256 static final boolean DEBUG_PROVIDER = localLOGV || false; 257 static final boolean DEBUG_RESULTS = localLOGV || false; 258 static final boolean DEBUG_SERVICE = localLOGV || false; 259 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 260 static final boolean DEBUG_STACK = localLOGV || false; 261 static final boolean DEBUG_SWITCH = localLOGV || false; 262 static final boolean DEBUG_TASKS = localLOGV || false; 263 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 264 static final boolean DEBUG_TRANSITION = localLOGV || false; 265 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 266 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 267 static final boolean DEBUG_VISBILITY = localLOGV || false; 268 static final boolean DEBUG_PSS = localLOGV || false; 269 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 270 static final boolean DEBUG_RECENTS = localLOGV || false; 271 static final boolean VALIDATE_TOKENS = false; 272 static final boolean SHOW_ACTIVITY_START_TIME = true; 273 274 // Control over CPU and battery monitoring. 275 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 276 static final boolean MONITOR_CPU_USAGE = true; 277 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 278 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 279 static final boolean MONITOR_THREAD_CPU_USAGE = false; 280 281 // The flags that are set for all calls we make to the package manager. 282 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 283 284 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 285 286 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mWaitingUpdate = false; 892 boolean mDidUpdate = false; 893 boolean mOnBattery = false; 894 boolean mLaunchWarningShown = false; 895 896 Context mContext; 897 898 int mFactoryTest; 899 900 boolean mCheckedForSetup; 901 902 /** 903 * The time at which we will allow normal application switches again, 904 * after a call to {@link #stopAppSwitches()}. 905 */ 906 long mAppSwitchesAllowedTime; 907 908 /** 909 * This is set to true after the first switch after mAppSwitchesAllowedTime 910 * is set; any switches after that will clear the time. 911 */ 912 boolean mDidAppSwitch; 913 914 /** 915 * Last time (in realtime) at which we checked for power usage. 916 */ 917 long mLastPowerCheckRealtime; 918 919 /** 920 * Last time (in uptime) at which we checked for power usage. 921 */ 922 long mLastPowerCheckUptime; 923 924 /** 925 * Set while we are wanting to sleep, to prevent any 926 * activities from being started/resumed. 927 */ 928 private boolean mSleeping = false; 929 930 /** 931 * Set while we are running a voice interaction. This overrides 932 * sleeping while it is active. 933 */ 934 private boolean mRunningVoice = false; 935 936 /** 937 * State of external calls telling us if the device is asleep. 938 */ 939 private boolean mWentToSleep = false; 940 941 /** 942 * State of external call telling us if the lock screen is shown. 943 */ 944 private boolean mLockScreenShown = false; 945 946 /** 947 * Set if we are shutting down the system, similar to sleeping. 948 */ 949 boolean mShuttingDown = false; 950 951 /** 952 * Current sequence id for oom_adj computation traversal. 953 */ 954 int mAdjSeq = 0; 955 956 /** 957 * Current sequence id for process LRU updating. 958 */ 959 int mLruSeq = 0; 960 961 /** 962 * Keep track of the non-cached/empty process we last found, to help 963 * determine how to distribute cached/empty processes next time. 964 */ 965 int mNumNonCachedProcs = 0; 966 967 /** 968 * Keep track of the number of cached hidden procs, to balance oom adj 969 * distribution between those and empty procs. 970 */ 971 int mNumCachedHiddenProcs = 0; 972 973 /** 974 * Keep track of the number of service processes we last found, to 975 * determine on the next iteration which should be B services. 976 */ 977 int mNumServiceProcs = 0; 978 int mNewNumAServiceProcs = 0; 979 int mNewNumServiceProcs = 0; 980 981 /** 982 * Allow the current computed overall memory level of the system to go down? 983 * This is set to false when we are killing processes for reasons other than 984 * memory management, so that the now smaller process list will not be taken as 985 * an indication that memory is tighter. 986 */ 987 boolean mAllowLowerMemLevel = false; 988 989 /** 990 * The last computed memory level, for holding when we are in a state that 991 * processes are going away for other reasons. 992 */ 993 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 994 995 /** 996 * The last total number of process we have, to determine if changes actually look 997 * like a shrinking number of process due to lower RAM. 998 */ 999 int mLastNumProcesses; 1000 1001 /** 1002 * The uptime of the last time we performed idle maintenance. 1003 */ 1004 long mLastIdleTime = SystemClock.uptimeMillis(); 1005 1006 /** 1007 * Total time spent with RAM that has been added in the past since the last idle time. 1008 */ 1009 long mLowRamTimeSinceLastIdle = 0; 1010 1011 /** 1012 * If RAM is currently low, when that horrible situation started. 1013 */ 1014 long mLowRamStartTime = 0; 1015 1016 /** 1017 * For reporting to battery stats the current top application. 1018 */ 1019 private String mCurResumedPackage = null; 1020 private int mCurResumedUid = -1; 1021 1022 /** 1023 * For reporting to battery stats the apps currently running foreground 1024 * service. The ProcessMap is package/uid tuples; each of these contain 1025 * an array of the currently foreground processes. 1026 */ 1027 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1028 = new ProcessMap<ArrayList<ProcessRecord>>(); 1029 1030 /** 1031 * This is set if we had to do a delayed dexopt of an app before launching 1032 * it, to increase the ANR timeouts in that case. 1033 */ 1034 boolean mDidDexOpt; 1035 1036 /** 1037 * Set if the systemServer made a call to enterSafeMode. 1038 */ 1039 boolean mSafeMode; 1040 1041 String mDebugApp = null; 1042 boolean mWaitForDebugger = false; 1043 boolean mDebugTransient = false; 1044 String mOrigDebugApp = null; 1045 boolean mOrigWaitForDebugger = false; 1046 boolean mAlwaysFinishActivities = false; 1047 IActivityController mController = null; 1048 String mProfileApp = null; 1049 ProcessRecord mProfileProc = null; 1050 String mProfileFile; 1051 ParcelFileDescriptor mProfileFd; 1052 int mSamplingInterval = 0; 1053 boolean mAutoStopProfiler = false; 1054 int mProfileType = 0; 1055 String mOpenGlTraceApp = null; 1056 1057 static class ProcessChangeItem { 1058 static final int CHANGE_ACTIVITIES = 1<<0; 1059 static final int CHANGE_PROCESS_STATE = 1<<1; 1060 int changes; 1061 int uid; 1062 int pid; 1063 int processState; 1064 boolean foregroundActivities; 1065 } 1066 1067 final RemoteCallbackList<IProcessObserver> mProcessObservers 1068 = new RemoteCallbackList<IProcessObserver>(); 1069 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1070 1071 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1072 = new ArrayList<ProcessChangeItem>(); 1073 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1074 = new ArrayList<ProcessChangeItem>(); 1075 1076 /** 1077 * Runtime CPU use collection thread. This object's lock is used to 1078 * protect all related state. 1079 */ 1080 final Thread mProcessCpuThread; 1081 1082 /** 1083 * Used to collect process stats when showing not responding dialog. 1084 * Protected by mProcessCpuThread. 1085 */ 1086 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1087 MONITOR_THREAD_CPU_USAGE); 1088 final AtomicLong mLastCpuTime = new AtomicLong(0); 1089 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1090 1091 long mLastWriteTime = 0; 1092 1093 /** 1094 * Used to retain an update lock when the foreground activity is in 1095 * immersive mode. 1096 */ 1097 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1098 1099 /** 1100 * Set to true after the system has finished booting. 1101 */ 1102 boolean mBooted = false; 1103 1104 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1105 int mProcessLimitOverride = -1; 1106 1107 WindowManagerService mWindowManager; 1108 1109 final ActivityThread mSystemThread; 1110 1111 // Holds the current foreground user's id 1112 int mCurrentUserId = 0; 1113 // Holds the target user's id during a user switch 1114 int mTargetUserId = UserHandle.USER_NULL; 1115 // If there are multiple profiles for the current user, their ids are here 1116 // Currently only the primary user can have managed profiles 1117 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1118 1119 /** 1120 * Mapping from each known user ID to the profile group ID it is associated with. 1121 */ 1122 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1123 1124 private UserManagerService mUserManager; 1125 1126 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1127 final ProcessRecord mApp; 1128 final int mPid; 1129 final IApplicationThread mAppThread; 1130 1131 AppDeathRecipient(ProcessRecord app, int pid, 1132 IApplicationThread thread) { 1133 if (localLOGV) Slog.v( 1134 TAG, "New death recipient " + this 1135 + " for thread " + thread.asBinder()); 1136 mApp = app; 1137 mPid = pid; 1138 mAppThread = thread; 1139 } 1140 1141 @Override 1142 public void binderDied() { 1143 if (localLOGV) Slog.v( 1144 TAG, "Death received in " + this 1145 + " for thread " + mAppThread.asBinder()); 1146 synchronized(ActivityManagerService.this) { 1147 appDiedLocked(mApp, mPid, mAppThread); 1148 } 1149 } 1150 } 1151 1152 static final int SHOW_ERROR_MSG = 1; 1153 static final int SHOW_NOT_RESPONDING_MSG = 2; 1154 static final int SHOW_FACTORY_ERROR_MSG = 3; 1155 static final int UPDATE_CONFIGURATION_MSG = 4; 1156 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1157 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1158 static final int SERVICE_TIMEOUT_MSG = 12; 1159 static final int UPDATE_TIME_ZONE = 13; 1160 static final int SHOW_UID_ERROR_MSG = 14; 1161 static final int IM_FEELING_LUCKY_MSG = 15; 1162 static final int PROC_START_TIMEOUT_MSG = 20; 1163 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1164 static final int KILL_APPLICATION_MSG = 22; 1165 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1166 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1167 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1168 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1169 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1170 static final int CLEAR_DNS_CACHE_MSG = 28; 1171 static final int UPDATE_HTTP_PROXY_MSG = 29; 1172 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1173 static final int DISPATCH_PROCESSES_CHANGED = 31; 1174 static final int DISPATCH_PROCESS_DIED = 32; 1175 static final int REPORT_MEM_USAGE_MSG = 33; 1176 static final int REPORT_USER_SWITCH_MSG = 34; 1177 static final int CONTINUE_USER_SWITCH_MSG = 35; 1178 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1179 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1180 static final int PERSIST_URI_GRANTS_MSG = 38; 1181 static final int REQUEST_ALL_PSS_MSG = 39; 1182 static final int START_PROFILES_MSG = 40; 1183 static final int UPDATE_TIME = 41; 1184 static final int SYSTEM_USER_START_MSG = 42; 1185 static final int SYSTEM_USER_CURRENT_MSG = 43; 1186 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1187 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1188 static final int START_USER_SWITCH_MSG = 46; 1189 1190 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1191 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1192 static final int FIRST_COMPAT_MODE_MSG = 300; 1193 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1194 1195 AlertDialog mUidAlert; 1196 CompatModeDialog mCompatModeDialog; 1197 long mLastMemUsageReportTime = 0; 1198 1199 private LockToAppRequestDialog mLockToAppRequest; 1200 1201 /** 1202 * Flag whether the current user is a "monkey", i.e. whether 1203 * the UI is driven by a UI automation tool. 1204 */ 1205 private boolean mUserIsMonkey; 1206 1207 /** Flag whether the device has a Recents UI */ 1208 boolean mHasRecents; 1209 1210 /** The dimensions of the thumbnails in the Recents UI. */ 1211 int mThumbnailWidth; 1212 int mThumbnailHeight; 1213 1214 final ServiceThread mHandlerThread; 1215 final MainHandler mHandler; 1216 1217 final class MainHandler extends Handler { 1218 public MainHandler(Looper looper) { 1219 super(looper, null, true); 1220 } 1221 1222 @Override 1223 public void handleMessage(Message msg) { 1224 switch (msg.what) { 1225 case SHOW_ERROR_MSG: { 1226 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1227 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1228 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord)data.get("app"); 1231 AppErrorResult res = (AppErrorResult) data.get("result"); 1232 if (proc != null && proc.crashDialog != null) { 1233 Slog.e(TAG, "App already has crash dialog: " + proc); 1234 if (res != null) { 1235 res.set(0); 1236 } 1237 return; 1238 } 1239 boolean isBackground = (UserHandle.getAppId(proc.uid) 1240 >= Process.FIRST_APPLICATION_UID 1241 && proc.pid != MY_PID); 1242 for (int userId : mCurrentProfileIds) { 1243 isBackground &= (proc.userId != userId); 1244 } 1245 if (isBackground && !showBackground) { 1246 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1247 if (res != null) { 1248 res.set(0); 1249 } 1250 return; 1251 } 1252 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1253 Dialog d = new AppErrorDialog(mContext, 1254 ActivityManagerService.this, res, proc); 1255 d.show(); 1256 proc.crashDialog = d; 1257 } else { 1258 // The device is asleep, so just pretend that the user 1259 // saw a crash dialog and hit "force quit". 1260 if (res != null) { 1261 res.set(0); 1262 } 1263 } 1264 } 1265 1266 ensureBootCompleted(); 1267 } break; 1268 case SHOW_NOT_RESPONDING_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1271 ProcessRecord proc = (ProcessRecord)data.get("app"); 1272 if (proc != null && proc.anrDialog != null) { 1273 Slog.e(TAG, "App already has anr dialog: " + proc); 1274 return; 1275 } 1276 1277 Intent intent = new Intent("android.intent.action.ANR"); 1278 if (!mProcessesReady) { 1279 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1280 | Intent.FLAG_RECEIVER_FOREGROUND); 1281 } 1282 broadcastIntentLocked(null, null, intent, 1283 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1284 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1285 1286 if (mShowDialogs) { 1287 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1288 mContext, proc, (ActivityRecord)data.get("activity"), 1289 msg.arg1 != 0); 1290 d.show(); 1291 proc.anrDialog = d; 1292 } else { 1293 // Just kill the app if there is no dialog to be shown. 1294 killAppAtUsersRequest(proc, null); 1295 } 1296 } 1297 1298 ensureBootCompleted(); 1299 } break; 1300 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1301 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord proc = (ProcessRecord) data.get("app"); 1304 if (proc == null) { 1305 Slog.e(TAG, "App not found when showing strict mode dialog."); 1306 break; 1307 } 1308 if (proc.crashDialog != null) { 1309 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1310 return; 1311 } 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1314 Dialog d = new StrictModeViolationDialog(mContext, 1315 ActivityManagerService.this, res, proc); 1316 d.show(); 1317 proc.crashDialog = d; 1318 } else { 1319 // The device is asleep, so just pretend that the user 1320 // saw a crash dialog and hit "force quit". 1321 res.set(0); 1322 } 1323 } 1324 ensureBootCompleted(); 1325 } break; 1326 case SHOW_FACTORY_ERROR_MSG: { 1327 Dialog d = new FactoryErrorDialog( 1328 mContext, msg.getData().getCharSequence("msg")); 1329 d.show(); 1330 ensureBootCompleted(); 1331 } break; 1332 case UPDATE_CONFIGURATION_MSG: { 1333 final ContentResolver resolver = mContext.getContentResolver(); 1334 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1335 } break; 1336 case GC_BACKGROUND_PROCESSES_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 performAppGcsIfAppropriateLocked(); 1339 } 1340 } break; 1341 case WAIT_FOR_DEBUGGER_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 ProcessRecord app = (ProcessRecord)msg.obj; 1344 if (msg.arg1 != 0) { 1345 if (!app.waitedForDebugger) { 1346 Dialog d = new AppWaitingForDebuggerDialog( 1347 ActivityManagerService.this, 1348 mContext, app); 1349 app.waitDialog = d; 1350 app.waitedForDebugger = true; 1351 d.show(); 1352 } 1353 } else { 1354 if (app.waitDialog != null) { 1355 app.waitDialog.dismiss(); 1356 app.waitDialog = null; 1357 } 1358 } 1359 } 1360 } break; 1361 case SERVICE_TIMEOUT_MSG: { 1362 if (mDidDexOpt) { 1363 mDidDexOpt = false; 1364 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1365 nmsg.obj = msg.obj; 1366 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1367 return; 1368 } 1369 mServices.serviceTimeout((ProcessRecord)msg.obj); 1370 } break; 1371 case UPDATE_TIME_ZONE: { 1372 synchronized (ActivityManagerService.this) { 1373 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1374 ProcessRecord r = mLruProcesses.get(i); 1375 if (r.thread != null) { 1376 try { 1377 r.thread.updateTimeZone(); 1378 } catch (RemoteException ex) { 1379 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case CLEAR_DNS_CACHE_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1388 ProcessRecord r = mLruProcesses.get(i); 1389 if (r.thread != null) { 1390 try { 1391 r.thread.clearDnsCache(); 1392 } catch (RemoteException ex) { 1393 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1394 } 1395 } 1396 } 1397 } 1398 } break; 1399 case UPDATE_HTTP_PROXY_MSG: { 1400 ProxyInfo proxy = (ProxyInfo)msg.obj; 1401 String host = ""; 1402 String port = ""; 1403 String exclList = ""; 1404 Uri pacFileUrl = Uri.EMPTY; 1405 if (proxy != null) { 1406 host = proxy.getHost(); 1407 port = Integer.toString(proxy.getPort()); 1408 exclList = proxy.getExclusionListAsString(); 1409 pacFileUrl = proxy.getPacFileUrl(); 1410 } 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update http proxy for: " + 1419 r.info.processName); 1420 } 1421 } 1422 } 1423 } 1424 } break; 1425 case SHOW_UID_ERROR_MSG: { 1426 String title = "System UIDs Inconsistent"; 1427 String text = "UIDs on the system are inconsistent, you need to wipe your" 1428 + " data partition or your device will be unstable."; 1429 Log.e(TAG, title + ": " + text); 1430 if (mShowDialogs) { 1431 // XXX This is a temporary dialog, no need to localize. 1432 AlertDialog d = new BaseErrorDialog(mContext); 1433 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1434 d.setCancelable(false); 1435 d.setTitle(title); 1436 d.setMessage(text); 1437 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1438 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1439 mUidAlert = d; 1440 d.show(); 1441 } 1442 } break; 1443 case IM_FEELING_LUCKY_MSG: { 1444 if (mUidAlert != null) { 1445 mUidAlert.dismiss(); 1446 mUidAlert = null; 1447 } 1448 } break; 1449 case PROC_START_TIMEOUT_MSG: { 1450 if (mDidDexOpt) { 1451 mDidDexOpt = false; 1452 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1453 nmsg.obj = msg.obj; 1454 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1455 return; 1456 } 1457 ProcessRecord app = (ProcessRecord)msg.obj; 1458 synchronized (ActivityManagerService.this) { 1459 processStartTimedOutLocked(app); 1460 } 1461 } break; 1462 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1463 synchronized (ActivityManagerService.this) { 1464 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1465 } 1466 } break; 1467 case KILL_APPLICATION_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 int appid = msg.arg1; 1470 boolean restart = (msg.arg2 == 1); 1471 Bundle bundle = (Bundle)msg.obj; 1472 String pkg = bundle.getString("pkg"); 1473 String reason = bundle.getString("reason"); 1474 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1475 false, UserHandle.USER_ALL, reason); 1476 } 1477 } break; 1478 case FINALIZE_PENDING_INTENT_MSG: { 1479 ((PendingIntentRecord)msg.obj).completeFinalize(); 1480 } break; 1481 case POST_HEAVY_NOTIFICATION_MSG: { 1482 INotificationManager inm = NotificationManager.getService(); 1483 if (inm == null) { 1484 return; 1485 } 1486 1487 ActivityRecord root = (ActivityRecord)msg.obj; 1488 ProcessRecord process = root.app; 1489 if (process == null) { 1490 return; 1491 } 1492 1493 try { 1494 Context context = mContext.createPackageContext(process.info.packageName, 0); 1495 String text = mContext.getString(R.string.heavy_weight_notification, 1496 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1497 Notification notification = new Notification(); 1498 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1499 notification.when = 0; 1500 notification.flags = Notification.FLAG_ONGOING_EVENT; 1501 notification.tickerText = text; 1502 notification.defaults = 0; // please be quiet 1503 notification.sound = null; 1504 notification.vibrate = null; 1505 notification.color = mContext.getResources().getColor( 1506 com.android.internal.R.color.system_notification_accent_color); 1507 notification.setLatestEventInfo(context, text, 1508 mContext.getText(R.string.heavy_weight_notification_detail), 1509 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1510 PendingIntent.FLAG_CANCEL_CURRENT, null, 1511 new UserHandle(root.userId))); 1512 1513 try { 1514 int[] outId = new int[1]; 1515 inm.enqueueNotificationWithTag("android", "android", null, 1516 R.string.heavy_weight_notification, 1517 notification, outId, root.userId); 1518 } catch (RuntimeException e) { 1519 Slog.w(ActivityManagerService.TAG, 1520 "Error showing notification for heavy-weight app", e); 1521 } catch (RemoteException e) { 1522 } 1523 } catch (NameNotFoundException e) { 1524 Slog.w(TAG, "Unable to create context for heavy notification", e); 1525 } 1526 } break; 1527 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1528 INotificationManager inm = NotificationManager.getService(); 1529 if (inm == null) { 1530 return; 1531 } 1532 try { 1533 inm.cancelNotificationWithTag("android", null, 1534 R.string.heavy_weight_notification, msg.arg1); 1535 } catch (RuntimeException e) { 1536 Slog.w(ActivityManagerService.TAG, 1537 "Error canceling notification for service", e); 1538 } catch (RemoteException e) { 1539 } 1540 } break; 1541 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1542 synchronized (ActivityManagerService.this) { 1543 checkExcessivePowerUsageLocked(true); 1544 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1546 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1547 } 1548 } break; 1549 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1550 synchronized (ActivityManagerService.this) { 1551 ActivityRecord ar = (ActivityRecord)msg.obj; 1552 if (mCompatModeDialog != null) { 1553 if (mCompatModeDialog.mAppInfo.packageName.equals( 1554 ar.info.applicationInfo.packageName)) { 1555 return; 1556 } 1557 mCompatModeDialog.dismiss(); 1558 mCompatModeDialog = null; 1559 } 1560 if (ar != null && false) { 1561 if (mCompatModePackages.getPackageAskCompatModeLocked( 1562 ar.packageName)) { 1563 int mode = mCompatModePackages.computeCompatModeLocked( 1564 ar.info.applicationInfo); 1565 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1566 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1567 mCompatModeDialog = new CompatModeDialog( 1568 ActivityManagerService.this, mContext, 1569 ar.info.applicationInfo); 1570 mCompatModeDialog.show(); 1571 } 1572 } 1573 } 1574 } 1575 break; 1576 } 1577 case DISPATCH_PROCESSES_CHANGED: { 1578 dispatchProcessesChanged(); 1579 break; 1580 } 1581 case DISPATCH_PROCESS_DIED: { 1582 final int pid = msg.arg1; 1583 final int uid = msg.arg2; 1584 dispatchProcessDied(pid, uid); 1585 break; 1586 } 1587 case REPORT_MEM_USAGE_MSG: { 1588 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1589 Thread thread = new Thread() { 1590 @Override public void run() { 1591 final SparseArray<ProcessMemInfo> infoMap 1592 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 infoMap.put(mi.pid, mi); 1596 } 1597 updateCpuStatsNow(); 1598 synchronized (mProcessCpuThread) { 1599 final int N = mProcessCpuTracker.countStats(); 1600 for (int i=0; i<N; i++) { 1601 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1602 if (st.vsize > 0) { 1603 long pss = Debug.getPss(st.pid, null); 1604 if (pss > 0) { 1605 if (infoMap.indexOfKey(st.pid) < 0) { 1606 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1607 ProcessList.NATIVE_ADJ, -1, "native", null); 1608 mi.pss = pss; 1609 memInfos.add(mi); 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 long totalPss = 0; 1617 for (int i=0, N=memInfos.size(); i<N; i++) { 1618 ProcessMemInfo mi = memInfos.get(i); 1619 if (mi.pss == 0) { 1620 mi.pss = Debug.getPss(mi.pid, null); 1621 } 1622 totalPss += mi.pss; 1623 } 1624 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1625 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1626 if (lhs.oomAdj != rhs.oomAdj) { 1627 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1628 } 1629 if (lhs.pss != rhs.pss) { 1630 return lhs.pss < rhs.pss ? 1 : -1; 1631 } 1632 return 0; 1633 } 1634 }); 1635 1636 StringBuilder tag = new StringBuilder(128); 1637 StringBuilder stack = new StringBuilder(128); 1638 tag.append("Low on memory -- "); 1639 appendMemBucket(tag, totalPss, "total", false); 1640 appendMemBucket(stack, totalPss, "total", true); 1641 1642 StringBuilder logBuilder = new StringBuilder(1024); 1643 logBuilder.append("Low on memory:\n"); 1644 1645 boolean firstLine = true; 1646 int lastOomAdj = Integer.MIN_VALUE; 1647 for (int i=0, N=memInfos.size(); i<N; i++) { 1648 ProcessMemInfo mi = memInfos.get(i); 1649 1650 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1651 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1652 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1653 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1654 if (lastOomAdj != mi.oomAdj) { 1655 lastOomAdj = mi.oomAdj; 1656 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1657 tag.append(" / "); 1658 } 1659 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1660 if (firstLine) { 1661 stack.append(":"); 1662 firstLine = false; 1663 } 1664 stack.append("\n\t at "); 1665 } else { 1666 stack.append("$"); 1667 } 1668 } else { 1669 tag.append(" "); 1670 stack.append("$"); 1671 } 1672 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1673 appendMemBucket(tag, mi.pss, mi.name, false); 1674 } 1675 appendMemBucket(stack, mi.pss, mi.name, true); 1676 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1677 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1678 stack.append("("); 1679 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1680 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1681 stack.append(DUMP_MEM_OOM_LABEL[k]); 1682 stack.append(":"); 1683 stack.append(DUMP_MEM_OOM_ADJ[k]); 1684 } 1685 } 1686 stack.append(")"); 1687 } 1688 } 1689 1690 logBuilder.append(" "); 1691 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1692 logBuilder.append(' '); 1693 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1694 logBuilder.append(' '); 1695 ProcessList.appendRamKb(logBuilder, mi.pss); 1696 logBuilder.append(" kB: "); 1697 logBuilder.append(mi.name); 1698 logBuilder.append(" ("); 1699 logBuilder.append(mi.pid); 1700 logBuilder.append(") "); 1701 logBuilder.append(mi.adjType); 1702 logBuilder.append('\n'); 1703 if (mi.adjReason != null) { 1704 logBuilder.append(" "); 1705 logBuilder.append(mi.adjReason); 1706 logBuilder.append('\n'); 1707 } 1708 } 1709 1710 logBuilder.append(" "); 1711 ProcessList.appendRamKb(logBuilder, totalPss); 1712 logBuilder.append(" kB: TOTAL\n"); 1713 1714 long[] infos = new long[Debug.MEMINFO_COUNT]; 1715 Debug.getMemInfo(infos); 1716 logBuilder.append(" MemInfo: "); 1717 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1718 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1719 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1720 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1721 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1722 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1723 logBuilder.append(" ZRAM: "); 1724 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1725 logBuilder.append(" kB RAM, "); 1726 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1727 logBuilder.append(" kB swap total, "); 1728 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1729 logBuilder.append(" kB swap free\n"); 1730 } 1731 Slog.i(TAG, logBuilder.toString()); 1732 1733 StringBuilder dropBuilder = new StringBuilder(1024); 1734 /* 1735 StringWriter oomSw = new StringWriter(); 1736 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1737 StringWriter catSw = new StringWriter(); 1738 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1739 String[] emptyArgs = new String[] { }; 1740 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1741 oomPw.flush(); 1742 String oomString = oomSw.toString(); 1743 */ 1744 dropBuilder.append(stack); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append('\n'); 1747 dropBuilder.append(logBuilder); 1748 dropBuilder.append('\n'); 1749 /* 1750 dropBuilder.append(oomString); 1751 dropBuilder.append('\n'); 1752 */ 1753 StringWriter catSw = new StringWriter(); 1754 synchronized (ActivityManagerService.this) { 1755 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1756 String[] emptyArgs = new String[] { }; 1757 catPw.println(); 1758 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1759 catPw.println(); 1760 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1761 false, false, null); 1762 catPw.println(); 1763 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1764 catPw.flush(); 1765 } 1766 dropBuilder.append(catSw.toString()); 1767 addErrorToDropBox("lowmem", null, "system_server", null, 1768 null, tag.toString(), dropBuilder.toString(), null, null); 1769 //Slog.i(TAG, "Sent to dropbox:"); 1770 //Slog.i(TAG, dropBuilder.toString()); 1771 synchronized (ActivityManagerService.this) { 1772 long now = SystemClock.uptimeMillis(); 1773 if (mLastMemUsageReportTime < now) { 1774 mLastMemUsageReportTime = now; 1775 } 1776 } 1777 } 1778 }; 1779 thread.start(); 1780 break; 1781 } 1782 case START_USER_SWITCH_MSG: { 1783 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1784 break; 1785 } 1786 case REPORT_USER_SWITCH_MSG: { 1787 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1788 break; 1789 } 1790 case CONTINUE_USER_SWITCH_MSG: { 1791 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1792 break; 1793 } 1794 case USER_SWITCH_TIMEOUT_MSG: { 1795 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1796 break; 1797 } 1798 case IMMERSIVE_MODE_LOCK_MSG: { 1799 final boolean nextState = (msg.arg1 != 0); 1800 if (mUpdateLock.isHeld() != nextState) { 1801 if (DEBUG_IMMERSIVE) { 1802 final ActivityRecord r = (ActivityRecord) msg.obj; 1803 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1804 } 1805 if (nextState) { 1806 mUpdateLock.acquire(); 1807 } else { 1808 mUpdateLock.release(); 1809 } 1810 } 1811 break; 1812 } 1813 case PERSIST_URI_GRANTS_MSG: { 1814 writeGrantedUriPermissions(); 1815 break; 1816 } 1817 case REQUEST_ALL_PSS_MSG: { 1818 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1819 break; 1820 } 1821 case START_PROFILES_MSG: { 1822 synchronized (ActivityManagerService.this) { 1823 startProfilesLocked(); 1824 } 1825 break; 1826 } 1827 case UPDATE_TIME: { 1828 synchronized (ActivityManagerService.this) { 1829 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1830 ProcessRecord r = mLruProcesses.get(i); 1831 if (r.thread != null) { 1832 try { 1833 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1834 } catch (RemoteException ex) { 1835 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1836 } 1837 } 1838 } 1839 } 1840 break; 1841 } 1842 case SYSTEM_USER_START_MSG: { 1843 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1844 Integer.toString(msg.arg1), msg.arg1); 1845 mSystemServiceManager.startUser(msg.arg1); 1846 break; 1847 } 1848 case SYSTEM_USER_CURRENT_MSG: { 1849 mBatteryStatsService.noteEvent( 1850 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1851 Integer.toString(msg.arg2), msg.arg2); 1852 mBatteryStatsService.noteEvent( 1853 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1854 Integer.toString(msg.arg1), msg.arg1); 1855 mSystemServiceManager.switchUser(msg.arg1); 1856 mLockToAppRequest.clearPrompt(); 1857 break; 1858 } 1859 case ENTER_ANIMATION_COMPLETE_MSG: { 1860 synchronized (ActivityManagerService.this) { 1861 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1862 if (r != null && r.app != null && r.app.thread != null) { 1863 try { 1864 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1865 } catch (RemoteException e) { 1866 } 1867 } 1868 } 1869 break; 1870 } 1871 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1872 enableScreenAfterBoot(); 1873 break; 1874 } 1875 } 1876 } 1877 }; 1878 1879 static final int COLLECT_PSS_BG_MSG = 1; 1880 1881 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1882 @Override 1883 public void handleMessage(Message msg) { 1884 switch (msg.what) { 1885 case COLLECT_PSS_BG_MSG: { 1886 long start = SystemClock.uptimeMillis(); 1887 MemInfoReader memInfo = null; 1888 synchronized (ActivityManagerService.this) { 1889 if (mFullPssPending) { 1890 mFullPssPending = false; 1891 memInfo = new MemInfoReader(); 1892 } 1893 } 1894 if (memInfo != null) { 1895 updateCpuStatsNow(); 1896 long nativeTotalPss = 0; 1897 synchronized (mProcessCpuThread) { 1898 final int N = mProcessCpuTracker.countStats(); 1899 for (int j=0; j<N; j++) { 1900 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1901 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1902 // This is definitely an application process; skip it. 1903 continue; 1904 } 1905 synchronized (mPidsSelfLocked) { 1906 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1907 // This is one of our own processes; skip it. 1908 continue; 1909 } 1910 } 1911 nativeTotalPss += Debug.getPss(st.pid, null); 1912 } 1913 } 1914 memInfo.readMemInfo(); 1915 synchronized (this) { 1916 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1917 + (SystemClock.uptimeMillis()-start) + "ms"); 1918 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1919 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1920 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1921 +memInfo.getSlabSizeKb(), 1922 nativeTotalPss); 1923 } 1924 } 1925 1926 int i=0, num=0; 1927 long[] tmp = new long[1]; 1928 do { 1929 ProcessRecord proc; 1930 int procState; 1931 int pid; 1932 synchronized (ActivityManagerService.this) { 1933 if (i >= mPendingPssProcesses.size()) { 1934 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1935 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1936 mPendingPssProcesses.clear(); 1937 return; 1938 } 1939 proc = mPendingPssProcesses.get(i); 1940 procState = proc.pssProcState; 1941 if (proc.thread != null && procState == proc.setProcState) { 1942 pid = proc.pid; 1943 } else { 1944 proc = null; 1945 pid = 0; 1946 } 1947 i++; 1948 } 1949 if (proc != null) { 1950 long pss = Debug.getPss(pid, tmp); 1951 synchronized (ActivityManagerService.this) { 1952 if (proc.thread != null && proc.setProcState == procState 1953 && proc.pid == pid) { 1954 num++; 1955 proc.lastPssTime = SystemClock.uptimeMillis(); 1956 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1957 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1958 + ": " + pss + " lastPss=" + proc.lastPss 1959 + " state=" + ProcessList.makeProcStateString(procState)); 1960 if (proc.initialIdlePss == 0) { 1961 proc.initialIdlePss = pss; 1962 } 1963 proc.lastPss = pss; 1964 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1965 proc.lastCachedPss = pss; 1966 } 1967 } 1968 } 1969 } 1970 } while (true); 1971 } 1972 } 1973 } 1974 }; 1975 1976 /** 1977 * Monitor for package changes and update our internal state. 1978 */ 1979 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1980 @Override 1981 public void onPackageRemoved(String packageName, int uid) { 1982 // Remove all tasks with activities in the specified package from the list of recent tasks 1983 synchronized (ActivityManagerService.this) { 1984 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1985 TaskRecord tr = mRecentTasks.get(i); 1986 ComponentName cn = tr.intent.getComponent(); 1987 if (cn != null && cn.getPackageName().equals(packageName)) { 1988 // If the package name matches, remove the task and kill the process 1989 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1990 } 1991 } 1992 } 1993 } 1994 1995 @Override 1996 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1997 onPackageModified(packageName); 1998 return true; 1999 } 2000 2001 @Override 2002 public void onPackageModified(String packageName) { 2003 final PackageManager pm = mContext.getPackageManager(); 2004 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2005 new ArrayList<Pair<Intent, Integer>>(); 2006 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2007 // Copy the list of recent tasks so that we don't hold onto the lock on 2008 // ActivityManagerService for long periods while checking if components exist. 2009 synchronized (ActivityManagerService.this) { 2010 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2011 TaskRecord tr = mRecentTasks.get(i); 2012 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2013 } 2014 } 2015 // Check the recent tasks and filter out all tasks with components that no longer exist. 2016 Intent tmpI = new Intent(); 2017 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2018 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2019 ComponentName cn = p.first.getComponent(); 2020 if (cn != null && cn.getPackageName().equals(packageName)) { 2021 try { 2022 // Add the task to the list to remove if the component no longer exists 2023 tmpI.setComponent(cn); 2024 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2025 tasksToRemove.add(p.second); 2026 } 2027 } catch (Exception e) {} 2028 } 2029 } 2030 // Prune all the tasks with removed components from the list of recent tasks 2031 synchronized (ActivityManagerService.this) { 2032 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2033 // Remove the task but don't kill the process (since other components in that 2034 // package may still be running and in the background) 2035 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2036 } 2037 } 2038 } 2039 2040 @Override 2041 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2042 // Force stop the specified packages 2043 if (packages != null) { 2044 for (String pkg : packages) { 2045 synchronized (ActivityManagerService.this) { 2046 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2047 "finished booting")) { 2048 return true; 2049 } 2050 } 2051 } 2052 } 2053 return false; 2054 } 2055 }; 2056 2057 public void setSystemProcess() { 2058 try { 2059 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2060 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2061 ServiceManager.addService("meminfo", new MemBinder(this)); 2062 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2063 ServiceManager.addService("dbinfo", new DbBinder(this)); 2064 if (MONITOR_CPU_USAGE) { 2065 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2066 } 2067 ServiceManager.addService("permission", new PermissionController(this)); 2068 2069 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2070 "android", STOCK_PM_FLAGS); 2071 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2072 2073 synchronized (this) { 2074 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2075 app.persistent = true; 2076 app.pid = MY_PID; 2077 app.maxAdj = ProcessList.SYSTEM_ADJ; 2078 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2079 mProcessNames.put(app.processName, app.uid, app); 2080 synchronized (mPidsSelfLocked) { 2081 mPidsSelfLocked.put(app.pid, app); 2082 } 2083 updateLruProcessLocked(app, false, null); 2084 updateOomAdjLocked(); 2085 } 2086 } catch (PackageManager.NameNotFoundException e) { 2087 throw new RuntimeException( 2088 "Unable to find android system package", e); 2089 } 2090 } 2091 2092 public void setWindowManager(WindowManagerService wm) { 2093 mWindowManager = wm; 2094 mStackSupervisor.setWindowManager(wm); 2095 } 2096 2097 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2098 mUsageStatsService = usageStatsManager; 2099 } 2100 2101 public void startObservingNativeCrashes() { 2102 final NativeCrashListener ncl = new NativeCrashListener(this); 2103 ncl.start(); 2104 } 2105 2106 public IAppOpsService getAppOpsService() { 2107 return mAppOpsService; 2108 } 2109 2110 static class MemBinder extends Binder { 2111 ActivityManagerService mActivityManagerService; 2112 MemBinder(ActivityManagerService activityManagerService) { 2113 mActivityManagerService = activityManagerService; 2114 } 2115 2116 @Override 2117 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2118 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2119 != PackageManager.PERMISSION_GRANTED) { 2120 pw.println("Permission Denial: can't dump meminfo from from pid=" 2121 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2122 + " without permission " + android.Manifest.permission.DUMP); 2123 return; 2124 } 2125 2126 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2127 } 2128 } 2129 2130 static class GraphicsBinder extends Binder { 2131 ActivityManagerService mActivityManagerService; 2132 GraphicsBinder(ActivityManagerService activityManagerService) { 2133 mActivityManagerService = activityManagerService; 2134 } 2135 2136 @Override 2137 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2138 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2139 != PackageManager.PERMISSION_GRANTED) { 2140 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2141 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2142 + " without permission " + android.Manifest.permission.DUMP); 2143 return; 2144 } 2145 2146 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2147 } 2148 } 2149 2150 static class DbBinder extends Binder { 2151 ActivityManagerService mActivityManagerService; 2152 DbBinder(ActivityManagerService activityManagerService) { 2153 mActivityManagerService = activityManagerService; 2154 } 2155 2156 @Override 2157 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2158 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2159 != PackageManager.PERMISSION_GRANTED) { 2160 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2161 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2162 + " without permission " + android.Manifest.permission.DUMP); 2163 return; 2164 } 2165 2166 mActivityManagerService.dumpDbInfo(fd, pw, args); 2167 } 2168 } 2169 2170 static class CpuBinder extends Binder { 2171 ActivityManagerService mActivityManagerService; 2172 CpuBinder(ActivityManagerService activityManagerService) { 2173 mActivityManagerService = activityManagerService; 2174 } 2175 2176 @Override 2177 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2178 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2179 != PackageManager.PERMISSION_GRANTED) { 2180 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2181 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2182 + " without permission " + android.Manifest.permission.DUMP); 2183 return; 2184 } 2185 2186 synchronized (mActivityManagerService.mProcessCpuThread) { 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2188 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2189 SystemClock.uptimeMillis())); 2190 } 2191 } 2192 } 2193 2194 public static final class Lifecycle extends SystemService { 2195 private final ActivityManagerService mService; 2196 2197 public Lifecycle(Context context) { 2198 super(context); 2199 mService = new ActivityManagerService(context); 2200 } 2201 2202 @Override 2203 public void onStart() { 2204 mService.start(); 2205 } 2206 2207 public ActivityManagerService getService() { 2208 return mService; 2209 } 2210 } 2211 2212 // Note: This method is invoked on the main thread but may need to attach various 2213 // handlers to other threads. So take care to be explicit about the looper. 2214 public ActivityManagerService(Context systemContext) { 2215 mContext = systemContext; 2216 mFactoryTest = FactoryTest.getMode(); 2217 mSystemThread = ActivityThread.currentActivityThread(); 2218 2219 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2220 2221 mHandlerThread = new ServiceThread(TAG, 2222 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2223 mHandlerThread.start(); 2224 mHandler = new MainHandler(mHandlerThread.getLooper()); 2225 2226 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2227 "foreground", BROADCAST_FG_TIMEOUT, false); 2228 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2229 "background", BROADCAST_BG_TIMEOUT, true); 2230 mBroadcastQueues[0] = mFgBroadcastQueue; 2231 mBroadcastQueues[1] = mBgBroadcastQueue; 2232 2233 mServices = new ActiveServices(this); 2234 mProviderMap = new ProviderMap(this); 2235 2236 // TODO: Move creation of battery stats service outside of activity manager service. 2237 File dataDir = Environment.getDataDirectory(); 2238 File systemDir = new File(dataDir, "system"); 2239 systemDir.mkdirs(); 2240 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2241 mBatteryStatsService.getActiveStatistics().readLocked(); 2242 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2243 mOnBattery = DEBUG_POWER ? true 2244 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2245 mBatteryStatsService.getActiveStatistics().setCallback(this); 2246 2247 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2248 2249 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2250 2251 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2252 2253 // User 0 is the first and only user that runs at boot. 2254 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2255 mUserLru.add(Integer.valueOf(0)); 2256 updateStartedUserArrayLocked(); 2257 2258 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2259 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2260 2261 mConfiguration.setToDefaults(); 2262 mConfiguration.setLocale(Locale.getDefault()); 2263 2264 mConfigurationSeq = mConfiguration.seq = 1; 2265 mProcessCpuTracker.init(); 2266 2267 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2268 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2269 mStackSupervisor = new ActivityStackSupervisor(this); 2270 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2271 2272 mProcessCpuThread = new Thread("CpuTracker") { 2273 @Override 2274 public void run() { 2275 while (true) { 2276 try { 2277 try { 2278 synchronized(this) { 2279 final long now = SystemClock.uptimeMillis(); 2280 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2281 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2282 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2283 // + ", write delay=" + nextWriteDelay); 2284 if (nextWriteDelay < nextCpuDelay) { 2285 nextCpuDelay = nextWriteDelay; 2286 } 2287 if (nextCpuDelay > 0) { 2288 mProcessCpuMutexFree.set(true); 2289 this.wait(nextCpuDelay); 2290 } 2291 } 2292 } catch (InterruptedException e) { 2293 } 2294 updateCpuStatsNow(); 2295 } catch (Exception e) { 2296 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2297 } 2298 } 2299 } 2300 }; 2301 2302 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2303 2304 Watchdog.getInstance().addMonitor(this); 2305 Watchdog.getInstance().addThread(mHandler); 2306 } 2307 2308 public void setSystemServiceManager(SystemServiceManager mgr) { 2309 mSystemServiceManager = mgr; 2310 } 2311 2312 private void start() { 2313 Process.removeAllProcessGroups(); 2314 mProcessCpuThread.start(); 2315 2316 mBatteryStatsService.publish(mContext); 2317 mAppOpsService.publish(mContext); 2318 Slog.d("AppOps", "AppOpsService published"); 2319 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2320 } 2321 2322 public void initPowerManagement() { 2323 mStackSupervisor.initPowerManagement(); 2324 mBatteryStatsService.initPowerManagement(); 2325 } 2326 2327 @Override 2328 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2329 throws RemoteException { 2330 if (code == SYSPROPS_TRANSACTION) { 2331 // We need to tell all apps about the system property change. 2332 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2333 synchronized(this) { 2334 final int NP = mProcessNames.getMap().size(); 2335 for (int ip=0; ip<NP; ip++) { 2336 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2337 final int NA = apps.size(); 2338 for (int ia=0; ia<NA; ia++) { 2339 ProcessRecord app = apps.valueAt(ia); 2340 if (app.thread != null) { 2341 procs.add(app.thread.asBinder()); 2342 } 2343 } 2344 } 2345 } 2346 2347 int N = procs.size(); 2348 for (int i=0; i<N; i++) { 2349 Parcel data2 = Parcel.obtain(); 2350 try { 2351 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2352 } catch (RemoteException e) { 2353 } 2354 data2.recycle(); 2355 } 2356 } 2357 try { 2358 return super.onTransact(code, data, reply, flags); 2359 } catch (RuntimeException e) { 2360 // The activity manager only throws security exceptions, so let's 2361 // log all others. 2362 if (!(e instanceof SecurityException)) { 2363 Slog.wtf(TAG, "Activity Manager Crash", e); 2364 } 2365 throw e; 2366 } 2367 } 2368 2369 void updateCpuStats() { 2370 final long now = SystemClock.uptimeMillis(); 2371 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2372 return; 2373 } 2374 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2375 synchronized (mProcessCpuThread) { 2376 mProcessCpuThread.notify(); 2377 } 2378 } 2379 } 2380 2381 void updateCpuStatsNow() { 2382 synchronized (mProcessCpuThread) { 2383 mProcessCpuMutexFree.set(false); 2384 final long now = SystemClock.uptimeMillis(); 2385 boolean haveNewCpuStats = false; 2386 2387 if (MONITOR_CPU_USAGE && 2388 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2389 mLastCpuTime.set(now); 2390 haveNewCpuStats = true; 2391 mProcessCpuTracker.update(); 2392 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2393 //Slog.i(TAG, "Total CPU usage: " 2394 // + mProcessCpu.getTotalCpuPercent() + "%"); 2395 2396 // Slog the cpu usage if the property is set. 2397 if ("true".equals(SystemProperties.get("events.cpu"))) { 2398 int user = mProcessCpuTracker.getLastUserTime(); 2399 int system = mProcessCpuTracker.getLastSystemTime(); 2400 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2401 int irq = mProcessCpuTracker.getLastIrqTime(); 2402 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2403 int idle = mProcessCpuTracker.getLastIdleTime(); 2404 2405 int total = user + system + iowait + irq + softIrq + idle; 2406 if (total == 0) total = 1; 2407 2408 EventLog.writeEvent(EventLogTags.CPU, 2409 ((user+system+iowait+irq+softIrq) * 100) / total, 2410 (user * 100) / total, 2411 (system * 100) / total, 2412 (iowait * 100) / total, 2413 (irq * 100) / total, 2414 (softIrq * 100) / total); 2415 } 2416 } 2417 2418 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2419 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2420 synchronized(bstats) { 2421 synchronized(mPidsSelfLocked) { 2422 if (haveNewCpuStats) { 2423 if (mOnBattery) { 2424 int perc = bstats.startAddingCpuLocked(); 2425 int totalUTime = 0; 2426 int totalSTime = 0; 2427 final int N = mProcessCpuTracker.countStats(); 2428 for (int i=0; i<N; i++) { 2429 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2430 if (!st.working) { 2431 continue; 2432 } 2433 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2434 int otherUTime = (st.rel_utime*perc)/100; 2435 int otherSTime = (st.rel_stime*perc)/100; 2436 totalUTime += otherUTime; 2437 totalSTime += otherSTime; 2438 if (pr != null) { 2439 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2440 if (ps == null || !ps.isActive()) { 2441 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2442 pr.info.uid, pr.processName); 2443 } 2444 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2445 st.rel_stime-otherSTime); 2446 ps.addSpeedStepTimes(cpuSpeedTimes); 2447 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2448 } else { 2449 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2450 if (ps == null || !ps.isActive()) { 2451 st.batteryStats = ps = bstats.getProcessStatsLocked( 2452 bstats.mapUid(st.uid), st.name); 2453 } 2454 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2455 st.rel_stime-otherSTime); 2456 ps.addSpeedStepTimes(cpuSpeedTimes); 2457 } 2458 } 2459 bstats.finishAddingCpuLocked(perc, totalUTime, 2460 totalSTime, cpuSpeedTimes); 2461 } 2462 } 2463 } 2464 2465 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2466 mLastWriteTime = now; 2467 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2468 } 2469 } 2470 } 2471 } 2472 2473 @Override 2474 public void batteryNeedsCpuUpdate() { 2475 updateCpuStatsNow(); 2476 } 2477 2478 @Override 2479 public void batteryPowerChanged(boolean onBattery) { 2480 // When plugging in, update the CPU stats first before changing 2481 // the plug state. 2482 updateCpuStatsNow(); 2483 synchronized (this) { 2484 synchronized(mPidsSelfLocked) { 2485 mOnBattery = DEBUG_POWER ? true : onBattery; 2486 } 2487 } 2488 } 2489 2490 /** 2491 * Initialize the application bind args. These are passed to each 2492 * process when the bindApplication() IPC is sent to the process. They're 2493 * lazily setup to make sure the services are running when they're asked for. 2494 */ 2495 private HashMap<String, IBinder> getCommonServicesLocked() { 2496 if (mAppBindArgs == null) { 2497 mAppBindArgs = new HashMap<String, IBinder>(); 2498 2499 // Setup the application init args 2500 mAppBindArgs.put("package", ServiceManager.getService("package")); 2501 mAppBindArgs.put("window", ServiceManager.getService("window")); 2502 mAppBindArgs.put(Context.ALARM_SERVICE, 2503 ServiceManager.getService(Context.ALARM_SERVICE)); 2504 } 2505 return mAppBindArgs; 2506 } 2507 2508 final void setFocusedActivityLocked(ActivityRecord r) { 2509 if (mFocusedActivity != r) { 2510 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2511 mFocusedActivity = r; 2512 if (r.task != null && r.task.voiceInteractor != null) { 2513 startRunningVoiceLocked(); 2514 } else { 2515 finishRunningVoiceLocked(); 2516 } 2517 mStackSupervisor.setFocusedStack(r); 2518 if (r != null) { 2519 mWindowManager.setFocusedApp(r.appToken, true); 2520 } 2521 applyUpdateLockStateLocked(r); 2522 } 2523 } 2524 2525 final void clearFocusedActivity(ActivityRecord r) { 2526 if (mFocusedActivity == r) { 2527 mFocusedActivity = null; 2528 } 2529 } 2530 2531 @Override 2532 public void setFocusedStack(int stackId) { 2533 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2534 synchronized (ActivityManagerService.this) { 2535 ActivityStack stack = mStackSupervisor.getStack(stackId); 2536 if (stack != null) { 2537 ActivityRecord r = stack.topRunningActivityLocked(null); 2538 if (r != null) { 2539 setFocusedActivityLocked(r); 2540 } 2541 } 2542 } 2543 } 2544 2545 @Override 2546 public void notifyActivityDrawn(IBinder token) { 2547 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2548 synchronized (this) { 2549 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2550 if (r != null) { 2551 r.task.stack.notifyActivityDrawnLocked(r); 2552 } 2553 } 2554 } 2555 2556 final void applyUpdateLockStateLocked(ActivityRecord r) { 2557 // Modifications to the UpdateLock state are done on our handler, outside 2558 // the activity manager's locks. The new state is determined based on the 2559 // state *now* of the relevant activity record. The object is passed to 2560 // the handler solely for logging detail, not to be consulted/modified. 2561 final boolean nextState = r != null && r.immersive; 2562 mHandler.sendMessage( 2563 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2564 } 2565 2566 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2567 Message msg = Message.obtain(); 2568 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2569 msg.obj = r.task.askedCompatMode ? null : r; 2570 mHandler.sendMessage(msg); 2571 } 2572 2573 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2574 String what, Object obj, ProcessRecord srcApp) { 2575 app.lastActivityTime = now; 2576 2577 if (app.activities.size() > 0) { 2578 // Don't want to touch dependent processes that are hosting activities. 2579 return index; 2580 } 2581 2582 int lrui = mLruProcesses.lastIndexOf(app); 2583 if (lrui < 0) { 2584 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2585 + what + " " + obj + " from " + srcApp); 2586 return index; 2587 } 2588 2589 if (lrui >= index) { 2590 // Don't want to cause this to move dependent processes *back* in the 2591 // list as if they were less frequently used. 2592 return index; 2593 } 2594 2595 if (lrui >= mLruProcessActivityStart) { 2596 // Don't want to touch dependent processes that are hosting activities. 2597 return index; 2598 } 2599 2600 mLruProcesses.remove(lrui); 2601 if (index > 0) { 2602 index--; 2603 } 2604 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2605 + " in LRU list: " + app); 2606 mLruProcesses.add(index, app); 2607 return index; 2608 } 2609 2610 final void removeLruProcessLocked(ProcessRecord app) { 2611 int lrui = mLruProcesses.lastIndexOf(app); 2612 if (lrui >= 0) { 2613 if (lrui <= mLruProcessActivityStart) { 2614 mLruProcessActivityStart--; 2615 } 2616 if (lrui <= mLruProcessServiceStart) { 2617 mLruProcessServiceStart--; 2618 } 2619 mLruProcesses.remove(lrui); 2620 } 2621 } 2622 2623 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2624 ProcessRecord client) { 2625 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2626 || app.treatLikeActivity; 2627 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2628 if (!activityChange && hasActivity) { 2629 // The process has activities, so we are only allowing activity-based adjustments 2630 // to move it. It should be kept in the front of the list with other 2631 // processes that have activities, and we don't want those to change their 2632 // order except due to activity operations. 2633 return; 2634 } 2635 2636 mLruSeq++; 2637 final long now = SystemClock.uptimeMillis(); 2638 app.lastActivityTime = now; 2639 2640 // First a quick reject: if the app is already at the position we will 2641 // put it, then there is nothing to do. 2642 if (hasActivity) { 2643 final int N = mLruProcesses.size(); 2644 if (N > 0 && mLruProcesses.get(N-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2646 return; 2647 } 2648 } else { 2649 if (mLruProcessServiceStart > 0 2650 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2651 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2652 return; 2653 } 2654 } 2655 2656 int lrui = mLruProcesses.lastIndexOf(app); 2657 2658 if (app.persistent && lrui >= 0) { 2659 // We don't care about the position of persistent processes, as long as 2660 // they are in the list. 2661 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2662 return; 2663 } 2664 2665 /* In progress: compute new position first, so we can avoid doing work 2666 if the process is not actually going to move. Not yet working. 2667 int addIndex; 2668 int nextIndex; 2669 boolean inActivity = false, inService = false; 2670 if (hasActivity) { 2671 // Process has activities, put it at the very tipsy-top. 2672 addIndex = mLruProcesses.size(); 2673 nextIndex = mLruProcessServiceStart; 2674 inActivity = true; 2675 } else if (hasService) { 2676 // Process has services, put it at the top of the service list. 2677 addIndex = mLruProcessActivityStart; 2678 nextIndex = mLruProcessServiceStart; 2679 inActivity = true; 2680 inService = true; 2681 } else { 2682 // Process not otherwise of interest, it goes to the top of the non-service area. 2683 addIndex = mLruProcessServiceStart; 2684 if (client != null) { 2685 int clientIndex = mLruProcesses.lastIndexOf(client); 2686 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2687 + app); 2688 if (clientIndex >= 0 && addIndex > clientIndex) { 2689 addIndex = clientIndex; 2690 } 2691 } 2692 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2693 } 2694 2695 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2696 + mLruProcessActivityStart + "): " + app); 2697 */ 2698 2699 if (lrui >= 0) { 2700 if (lrui < mLruProcessActivityStart) { 2701 mLruProcessActivityStart--; 2702 } 2703 if (lrui < mLruProcessServiceStart) { 2704 mLruProcessServiceStart--; 2705 } 2706 /* 2707 if (addIndex > lrui) { 2708 addIndex--; 2709 } 2710 if (nextIndex > lrui) { 2711 nextIndex--; 2712 } 2713 */ 2714 mLruProcesses.remove(lrui); 2715 } 2716 2717 /* 2718 mLruProcesses.add(addIndex, app); 2719 if (inActivity) { 2720 mLruProcessActivityStart++; 2721 } 2722 if (inService) { 2723 mLruProcessActivityStart++; 2724 } 2725 */ 2726 2727 int nextIndex; 2728 if (hasActivity) { 2729 final int N = mLruProcesses.size(); 2730 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2731 // Process doesn't have activities, but has clients with 2732 // activities... move it up, but one below the top (the top 2733 // should always have a real activity). 2734 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2735 mLruProcesses.add(N-1, app); 2736 // To keep it from spamming the LRU list (by making a bunch of clients), 2737 // we will push down any other entries owned by the app. 2738 final int uid = app.info.uid; 2739 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2740 ProcessRecord subProc = mLruProcesses.get(i); 2741 if (subProc.info.uid == uid) { 2742 // We want to push this one down the list. If the process after 2743 // it is for the same uid, however, don't do so, because we don't 2744 // want them internally to be re-ordered. 2745 if (mLruProcesses.get(i-1).info.uid != uid) { 2746 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2747 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2748 ProcessRecord tmp = mLruProcesses.get(i); 2749 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2750 mLruProcesses.set(i-1, tmp); 2751 i--; 2752 } 2753 } else { 2754 // A gap, we can stop here. 2755 break; 2756 } 2757 } 2758 } else { 2759 // Process has activities, put it at the very tipsy-top. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2761 mLruProcesses.add(app); 2762 } 2763 nextIndex = mLruProcessServiceStart; 2764 } else if (hasService) { 2765 // Process has services, put it at the top of the service list. 2766 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2767 mLruProcesses.add(mLruProcessActivityStart, app); 2768 nextIndex = mLruProcessServiceStart; 2769 mLruProcessActivityStart++; 2770 } else { 2771 // Process not otherwise of interest, it goes to the top of the non-service area. 2772 int index = mLruProcessServiceStart; 2773 if (client != null) { 2774 // If there is a client, don't allow the process to be moved up higher 2775 // in the list than that client. 2776 int clientIndex = mLruProcesses.lastIndexOf(client); 2777 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2778 + " when updating " + app); 2779 if (clientIndex <= lrui) { 2780 // Don't allow the client index restriction to push it down farther in the 2781 // list than it already is. 2782 clientIndex = lrui; 2783 } 2784 if (clientIndex >= 0 && index > clientIndex) { 2785 index = clientIndex; 2786 } 2787 } 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2789 mLruProcesses.add(index, app); 2790 nextIndex = index-1; 2791 mLruProcessActivityStart++; 2792 mLruProcessServiceStart++; 2793 } 2794 2795 // If the app is currently using a content provider or service, 2796 // bump those processes as well. 2797 for (int j=app.connections.size()-1; j>=0; j--) { 2798 ConnectionRecord cr = app.connections.valueAt(j); 2799 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2800 && cr.binding.service.app != null 2801 && cr.binding.service.app.lruSeq != mLruSeq 2802 && !cr.binding.service.app.persistent) { 2803 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2804 "service connection", cr, app); 2805 } 2806 } 2807 for (int j=app.conProviders.size()-1; j>=0; j--) { 2808 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2809 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2810 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2811 "provider reference", cpr, app); 2812 } 2813 } 2814 } 2815 2816 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2817 if (uid == Process.SYSTEM_UID) { 2818 // The system gets to run in any process. If there are multiple 2819 // processes with the same uid, just pick the first (this 2820 // should never happen). 2821 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2822 if (procs == null) return null; 2823 final int N = procs.size(); 2824 for (int i = 0; i < N; i++) { 2825 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2826 } 2827 } 2828 ProcessRecord proc = mProcessNames.get(processName, uid); 2829 if (false && proc != null && !keepIfLarge 2830 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2831 && proc.lastCachedPss >= 4000) { 2832 // Turn this condition on to cause killing to happen regularly, for testing. 2833 if (proc.baseProcessTracker != null) { 2834 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2835 } 2836 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2837 } else if (proc != null && !keepIfLarge 2838 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2839 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2840 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2841 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2842 if (proc.baseProcessTracker != null) { 2843 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2844 } 2845 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2846 } 2847 } 2848 return proc; 2849 } 2850 2851 void ensurePackageDexOpt(String packageName) { 2852 IPackageManager pm = AppGlobals.getPackageManager(); 2853 try { 2854 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2855 mDidDexOpt = true; 2856 } 2857 } catch (RemoteException e) { 2858 } 2859 } 2860 2861 boolean isNextTransitionForward() { 2862 int transit = mWindowManager.getPendingAppTransition(); 2863 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_OPEN 2865 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2866 } 2867 2868 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2869 String processName, String abiOverride, int uid, Runnable crashHandler) { 2870 synchronized(this) { 2871 ApplicationInfo info = new ApplicationInfo(); 2872 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2873 // For isolated processes, the former contains the parent's uid and the latter the 2874 // actual uid of the isolated process. 2875 // In the special case introduced by this method (which is, starting an isolated 2876 // process directly from the SystemServer without an actual parent app process) the 2877 // closest thing to a parent's uid is SYSTEM_UID. 2878 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2879 // the |isolated| logic in the ProcessRecord constructor. 2880 info.uid = Process.SYSTEM_UID; 2881 info.processName = processName; 2882 info.className = entryPoint; 2883 info.packageName = "android"; 2884 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2885 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2886 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2887 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2888 crashHandler); 2889 return proc != null ? proc.pid : 0; 2890 } 2891 } 2892 2893 final ProcessRecord startProcessLocked(String processName, 2894 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2895 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2896 boolean isolated, boolean keepIfLarge) { 2897 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2898 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2899 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2900 null /* crashHandler */); 2901 } 2902 2903 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2904 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2905 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2906 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2907 long startTime = SystemClock.elapsedRealtime(); 2908 ProcessRecord app; 2909 if (!isolated) { 2910 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2911 checkTime(startTime, "startProcess: after getProcessRecord"); 2912 } else { 2913 // If this is an isolated process, it can't re-use an existing process. 2914 app = null; 2915 } 2916 // We don't have to do anything more if: 2917 // (1) There is an existing application record; and 2918 // (2) The caller doesn't think it is dead, OR there is no thread 2919 // object attached to it so we know it couldn't have crashed; and 2920 // (3) There is a pid assigned to it, so it is either starting or 2921 // already running. 2922 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2923 + " app=" + app + " knownToBeDead=" + knownToBeDead 2924 + " thread=" + (app != null ? app.thread : null) 2925 + " pid=" + (app != null ? app.pid : -1)); 2926 if (app != null && app.pid > 0) { 2927 if (!knownToBeDead || app.thread == null) { 2928 // We already have the app running, or are waiting for it to 2929 // come up (we have a pid but not yet its thread), so keep it. 2930 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2931 // If this is a new package in the process, add the package to the list 2932 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2933 checkTime(startTime, "startProcess: done, added package to proc"); 2934 return app; 2935 } 2936 2937 // An application record is attached to a previous process, 2938 // clean it up now. 2939 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2940 checkTime(startTime, "startProcess: bad proc running, killing"); 2941 Process.killProcessGroup(app.info.uid, app.pid); 2942 handleAppDiedLocked(app, true, true); 2943 checkTime(startTime, "startProcess: done killing old proc"); 2944 } 2945 2946 String hostingNameStr = hostingName != null 2947 ? hostingName.flattenToShortString() : null; 2948 2949 if (!isolated) { 2950 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2951 // If we are in the background, then check to see if this process 2952 // is bad. If so, we will just silently fail. 2953 if (mBadProcesses.get(info.processName, info.uid) != null) { 2954 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2955 + "/" + info.processName); 2956 return null; 2957 } 2958 } else { 2959 // When the user is explicitly starting a process, then clear its 2960 // crash count so that we won't make it bad until they see at 2961 // least one crash dialog again, and make the process good again 2962 // if it had been bad. 2963 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2964 + "/" + info.processName); 2965 mProcessCrashTimes.remove(info.processName, info.uid); 2966 if (mBadProcesses.get(info.processName, info.uid) != null) { 2967 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2968 UserHandle.getUserId(info.uid), info.uid, 2969 info.processName); 2970 mBadProcesses.remove(info.processName, info.uid); 2971 if (app != null) { 2972 app.bad = false; 2973 } 2974 } 2975 } 2976 } 2977 2978 if (app == null) { 2979 checkTime(startTime, "startProcess: creating new process record"); 2980 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2981 app.crashHandler = crashHandler; 2982 if (app == null) { 2983 Slog.w(TAG, "Failed making new process record for " 2984 + processName + "/" + info.uid + " isolated=" + isolated); 2985 return null; 2986 } 2987 mProcessNames.put(processName, app.uid, app); 2988 if (isolated) { 2989 mIsolatedProcesses.put(app.uid, app); 2990 } 2991 checkTime(startTime, "startProcess: done creating new process record"); 2992 } else { 2993 // If this is a new package in the process, add the package to the list 2994 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2995 checkTime(startTime, "startProcess: added package to existing proc"); 2996 } 2997 2998 // If the system is not ready yet, then hold off on starting this 2999 // process until it is. 3000 if (!mProcessesReady 3001 && !isAllowedWhileBooting(info) 3002 && !allowWhileBooting) { 3003 if (!mProcessesOnHold.contains(app)) { 3004 mProcessesOnHold.add(app); 3005 } 3006 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3007 checkTime(startTime, "startProcess: returning with proc on hold"); 3008 return app; 3009 } 3010 3011 checkTime(startTime, "startProcess: stepping in to startProcess"); 3012 startProcessLocked( 3013 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3014 checkTime(startTime, "startProcess: done starting proc!"); 3015 return (app.pid != 0) ? app : null; 3016 } 3017 3018 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3019 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3020 } 3021 3022 private final void startProcessLocked(ProcessRecord app, 3023 String hostingType, String hostingNameStr) { 3024 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3025 null /* entryPoint */, null /* entryPointArgs */); 3026 } 3027 3028 private final void startProcessLocked(ProcessRecord app, String hostingType, 3029 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3030 long startTime = SystemClock.elapsedRealtime(); 3031 if (app.pid > 0 && app.pid != MY_PID) { 3032 checkTime(startTime, "startProcess: removing from pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 mPidsSelfLocked.remove(app.pid); 3035 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3036 } 3037 checkTime(startTime, "startProcess: done removing from pids map"); 3038 app.setPid(0); 3039 } 3040 3041 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3042 "startProcessLocked removing on hold: " + app); 3043 mProcessesOnHold.remove(app); 3044 3045 checkTime(startTime, "startProcess: starting to update cpu stats"); 3046 updateCpuStats(); 3047 checkTime(startTime, "startProcess: done updating cpu stats"); 3048 3049 try { 3050 int uid = app.uid; 3051 3052 int[] gids = null; 3053 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3054 if (!app.isolated) { 3055 int[] permGids = null; 3056 try { 3057 checkTime(startTime, "startProcess: getting gids from package manager"); 3058 final PackageManager pm = mContext.getPackageManager(); 3059 permGids = pm.getPackageGids(app.info.packageName); 3060 3061 if (Environment.isExternalStorageEmulated()) { 3062 checkTime(startTime, "startProcess: checking external storage perm"); 3063 if (pm.checkPermission( 3064 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3065 app.info.packageName) == PERMISSION_GRANTED) { 3066 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3067 } else { 3068 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3069 } 3070 } 3071 } catch (PackageManager.NameNotFoundException e) { 3072 Slog.w(TAG, "Unable to retrieve gids", e); 3073 } 3074 3075 /* 3076 * Add shared application and profile GIDs so applications can share some 3077 * resources like shared libraries and access user-wide resources 3078 */ 3079 if (permGids == null) { 3080 gids = new int[2]; 3081 } else { 3082 gids = new int[permGids.length + 2]; 3083 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3084 } 3085 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3086 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3087 } 3088 checkTime(startTime, "startProcess: building args"); 3089 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3090 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3091 && mTopComponent != null 3092 && app.processName.equals(mTopComponent.getPackageName())) { 3093 uid = 0; 3094 } 3095 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3096 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3097 uid = 0; 3098 } 3099 } 3100 int debugFlags = 0; 3101 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3102 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3103 // Also turn on CheckJNI for debuggable apps. It's quite 3104 // awkward to turn on otherwise. 3105 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3106 } 3107 // Run the app in safe mode if its manifest requests so or the 3108 // system is booted in safe mode. 3109 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3110 mSafeMode == true) { 3111 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3112 } 3113 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3114 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3115 } 3116 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3117 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3118 } 3119 if ("1".equals(SystemProperties.get("debug.assert"))) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3121 } 3122 3123 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3124 if (requiredAbi == null) { 3125 requiredAbi = Build.SUPPORTED_ABIS[0]; 3126 } 3127 3128 String instructionSet = null; 3129 if (app.info.primaryCpuAbi != null) { 3130 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3131 } 3132 3133 // Start the process. It will either succeed and return a result containing 3134 // the PID of the new process, or else throw a RuntimeException. 3135 boolean isActivityProcess = (entryPoint == null); 3136 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3137 checkTime(startTime, "startProcess: asking zygote to start proc"); 3138 Process.ProcessStartResult startResult = Process.start(entryPoint, 3139 app.processName, uid, uid, gids, debugFlags, mountExternal, 3140 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3141 entryPointArgs); 3142 checkTime(startTime, "startProcess: returned from zygote!"); 3143 3144 if (app.isolated) { 3145 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3146 } 3147 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3148 checkTime(startTime, "startProcess: done updating battery stats"); 3149 3150 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3151 UserHandle.getUserId(uid), startResult.pid, uid, 3152 app.processName, hostingType, 3153 hostingNameStr != null ? hostingNameStr : ""); 3154 3155 if (app.persistent) { 3156 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3157 } 3158 3159 checkTime(startTime, "startProcess: building log message"); 3160 StringBuilder buf = mStringBuilder; 3161 buf.setLength(0); 3162 buf.append("Start proc "); 3163 buf.append(app.processName); 3164 if (!isActivityProcess) { 3165 buf.append(" ["); 3166 buf.append(entryPoint); 3167 buf.append("]"); 3168 } 3169 buf.append(" for "); 3170 buf.append(hostingType); 3171 if (hostingNameStr != null) { 3172 buf.append(" "); 3173 buf.append(hostingNameStr); 3174 } 3175 buf.append(": pid="); 3176 buf.append(startResult.pid); 3177 buf.append(" uid="); 3178 buf.append(uid); 3179 buf.append(" gids={"); 3180 if (gids != null) { 3181 for (int gi=0; gi<gids.length; gi++) { 3182 if (gi != 0) buf.append(", "); 3183 buf.append(gids[gi]); 3184 3185 } 3186 } 3187 buf.append("}"); 3188 if (requiredAbi != null) { 3189 buf.append(" abi="); 3190 buf.append(requiredAbi); 3191 } 3192 Slog.i(TAG, buf.toString()); 3193 app.setPid(startResult.pid); 3194 app.usingWrapper = startResult.usingWrapper; 3195 app.removed = false; 3196 app.killedByAm = false; 3197 checkTime(startTime, "startProcess: starting to update pids map"); 3198 synchronized (mPidsSelfLocked) { 3199 this.mPidsSelfLocked.put(startResult.pid, app); 3200 if (isActivityProcess) { 3201 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3202 msg.obj = app; 3203 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3204 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3205 } 3206 } 3207 checkTime(startTime, "startProcess: done updating pids map"); 3208 } catch (RuntimeException e) { 3209 // XXX do better error recovery. 3210 app.setPid(0); 3211 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3212 if (app.isolated) { 3213 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3214 } 3215 Slog.e(TAG, "Failure starting process " + app.processName, e); 3216 } 3217 } 3218 3219 void updateUsageStats(ActivityRecord component, boolean resumed) { 3220 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3221 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3222 if (resumed) { 3223 if (mUsageStatsService != null) { 3224 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3225 UsageEvents.Event.MOVE_TO_FOREGROUND); 3226 } 3227 synchronized (stats) { 3228 stats.noteActivityResumedLocked(component.app.uid); 3229 } 3230 } else { 3231 if (mUsageStatsService != null) { 3232 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3233 UsageEvents.Event.MOVE_TO_BACKGROUND); 3234 } 3235 synchronized (stats) { 3236 stats.noteActivityPausedLocked(component.app.uid); 3237 } 3238 } 3239 } 3240 3241 Intent getHomeIntent() { 3242 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3243 intent.setComponent(mTopComponent); 3244 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3245 intent.addCategory(Intent.CATEGORY_HOME); 3246 } 3247 return intent; 3248 } 3249 3250 boolean startHomeActivityLocked(int userId) { 3251 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3252 && mTopAction == null) { 3253 // We are running in factory test mode, but unable to find 3254 // the factory test app, so just sit around displaying the 3255 // error message and don't try to start anything. 3256 return false; 3257 } 3258 Intent intent = getHomeIntent(); 3259 ActivityInfo aInfo = 3260 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3261 if (aInfo != null) { 3262 intent.setComponent(new ComponentName( 3263 aInfo.applicationInfo.packageName, aInfo.name)); 3264 // Don't do this if the home app is currently being 3265 // instrumented. 3266 aInfo = new ActivityInfo(aInfo); 3267 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3268 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3269 aInfo.applicationInfo.uid, true); 3270 if (app == null || app.instrumentationClass == null) { 3271 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3272 mStackSupervisor.startHomeActivity(intent, aInfo); 3273 } 3274 } 3275 3276 return true; 3277 } 3278 3279 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3280 ActivityInfo ai = null; 3281 ComponentName comp = intent.getComponent(); 3282 try { 3283 if (comp != null) { 3284 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3285 } else { 3286 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3287 intent, 3288 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3289 flags, userId); 3290 3291 if (info != null) { 3292 ai = info.activityInfo; 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 // ignore 3297 } 3298 3299 return ai; 3300 } 3301 3302 /** 3303 * Starts the "new version setup screen" if appropriate. 3304 */ 3305 void startSetupActivityLocked() { 3306 // Only do this once per boot. 3307 if (mCheckedForSetup) { 3308 return; 3309 } 3310 3311 // We will show this screen if the current one is a different 3312 // version than the last one shown, and we are not running in 3313 // low-level factory test mode. 3314 final ContentResolver resolver = mContext.getContentResolver(); 3315 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3316 Settings.Global.getInt(resolver, 3317 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3318 mCheckedForSetup = true; 3319 3320 // See if we should be showing the platform update setup UI. 3321 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3322 List<ResolveInfo> ris = mContext.getPackageManager() 3323 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3324 3325 // We don't allow third party apps to replace this. 3326 ResolveInfo ri = null; 3327 for (int i=0; ris != null && i<ris.size(); i++) { 3328 if ((ris.get(i).activityInfo.applicationInfo.flags 3329 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3330 ri = ris.get(i); 3331 break; 3332 } 3333 } 3334 3335 if (ri != null) { 3336 String vers = ri.activityInfo.metaData != null 3337 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3338 : null; 3339 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3340 vers = ri.activityInfo.applicationInfo.metaData.getString( 3341 Intent.METADATA_SETUP_VERSION); 3342 } 3343 String lastVers = Settings.Secure.getString( 3344 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3345 if (vers != null && !vers.equals(lastVers)) { 3346 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3347 intent.setComponent(new ComponentName( 3348 ri.activityInfo.packageName, ri.activityInfo.name)); 3349 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3350 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3351 null); 3352 } 3353 } 3354 } 3355 } 3356 3357 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3358 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3359 } 3360 3361 void enforceNotIsolatedCaller(String caller) { 3362 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3363 throw new SecurityException("Isolated process not allowed to call " + caller); 3364 } 3365 } 3366 3367 @Override 3368 public int getFrontActivityScreenCompatMode() { 3369 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3370 synchronized (this) { 3371 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3372 } 3373 } 3374 3375 @Override 3376 public void setFrontActivityScreenCompatMode(int mode) { 3377 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3378 "setFrontActivityScreenCompatMode"); 3379 synchronized (this) { 3380 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3381 } 3382 } 3383 3384 @Override 3385 public int getPackageScreenCompatMode(String packageName) { 3386 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3387 synchronized (this) { 3388 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3389 } 3390 } 3391 3392 @Override 3393 public void setPackageScreenCompatMode(String packageName, int mode) { 3394 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3395 "setPackageScreenCompatMode"); 3396 synchronized (this) { 3397 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3398 } 3399 } 3400 3401 @Override 3402 public boolean getPackageAskScreenCompat(String packageName) { 3403 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3404 synchronized (this) { 3405 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3406 } 3407 } 3408 3409 @Override 3410 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3412 "setPackageAskScreenCompat"); 3413 synchronized (this) { 3414 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3415 } 3416 } 3417 3418 private void dispatchProcessesChanged() { 3419 int N; 3420 synchronized (this) { 3421 N = mPendingProcessChanges.size(); 3422 if (mActiveProcessChanges.length < N) { 3423 mActiveProcessChanges = new ProcessChangeItem[N]; 3424 } 3425 mPendingProcessChanges.toArray(mActiveProcessChanges); 3426 mAvailProcessChanges.addAll(mPendingProcessChanges); 3427 mPendingProcessChanges.clear(); 3428 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3429 } 3430 3431 int i = mProcessObservers.beginBroadcast(); 3432 while (i > 0) { 3433 i--; 3434 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3435 if (observer != null) { 3436 try { 3437 for (int j=0; j<N; j++) { 3438 ProcessChangeItem item = mActiveProcessChanges[j]; 3439 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3440 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3441 + item.pid + " uid=" + item.uid + ": " 3442 + item.foregroundActivities); 3443 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3444 item.foregroundActivities); 3445 } 3446 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3447 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3448 + item.pid + " uid=" + item.uid + ": " + item.processState); 3449 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3450 } 3451 } 3452 } catch (RemoteException e) { 3453 } 3454 } 3455 } 3456 mProcessObservers.finishBroadcast(); 3457 } 3458 3459 private void dispatchProcessDied(int pid, int uid) { 3460 int i = mProcessObservers.beginBroadcast(); 3461 while (i > 0) { 3462 i--; 3463 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3464 if (observer != null) { 3465 try { 3466 observer.onProcessDied(pid, uid); 3467 } catch (RemoteException e) { 3468 } 3469 } 3470 } 3471 mProcessObservers.finishBroadcast(); 3472 } 3473 3474 @Override 3475 public final int startActivity(IApplicationThread caller, String callingPackage, 3476 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3477 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3478 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3479 resultWho, requestCode, startFlags, profilerInfo, options, 3480 UserHandle.getCallingUserId()); 3481 } 3482 3483 @Override 3484 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3485 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3486 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3487 enforceNotIsolatedCaller("startActivity"); 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3489 false, ALLOW_FULL_ONLY, "startActivity", null); 3490 // TODO: Switch to user app stacks here. 3491 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3492 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3493 profilerInfo, null, null, options, userId, null, null); 3494 } 3495 3496 @Override 3497 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3498 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3499 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3500 3501 // This is very dangerous -- it allows you to perform a start activity (including 3502 // permission grants) as any app that may launch one of your own activities. So 3503 // we will only allow this to be done from activities that are part of the core framework, 3504 // and then only when they are running as the system. 3505 final ActivityRecord sourceRecord; 3506 final int targetUid; 3507 final String targetPackage; 3508 synchronized (this) { 3509 if (resultTo == null) { 3510 throw new SecurityException("Must be called from an activity"); 3511 } 3512 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3513 if (sourceRecord == null) { 3514 throw new SecurityException("Called with bad activity token: " + resultTo); 3515 } 3516 if (!sourceRecord.info.packageName.equals("android")) { 3517 throw new SecurityException( 3518 "Must be called from an activity that is declared in the android package"); 3519 } 3520 if (sourceRecord.app == null) { 3521 throw new SecurityException("Called without a process attached to activity"); 3522 } 3523 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3524 // This is still okay, as long as this activity is running under the 3525 // uid of the original calling activity. 3526 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3527 throw new SecurityException( 3528 "Calling activity in uid " + sourceRecord.app.uid 3529 + " must be system uid or original calling uid " 3530 + sourceRecord.launchedFromUid); 3531 } 3532 } 3533 targetUid = sourceRecord.launchedFromUid; 3534 targetPackage = sourceRecord.launchedFromPackage; 3535 } 3536 3537 // TODO: Switch to user app stacks here. 3538 try { 3539 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3540 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3541 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3542 return ret; 3543 } catch (SecurityException e) { 3544 // XXX need to figure out how to propagate to original app. 3545 // A SecurityException here is generally actually a fault of the original 3546 // calling activity (such as a fairly granting permissions), so propagate it 3547 // back to them. 3548 /* 3549 StringBuilder msg = new StringBuilder(); 3550 msg.append("While launching"); 3551 msg.append(intent.toString()); 3552 msg.append(": "); 3553 msg.append(e.getMessage()); 3554 */ 3555 throw e; 3556 } 3557 } 3558 3559 @Override 3560 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3561 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3562 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3563 enforceNotIsolatedCaller("startActivityAndWait"); 3564 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3565 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3566 WaitResult res = new WaitResult(); 3567 // TODO: Switch to user app stacks here. 3568 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3569 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3570 options, userId, null, null); 3571 return res; 3572 } 3573 3574 @Override 3575 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3576 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3577 int startFlags, Configuration config, Bundle options, int userId) { 3578 enforceNotIsolatedCaller("startActivityWithConfig"); 3579 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3580 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3581 // TODO: Switch to user app stacks here. 3582 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3583 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3584 null, null, config, options, userId, null, null); 3585 return ret; 3586 } 3587 3588 @Override 3589 public int startActivityIntentSender(IApplicationThread caller, 3590 IntentSender intent, Intent fillInIntent, String resolvedType, 3591 IBinder resultTo, String resultWho, int requestCode, 3592 int flagsMask, int flagsValues, Bundle options) { 3593 enforceNotIsolatedCaller("startActivityIntentSender"); 3594 // Refuse possible leaked file descriptors 3595 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3596 throw new IllegalArgumentException("File descriptors passed in Intent"); 3597 } 3598 3599 IIntentSender sender = intent.getTarget(); 3600 if (!(sender instanceof PendingIntentRecord)) { 3601 throw new IllegalArgumentException("Bad PendingIntent object"); 3602 } 3603 3604 PendingIntentRecord pir = (PendingIntentRecord)sender; 3605 3606 synchronized (this) { 3607 // If this is coming from the currently resumed activity, it is 3608 // effectively saying that app switches are allowed at this point. 3609 final ActivityStack stack = getFocusedStack(); 3610 if (stack.mResumedActivity != null && 3611 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3612 mAppSwitchesAllowedTime = 0; 3613 } 3614 } 3615 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3616 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3617 return ret; 3618 } 3619 3620 @Override 3621 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3622 Intent intent, String resolvedType, IVoiceInteractionSession session, 3623 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3624 Bundle options, int userId) { 3625 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3626 != PackageManager.PERMISSION_GRANTED) { 3627 String msg = "Permission Denial: startVoiceActivity() from pid=" 3628 + Binder.getCallingPid() 3629 + ", uid=" + Binder.getCallingUid() 3630 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3631 Slog.w(TAG, msg); 3632 throw new SecurityException(msg); 3633 } 3634 if (session == null || interactor == null) { 3635 throw new NullPointerException("null session or interactor"); 3636 } 3637 userId = handleIncomingUser(callingPid, callingUid, userId, 3638 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3639 // TODO: Switch to user app stacks here. 3640 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3641 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3642 null, options, userId, null, null); 3643 } 3644 3645 @Override 3646 public boolean startNextMatchingActivity(IBinder callingActivity, 3647 Intent intent, Bundle options) { 3648 // Refuse possible leaked file descriptors 3649 if (intent != null && intent.hasFileDescriptors() == true) { 3650 throw new IllegalArgumentException("File descriptors passed in Intent"); 3651 } 3652 3653 synchronized (this) { 3654 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3655 if (r == null) { 3656 ActivityOptions.abort(options); 3657 return false; 3658 } 3659 if (r.app == null || r.app.thread == null) { 3660 // The caller is not running... d'oh! 3661 ActivityOptions.abort(options); 3662 return false; 3663 } 3664 intent = new Intent(intent); 3665 // The caller is not allowed to change the data. 3666 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3667 // And we are resetting to find the next component... 3668 intent.setComponent(null); 3669 3670 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3671 3672 ActivityInfo aInfo = null; 3673 try { 3674 List<ResolveInfo> resolves = 3675 AppGlobals.getPackageManager().queryIntentActivities( 3676 intent, r.resolvedType, 3677 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3678 UserHandle.getCallingUserId()); 3679 3680 // Look for the original activity in the list... 3681 final int N = resolves != null ? resolves.size() : 0; 3682 for (int i=0; i<N; i++) { 3683 ResolveInfo rInfo = resolves.get(i); 3684 if (rInfo.activityInfo.packageName.equals(r.packageName) 3685 && rInfo.activityInfo.name.equals(r.info.name)) { 3686 // We found the current one... the next matching is 3687 // after it. 3688 i++; 3689 if (i<N) { 3690 aInfo = resolves.get(i).activityInfo; 3691 } 3692 if (debug) { 3693 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3694 + "/" + r.info.name); 3695 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3696 + "/" + aInfo.name); 3697 } 3698 break; 3699 } 3700 } 3701 } catch (RemoteException e) { 3702 } 3703 3704 if (aInfo == null) { 3705 // Nobody who is next! 3706 ActivityOptions.abort(options); 3707 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3708 return false; 3709 } 3710 3711 intent.setComponent(new ComponentName( 3712 aInfo.applicationInfo.packageName, aInfo.name)); 3713 intent.setFlags(intent.getFlags()&~( 3714 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3715 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3716 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3717 Intent.FLAG_ACTIVITY_NEW_TASK)); 3718 3719 // Okay now we need to start the new activity, replacing the 3720 // currently running activity. This is a little tricky because 3721 // we want to start the new one as if the current one is finished, 3722 // but not finish the current one first so that there is no flicker. 3723 // And thus... 3724 final boolean wasFinishing = r.finishing; 3725 r.finishing = true; 3726 3727 // Propagate reply information over to the new activity. 3728 final ActivityRecord resultTo = r.resultTo; 3729 final String resultWho = r.resultWho; 3730 final int requestCode = r.requestCode; 3731 r.resultTo = null; 3732 if (resultTo != null) { 3733 resultTo.removeResultsLocked(r, resultWho, requestCode); 3734 } 3735 3736 final long origId = Binder.clearCallingIdentity(); 3737 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3738 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3739 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3740 options, false, null, null, null); 3741 Binder.restoreCallingIdentity(origId); 3742 3743 r.finishing = wasFinishing; 3744 if (res != ActivityManager.START_SUCCESS) { 3745 return false; 3746 } 3747 return true; 3748 } 3749 } 3750 3751 @Override 3752 public final int startActivityFromRecents(int taskId, Bundle options) { 3753 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3754 String msg = "Permission Denial: startActivityFromRecents called without " + 3755 START_TASKS_FROM_RECENTS; 3756 Slog.w(TAG, msg); 3757 throw new SecurityException(msg); 3758 } 3759 return startActivityFromRecentsInner(taskId, options); 3760 } 3761 3762 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3763 final TaskRecord task; 3764 final int callingUid; 3765 final String callingPackage; 3766 final Intent intent; 3767 final int userId; 3768 synchronized (this) { 3769 task = recentTaskForIdLocked(taskId); 3770 if (task == null) { 3771 throw new IllegalArgumentException("Task " + taskId + " not found."); 3772 } 3773 callingUid = task.mCallingUid; 3774 callingPackage = task.mCallingPackage; 3775 intent = task.intent; 3776 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3777 userId = task.userId; 3778 } 3779 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3780 options, userId, null, task); 3781 } 3782 3783 final int startActivityInPackage(int uid, String callingPackage, 3784 Intent intent, String resolvedType, IBinder resultTo, 3785 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3786 IActivityContainer container, TaskRecord inTask) { 3787 3788 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3789 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3790 3791 // TODO: Switch to user app stacks here. 3792 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3793 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3794 null, null, null, options, userId, container, inTask); 3795 return ret; 3796 } 3797 3798 @Override 3799 public final int startActivities(IApplicationThread caller, String callingPackage, 3800 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3801 int userId) { 3802 enforceNotIsolatedCaller("startActivities"); 3803 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3804 false, ALLOW_FULL_ONLY, "startActivity", null); 3805 // TODO: Switch to user app stacks here. 3806 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3807 resolvedTypes, resultTo, options, userId); 3808 return ret; 3809 } 3810 3811 final int startActivitiesInPackage(int uid, String callingPackage, 3812 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3813 Bundle options, int userId) { 3814 3815 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3816 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3817 // TODO: Switch to user app stacks here. 3818 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3819 resultTo, options, userId); 3820 return ret; 3821 } 3822 3823 //explicitly remove thd old information in mRecentTasks when removing existing user. 3824 private void removeRecentTasksForUserLocked(int userId) { 3825 if(userId <= 0) { 3826 Slog.i(TAG, "Can't remove recent task on user " + userId); 3827 return; 3828 } 3829 3830 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3831 TaskRecord tr = mRecentTasks.get(i); 3832 if (tr.userId == userId) { 3833 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3834 + " when finishing user" + userId); 3835 mRecentTasks.remove(i); 3836 tr.removedFromRecents(mTaskPersister); 3837 } 3838 } 3839 3840 // Remove tasks from persistent storage. 3841 mTaskPersister.wakeup(null, true); 3842 } 3843 3844 /** 3845 * Update the recent tasks lists: make sure tasks should still be here (their 3846 * applications / activities still exist), update their availability, fixup ordering 3847 * of affiliations. 3848 */ 3849 void cleanupRecentTasksLocked(int userId) { 3850 if (mRecentTasks == null) { 3851 // Happens when called from the packagemanager broadcast before boot. 3852 return; 3853 } 3854 3855 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3856 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3857 final IPackageManager pm = AppGlobals.getPackageManager(); 3858 final ActivityInfo dummyAct = new ActivityInfo(); 3859 final ApplicationInfo dummyApp = new ApplicationInfo(); 3860 3861 int N = mRecentTasks.size(); 3862 3863 int[] users = userId == UserHandle.USER_ALL 3864 ? getUsersLocked() : new int[] { userId }; 3865 for (int user : users) { 3866 for (int i = 0; i < N; i++) { 3867 TaskRecord task = mRecentTasks.get(i); 3868 if (task.userId != user) { 3869 // Only look at tasks for the user ID of interest. 3870 continue; 3871 } 3872 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3873 // This situation is broken, and we should just get rid of it now. 3874 mRecentTasks.remove(i); 3875 task.removedFromRecents(mTaskPersister); 3876 i--; 3877 N--; 3878 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3879 continue; 3880 } 3881 // Check whether this activity is currently available. 3882 if (task.realActivity != null) { 3883 ActivityInfo ai = availActCache.get(task.realActivity); 3884 if (ai == null) { 3885 try { 3886 ai = pm.getActivityInfo(task.realActivity, 3887 PackageManager.GET_UNINSTALLED_PACKAGES 3888 | PackageManager.GET_DISABLED_COMPONENTS, user); 3889 } catch (RemoteException e) { 3890 // Will never happen. 3891 continue; 3892 } 3893 if (ai == null) { 3894 ai = dummyAct; 3895 } 3896 availActCache.put(task.realActivity, ai); 3897 } 3898 if (ai == dummyAct) { 3899 // This could be either because the activity no longer exists, or the 3900 // app is temporarily gone. For the former we want to remove the recents 3901 // entry; for the latter we want to mark it as unavailable. 3902 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3903 if (app == null) { 3904 try { 3905 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3906 PackageManager.GET_UNINSTALLED_PACKAGES 3907 | PackageManager.GET_DISABLED_COMPONENTS, user); 3908 } catch (RemoteException e) { 3909 // Will never happen. 3910 continue; 3911 } 3912 if (app == null) { 3913 app = dummyApp; 3914 } 3915 availAppCache.put(task.realActivity.getPackageName(), app); 3916 } 3917 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3918 // Doesn't exist any more! Good-bye. 3919 mRecentTasks.remove(i); 3920 task.removedFromRecents(mTaskPersister); 3921 i--; 3922 N--; 3923 Slog.w(TAG, "Removing no longer valid recent: " + task); 3924 continue; 3925 } else { 3926 // Otherwise just not available for now. 3927 if (task.isAvailable) { 3928 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3929 + task); 3930 } 3931 task.isAvailable = false; 3932 } 3933 } else { 3934 if (!ai.enabled || !ai.applicationInfo.enabled 3935 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3936 if (task.isAvailable) { 3937 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3938 + task + " (enabled=" + ai.enabled + "/" 3939 + ai.applicationInfo.enabled + " flags=" 3940 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3941 } 3942 task.isAvailable = false; 3943 } else { 3944 if (!task.isAvailable) { 3945 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3946 + task); 3947 } 3948 task.isAvailable = true; 3949 } 3950 } 3951 } 3952 } 3953 } 3954 3955 // Verify the affiliate chain for each task. 3956 for (int i = 0; i < N; ) { 3957 TaskRecord task = mRecentTasks.remove(i); 3958 if (mTmpRecents.contains(task)) { 3959 continue; 3960 } 3961 int affiliatedTaskId = task.mAffiliatedTaskId; 3962 while (true) { 3963 TaskRecord next = task.mNextAffiliate; 3964 if (next == null) { 3965 break; 3966 } 3967 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3968 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3969 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3970 task.setNextAffiliate(null); 3971 if (next.mPrevAffiliate == task) { 3972 next.setPrevAffiliate(null); 3973 } 3974 break; 3975 } 3976 if (next.mPrevAffiliate != task) { 3977 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3978 next.mPrevAffiliate + " task=" + task); 3979 next.setPrevAffiliate(null); 3980 task.setNextAffiliate(null); 3981 break; 3982 } 3983 if (!mRecentTasks.contains(next)) { 3984 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3985 task.setNextAffiliate(null); 3986 // We know that next.mPrevAffiliate is always task, from above, so clear 3987 // its previous affiliate. 3988 next.setPrevAffiliate(null); 3989 break; 3990 } 3991 task = next; 3992 } 3993 // task is now the end of the list 3994 do { 3995 mRecentTasks.remove(task); 3996 mRecentTasks.add(i++, task); 3997 mTmpRecents.add(task); 3998 task.inRecents = true; 3999 } while ((task = task.mPrevAffiliate) != null); 4000 } 4001 mTmpRecents.clear(); 4002 // mRecentTasks is now in sorted, affiliated order. 4003 } 4004 4005 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4006 int N = mRecentTasks.size(); 4007 TaskRecord top = task; 4008 int topIndex = taskIndex; 4009 while (top.mNextAffiliate != null && topIndex > 0) { 4010 top = top.mNextAffiliate; 4011 topIndex--; 4012 } 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4014 + topIndex + " from intial " + taskIndex); 4015 // Find the end of the chain, doing a sanity check along the way. 4016 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4017 int endIndex = topIndex; 4018 TaskRecord prev = top; 4019 while (endIndex < N) { 4020 TaskRecord cur = mRecentTasks.get(endIndex); 4021 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4022 + endIndex + " " + cur); 4023 if (cur == top) { 4024 // Verify start of the chain. 4025 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4026 Slog.wtf(TAG, "Bad chain @" + endIndex 4027 + ": first task has next affiliate: " + prev); 4028 sane = false; 4029 break; 4030 } 4031 } else { 4032 // Verify middle of the chain's next points back to the one before. 4033 if (cur.mNextAffiliate != prev 4034 || cur.mNextAffiliateTaskId != prev.taskId) { 4035 Slog.wtf(TAG, "Bad chain @" + endIndex 4036 + ": middle task " + cur + " @" + endIndex 4037 + " has bad next affiliate " 4038 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4039 + ", expected " + prev); 4040 sane = false; 4041 break; 4042 } 4043 } 4044 if (cur.mPrevAffiliateTaskId == -1) { 4045 // Chain ends here. 4046 if (cur.mPrevAffiliate != null) { 4047 Slog.wtf(TAG, "Bad chain @" + endIndex 4048 + ": last task " + cur + " has previous affiliate " 4049 + cur.mPrevAffiliate); 4050 sane = false; 4051 } 4052 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4053 break; 4054 } else { 4055 // Verify middle of the chain's prev points to a valid item. 4056 if (cur.mPrevAffiliate == null) { 4057 Slog.wtf(TAG, "Bad chain @" + endIndex 4058 + ": task " + cur + " has previous affiliate " 4059 + cur.mPrevAffiliate + " but should be id " 4060 + cur.mPrevAffiliate); 4061 sane = false; 4062 break; 4063 } 4064 } 4065 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4066 Slog.wtf(TAG, "Bad chain @" + endIndex 4067 + ": task " + cur + " has affiliated id " 4068 + cur.mAffiliatedTaskId + " but should be " 4069 + task.mAffiliatedTaskId); 4070 sane = false; 4071 break; 4072 } 4073 prev = cur; 4074 endIndex++; 4075 if (endIndex >= N) { 4076 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4077 + ": last task " + prev); 4078 sane = false; 4079 break; 4080 } 4081 } 4082 if (sane) { 4083 if (endIndex < taskIndex) { 4084 Slog.wtf(TAG, "Bad chain @" + endIndex 4085 + ": did not extend to task " + task + " @" + taskIndex); 4086 sane = false; 4087 } 4088 } 4089 if (sane) { 4090 // All looks good, we can just move all of the affiliated tasks 4091 // to the top. 4092 for (int i=topIndex; i<=endIndex; i++) { 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4094 + " from " + i + " to " + (i-topIndex)); 4095 TaskRecord cur = mRecentTasks.remove(i); 4096 mRecentTasks.add(i-topIndex, cur); 4097 } 4098 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4099 + " to " + endIndex); 4100 return true; 4101 } 4102 4103 // Whoops, couldn't do it. 4104 return false; 4105 } 4106 4107 final void addRecentTaskLocked(TaskRecord task) { 4108 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4109 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4110 4111 int N = mRecentTasks.size(); 4112 // Quick case: check if the top-most recent task is the same. 4113 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4114 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4115 return; 4116 } 4117 // Another quick case: check if this is part of a set of affiliated 4118 // tasks that are at the top. 4119 if (isAffiliated && N > 0 && task.inRecents 4120 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4121 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4122 + " at top when adding " + task); 4123 return; 4124 } 4125 // Another quick case: never add voice sessions. 4126 if (task.voiceSession != null) { 4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4128 return; 4129 } 4130 4131 boolean needAffiliationFix = false; 4132 4133 // Slightly less quick case: the task is already in recents, so all we need 4134 // to do is move it. 4135 if (task.inRecents) { 4136 int taskIndex = mRecentTasks.indexOf(task); 4137 if (taskIndex >= 0) { 4138 if (!isAffiliated) { 4139 // Simple case: this is not an affiliated task, so we just move it to the front. 4140 mRecentTasks.remove(taskIndex); 4141 mRecentTasks.add(0, task); 4142 notifyTaskPersisterLocked(task, false); 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4144 + " from " + taskIndex); 4145 return; 4146 } else { 4147 // More complicated: need to keep all affiliated tasks together. 4148 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4149 // All went well. 4150 return; 4151 } 4152 4153 // Uh oh... something bad in the affiliation chain, try to rebuild 4154 // everything and then go through our general path of adding a new task. 4155 needAffiliationFix = true; 4156 } 4157 } else { 4158 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4159 needAffiliationFix = true; 4160 } 4161 } 4162 4163 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4164 trimRecentsForTask(task, true); 4165 4166 N = mRecentTasks.size(); 4167 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4168 final TaskRecord tr = mRecentTasks.remove(N - 1); 4169 tr.removedFromRecents(mTaskPersister); 4170 N--; 4171 } 4172 task.inRecents = true; 4173 if (!isAffiliated || needAffiliationFix) { 4174 // If this is a simple non-affiliated task, or we had some failure trying to 4175 // handle it as part of an affilated task, then just place it at the top. 4176 mRecentTasks.add(0, task); 4177 } else if (isAffiliated) { 4178 // If this is a new affiliated task, then move all of the affiliated tasks 4179 // to the front and insert this new one. 4180 TaskRecord other = task.mNextAffiliate; 4181 if (other == null) { 4182 other = task.mPrevAffiliate; 4183 } 4184 if (other != null) { 4185 int otherIndex = mRecentTasks.indexOf(other); 4186 if (otherIndex >= 0) { 4187 // Insert new task at appropriate location. 4188 int taskIndex; 4189 if (other == task.mNextAffiliate) { 4190 // We found the index of our next affiliation, which is who is 4191 // before us in the list, so add after that point. 4192 taskIndex = otherIndex+1; 4193 } else { 4194 // We found the index of our previous affiliation, which is who is 4195 // after us in the list, so add at their position. 4196 taskIndex = otherIndex; 4197 } 4198 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4199 + taskIndex + ": " + task); 4200 mRecentTasks.add(taskIndex, task); 4201 4202 // Now move everything to the front. 4203 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4204 // All went well. 4205 return; 4206 } 4207 4208 // Uh oh... something bad in the affiliation chain, try to rebuild 4209 // everything and then go through our general path of adding a new task. 4210 needAffiliationFix = true; 4211 } else { 4212 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4213 + other); 4214 needAffiliationFix = true; 4215 } 4216 } else { 4217 if (DEBUG_RECENTS) Slog.d(TAG, 4218 "addRecent: adding affiliated task without next/prev:" + task); 4219 needAffiliationFix = true; 4220 } 4221 } 4222 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4223 4224 if (needAffiliationFix) { 4225 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4226 cleanupRecentTasksLocked(task.userId); 4227 } 4228 } 4229 4230 /** 4231 * If needed, remove oldest existing entries in recents that are for the same kind 4232 * of task as the given one. 4233 */ 4234 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4235 int N = mRecentTasks.size(); 4236 final Intent intent = task.intent; 4237 final boolean document = intent != null && intent.isDocument(); 4238 4239 int maxRecents = task.maxRecents - 1; 4240 for (int i=0; i<N; i++) { 4241 final TaskRecord tr = mRecentTasks.get(i); 4242 if (task != tr) { 4243 if (task.userId != tr.userId) { 4244 continue; 4245 } 4246 if (i > MAX_RECENT_BITMAPS) { 4247 tr.freeLastThumbnail(); 4248 } 4249 final Intent trIntent = tr.intent; 4250 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4251 (intent == null || !intent.filterEquals(trIntent))) { 4252 continue; 4253 } 4254 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4255 if (document && trIsDocument) { 4256 // These are the same document activity (not necessarily the same doc). 4257 if (maxRecents > 0) { 4258 --maxRecents; 4259 continue; 4260 } 4261 // Hit the maximum number of documents for this task. Fall through 4262 // and remove this document from recents. 4263 } else if (document || trIsDocument) { 4264 // Only one of these is a document. Not the droid we're looking for. 4265 continue; 4266 } 4267 } 4268 4269 if (!doTrim) { 4270 // If the caller is not actually asking for a trim, just tell them we reached 4271 // a point where the trim would happen. 4272 return i; 4273 } 4274 4275 // Either task and tr are the same or, their affinities match or their intents match 4276 // and neither of them is a document, or they are documents using the same activity 4277 // and their maxRecents has been reached. 4278 tr.disposeThumbnail(); 4279 mRecentTasks.remove(i); 4280 if (task != tr) { 4281 tr.removedFromRecents(mTaskPersister); 4282 } 4283 i--; 4284 N--; 4285 if (task.intent == null) { 4286 // If the new recent task we are adding is not fully 4287 // specified, then replace it with the existing recent task. 4288 task = tr; 4289 } 4290 notifyTaskPersisterLocked(tr, false); 4291 } 4292 4293 return -1; 4294 } 4295 4296 @Override 4297 public void reportActivityFullyDrawn(IBinder token) { 4298 synchronized (this) { 4299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4300 if (r == null) { 4301 return; 4302 } 4303 r.reportFullyDrawnLocked(); 4304 } 4305 } 4306 4307 @Override 4308 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4309 synchronized (this) { 4310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4311 if (r == null) { 4312 return; 4313 } 4314 final long origId = Binder.clearCallingIdentity(); 4315 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4316 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4317 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4318 if (config != null) { 4319 r.frozenBeforeDestroy = true; 4320 if (!updateConfigurationLocked(config, r, false, false)) { 4321 mStackSupervisor.resumeTopActivitiesLocked(); 4322 } 4323 } 4324 Binder.restoreCallingIdentity(origId); 4325 } 4326 } 4327 4328 @Override 4329 public int getRequestedOrientation(IBinder token) { 4330 synchronized (this) { 4331 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4332 if (r == null) { 4333 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4334 } 4335 return mWindowManager.getAppOrientation(r.appToken); 4336 } 4337 } 4338 4339 /** 4340 * This is the internal entry point for handling Activity.finish(). 4341 * 4342 * @param token The Binder token referencing the Activity we want to finish. 4343 * @param resultCode Result code, if any, from this Activity. 4344 * @param resultData Result data (Intent), if any, from this Activity. 4345 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4346 * the root Activity in the task. 4347 * 4348 * @return Returns true if the activity successfully finished, or false if it is still running. 4349 */ 4350 @Override 4351 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4352 boolean finishTask) { 4353 // Refuse possible leaked file descriptors 4354 if (resultData != null && resultData.hasFileDescriptors() == true) { 4355 throw new IllegalArgumentException("File descriptors passed in Intent"); 4356 } 4357 4358 synchronized(this) { 4359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4360 if (r == null) { 4361 return true; 4362 } 4363 // Keep track of the root activity of the task before we finish it 4364 TaskRecord tr = r.task; 4365 ActivityRecord rootR = tr.getRootActivity(); 4366 // Do not allow task to finish in Lock Task mode. 4367 if (tr == mStackSupervisor.mLockTaskModeTask) { 4368 if (rootR == r) { 4369 mStackSupervisor.showLockTaskToast(); 4370 return false; 4371 } 4372 } 4373 if (mController != null) { 4374 // Find the first activity that is not finishing. 4375 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4376 if (next != null) { 4377 // ask watcher if this is allowed 4378 boolean resumeOK = true; 4379 try { 4380 resumeOK = mController.activityResuming(next.packageName); 4381 } catch (RemoteException e) { 4382 mController = null; 4383 Watchdog.getInstance().setActivityController(null); 4384 } 4385 4386 if (!resumeOK) { 4387 return false; 4388 } 4389 } 4390 } 4391 final long origId = Binder.clearCallingIdentity(); 4392 try { 4393 boolean res; 4394 if (finishTask && r == rootR) { 4395 // If requested, remove the task that is associated to this activity only if it 4396 // was the root activity in the task. The result code and data is ignored because 4397 // we don't support returning them across task boundaries. 4398 res = removeTaskByIdLocked(tr.taskId, 0); 4399 } else { 4400 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4401 resultData, "app-request", true); 4402 } 4403 return res; 4404 } finally { 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 } 4409 4410 @Override 4411 public final void finishHeavyWeightApp() { 4412 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4413 != PackageManager.PERMISSION_GRANTED) { 4414 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4415 + Binder.getCallingPid() 4416 + ", uid=" + Binder.getCallingUid() 4417 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4418 Slog.w(TAG, msg); 4419 throw new SecurityException(msg); 4420 } 4421 4422 synchronized(this) { 4423 if (mHeavyWeightProcess == null) { 4424 return; 4425 } 4426 4427 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4428 mHeavyWeightProcess.activities); 4429 for (int i=0; i<activities.size(); i++) { 4430 ActivityRecord r = activities.get(i); 4431 if (!r.finishing) { 4432 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4433 null, "finish-heavy", true); 4434 } 4435 } 4436 4437 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4438 mHeavyWeightProcess.userId, 0)); 4439 mHeavyWeightProcess = null; 4440 } 4441 } 4442 4443 @Override 4444 public void crashApplication(int uid, int initialPid, String packageName, 4445 String message) { 4446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4447 != PackageManager.PERMISSION_GRANTED) { 4448 String msg = "Permission Denial: crashApplication() from pid=" 4449 + Binder.getCallingPid() 4450 + ", uid=" + Binder.getCallingUid() 4451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4452 Slog.w(TAG, msg); 4453 throw new SecurityException(msg); 4454 } 4455 4456 synchronized(this) { 4457 ProcessRecord proc = null; 4458 4459 // Figure out which process to kill. We don't trust that initialPid 4460 // still has any relation to current pids, so must scan through the 4461 // list. 4462 synchronized (mPidsSelfLocked) { 4463 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4464 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4465 if (p.uid != uid) { 4466 continue; 4467 } 4468 if (p.pid == initialPid) { 4469 proc = p; 4470 break; 4471 } 4472 if (p.pkgList.containsKey(packageName)) { 4473 proc = p; 4474 } 4475 } 4476 } 4477 4478 if (proc == null) { 4479 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4480 + " initialPid=" + initialPid 4481 + " packageName=" + packageName); 4482 return; 4483 } 4484 4485 if (proc.thread != null) { 4486 if (proc.pid == Process.myPid()) { 4487 Log.w(TAG, "crashApplication: trying to crash self!"); 4488 return; 4489 } 4490 long ident = Binder.clearCallingIdentity(); 4491 try { 4492 proc.thread.scheduleCrash(message); 4493 } catch (RemoteException e) { 4494 } 4495 Binder.restoreCallingIdentity(ident); 4496 } 4497 } 4498 } 4499 4500 @Override 4501 public final void finishSubActivity(IBinder token, String resultWho, 4502 int requestCode) { 4503 synchronized(this) { 4504 final long origId = Binder.clearCallingIdentity(); 4505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4506 if (r != null) { 4507 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4508 } 4509 Binder.restoreCallingIdentity(origId); 4510 } 4511 } 4512 4513 @Override 4514 public boolean finishActivityAffinity(IBinder token) { 4515 synchronized(this) { 4516 final long origId = Binder.clearCallingIdentity(); 4517 try { 4518 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4519 4520 ActivityRecord rootR = r.task.getRootActivity(); 4521 // Do not allow task to finish in Lock Task mode. 4522 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4523 if (rootR == r) { 4524 mStackSupervisor.showLockTaskToast(); 4525 return false; 4526 } 4527 } 4528 boolean res = false; 4529 if (r != null) { 4530 res = r.task.stack.finishActivityAffinityLocked(r); 4531 } 4532 return res; 4533 } finally { 4534 Binder.restoreCallingIdentity(origId); 4535 } 4536 } 4537 } 4538 4539 @Override 4540 public void finishVoiceTask(IVoiceInteractionSession session) { 4541 synchronized(this) { 4542 final long origId = Binder.clearCallingIdentity(); 4543 try { 4544 mStackSupervisor.finishVoiceTask(session); 4545 } finally { 4546 Binder.restoreCallingIdentity(origId); 4547 } 4548 } 4549 4550 } 4551 4552 @Override 4553 public boolean releaseActivityInstance(IBinder token) { 4554 synchronized(this) { 4555 final long origId = Binder.clearCallingIdentity(); 4556 try { 4557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4558 if (r.task == null || r.task.stack == null) { 4559 return false; 4560 } 4561 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4562 } finally { 4563 Binder.restoreCallingIdentity(origId); 4564 } 4565 } 4566 } 4567 4568 @Override 4569 public void releaseSomeActivities(IApplicationThread appInt) { 4570 synchronized(this) { 4571 final long origId = Binder.clearCallingIdentity(); 4572 try { 4573 ProcessRecord app = getRecordForAppLocked(appInt); 4574 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4575 } finally { 4576 Binder.restoreCallingIdentity(origId); 4577 } 4578 } 4579 } 4580 4581 @Override 4582 public boolean willActivityBeVisible(IBinder token) { 4583 synchronized(this) { 4584 ActivityStack stack = ActivityRecord.getStackLocked(token); 4585 if (stack != null) { 4586 return stack.willActivityBeVisibleLocked(token); 4587 } 4588 return false; 4589 } 4590 } 4591 4592 @Override 4593 public void overridePendingTransition(IBinder token, String packageName, 4594 int enterAnim, int exitAnim) { 4595 synchronized(this) { 4596 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4597 if (self == null) { 4598 return; 4599 } 4600 4601 final long origId = Binder.clearCallingIdentity(); 4602 4603 if (self.state == ActivityState.RESUMED 4604 || self.state == ActivityState.PAUSING) { 4605 mWindowManager.overridePendingAppTransition(packageName, 4606 enterAnim, exitAnim, null); 4607 } 4608 4609 Binder.restoreCallingIdentity(origId); 4610 } 4611 } 4612 4613 /** 4614 * Main function for removing an existing process from the activity manager 4615 * as a result of that process going away. Clears out all connections 4616 * to the process. 4617 */ 4618 private final void handleAppDiedLocked(ProcessRecord app, 4619 boolean restarting, boolean allowRestart) { 4620 int pid = app.pid; 4621 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4622 if (!restarting) { 4623 removeLruProcessLocked(app); 4624 if (pid > 0) { 4625 ProcessList.remove(pid); 4626 } 4627 } 4628 4629 if (mProfileProc == app) { 4630 clearProfilerLocked(); 4631 } 4632 4633 // Remove this application's activities from active lists. 4634 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4635 4636 app.activities.clear(); 4637 4638 if (app.instrumentationClass != null) { 4639 Slog.w(TAG, "Crash of app " + app.processName 4640 + " running instrumentation " + app.instrumentationClass); 4641 Bundle info = new Bundle(); 4642 info.putString("shortMsg", "Process crashed."); 4643 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4644 } 4645 4646 if (!restarting) { 4647 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4648 // If there was nothing to resume, and we are not already 4649 // restarting this process, but there is a visible activity that 4650 // is hosted by the process... then make sure all visible 4651 // activities are running, taking care of restarting this 4652 // process. 4653 if (hasVisibleActivities) { 4654 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4655 } 4656 } 4657 } 4658 } 4659 4660 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4661 IBinder threadBinder = thread.asBinder(); 4662 // Find the application record. 4663 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4664 ProcessRecord rec = mLruProcesses.get(i); 4665 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4666 return i; 4667 } 4668 } 4669 return -1; 4670 } 4671 4672 final ProcessRecord getRecordForAppLocked( 4673 IApplicationThread thread) { 4674 if (thread == null) { 4675 return null; 4676 } 4677 4678 int appIndex = getLRURecordIndexForAppLocked(thread); 4679 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4680 } 4681 4682 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4683 // If there are no longer any background processes running, 4684 // and the app that died was not running instrumentation, 4685 // then tell everyone we are now low on memory. 4686 boolean haveBg = false; 4687 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4688 ProcessRecord rec = mLruProcesses.get(i); 4689 if (rec.thread != null 4690 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4691 haveBg = true; 4692 break; 4693 } 4694 } 4695 4696 if (!haveBg) { 4697 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4698 if (doReport) { 4699 long now = SystemClock.uptimeMillis(); 4700 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4701 doReport = false; 4702 } else { 4703 mLastMemUsageReportTime = now; 4704 } 4705 } 4706 final ArrayList<ProcessMemInfo> memInfos 4707 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4708 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4709 long now = SystemClock.uptimeMillis(); 4710 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4711 ProcessRecord rec = mLruProcesses.get(i); 4712 if (rec == dyingProc || rec.thread == null) { 4713 continue; 4714 } 4715 if (doReport) { 4716 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4717 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4718 } 4719 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4720 // The low memory report is overriding any current 4721 // state for a GC request. Make sure to do 4722 // heavy/important/visible/foreground processes first. 4723 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4724 rec.lastRequestedGc = 0; 4725 } else { 4726 rec.lastRequestedGc = rec.lastLowMemory; 4727 } 4728 rec.reportLowMemory = true; 4729 rec.lastLowMemory = now; 4730 mProcessesToGc.remove(rec); 4731 addProcessToGcListLocked(rec); 4732 } 4733 } 4734 if (doReport) { 4735 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4736 mHandler.sendMessage(msg); 4737 } 4738 scheduleAppGcsLocked(); 4739 } 4740 } 4741 4742 final void appDiedLocked(ProcessRecord app) { 4743 appDiedLocked(app, app.pid, app.thread); 4744 } 4745 4746 final void appDiedLocked(ProcessRecord app, int pid, 4747 IApplicationThread thread) { 4748 4749 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4750 synchronized (stats) { 4751 stats.noteProcessDiedLocked(app.info.uid, pid); 4752 } 4753 4754 Process.killProcessGroup(app.info.uid, pid); 4755 4756 // Clean up already done if the process has been re-started. 4757 if (app.pid == pid && app.thread != null && 4758 app.thread.asBinder() == thread.asBinder()) { 4759 boolean doLowMem = app.instrumentationClass == null; 4760 boolean doOomAdj = doLowMem; 4761 if (!app.killedByAm) { 4762 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4763 + ") has died."); 4764 mAllowLowerMemLevel = true; 4765 } else { 4766 // Note that we always want to do oom adj to update our state with the 4767 // new number of procs. 4768 mAllowLowerMemLevel = false; 4769 doLowMem = false; 4770 } 4771 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4772 if (DEBUG_CLEANUP) Slog.v( 4773 TAG, "Dying app: " + app + ", pid: " + pid 4774 + ", thread: " + thread.asBinder()); 4775 handleAppDiedLocked(app, false, true); 4776 4777 if (doOomAdj) { 4778 updateOomAdjLocked(); 4779 } 4780 if (doLowMem) { 4781 doLowMemReportIfNeededLocked(app); 4782 } 4783 } else if (app.pid != pid) { 4784 // A new process has already been started. 4785 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4786 + ") has died and restarted (pid " + app.pid + ")."); 4787 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4788 } else if (DEBUG_PROCESSES) { 4789 Slog.d(TAG, "Received spurious death notification for thread " 4790 + thread.asBinder()); 4791 } 4792 } 4793 4794 /** 4795 * If a stack trace dump file is configured, dump process stack traces. 4796 * @param clearTraces causes the dump file to be erased prior to the new 4797 * traces being written, if true; when false, the new traces will be 4798 * appended to any existing file content. 4799 * @param firstPids of dalvik VM processes to dump stack traces for first 4800 * @param lastPids of dalvik VM processes to dump stack traces for last 4801 * @param nativeProcs optional list of native process names to dump stack crawls 4802 * @return file containing stack traces, or null if no dump file is configured 4803 */ 4804 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4805 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4806 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4807 if (tracesPath == null || tracesPath.length() == 0) { 4808 return null; 4809 } 4810 4811 File tracesFile = new File(tracesPath); 4812 try { 4813 File tracesDir = tracesFile.getParentFile(); 4814 if (!tracesDir.exists()) { 4815 tracesFile.mkdirs(); 4816 if (!SELinux.restorecon(tracesDir)) { 4817 return null; 4818 } 4819 } 4820 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4821 4822 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4823 tracesFile.createNewFile(); 4824 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4825 } catch (IOException e) { 4826 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4827 return null; 4828 } 4829 4830 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4831 return tracesFile; 4832 } 4833 4834 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4835 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4836 // Use a FileObserver to detect when traces finish writing. 4837 // The order of traces is considered important to maintain for legibility. 4838 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4839 @Override 4840 public synchronized void onEvent(int event, String path) { notify(); } 4841 }; 4842 4843 try { 4844 observer.startWatching(); 4845 4846 // First collect all of the stacks of the most important pids. 4847 if (firstPids != null) { 4848 try { 4849 int num = firstPids.size(); 4850 for (int i = 0; i < num; i++) { 4851 synchronized (observer) { 4852 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4853 observer.wait(200); // Wait for write-close, give up after 200msec 4854 } 4855 } 4856 } catch (InterruptedException e) { 4857 Log.wtf(TAG, e); 4858 } 4859 } 4860 4861 // Next collect the stacks of the native pids 4862 if (nativeProcs != null) { 4863 int[] pids = Process.getPidsForCommands(nativeProcs); 4864 if (pids != null) { 4865 for (int pid : pids) { 4866 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4867 } 4868 } 4869 } 4870 4871 // Lastly, measure CPU usage. 4872 if (processCpuTracker != null) { 4873 processCpuTracker.init(); 4874 System.gc(); 4875 processCpuTracker.update(); 4876 try { 4877 synchronized (processCpuTracker) { 4878 processCpuTracker.wait(500); // measure over 1/2 second. 4879 } 4880 } catch (InterruptedException e) { 4881 } 4882 processCpuTracker.update(); 4883 4884 // We'll take the stack crawls of just the top apps using CPU. 4885 final int N = processCpuTracker.countWorkingStats(); 4886 int numProcs = 0; 4887 for (int i=0; i<N && numProcs<5; i++) { 4888 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4889 if (lastPids.indexOfKey(stats.pid) >= 0) { 4890 numProcs++; 4891 try { 4892 synchronized (observer) { 4893 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4894 observer.wait(200); // Wait for write-close, give up after 200msec 4895 } 4896 } catch (InterruptedException e) { 4897 Log.wtf(TAG, e); 4898 } 4899 4900 } 4901 } 4902 } 4903 } finally { 4904 observer.stopWatching(); 4905 } 4906 } 4907 4908 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4909 if (true || IS_USER_BUILD) { 4910 return; 4911 } 4912 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4913 if (tracesPath == null || tracesPath.length() == 0) { 4914 return; 4915 } 4916 4917 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4918 StrictMode.allowThreadDiskWrites(); 4919 try { 4920 final File tracesFile = new File(tracesPath); 4921 final File tracesDir = tracesFile.getParentFile(); 4922 final File tracesTmp = new File(tracesDir, "__tmp__"); 4923 try { 4924 if (!tracesDir.exists()) { 4925 tracesFile.mkdirs(); 4926 if (!SELinux.restorecon(tracesDir.getPath())) { 4927 return; 4928 } 4929 } 4930 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4931 4932 if (tracesFile.exists()) { 4933 tracesTmp.delete(); 4934 tracesFile.renameTo(tracesTmp); 4935 } 4936 StringBuilder sb = new StringBuilder(); 4937 Time tobj = new Time(); 4938 tobj.set(System.currentTimeMillis()); 4939 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4940 sb.append(": "); 4941 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4942 sb.append(" since "); 4943 sb.append(msg); 4944 FileOutputStream fos = new FileOutputStream(tracesFile); 4945 fos.write(sb.toString().getBytes()); 4946 if (app == null) { 4947 fos.write("\n*** No application process!".getBytes()); 4948 } 4949 fos.close(); 4950 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4951 } catch (IOException e) { 4952 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4953 return; 4954 } 4955 4956 if (app != null) { 4957 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4958 firstPids.add(app.pid); 4959 dumpStackTraces(tracesPath, firstPids, null, null, null); 4960 } 4961 4962 File lastTracesFile = null; 4963 File curTracesFile = null; 4964 for (int i=9; i>=0; i--) { 4965 String name = String.format(Locale.US, "slow%02d.txt", i); 4966 curTracesFile = new File(tracesDir, name); 4967 if (curTracesFile.exists()) { 4968 if (lastTracesFile != null) { 4969 curTracesFile.renameTo(lastTracesFile); 4970 } else { 4971 curTracesFile.delete(); 4972 } 4973 } 4974 lastTracesFile = curTracesFile; 4975 } 4976 tracesFile.renameTo(curTracesFile); 4977 if (tracesTmp.exists()) { 4978 tracesTmp.renameTo(tracesFile); 4979 } 4980 } finally { 4981 StrictMode.setThreadPolicy(oldPolicy); 4982 } 4983 } 4984 4985 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4986 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4987 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4988 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4989 4990 if (mController != null) { 4991 try { 4992 // 0 == continue, -1 = kill process immediately 4993 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4994 if (res < 0 && app.pid != MY_PID) { 4995 app.kill("anr", true); 4996 } 4997 } catch (RemoteException e) { 4998 mController = null; 4999 Watchdog.getInstance().setActivityController(null); 5000 } 5001 } 5002 5003 long anrTime = SystemClock.uptimeMillis(); 5004 if (MONITOR_CPU_USAGE) { 5005 updateCpuStatsNow(); 5006 } 5007 5008 synchronized (this) { 5009 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5010 if (mShuttingDown) { 5011 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5012 return; 5013 } else if (app.notResponding) { 5014 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5015 return; 5016 } else if (app.crashing) { 5017 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5018 return; 5019 } 5020 5021 // In case we come through here for the same app before completing 5022 // this one, mark as anring now so we will bail out. 5023 app.notResponding = true; 5024 5025 // Log the ANR to the event log. 5026 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5027 app.processName, app.info.flags, annotation); 5028 5029 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5030 firstPids.add(app.pid); 5031 5032 int parentPid = app.pid; 5033 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5034 if (parentPid != app.pid) firstPids.add(parentPid); 5035 5036 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5037 5038 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5039 ProcessRecord r = mLruProcesses.get(i); 5040 if (r != null && r.thread != null) { 5041 int pid = r.pid; 5042 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5043 if (r.persistent) { 5044 firstPids.add(pid); 5045 } else { 5046 lastPids.put(pid, Boolean.TRUE); 5047 } 5048 } 5049 } 5050 } 5051 } 5052 5053 // Log the ANR to the main log. 5054 StringBuilder info = new StringBuilder(); 5055 info.setLength(0); 5056 info.append("ANR in ").append(app.processName); 5057 if (activity != null && activity.shortComponentName != null) { 5058 info.append(" (").append(activity.shortComponentName).append(")"); 5059 } 5060 info.append("\n"); 5061 info.append("PID: ").append(app.pid).append("\n"); 5062 if (annotation != null) { 5063 info.append("Reason: ").append(annotation).append("\n"); 5064 } 5065 if (parent != null && parent != activity) { 5066 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5067 } 5068 5069 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5070 5071 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5072 NATIVE_STACKS_OF_INTEREST); 5073 5074 String cpuInfo = null; 5075 if (MONITOR_CPU_USAGE) { 5076 updateCpuStatsNow(); 5077 synchronized (mProcessCpuThread) { 5078 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5079 } 5080 info.append(processCpuTracker.printCurrentLoad()); 5081 info.append(cpuInfo); 5082 } 5083 5084 info.append(processCpuTracker.printCurrentState(anrTime)); 5085 5086 Slog.e(TAG, info.toString()); 5087 if (tracesFile == null) { 5088 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5089 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5090 } 5091 5092 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5093 cpuInfo, tracesFile, null); 5094 5095 if (mController != null) { 5096 try { 5097 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5098 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5099 if (res != 0) { 5100 if (res < 0 && app.pid != MY_PID) { 5101 app.kill("anr", true); 5102 } else { 5103 synchronized (this) { 5104 mServices.scheduleServiceTimeoutLocked(app); 5105 } 5106 } 5107 return; 5108 } 5109 } catch (RemoteException e) { 5110 mController = null; 5111 Watchdog.getInstance().setActivityController(null); 5112 } 5113 } 5114 5115 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5116 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5117 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5118 5119 synchronized (this) { 5120 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5121 app.kill("bg anr", true); 5122 return; 5123 } 5124 5125 // Set the app's notResponding state, and look up the errorReportReceiver 5126 makeAppNotRespondingLocked(app, 5127 activity != null ? activity.shortComponentName : null, 5128 annotation != null ? "ANR " + annotation : "ANR", 5129 info.toString()); 5130 5131 // Bring up the infamous App Not Responding dialog 5132 Message msg = Message.obtain(); 5133 HashMap<String, Object> map = new HashMap<String, Object>(); 5134 msg.what = SHOW_NOT_RESPONDING_MSG; 5135 msg.obj = map; 5136 msg.arg1 = aboveSystem ? 1 : 0; 5137 map.put("app", app); 5138 if (activity != null) { 5139 map.put("activity", activity); 5140 } 5141 5142 mHandler.sendMessage(msg); 5143 } 5144 } 5145 5146 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5147 if (!mLaunchWarningShown) { 5148 mLaunchWarningShown = true; 5149 mHandler.post(new Runnable() { 5150 @Override 5151 public void run() { 5152 synchronized (ActivityManagerService.this) { 5153 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5154 d.show(); 5155 mHandler.postDelayed(new Runnable() { 5156 @Override 5157 public void run() { 5158 synchronized (ActivityManagerService.this) { 5159 d.dismiss(); 5160 mLaunchWarningShown = false; 5161 } 5162 } 5163 }, 4000); 5164 } 5165 } 5166 }); 5167 } 5168 } 5169 5170 @Override 5171 public boolean clearApplicationUserData(final String packageName, 5172 final IPackageDataObserver observer, int userId) { 5173 enforceNotIsolatedCaller("clearApplicationUserData"); 5174 int uid = Binder.getCallingUid(); 5175 int pid = Binder.getCallingPid(); 5176 userId = handleIncomingUser(pid, uid, 5177 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5178 long callingId = Binder.clearCallingIdentity(); 5179 try { 5180 IPackageManager pm = AppGlobals.getPackageManager(); 5181 int pkgUid = -1; 5182 synchronized(this) { 5183 try { 5184 pkgUid = pm.getPackageUid(packageName, userId); 5185 } catch (RemoteException e) { 5186 } 5187 if (pkgUid == -1) { 5188 Slog.w(TAG, "Invalid packageName: " + packageName); 5189 if (observer != null) { 5190 try { 5191 observer.onRemoveCompleted(packageName, false); 5192 } catch (RemoteException e) { 5193 Slog.i(TAG, "Observer no longer exists."); 5194 } 5195 } 5196 return false; 5197 } 5198 if (uid == pkgUid || checkComponentPermission( 5199 android.Manifest.permission.CLEAR_APP_USER_DATA, 5200 pid, uid, -1, true) 5201 == PackageManager.PERMISSION_GRANTED) { 5202 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5203 } else { 5204 throw new SecurityException("PID " + pid + " does not have permission " 5205 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5206 + " of package " + packageName); 5207 } 5208 5209 // Remove all tasks match the cleared application package and user 5210 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5211 final TaskRecord tr = mRecentTasks.get(i); 5212 final String taskPackageName = 5213 tr.getBaseIntent().getComponent().getPackageName(); 5214 if (tr.userId != userId) continue; 5215 if (!taskPackageName.equals(packageName)) continue; 5216 removeTaskByIdLocked(tr.taskId, 0); 5217 } 5218 } 5219 5220 try { 5221 // Clear application user data 5222 pm.clearApplicationUserData(packageName, observer, userId); 5223 5224 synchronized(this) { 5225 // Remove all permissions granted from/to this package 5226 removeUriPermissionsForPackageLocked(packageName, userId, true); 5227 } 5228 5229 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5230 Uri.fromParts("package", packageName, null)); 5231 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5232 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5233 null, null, 0, null, null, null, false, false, userId); 5234 } catch (RemoteException e) { 5235 } 5236 } finally { 5237 Binder.restoreCallingIdentity(callingId); 5238 } 5239 return true; 5240 } 5241 5242 @Override 5243 public void killBackgroundProcesses(final String packageName, int userId) { 5244 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5245 != PackageManager.PERMISSION_GRANTED && 5246 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5247 != PackageManager.PERMISSION_GRANTED) { 5248 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5249 + Binder.getCallingPid() 5250 + ", uid=" + Binder.getCallingUid() 5251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5252 Slog.w(TAG, msg); 5253 throw new SecurityException(msg); 5254 } 5255 5256 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5257 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5258 long callingId = Binder.clearCallingIdentity(); 5259 try { 5260 IPackageManager pm = AppGlobals.getPackageManager(); 5261 synchronized(this) { 5262 int appId = -1; 5263 try { 5264 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5265 } catch (RemoteException e) { 5266 } 5267 if (appId == -1) { 5268 Slog.w(TAG, "Invalid packageName: " + packageName); 5269 return; 5270 } 5271 killPackageProcessesLocked(packageName, appId, userId, 5272 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 } 5278 5279 @Override 5280 public void killAllBackgroundProcesses() { 5281 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5282 != PackageManager.PERMISSION_GRANTED) { 5283 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5284 + Binder.getCallingPid() 5285 + ", uid=" + Binder.getCallingUid() 5286 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5287 Slog.w(TAG, msg); 5288 throw new SecurityException(msg); 5289 } 5290 5291 long callingId = Binder.clearCallingIdentity(); 5292 try { 5293 synchronized(this) { 5294 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5295 final int NP = mProcessNames.getMap().size(); 5296 for (int ip=0; ip<NP; ip++) { 5297 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5298 final int NA = apps.size(); 5299 for (int ia=0; ia<NA; ia++) { 5300 ProcessRecord app = apps.valueAt(ia); 5301 if (app.persistent) { 5302 // we don't kill persistent processes 5303 continue; 5304 } 5305 if (app.removed) { 5306 procs.add(app); 5307 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5308 app.removed = true; 5309 procs.add(app); 5310 } 5311 } 5312 } 5313 5314 int N = procs.size(); 5315 for (int i=0; i<N; i++) { 5316 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5317 } 5318 mAllowLowerMemLevel = true; 5319 updateOomAdjLocked(); 5320 doLowMemReportIfNeededLocked(null); 5321 } 5322 } finally { 5323 Binder.restoreCallingIdentity(callingId); 5324 } 5325 } 5326 5327 @Override 5328 public void forceStopPackage(final String packageName, int userId) { 5329 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5330 != PackageManager.PERMISSION_GRANTED) { 5331 String msg = "Permission Denial: forceStopPackage() from pid=" 5332 + Binder.getCallingPid() 5333 + ", uid=" + Binder.getCallingUid() 5334 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5335 Slog.w(TAG, msg); 5336 throw new SecurityException(msg); 5337 } 5338 final int callingPid = Binder.getCallingPid(); 5339 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5340 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5341 long callingId = Binder.clearCallingIdentity(); 5342 try { 5343 IPackageManager pm = AppGlobals.getPackageManager(); 5344 synchronized(this) { 5345 int[] users = userId == UserHandle.USER_ALL 5346 ? getUsersLocked() : new int[] { userId }; 5347 for (int user : users) { 5348 int pkgUid = -1; 5349 try { 5350 pkgUid = pm.getPackageUid(packageName, user); 5351 } catch (RemoteException e) { 5352 } 5353 if (pkgUid == -1) { 5354 Slog.w(TAG, "Invalid packageName: " + packageName); 5355 continue; 5356 } 5357 try { 5358 pm.setPackageStoppedState(packageName, true, user); 5359 } catch (RemoteException e) { 5360 } catch (IllegalArgumentException e) { 5361 Slog.w(TAG, "Failed trying to unstop package " 5362 + packageName + ": " + e); 5363 } 5364 if (isUserRunningLocked(user, false)) { 5365 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5366 } 5367 } 5368 } 5369 } finally { 5370 Binder.restoreCallingIdentity(callingId); 5371 } 5372 } 5373 5374 @Override 5375 public void addPackageDependency(String packageName) { 5376 synchronized (this) { 5377 int callingPid = Binder.getCallingPid(); 5378 if (callingPid == Process.myPid()) { 5379 // Yeah, um, no. 5380 Slog.w(TAG, "Can't addPackageDependency on system process"); 5381 return; 5382 } 5383 ProcessRecord proc; 5384 synchronized (mPidsSelfLocked) { 5385 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5386 } 5387 if (proc != null) { 5388 if (proc.pkgDeps == null) { 5389 proc.pkgDeps = new ArraySet<String>(1); 5390 } 5391 proc.pkgDeps.add(packageName); 5392 } 5393 } 5394 } 5395 5396 /* 5397 * The pkg name and app id have to be specified. 5398 */ 5399 @Override 5400 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5401 if (pkg == null) { 5402 return; 5403 } 5404 // Make sure the uid is valid. 5405 if (appid < 0) { 5406 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5407 return; 5408 } 5409 int callerUid = Binder.getCallingUid(); 5410 // Only the system server can kill an application 5411 if (callerUid == Process.SYSTEM_UID) { 5412 // Post an aysnc message to kill the application 5413 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5414 msg.arg1 = appid; 5415 msg.arg2 = 0; 5416 Bundle bundle = new Bundle(); 5417 bundle.putString("pkg", pkg); 5418 bundle.putString("reason", reason); 5419 msg.obj = bundle; 5420 mHandler.sendMessage(msg); 5421 } else { 5422 throw new SecurityException(callerUid + " cannot kill pkg: " + 5423 pkg); 5424 } 5425 } 5426 5427 @Override 5428 public void closeSystemDialogs(String reason) { 5429 enforceNotIsolatedCaller("closeSystemDialogs"); 5430 5431 final int pid = Binder.getCallingPid(); 5432 final int uid = Binder.getCallingUid(); 5433 final long origId = Binder.clearCallingIdentity(); 5434 try { 5435 synchronized (this) { 5436 // Only allow this from foreground processes, so that background 5437 // applications can't abuse it to prevent system UI from being shown. 5438 if (uid >= Process.FIRST_APPLICATION_UID) { 5439 ProcessRecord proc; 5440 synchronized (mPidsSelfLocked) { 5441 proc = mPidsSelfLocked.get(pid); 5442 } 5443 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5444 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5445 + " from background process " + proc); 5446 return; 5447 } 5448 } 5449 closeSystemDialogsLocked(reason); 5450 } 5451 } finally { 5452 Binder.restoreCallingIdentity(origId); 5453 } 5454 } 5455 5456 void closeSystemDialogsLocked(String reason) { 5457 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5458 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5459 | Intent.FLAG_RECEIVER_FOREGROUND); 5460 if (reason != null) { 5461 intent.putExtra("reason", reason); 5462 } 5463 mWindowManager.closeSystemDialogs(reason); 5464 5465 mStackSupervisor.closeSystemDialogsLocked(); 5466 5467 broadcastIntentLocked(null, null, intent, null, 5468 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5469 Process.SYSTEM_UID, UserHandle.USER_ALL); 5470 } 5471 5472 @Override 5473 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5474 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5475 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5476 for (int i=pids.length-1; i>=0; i--) { 5477 ProcessRecord proc; 5478 int oomAdj; 5479 synchronized (this) { 5480 synchronized (mPidsSelfLocked) { 5481 proc = mPidsSelfLocked.get(pids[i]); 5482 oomAdj = proc != null ? proc.setAdj : 0; 5483 } 5484 } 5485 infos[i] = new Debug.MemoryInfo(); 5486 Debug.getMemoryInfo(pids[i], infos[i]); 5487 if (proc != null) { 5488 synchronized (this) { 5489 if (proc.thread != null && proc.setAdj == oomAdj) { 5490 // Record this for posterity if the process has been stable. 5491 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5492 infos[i].getTotalUss(), false, proc.pkgList); 5493 } 5494 } 5495 } 5496 } 5497 return infos; 5498 } 5499 5500 @Override 5501 public long[] getProcessPss(int[] pids) { 5502 enforceNotIsolatedCaller("getProcessPss"); 5503 long[] pss = new long[pids.length]; 5504 for (int i=pids.length-1; i>=0; i--) { 5505 ProcessRecord proc; 5506 int oomAdj; 5507 synchronized (this) { 5508 synchronized (mPidsSelfLocked) { 5509 proc = mPidsSelfLocked.get(pids[i]); 5510 oomAdj = proc != null ? proc.setAdj : 0; 5511 } 5512 } 5513 long[] tmpUss = new long[1]; 5514 pss[i] = Debug.getPss(pids[i], tmpUss); 5515 if (proc != null) { 5516 synchronized (this) { 5517 if (proc.thread != null && proc.setAdj == oomAdj) { 5518 // Record this for posterity if the process has been stable. 5519 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5520 } 5521 } 5522 } 5523 } 5524 return pss; 5525 } 5526 5527 @Override 5528 public void killApplicationProcess(String processName, int uid) { 5529 if (processName == null) { 5530 return; 5531 } 5532 5533 int callerUid = Binder.getCallingUid(); 5534 // Only the system server can kill an application 5535 if (callerUid == Process.SYSTEM_UID) { 5536 synchronized (this) { 5537 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5538 if (app != null && app.thread != null) { 5539 try { 5540 app.thread.scheduleSuicide(); 5541 } catch (RemoteException e) { 5542 // If the other end already died, then our work here is done. 5543 } 5544 } else { 5545 Slog.w(TAG, "Process/uid not found attempting kill of " 5546 + processName + " / " + uid); 5547 } 5548 } 5549 } else { 5550 throw new SecurityException(callerUid + " cannot kill app process: " + 5551 processName); 5552 } 5553 } 5554 5555 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5556 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5557 false, true, false, false, UserHandle.getUserId(uid), reason); 5558 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5559 Uri.fromParts("package", packageName, null)); 5560 if (!mProcessesReady) { 5561 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5562 | Intent.FLAG_RECEIVER_FOREGROUND); 5563 } 5564 intent.putExtra(Intent.EXTRA_UID, uid); 5565 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5566 broadcastIntentLocked(null, null, intent, 5567 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5568 false, false, 5569 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5570 } 5571 5572 private void forceStopUserLocked(int userId, String reason) { 5573 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5574 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5575 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5576 | Intent.FLAG_RECEIVER_FOREGROUND); 5577 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5578 broadcastIntentLocked(null, null, intent, 5579 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5580 false, false, 5581 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5582 } 5583 5584 private final boolean killPackageProcessesLocked(String packageName, int appId, 5585 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5586 boolean doit, boolean evenPersistent, String reason) { 5587 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5588 5589 // Remove all processes this package may have touched: all with the 5590 // same UID (except for the system or root user), and all whose name 5591 // matches the package name. 5592 final int NP = mProcessNames.getMap().size(); 5593 for (int ip=0; ip<NP; ip++) { 5594 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5595 final int NA = apps.size(); 5596 for (int ia=0; ia<NA; ia++) { 5597 ProcessRecord app = apps.valueAt(ia); 5598 if (app.persistent && !evenPersistent) { 5599 // we don't kill persistent processes 5600 continue; 5601 } 5602 if (app.removed) { 5603 if (doit) { 5604 procs.add(app); 5605 } 5606 continue; 5607 } 5608 5609 // Skip process if it doesn't meet our oom adj requirement. 5610 if (app.setAdj < minOomAdj) { 5611 continue; 5612 } 5613 5614 // If no package is specified, we call all processes under the 5615 // give user id. 5616 if (packageName == null) { 5617 if (app.userId != userId) { 5618 continue; 5619 } 5620 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5621 continue; 5622 } 5623 // Package has been specified, we want to hit all processes 5624 // that match it. We need to qualify this by the processes 5625 // that are running under the specified app and user ID. 5626 } else { 5627 final boolean isDep = app.pkgDeps != null 5628 && app.pkgDeps.contains(packageName); 5629 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5630 continue; 5631 } 5632 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5633 continue; 5634 } 5635 if (!app.pkgList.containsKey(packageName) && !isDep) { 5636 continue; 5637 } 5638 } 5639 5640 // Process has passed all conditions, kill it! 5641 if (!doit) { 5642 return true; 5643 } 5644 app.removed = true; 5645 procs.add(app); 5646 } 5647 } 5648 5649 int N = procs.size(); 5650 for (int i=0; i<N; i++) { 5651 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5652 } 5653 updateOomAdjLocked(); 5654 return N > 0; 5655 } 5656 5657 private final boolean forceStopPackageLocked(String name, int appId, 5658 boolean callerWillRestart, boolean purgeCache, boolean doit, 5659 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5660 int i; 5661 int N; 5662 5663 if (userId == UserHandle.USER_ALL && name == null) { 5664 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5665 } 5666 5667 if (appId < 0 && name != null) { 5668 try { 5669 appId = UserHandle.getAppId( 5670 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5671 } catch (RemoteException e) { 5672 } 5673 } 5674 5675 if (doit) { 5676 if (name != null) { 5677 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5678 + " user=" + userId + ": " + reason); 5679 } else { 5680 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5681 } 5682 5683 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5684 for (int ip=pmap.size()-1; ip>=0; ip--) { 5685 SparseArray<Long> ba = pmap.valueAt(ip); 5686 for (i=ba.size()-1; i>=0; i--) { 5687 boolean remove = false; 5688 final int entUid = ba.keyAt(i); 5689 if (name != null) { 5690 if (userId == UserHandle.USER_ALL) { 5691 if (UserHandle.getAppId(entUid) == appId) { 5692 remove = true; 5693 } 5694 } else { 5695 if (entUid == UserHandle.getUid(userId, appId)) { 5696 remove = true; 5697 } 5698 } 5699 } else if (UserHandle.getUserId(entUid) == userId) { 5700 remove = true; 5701 } 5702 if (remove) { 5703 ba.removeAt(i); 5704 } 5705 } 5706 if (ba.size() == 0) { 5707 pmap.removeAt(ip); 5708 } 5709 } 5710 } 5711 5712 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5713 -100, callerWillRestart, true, doit, evenPersistent, 5714 name == null ? ("stop user " + userId) : ("stop " + name)); 5715 5716 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5717 if (!doit) { 5718 return true; 5719 } 5720 didSomething = true; 5721 } 5722 5723 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5724 if (!doit) { 5725 return true; 5726 } 5727 didSomething = true; 5728 } 5729 5730 if (name == null) { 5731 // Remove all sticky broadcasts from this user. 5732 mStickyBroadcasts.remove(userId); 5733 } 5734 5735 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5736 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5737 userId, providers)) { 5738 if (!doit) { 5739 return true; 5740 } 5741 didSomething = true; 5742 } 5743 N = providers.size(); 5744 for (i=0; i<N; i++) { 5745 removeDyingProviderLocked(null, providers.get(i), true); 5746 } 5747 5748 // Remove transient permissions granted from/to this package/user 5749 removeUriPermissionsForPackageLocked(name, userId, false); 5750 5751 if (name == null || uninstalling) { 5752 // Remove pending intents. For now we only do this when force 5753 // stopping users, because we have some problems when doing this 5754 // for packages -- app widgets are not currently cleaned up for 5755 // such packages, so they can be left with bad pending intents. 5756 if (mIntentSenderRecords.size() > 0) { 5757 Iterator<WeakReference<PendingIntentRecord>> it 5758 = mIntentSenderRecords.values().iterator(); 5759 while (it.hasNext()) { 5760 WeakReference<PendingIntentRecord> wpir = it.next(); 5761 if (wpir == null) { 5762 it.remove(); 5763 continue; 5764 } 5765 PendingIntentRecord pir = wpir.get(); 5766 if (pir == null) { 5767 it.remove(); 5768 continue; 5769 } 5770 if (name == null) { 5771 // Stopping user, remove all objects for the user. 5772 if (pir.key.userId != userId) { 5773 // Not the same user, skip it. 5774 continue; 5775 } 5776 } else { 5777 if (UserHandle.getAppId(pir.uid) != appId) { 5778 // Different app id, skip it. 5779 continue; 5780 } 5781 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5782 // Different user, skip it. 5783 continue; 5784 } 5785 if (!pir.key.packageName.equals(name)) { 5786 // Different package, skip it. 5787 continue; 5788 } 5789 } 5790 if (!doit) { 5791 return true; 5792 } 5793 didSomething = true; 5794 it.remove(); 5795 pir.canceled = true; 5796 if (pir.key.activity != null) { 5797 pir.key.activity.pendingResults.remove(pir.ref); 5798 } 5799 } 5800 } 5801 } 5802 5803 if (doit) { 5804 if (purgeCache && name != null) { 5805 AttributeCache ac = AttributeCache.instance(); 5806 if (ac != null) { 5807 ac.removePackage(name); 5808 } 5809 } 5810 if (mBooted) { 5811 mStackSupervisor.resumeTopActivitiesLocked(); 5812 mStackSupervisor.scheduleIdleLocked(); 5813 } 5814 } 5815 5816 return didSomething; 5817 } 5818 5819 private final boolean removeProcessLocked(ProcessRecord app, 5820 boolean callerWillRestart, boolean allowRestart, String reason) { 5821 final String name = app.processName; 5822 final int uid = app.uid; 5823 if (DEBUG_PROCESSES) Slog.d( 5824 TAG, "Force removing proc " + app.toShortString() + " (" + name 5825 + "/" + uid + ")"); 5826 5827 mProcessNames.remove(name, uid); 5828 mIsolatedProcesses.remove(app.uid); 5829 if (mHeavyWeightProcess == app) { 5830 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5831 mHeavyWeightProcess.userId, 0)); 5832 mHeavyWeightProcess = null; 5833 } 5834 boolean needRestart = false; 5835 if (app.pid > 0 && app.pid != MY_PID) { 5836 int pid = app.pid; 5837 synchronized (mPidsSelfLocked) { 5838 mPidsSelfLocked.remove(pid); 5839 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5840 } 5841 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5842 if (app.isolated) { 5843 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5844 } 5845 app.kill(reason, true); 5846 handleAppDiedLocked(app, true, allowRestart); 5847 removeLruProcessLocked(app); 5848 5849 if (app.persistent && !app.isolated) { 5850 if (!callerWillRestart) { 5851 addAppLocked(app.info, false, null /* ABI override */); 5852 } else { 5853 needRestart = true; 5854 } 5855 } 5856 } else { 5857 mRemovedProcesses.add(app); 5858 } 5859 5860 return needRestart; 5861 } 5862 5863 private final void processStartTimedOutLocked(ProcessRecord app) { 5864 final int pid = app.pid; 5865 boolean gone = false; 5866 synchronized (mPidsSelfLocked) { 5867 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5868 if (knownApp != null && knownApp.thread == null) { 5869 mPidsSelfLocked.remove(pid); 5870 gone = true; 5871 } 5872 } 5873 5874 if (gone) { 5875 Slog.w(TAG, "Process " + app + " failed to attach"); 5876 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5877 pid, app.uid, app.processName); 5878 mProcessNames.remove(app.processName, app.uid); 5879 mIsolatedProcesses.remove(app.uid); 5880 if (mHeavyWeightProcess == app) { 5881 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5882 mHeavyWeightProcess.userId, 0)); 5883 mHeavyWeightProcess = null; 5884 } 5885 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5886 if (app.isolated) { 5887 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5888 } 5889 // Take care of any launching providers waiting for this process. 5890 checkAppInLaunchingProvidersLocked(app, true); 5891 // Take care of any services that are waiting for the process. 5892 mServices.processStartTimedOutLocked(app); 5893 app.kill("start timeout", true); 5894 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5895 Slog.w(TAG, "Unattached app died before backup, skipping"); 5896 try { 5897 IBackupManager bm = IBackupManager.Stub.asInterface( 5898 ServiceManager.getService(Context.BACKUP_SERVICE)); 5899 bm.agentDisconnected(app.info.packageName); 5900 } catch (RemoteException e) { 5901 // Can't happen; the backup manager is local 5902 } 5903 } 5904 if (isPendingBroadcastProcessLocked(pid)) { 5905 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5906 skipPendingBroadcastLocked(pid); 5907 } 5908 } else { 5909 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5910 } 5911 } 5912 5913 private final boolean attachApplicationLocked(IApplicationThread thread, 5914 int pid) { 5915 5916 // Find the application record that is being attached... either via 5917 // the pid if we are running in multiple processes, or just pull the 5918 // next app record if we are emulating process with anonymous threads. 5919 ProcessRecord app; 5920 if (pid != MY_PID && pid >= 0) { 5921 synchronized (mPidsSelfLocked) { 5922 app = mPidsSelfLocked.get(pid); 5923 } 5924 } else { 5925 app = null; 5926 } 5927 5928 if (app == null) { 5929 Slog.w(TAG, "No pending application record for pid " + pid 5930 + " (IApplicationThread " + thread + "); dropping process"); 5931 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5932 if (pid > 0 && pid != MY_PID) { 5933 Process.killProcessQuiet(pid); 5934 //TODO: Process.killProcessGroup(app.info.uid, pid); 5935 } else { 5936 try { 5937 thread.scheduleExit(); 5938 } catch (Exception e) { 5939 // Ignore exceptions. 5940 } 5941 } 5942 return false; 5943 } 5944 5945 // If this application record is still attached to a previous 5946 // process, clean it up now. 5947 if (app.thread != null) { 5948 handleAppDiedLocked(app, true, true); 5949 } 5950 5951 // Tell the process all about itself. 5952 5953 if (localLOGV) Slog.v( 5954 TAG, "Binding process pid " + pid + " to record " + app); 5955 5956 final String processName = app.processName; 5957 try { 5958 AppDeathRecipient adr = new AppDeathRecipient( 5959 app, pid, thread); 5960 thread.asBinder().linkToDeath(adr, 0); 5961 app.deathRecipient = adr; 5962 } catch (RemoteException e) { 5963 app.resetPackageList(mProcessStats); 5964 startProcessLocked(app, "link fail", processName); 5965 return false; 5966 } 5967 5968 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5969 5970 app.makeActive(thread, mProcessStats); 5971 app.curAdj = app.setAdj = -100; 5972 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5973 app.forcingToForeground = null; 5974 updateProcessForegroundLocked(app, false, false); 5975 app.hasShownUi = false; 5976 app.debugging = false; 5977 app.cached = false; 5978 5979 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5980 5981 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5982 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5983 5984 if (!normalMode) { 5985 Slog.i(TAG, "Launching preboot mode app: " + app); 5986 } 5987 5988 if (localLOGV) Slog.v( 5989 TAG, "New app record " + app 5990 + " thread=" + thread.asBinder() + " pid=" + pid); 5991 try { 5992 int testMode = IApplicationThread.DEBUG_OFF; 5993 if (mDebugApp != null && mDebugApp.equals(processName)) { 5994 testMode = mWaitForDebugger 5995 ? IApplicationThread.DEBUG_WAIT 5996 : IApplicationThread.DEBUG_ON; 5997 app.debugging = true; 5998 if (mDebugTransient) { 5999 mDebugApp = mOrigDebugApp; 6000 mWaitForDebugger = mOrigWaitForDebugger; 6001 } 6002 } 6003 String profileFile = app.instrumentationProfileFile; 6004 ParcelFileDescriptor profileFd = null; 6005 int samplingInterval = 0; 6006 boolean profileAutoStop = false; 6007 if (mProfileApp != null && mProfileApp.equals(processName)) { 6008 mProfileProc = app; 6009 profileFile = mProfileFile; 6010 profileFd = mProfileFd; 6011 samplingInterval = mSamplingInterval; 6012 profileAutoStop = mAutoStopProfiler; 6013 } 6014 boolean enableOpenGlTrace = false; 6015 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6016 enableOpenGlTrace = true; 6017 mOpenGlTraceApp = null; 6018 } 6019 6020 // If the app is being launched for restore or full backup, set it up specially 6021 boolean isRestrictedBackupMode = false; 6022 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6023 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6024 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6025 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6026 } 6027 6028 ensurePackageDexOpt(app.instrumentationInfo != null 6029 ? app.instrumentationInfo.packageName 6030 : app.info.packageName); 6031 if (app.instrumentationClass != null) { 6032 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6033 } 6034 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6035 + processName + " with config " + mConfiguration); 6036 ApplicationInfo appInfo = app.instrumentationInfo != null 6037 ? app.instrumentationInfo : app.info; 6038 app.compat = compatibilityInfoForPackageLocked(appInfo); 6039 if (profileFd != null) { 6040 profileFd = profileFd.dup(); 6041 } 6042 ProfilerInfo profilerInfo = profileFile == null ? null 6043 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6044 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6045 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6046 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6047 isRestrictedBackupMode || !normalMode, app.persistent, 6048 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6049 mCoreSettingsObserver.getCoreSettingsLocked()); 6050 updateLruProcessLocked(app, false, null); 6051 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6052 } catch (Exception e) { 6053 // todo: Yikes! What should we do? For now we will try to 6054 // start another process, but that could easily get us in 6055 // an infinite loop of restarting processes... 6056 Slog.w(TAG, "Exception thrown during bind!", e); 6057 6058 app.resetPackageList(mProcessStats); 6059 app.unlinkDeathRecipient(); 6060 startProcessLocked(app, "bind fail", processName); 6061 return false; 6062 } 6063 6064 // Remove this record from the list of starting applications. 6065 mPersistentStartingProcesses.remove(app); 6066 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6067 "Attach application locked removing on hold: " + app); 6068 mProcessesOnHold.remove(app); 6069 6070 boolean badApp = false; 6071 boolean didSomething = false; 6072 6073 // See if the top visible activity is waiting to run in this process... 6074 if (normalMode) { 6075 try { 6076 if (mStackSupervisor.attachApplicationLocked(app)) { 6077 didSomething = true; 6078 } 6079 } catch (Exception e) { 6080 badApp = true; 6081 } 6082 } 6083 6084 // Find any services that should be running in this process... 6085 if (!badApp) { 6086 try { 6087 didSomething |= mServices.attachApplicationLocked(app, processName); 6088 } catch (Exception e) { 6089 badApp = true; 6090 } 6091 } 6092 6093 // Check if a next-broadcast receiver is in this process... 6094 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6095 try { 6096 didSomething |= sendPendingBroadcastsLocked(app); 6097 } catch (Exception e) { 6098 // If the app died trying to launch the receiver we declare it 'bad' 6099 badApp = true; 6100 } 6101 } 6102 6103 // Check whether the next backup agent is in this process... 6104 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6105 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6106 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6107 try { 6108 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6109 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6110 mBackupTarget.backupMode); 6111 } catch (Exception e) { 6112 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6113 e.printStackTrace(); 6114 } 6115 } 6116 6117 if (badApp) { 6118 // todo: Also need to kill application to deal with all 6119 // kinds of exceptions. 6120 handleAppDiedLocked(app, false, true); 6121 return false; 6122 } 6123 6124 if (!didSomething) { 6125 updateOomAdjLocked(); 6126 } 6127 6128 return true; 6129 } 6130 6131 @Override 6132 public final void attachApplication(IApplicationThread thread) { 6133 synchronized (this) { 6134 int callingPid = Binder.getCallingPid(); 6135 final long origId = Binder.clearCallingIdentity(); 6136 attachApplicationLocked(thread, callingPid); 6137 Binder.restoreCallingIdentity(origId); 6138 } 6139 } 6140 6141 @Override 6142 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6143 final long origId = Binder.clearCallingIdentity(); 6144 synchronized (this) { 6145 ActivityStack stack = ActivityRecord.getStackLocked(token); 6146 if (stack != null) { 6147 ActivityRecord r = 6148 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6149 if (stopProfiling) { 6150 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6151 try { 6152 mProfileFd.close(); 6153 } catch (IOException e) { 6154 } 6155 clearProfilerLocked(); 6156 } 6157 } 6158 } 6159 } 6160 Binder.restoreCallingIdentity(origId); 6161 } 6162 6163 void postEnableScreenAfterBootLocked() { 6164 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6165 } 6166 6167 void enableScreenAfterBoot() { 6168 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6169 SystemClock.uptimeMillis()); 6170 mWindowManager.enableScreenAfterBoot(); 6171 6172 synchronized (this) { 6173 updateEventDispatchingLocked(); 6174 } 6175 } 6176 6177 @Override 6178 public void showBootMessage(final CharSequence msg, final boolean always) { 6179 enforceNotIsolatedCaller("showBootMessage"); 6180 mWindowManager.showBootMessage(msg, always); 6181 } 6182 6183 @Override 6184 public void keyguardWaitingForActivityDrawn() { 6185 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6186 final long token = Binder.clearCallingIdentity(); 6187 try { 6188 synchronized (this) { 6189 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6190 mWindowManager.keyguardWaitingForActivityDrawn(); 6191 } 6192 } finally { 6193 Binder.restoreCallingIdentity(token); 6194 } 6195 } 6196 6197 final void finishBooting() { 6198 // Register receivers to handle package update events 6199 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6200 6201 // Let system services know. 6202 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6203 6204 synchronized (this) { 6205 // Ensure that any processes we had put on hold are now started 6206 // up. 6207 final int NP = mProcessesOnHold.size(); 6208 if (NP > 0) { 6209 ArrayList<ProcessRecord> procs = 6210 new ArrayList<ProcessRecord>(mProcessesOnHold); 6211 for (int ip=0; ip<NP; ip++) { 6212 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6213 + procs.get(ip)); 6214 startProcessLocked(procs.get(ip), "on-hold", null); 6215 } 6216 } 6217 6218 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6219 // Start looking for apps that are abusing wake locks. 6220 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6221 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6222 // Tell anyone interested that we are done booting! 6223 SystemProperties.set("sys.boot_completed", "1"); 6224 SystemProperties.set("dev.bootcomplete", "1"); 6225 for (int i=0; i<mStartedUsers.size(); i++) { 6226 UserStartedState uss = mStartedUsers.valueAt(i); 6227 if (uss.mState == UserStartedState.STATE_BOOTING) { 6228 uss.mState = UserStartedState.STATE_RUNNING; 6229 final int userId = mStartedUsers.keyAt(i); 6230 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6231 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6232 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6233 broadcastIntentLocked(null, null, intent, null, 6234 new IIntentReceiver.Stub() { 6235 @Override 6236 public void performReceive(Intent intent, int resultCode, 6237 String data, Bundle extras, boolean ordered, 6238 boolean sticky, int sendingUser) { 6239 synchronized (ActivityManagerService.this) { 6240 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6241 true, false); 6242 } 6243 } 6244 }, 6245 0, null, null, 6246 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6247 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6248 userId); 6249 } 6250 } 6251 scheduleStartProfilesLocked(); 6252 } 6253 } 6254 } 6255 6256 final void ensureBootCompleted() { 6257 boolean booting; 6258 boolean enableScreen; 6259 synchronized (this) { 6260 booting = mBooting; 6261 mBooting = false; 6262 enableScreen = !mBooted; 6263 mBooted = true; 6264 } 6265 6266 if (booting) { 6267 finishBooting(); 6268 } 6269 6270 if (enableScreen) { 6271 enableScreenAfterBoot(); 6272 } 6273 } 6274 6275 @Override 6276 public final void activityResumed(IBinder token) { 6277 final long origId = Binder.clearCallingIdentity(); 6278 synchronized(this) { 6279 ActivityStack stack = ActivityRecord.getStackLocked(token); 6280 if (stack != null) { 6281 ActivityRecord.activityResumedLocked(token); 6282 } 6283 } 6284 Binder.restoreCallingIdentity(origId); 6285 } 6286 6287 @Override 6288 public final void activityPaused(IBinder token) { 6289 final long origId = Binder.clearCallingIdentity(); 6290 synchronized(this) { 6291 ActivityStack stack = ActivityRecord.getStackLocked(token); 6292 if (stack != null) { 6293 stack.activityPausedLocked(token, false); 6294 } 6295 } 6296 Binder.restoreCallingIdentity(origId); 6297 } 6298 6299 @Override 6300 public final void activityStopped(IBinder token, Bundle icicle, 6301 PersistableBundle persistentState, CharSequence description) { 6302 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6303 6304 // Refuse possible leaked file descriptors 6305 if (icicle != null && icicle.hasFileDescriptors()) { 6306 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6307 } 6308 6309 final long origId = Binder.clearCallingIdentity(); 6310 6311 synchronized (this) { 6312 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6313 if (r != null) { 6314 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6315 } 6316 } 6317 6318 trimApplications(); 6319 6320 Binder.restoreCallingIdentity(origId); 6321 } 6322 6323 @Override 6324 public final void activityDestroyed(IBinder token) { 6325 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6326 synchronized (this) { 6327 ActivityStack stack = ActivityRecord.getStackLocked(token); 6328 if (stack != null) { 6329 stack.activityDestroyedLocked(token); 6330 } 6331 } 6332 } 6333 6334 @Override 6335 public final void backgroundResourcesReleased(IBinder token) { 6336 final long origId = Binder.clearCallingIdentity(); 6337 try { 6338 synchronized (this) { 6339 ActivityStack stack = ActivityRecord.getStackLocked(token); 6340 if (stack != null) { 6341 stack.backgroundResourcesReleased(token); 6342 } 6343 } 6344 } finally { 6345 Binder.restoreCallingIdentity(origId); 6346 } 6347 } 6348 6349 @Override 6350 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6351 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6352 } 6353 6354 @Override 6355 public final void notifyEnterAnimationComplete(IBinder token) { 6356 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6357 } 6358 6359 @Override 6360 public String getCallingPackage(IBinder token) { 6361 synchronized (this) { 6362 ActivityRecord r = getCallingRecordLocked(token); 6363 return r != null ? r.info.packageName : null; 6364 } 6365 } 6366 6367 @Override 6368 public ComponentName getCallingActivity(IBinder token) { 6369 synchronized (this) { 6370 ActivityRecord r = getCallingRecordLocked(token); 6371 return r != null ? r.intent.getComponent() : null; 6372 } 6373 } 6374 6375 private ActivityRecord getCallingRecordLocked(IBinder token) { 6376 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6377 if (r == null) { 6378 return null; 6379 } 6380 return r.resultTo; 6381 } 6382 6383 @Override 6384 public ComponentName getActivityClassForToken(IBinder token) { 6385 synchronized(this) { 6386 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6387 if (r == null) { 6388 return null; 6389 } 6390 return r.intent.getComponent(); 6391 } 6392 } 6393 6394 @Override 6395 public String getPackageForToken(IBinder token) { 6396 synchronized(this) { 6397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6398 if (r == null) { 6399 return null; 6400 } 6401 return r.packageName; 6402 } 6403 } 6404 6405 @Override 6406 public IIntentSender getIntentSender(int type, 6407 String packageName, IBinder token, String resultWho, 6408 int requestCode, Intent[] intents, String[] resolvedTypes, 6409 int flags, Bundle options, int userId) { 6410 enforceNotIsolatedCaller("getIntentSender"); 6411 // Refuse possible leaked file descriptors 6412 if (intents != null) { 6413 if (intents.length < 1) { 6414 throw new IllegalArgumentException("Intents array length must be >= 1"); 6415 } 6416 for (int i=0; i<intents.length; i++) { 6417 Intent intent = intents[i]; 6418 if (intent != null) { 6419 if (intent.hasFileDescriptors()) { 6420 throw new IllegalArgumentException("File descriptors passed in Intent"); 6421 } 6422 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6423 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6424 throw new IllegalArgumentException( 6425 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6426 } 6427 intents[i] = new Intent(intent); 6428 } 6429 } 6430 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6431 throw new IllegalArgumentException( 6432 "Intent array length does not match resolvedTypes length"); 6433 } 6434 } 6435 if (options != null) { 6436 if (options.hasFileDescriptors()) { 6437 throw new IllegalArgumentException("File descriptors passed in options"); 6438 } 6439 } 6440 6441 synchronized(this) { 6442 int callingUid = Binder.getCallingUid(); 6443 int origUserId = userId; 6444 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6445 type == ActivityManager.INTENT_SENDER_BROADCAST, 6446 ALLOW_NON_FULL, "getIntentSender", null); 6447 if (origUserId == UserHandle.USER_CURRENT) { 6448 // We don't want to evaluate this until the pending intent is 6449 // actually executed. However, we do want to always do the 6450 // security checking for it above. 6451 userId = UserHandle.USER_CURRENT; 6452 } 6453 try { 6454 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6455 int uid = AppGlobals.getPackageManager() 6456 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6457 if (!UserHandle.isSameApp(callingUid, uid)) { 6458 String msg = "Permission Denial: getIntentSender() from pid=" 6459 + Binder.getCallingPid() 6460 + ", uid=" + Binder.getCallingUid() 6461 + ", (need uid=" + uid + ")" 6462 + " is not allowed to send as package " + packageName; 6463 Slog.w(TAG, msg); 6464 throw new SecurityException(msg); 6465 } 6466 } 6467 6468 return getIntentSenderLocked(type, packageName, callingUid, userId, 6469 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6470 6471 } catch (RemoteException e) { 6472 throw new SecurityException(e); 6473 } 6474 } 6475 } 6476 6477 IIntentSender getIntentSenderLocked(int type, String packageName, 6478 int callingUid, int userId, IBinder token, String resultWho, 6479 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6480 Bundle options) { 6481 if (DEBUG_MU) 6482 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6483 ActivityRecord activity = null; 6484 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6485 activity = ActivityRecord.isInStackLocked(token); 6486 if (activity == null) { 6487 return null; 6488 } 6489 if (activity.finishing) { 6490 return null; 6491 } 6492 } 6493 6494 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6495 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6496 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6497 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6498 |PendingIntent.FLAG_UPDATE_CURRENT); 6499 6500 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6501 type, packageName, activity, resultWho, 6502 requestCode, intents, resolvedTypes, flags, options, userId); 6503 WeakReference<PendingIntentRecord> ref; 6504 ref = mIntentSenderRecords.get(key); 6505 PendingIntentRecord rec = ref != null ? ref.get() : null; 6506 if (rec != null) { 6507 if (!cancelCurrent) { 6508 if (updateCurrent) { 6509 if (rec.key.requestIntent != null) { 6510 rec.key.requestIntent.replaceExtras(intents != null ? 6511 intents[intents.length - 1] : null); 6512 } 6513 if (intents != null) { 6514 intents[intents.length-1] = rec.key.requestIntent; 6515 rec.key.allIntents = intents; 6516 rec.key.allResolvedTypes = resolvedTypes; 6517 } else { 6518 rec.key.allIntents = null; 6519 rec.key.allResolvedTypes = null; 6520 } 6521 } 6522 return rec; 6523 } 6524 rec.canceled = true; 6525 mIntentSenderRecords.remove(key); 6526 } 6527 if (noCreate) { 6528 return rec; 6529 } 6530 rec = new PendingIntentRecord(this, key, callingUid); 6531 mIntentSenderRecords.put(key, rec.ref); 6532 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6533 if (activity.pendingResults == null) { 6534 activity.pendingResults 6535 = new HashSet<WeakReference<PendingIntentRecord>>(); 6536 } 6537 activity.pendingResults.add(rec.ref); 6538 } 6539 return rec; 6540 } 6541 6542 @Override 6543 public void cancelIntentSender(IIntentSender sender) { 6544 if (!(sender instanceof PendingIntentRecord)) { 6545 return; 6546 } 6547 synchronized(this) { 6548 PendingIntentRecord rec = (PendingIntentRecord)sender; 6549 try { 6550 int uid = AppGlobals.getPackageManager() 6551 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6552 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6553 String msg = "Permission Denial: cancelIntentSender() from pid=" 6554 + Binder.getCallingPid() 6555 + ", uid=" + Binder.getCallingUid() 6556 + " is not allowed to cancel packges " 6557 + rec.key.packageName; 6558 Slog.w(TAG, msg); 6559 throw new SecurityException(msg); 6560 } 6561 } catch (RemoteException e) { 6562 throw new SecurityException(e); 6563 } 6564 cancelIntentSenderLocked(rec, true); 6565 } 6566 } 6567 6568 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6569 rec.canceled = true; 6570 mIntentSenderRecords.remove(rec.key); 6571 if (cleanActivity && rec.key.activity != null) { 6572 rec.key.activity.pendingResults.remove(rec.ref); 6573 } 6574 } 6575 6576 @Override 6577 public String getPackageForIntentSender(IIntentSender pendingResult) { 6578 if (!(pendingResult instanceof PendingIntentRecord)) { 6579 return null; 6580 } 6581 try { 6582 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6583 return res.key.packageName; 6584 } catch (ClassCastException e) { 6585 } 6586 return null; 6587 } 6588 6589 @Override 6590 public int getUidForIntentSender(IIntentSender sender) { 6591 if (sender instanceof PendingIntentRecord) { 6592 try { 6593 PendingIntentRecord res = (PendingIntentRecord)sender; 6594 return res.uid; 6595 } catch (ClassCastException e) { 6596 } 6597 } 6598 return -1; 6599 } 6600 6601 @Override 6602 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6603 if (!(pendingResult instanceof PendingIntentRecord)) { 6604 return false; 6605 } 6606 try { 6607 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6608 if (res.key.allIntents == null) { 6609 return false; 6610 } 6611 for (int i=0; i<res.key.allIntents.length; i++) { 6612 Intent intent = res.key.allIntents[i]; 6613 if (intent.getPackage() != null && intent.getComponent() != null) { 6614 return false; 6615 } 6616 } 6617 return true; 6618 } catch (ClassCastException e) { 6619 } 6620 return false; 6621 } 6622 6623 @Override 6624 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6625 if (!(pendingResult instanceof PendingIntentRecord)) { 6626 return false; 6627 } 6628 try { 6629 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6630 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6631 return true; 6632 } 6633 return false; 6634 } catch (ClassCastException e) { 6635 } 6636 return false; 6637 } 6638 6639 @Override 6640 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6641 if (!(pendingResult instanceof PendingIntentRecord)) { 6642 return null; 6643 } 6644 try { 6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6646 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6647 } catch (ClassCastException e) { 6648 } 6649 return null; 6650 } 6651 6652 @Override 6653 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6654 if (!(pendingResult instanceof PendingIntentRecord)) { 6655 return null; 6656 } 6657 try { 6658 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6659 Intent intent = res.key.requestIntent; 6660 if (intent != null) { 6661 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6662 || res.lastTagPrefix.equals(prefix))) { 6663 return res.lastTag; 6664 } 6665 res.lastTagPrefix = prefix; 6666 StringBuilder sb = new StringBuilder(128); 6667 if (prefix != null) { 6668 sb.append(prefix); 6669 } 6670 if (intent.getAction() != null) { 6671 sb.append(intent.getAction()); 6672 } else if (intent.getComponent() != null) { 6673 intent.getComponent().appendShortString(sb); 6674 } else { 6675 sb.append("?"); 6676 } 6677 return res.lastTag = sb.toString(); 6678 } 6679 } catch (ClassCastException e) { 6680 } 6681 return null; 6682 } 6683 6684 @Override 6685 public void setProcessLimit(int max) { 6686 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6687 "setProcessLimit()"); 6688 synchronized (this) { 6689 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6690 mProcessLimitOverride = max; 6691 } 6692 trimApplications(); 6693 } 6694 6695 @Override 6696 public int getProcessLimit() { 6697 synchronized (this) { 6698 return mProcessLimitOverride; 6699 } 6700 } 6701 6702 void foregroundTokenDied(ForegroundToken token) { 6703 synchronized (ActivityManagerService.this) { 6704 synchronized (mPidsSelfLocked) { 6705 ForegroundToken cur 6706 = mForegroundProcesses.get(token.pid); 6707 if (cur != token) { 6708 return; 6709 } 6710 mForegroundProcesses.remove(token.pid); 6711 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6712 if (pr == null) { 6713 return; 6714 } 6715 pr.forcingToForeground = null; 6716 updateProcessForegroundLocked(pr, false, false); 6717 } 6718 updateOomAdjLocked(); 6719 } 6720 } 6721 6722 @Override 6723 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6724 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6725 "setProcessForeground()"); 6726 synchronized(this) { 6727 boolean changed = false; 6728 6729 synchronized (mPidsSelfLocked) { 6730 ProcessRecord pr = mPidsSelfLocked.get(pid); 6731 if (pr == null && isForeground) { 6732 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6733 return; 6734 } 6735 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6736 if (oldToken != null) { 6737 oldToken.token.unlinkToDeath(oldToken, 0); 6738 mForegroundProcesses.remove(pid); 6739 if (pr != null) { 6740 pr.forcingToForeground = null; 6741 } 6742 changed = true; 6743 } 6744 if (isForeground && token != null) { 6745 ForegroundToken newToken = new ForegroundToken() { 6746 @Override 6747 public void binderDied() { 6748 foregroundTokenDied(this); 6749 } 6750 }; 6751 newToken.pid = pid; 6752 newToken.token = token; 6753 try { 6754 token.linkToDeath(newToken, 0); 6755 mForegroundProcesses.put(pid, newToken); 6756 pr.forcingToForeground = token; 6757 changed = true; 6758 } catch (RemoteException e) { 6759 // If the process died while doing this, we will later 6760 // do the cleanup with the process death link. 6761 } 6762 } 6763 } 6764 6765 if (changed) { 6766 updateOomAdjLocked(); 6767 } 6768 } 6769 } 6770 6771 // ========================================================= 6772 // PERMISSIONS 6773 // ========================================================= 6774 6775 static class PermissionController extends IPermissionController.Stub { 6776 ActivityManagerService mActivityManagerService; 6777 PermissionController(ActivityManagerService activityManagerService) { 6778 mActivityManagerService = activityManagerService; 6779 } 6780 6781 @Override 6782 public boolean checkPermission(String permission, int pid, int uid) { 6783 return mActivityManagerService.checkPermission(permission, pid, 6784 uid) == PackageManager.PERMISSION_GRANTED; 6785 } 6786 } 6787 6788 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6789 @Override 6790 public int checkComponentPermission(String permission, int pid, int uid, 6791 int owningUid, boolean exported) { 6792 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6793 owningUid, exported); 6794 } 6795 6796 @Override 6797 public Object getAMSLock() { 6798 return ActivityManagerService.this; 6799 } 6800 } 6801 6802 /** 6803 * This can be called with or without the global lock held. 6804 */ 6805 int checkComponentPermission(String permission, int pid, int uid, 6806 int owningUid, boolean exported) { 6807 // We might be performing an operation on behalf of an indirect binder 6808 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6809 // client identity accordingly before proceeding. 6810 Identity tlsIdentity = sCallerIdentity.get(); 6811 if (tlsIdentity != null) { 6812 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6813 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6814 uid = tlsIdentity.uid; 6815 pid = tlsIdentity.pid; 6816 } 6817 6818 if (pid == MY_PID) { 6819 return PackageManager.PERMISSION_GRANTED; 6820 } 6821 6822 return ActivityManager.checkComponentPermission(permission, uid, 6823 owningUid, exported); 6824 } 6825 6826 /** 6827 * As the only public entry point for permissions checking, this method 6828 * can enforce the semantic that requesting a check on a null global 6829 * permission is automatically denied. (Internally a null permission 6830 * string is used when calling {@link #checkComponentPermission} in cases 6831 * when only uid-based security is needed.) 6832 * 6833 * This can be called with or without the global lock held. 6834 */ 6835 @Override 6836 public int checkPermission(String permission, int pid, int uid) { 6837 if (permission == null) { 6838 return PackageManager.PERMISSION_DENIED; 6839 } 6840 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6841 } 6842 6843 /** 6844 * Binder IPC calls go through the public entry point. 6845 * This can be called with or without the global lock held. 6846 */ 6847 int checkCallingPermission(String permission) { 6848 return checkPermission(permission, 6849 Binder.getCallingPid(), 6850 UserHandle.getAppId(Binder.getCallingUid())); 6851 } 6852 6853 /** 6854 * This can be called with or without the global lock held. 6855 */ 6856 void enforceCallingPermission(String permission, String func) { 6857 if (checkCallingPermission(permission) 6858 == PackageManager.PERMISSION_GRANTED) { 6859 return; 6860 } 6861 6862 String msg = "Permission Denial: " + func + " from pid=" 6863 + Binder.getCallingPid() 6864 + ", uid=" + Binder.getCallingUid() 6865 + " requires " + permission; 6866 Slog.w(TAG, msg); 6867 throw new SecurityException(msg); 6868 } 6869 6870 /** 6871 * Determine if UID is holding permissions required to access {@link Uri} in 6872 * the given {@link ProviderInfo}. Final permission checking is always done 6873 * in {@link ContentProvider}. 6874 */ 6875 private final boolean checkHoldingPermissionsLocked( 6876 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6877 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6878 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6879 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6880 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6881 != PERMISSION_GRANTED) { 6882 return false; 6883 } 6884 } 6885 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6886 } 6887 6888 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6889 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6890 if (pi.applicationInfo.uid == uid) { 6891 return true; 6892 } else if (!pi.exported) { 6893 return false; 6894 } 6895 6896 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6897 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6898 try { 6899 // check if target holds top-level <provider> permissions 6900 if (!readMet && pi.readPermission != null && considerUidPermissions 6901 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6902 readMet = true; 6903 } 6904 if (!writeMet && pi.writePermission != null && considerUidPermissions 6905 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6906 writeMet = true; 6907 } 6908 6909 // track if unprotected read/write is allowed; any denied 6910 // <path-permission> below removes this ability 6911 boolean allowDefaultRead = pi.readPermission == null; 6912 boolean allowDefaultWrite = pi.writePermission == null; 6913 6914 // check if target holds any <path-permission> that match uri 6915 final PathPermission[] pps = pi.pathPermissions; 6916 if (pps != null) { 6917 final String path = grantUri.uri.getPath(); 6918 int i = pps.length; 6919 while (i > 0 && (!readMet || !writeMet)) { 6920 i--; 6921 PathPermission pp = pps[i]; 6922 if (pp.match(path)) { 6923 if (!readMet) { 6924 final String pprperm = pp.getReadPermission(); 6925 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6926 + pprperm + " for " + pp.getPath() 6927 + ": match=" + pp.match(path) 6928 + " check=" + pm.checkUidPermission(pprperm, uid)); 6929 if (pprperm != null) { 6930 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6931 == PERMISSION_GRANTED) { 6932 readMet = true; 6933 } else { 6934 allowDefaultRead = false; 6935 } 6936 } 6937 } 6938 if (!writeMet) { 6939 final String ppwperm = pp.getWritePermission(); 6940 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6941 + ppwperm + " for " + pp.getPath() 6942 + ": match=" + pp.match(path) 6943 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6944 if (ppwperm != null) { 6945 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6946 == PERMISSION_GRANTED) { 6947 writeMet = true; 6948 } else { 6949 allowDefaultWrite = false; 6950 } 6951 } 6952 } 6953 } 6954 } 6955 } 6956 6957 // grant unprotected <provider> read/write, if not blocked by 6958 // <path-permission> above 6959 if (allowDefaultRead) readMet = true; 6960 if (allowDefaultWrite) writeMet = true; 6961 6962 } catch (RemoteException e) { 6963 return false; 6964 } 6965 6966 return readMet && writeMet; 6967 } 6968 6969 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6970 ProviderInfo pi = null; 6971 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6972 if (cpr != null) { 6973 pi = cpr.info; 6974 } else { 6975 try { 6976 pi = AppGlobals.getPackageManager().resolveContentProvider( 6977 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6978 } catch (RemoteException ex) { 6979 } 6980 } 6981 return pi; 6982 } 6983 6984 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6985 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6986 if (targetUris != null) { 6987 return targetUris.get(grantUri); 6988 } 6989 return null; 6990 } 6991 6992 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6993 String targetPkg, int targetUid, GrantUri grantUri) { 6994 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6995 if (targetUris == null) { 6996 targetUris = Maps.newArrayMap(); 6997 mGrantedUriPermissions.put(targetUid, targetUris); 6998 } 6999 7000 UriPermission perm = targetUris.get(grantUri); 7001 if (perm == null) { 7002 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7003 targetUris.put(grantUri, perm); 7004 } 7005 7006 return perm; 7007 } 7008 7009 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7010 final int modeFlags) { 7011 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7012 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7013 : UriPermission.STRENGTH_OWNED; 7014 7015 // Root gets to do everything. 7016 if (uid == 0) { 7017 return true; 7018 } 7019 7020 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7021 if (perms == null) return false; 7022 7023 // First look for exact match 7024 final UriPermission exactPerm = perms.get(grantUri); 7025 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7026 return true; 7027 } 7028 7029 // No exact match, look for prefixes 7030 final int N = perms.size(); 7031 for (int i = 0; i < N; i++) { 7032 final UriPermission perm = perms.valueAt(i); 7033 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7034 && perm.getStrength(modeFlags) >= minStrength) { 7035 return true; 7036 } 7037 } 7038 7039 return false; 7040 } 7041 7042 /** 7043 * @param uri This uri must NOT contain an embedded userId. 7044 * @param userId The userId in which the uri is to be resolved. 7045 */ 7046 @Override 7047 public int checkUriPermission(Uri uri, int pid, int uid, 7048 final int modeFlags, int userId) { 7049 enforceNotIsolatedCaller("checkUriPermission"); 7050 7051 // Another redirected-binder-call permissions check as in 7052 // {@link checkComponentPermission}. 7053 Identity tlsIdentity = sCallerIdentity.get(); 7054 if (tlsIdentity != null) { 7055 uid = tlsIdentity.uid; 7056 pid = tlsIdentity.pid; 7057 } 7058 7059 // Our own process gets to do everything. 7060 if (pid == MY_PID) { 7061 return PackageManager.PERMISSION_GRANTED; 7062 } 7063 synchronized (this) { 7064 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7065 ? PackageManager.PERMISSION_GRANTED 7066 : PackageManager.PERMISSION_DENIED; 7067 } 7068 } 7069 7070 /** 7071 * Check if the targetPkg can be granted permission to access uri by 7072 * the callingUid using the given modeFlags. Throws a security exception 7073 * if callingUid is not allowed to do this. Returns the uid of the target 7074 * if the URI permission grant should be performed; returns -1 if it is not 7075 * needed (for example targetPkg already has permission to access the URI). 7076 * If you already know the uid of the target, you can supply it in 7077 * lastTargetUid else set that to -1. 7078 */ 7079 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7080 final int modeFlags, int lastTargetUid) { 7081 if (!Intent.isAccessUriMode(modeFlags)) { 7082 return -1; 7083 } 7084 7085 if (targetPkg != null) { 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Checking grant " + targetPkg + " permission to " + grantUri); 7088 } 7089 7090 final IPackageManager pm = AppGlobals.getPackageManager(); 7091 7092 // If this is not a content: uri, we can't do anything with it. 7093 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7094 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7095 "Can't grant URI permission for non-content URI: " + grantUri); 7096 return -1; 7097 } 7098 7099 final String authority = grantUri.uri.getAuthority(); 7100 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7101 if (pi == null) { 7102 Slog.w(TAG, "No content provider found for permission check: " + 7103 grantUri.uri.toSafeString()); 7104 return -1; 7105 } 7106 7107 int targetUid = lastTargetUid; 7108 if (targetUid < 0 && targetPkg != null) { 7109 try { 7110 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7111 if (targetUid < 0) { 7112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7113 "Can't grant URI permission no uid for: " + targetPkg); 7114 return -1; 7115 } 7116 } catch (RemoteException ex) { 7117 return -1; 7118 } 7119 } 7120 7121 if (targetUid >= 0) { 7122 // First... does the target actually need this permission? 7123 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7124 // No need to grant the target this permission. 7125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7126 "Target " + targetPkg + " already has full permission to " + grantUri); 7127 return -1; 7128 } 7129 } else { 7130 // First... there is no target package, so can anyone access it? 7131 boolean allowed = pi.exported; 7132 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7133 if (pi.readPermission != null) { 7134 allowed = false; 7135 } 7136 } 7137 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7138 if (pi.writePermission != null) { 7139 allowed = false; 7140 } 7141 } 7142 if (allowed) { 7143 return -1; 7144 } 7145 } 7146 7147 /* There is a special cross user grant if: 7148 * - The target is on another user. 7149 * - Apps on the current user can access the uri without any uid permissions. 7150 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7151 * grant uri permissions. 7152 */ 7153 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7154 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7155 modeFlags, false /*without considering the uid permissions*/); 7156 7157 // Second... is the provider allowing granting of URI permissions? 7158 if (!specialCrossUserGrant) { 7159 if (!pi.grantUriPermissions) { 7160 throw new SecurityException("Provider " + pi.packageName 7161 + "/" + pi.name 7162 + " does not allow granting of Uri permissions (uri " 7163 + grantUri + ")"); 7164 } 7165 if (pi.uriPermissionPatterns != null) { 7166 final int N = pi.uriPermissionPatterns.length; 7167 boolean allowed = false; 7168 for (int i=0; i<N; i++) { 7169 if (pi.uriPermissionPatterns[i] != null 7170 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7171 allowed = true; 7172 break; 7173 } 7174 } 7175 if (!allowed) { 7176 throw new SecurityException("Provider " + pi.packageName 7177 + "/" + pi.name 7178 + " does not allow granting of permission to path of Uri " 7179 + grantUri); 7180 } 7181 } 7182 } 7183 7184 // Third... does the caller itself have permission to access 7185 // this uri? 7186 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7187 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7188 // Require they hold a strong enough Uri permission 7189 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7190 throw new SecurityException("Uid " + callingUid 7191 + " does not have permission to uri " + grantUri); 7192 } 7193 } 7194 } 7195 return targetUid; 7196 } 7197 7198 /** 7199 * @param uri This uri must NOT contain an embedded userId. 7200 * @param userId The userId in which the uri is to be resolved. 7201 */ 7202 @Override 7203 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7204 final int modeFlags, int userId) { 7205 enforceNotIsolatedCaller("checkGrantUriPermission"); 7206 synchronized(this) { 7207 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7208 new GrantUri(userId, uri, false), modeFlags, -1); 7209 } 7210 } 7211 7212 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7213 final int modeFlags, UriPermissionOwner owner) { 7214 if (!Intent.isAccessUriMode(modeFlags)) { 7215 return; 7216 } 7217 7218 // So here we are: the caller has the assumed permission 7219 // to the uri, and the target doesn't. Let's now give this to 7220 // the target. 7221 7222 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7223 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7224 7225 final String authority = grantUri.uri.getAuthority(); 7226 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7227 if (pi == null) { 7228 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7229 return; 7230 } 7231 7232 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7233 grantUri.prefix = true; 7234 } 7235 final UriPermission perm = findOrCreateUriPermissionLocked( 7236 pi.packageName, targetPkg, targetUid, grantUri); 7237 perm.grantModes(modeFlags, owner); 7238 } 7239 7240 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7241 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7242 if (targetPkg == null) { 7243 throw new NullPointerException("targetPkg"); 7244 } 7245 int targetUid; 7246 final IPackageManager pm = AppGlobals.getPackageManager(); 7247 try { 7248 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7249 } catch (RemoteException ex) { 7250 return; 7251 } 7252 7253 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7254 targetUid); 7255 if (targetUid < 0) { 7256 return; 7257 } 7258 7259 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7260 owner); 7261 } 7262 7263 static class NeededUriGrants extends ArrayList<GrantUri> { 7264 final String targetPkg; 7265 final int targetUid; 7266 final int flags; 7267 7268 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7269 this.targetPkg = targetPkg; 7270 this.targetUid = targetUid; 7271 this.flags = flags; 7272 } 7273 } 7274 7275 /** 7276 * Like checkGrantUriPermissionLocked, but takes an Intent. 7277 */ 7278 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7279 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7280 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7281 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7282 + " clip=" + (intent != null ? intent.getClipData() : null) 7283 + " from " + intent + "; flags=0x" 7284 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7285 7286 if (targetPkg == null) { 7287 throw new NullPointerException("targetPkg"); 7288 } 7289 7290 if (intent == null) { 7291 return null; 7292 } 7293 Uri data = intent.getData(); 7294 ClipData clip = intent.getClipData(); 7295 if (data == null && clip == null) { 7296 return null; 7297 } 7298 // Default userId for uris in the intent (if they don't specify it themselves) 7299 int contentUserHint = intent.getContentUserHint(); 7300 if (contentUserHint == UserHandle.USER_CURRENT) { 7301 contentUserHint = UserHandle.getUserId(callingUid); 7302 } 7303 final IPackageManager pm = AppGlobals.getPackageManager(); 7304 int targetUid; 7305 if (needed != null) { 7306 targetUid = needed.targetUid; 7307 } else { 7308 try { 7309 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7310 } catch (RemoteException ex) { 7311 return null; 7312 } 7313 if (targetUid < 0) { 7314 if (DEBUG_URI_PERMISSION) { 7315 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7316 + " on user " + targetUserId); 7317 } 7318 return null; 7319 } 7320 } 7321 if (data != null) { 7322 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7323 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7324 targetUid); 7325 if (targetUid > 0) { 7326 if (needed == null) { 7327 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7328 } 7329 needed.add(grantUri); 7330 } 7331 } 7332 if (clip != null) { 7333 for (int i=0; i<clip.getItemCount(); i++) { 7334 Uri uri = clip.getItemAt(i).getUri(); 7335 if (uri != null) { 7336 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7337 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7338 targetUid); 7339 if (targetUid > 0) { 7340 if (needed == null) { 7341 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7342 } 7343 needed.add(grantUri); 7344 } 7345 } else { 7346 Intent clipIntent = clip.getItemAt(i).getIntent(); 7347 if (clipIntent != null) { 7348 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7349 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7350 if (newNeeded != null) { 7351 needed = newNeeded; 7352 } 7353 } 7354 } 7355 } 7356 } 7357 7358 return needed; 7359 } 7360 7361 /** 7362 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7363 */ 7364 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7365 UriPermissionOwner owner) { 7366 if (needed != null) { 7367 for (int i=0; i<needed.size(); i++) { 7368 GrantUri grantUri = needed.get(i); 7369 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7370 grantUri, needed.flags, owner); 7371 } 7372 } 7373 } 7374 7375 void grantUriPermissionFromIntentLocked(int callingUid, 7376 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7377 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7378 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7379 if (needed == null) { 7380 return; 7381 } 7382 7383 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7384 } 7385 7386 /** 7387 * @param uri This uri must NOT contain an embedded userId. 7388 * @param userId The userId in which the uri is to be resolved. 7389 */ 7390 @Override 7391 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7392 final int modeFlags, int userId) { 7393 enforceNotIsolatedCaller("grantUriPermission"); 7394 GrantUri grantUri = new GrantUri(userId, uri, false); 7395 synchronized(this) { 7396 final ProcessRecord r = getRecordForAppLocked(caller); 7397 if (r == null) { 7398 throw new SecurityException("Unable to find app for caller " 7399 + caller 7400 + " when granting permission to uri " + grantUri); 7401 } 7402 if (targetPkg == null) { 7403 throw new IllegalArgumentException("null target"); 7404 } 7405 if (grantUri == null) { 7406 throw new IllegalArgumentException("null uri"); 7407 } 7408 7409 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7410 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7411 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7412 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7413 7414 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7415 UserHandle.getUserId(r.uid)); 7416 } 7417 } 7418 7419 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7420 if (perm.modeFlags == 0) { 7421 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7422 perm.targetUid); 7423 if (perms != null) { 7424 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7425 "Removing " + perm.targetUid + " permission to " + perm.uri); 7426 7427 perms.remove(perm.uri); 7428 if (perms.isEmpty()) { 7429 mGrantedUriPermissions.remove(perm.targetUid); 7430 } 7431 } 7432 } 7433 } 7434 7435 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7436 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7437 7438 final IPackageManager pm = AppGlobals.getPackageManager(); 7439 final String authority = grantUri.uri.getAuthority(); 7440 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7441 if (pi == null) { 7442 Slog.w(TAG, "No content provider found for permission revoke: " 7443 + grantUri.toSafeString()); 7444 return; 7445 } 7446 7447 // Does the caller have this permission on the URI? 7448 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7449 // Right now, if you are not the original owner of the permission, 7450 // you are not allowed to revoke it. 7451 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7452 throw new SecurityException("Uid " + callingUid 7453 + " does not have permission to uri " + grantUri); 7454 //} 7455 } 7456 7457 boolean persistChanged = false; 7458 7459 // Go through all of the permissions and remove any that match. 7460 int N = mGrantedUriPermissions.size(); 7461 for (int i = 0; i < N; i++) { 7462 final int targetUid = mGrantedUriPermissions.keyAt(i); 7463 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7464 7465 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7466 final UriPermission perm = it.next(); 7467 if (perm.uri.sourceUserId == grantUri.sourceUserId 7468 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7469 if (DEBUG_URI_PERMISSION) 7470 Slog.v(TAG, 7471 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7472 persistChanged |= perm.revokeModes( 7473 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7474 if (perm.modeFlags == 0) { 7475 it.remove(); 7476 } 7477 } 7478 } 7479 7480 if (perms.isEmpty()) { 7481 mGrantedUriPermissions.remove(targetUid); 7482 N--; 7483 i--; 7484 } 7485 } 7486 7487 if (persistChanged) { 7488 schedulePersistUriGrants(); 7489 } 7490 } 7491 7492 /** 7493 * @param uri This uri must NOT contain an embedded userId. 7494 * @param userId The userId in which the uri is to be resolved. 7495 */ 7496 @Override 7497 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7498 int userId) { 7499 enforceNotIsolatedCaller("revokeUriPermission"); 7500 synchronized(this) { 7501 final ProcessRecord r = getRecordForAppLocked(caller); 7502 if (r == null) { 7503 throw new SecurityException("Unable to find app for caller " 7504 + caller 7505 + " when revoking permission to uri " + uri); 7506 } 7507 if (uri == null) { 7508 Slog.w(TAG, "revokeUriPermission: null uri"); 7509 return; 7510 } 7511 7512 if (!Intent.isAccessUriMode(modeFlags)) { 7513 return; 7514 } 7515 7516 final IPackageManager pm = AppGlobals.getPackageManager(); 7517 final String authority = uri.getAuthority(); 7518 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7519 if (pi == null) { 7520 Slog.w(TAG, "No content provider found for permission revoke: " 7521 + uri.toSafeString()); 7522 return; 7523 } 7524 7525 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7526 } 7527 } 7528 7529 /** 7530 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7531 * given package. 7532 * 7533 * @param packageName Package name to match, or {@code null} to apply to all 7534 * packages. 7535 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7536 * to all users. 7537 * @param persistable If persistable grants should be removed. 7538 */ 7539 private void removeUriPermissionsForPackageLocked( 7540 String packageName, int userHandle, boolean persistable) { 7541 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7542 throw new IllegalArgumentException("Must narrow by either package or user"); 7543 } 7544 7545 boolean persistChanged = false; 7546 7547 int N = mGrantedUriPermissions.size(); 7548 for (int i = 0; i < N; i++) { 7549 final int targetUid = mGrantedUriPermissions.keyAt(i); 7550 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7551 7552 // Only inspect grants matching user 7553 if (userHandle == UserHandle.USER_ALL 7554 || userHandle == UserHandle.getUserId(targetUid)) { 7555 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7556 final UriPermission perm = it.next(); 7557 7558 // Only inspect grants matching package 7559 if (packageName == null || perm.sourcePkg.equals(packageName) 7560 || perm.targetPkg.equals(packageName)) { 7561 persistChanged |= perm.revokeModes( 7562 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7563 7564 // Only remove when no modes remain; any persisted grants 7565 // will keep this alive. 7566 if (perm.modeFlags == 0) { 7567 it.remove(); 7568 } 7569 } 7570 } 7571 7572 if (perms.isEmpty()) { 7573 mGrantedUriPermissions.remove(targetUid); 7574 N--; 7575 i--; 7576 } 7577 } 7578 } 7579 7580 if (persistChanged) { 7581 schedulePersistUriGrants(); 7582 } 7583 } 7584 7585 @Override 7586 public IBinder newUriPermissionOwner(String name) { 7587 enforceNotIsolatedCaller("newUriPermissionOwner"); 7588 synchronized(this) { 7589 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7590 return owner.getExternalTokenLocked(); 7591 } 7592 } 7593 7594 /** 7595 * @param uri This uri must NOT contain an embedded userId. 7596 * @param sourceUserId The userId in which the uri is to be resolved. 7597 * @param targetUserId The userId of the app that receives the grant. 7598 */ 7599 @Override 7600 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7601 final int modeFlags, int sourceUserId, int targetUserId) { 7602 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7603 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7604 synchronized(this) { 7605 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7606 if (owner == null) { 7607 throw new IllegalArgumentException("Unknown owner: " + token); 7608 } 7609 if (fromUid != Binder.getCallingUid()) { 7610 if (Binder.getCallingUid() != Process.myUid()) { 7611 // Only system code can grant URI permissions on behalf 7612 // of other users. 7613 throw new SecurityException("nice try"); 7614 } 7615 } 7616 if (targetPkg == null) { 7617 throw new IllegalArgumentException("null target"); 7618 } 7619 if (uri == null) { 7620 throw new IllegalArgumentException("null uri"); 7621 } 7622 7623 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7624 modeFlags, owner, targetUserId); 7625 } 7626 } 7627 7628 /** 7629 * @param uri This uri must NOT contain an embedded userId. 7630 * @param userId The userId in which the uri is to be resolved. 7631 */ 7632 @Override 7633 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7634 synchronized(this) { 7635 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7636 if (owner == null) { 7637 throw new IllegalArgumentException("Unknown owner: " + token); 7638 } 7639 7640 if (uri == null) { 7641 owner.removeUriPermissionsLocked(mode); 7642 } else { 7643 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7644 } 7645 } 7646 } 7647 7648 private void schedulePersistUriGrants() { 7649 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7650 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7651 10 * DateUtils.SECOND_IN_MILLIS); 7652 } 7653 } 7654 7655 private void writeGrantedUriPermissions() { 7656 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7657 7658 // Snapshot permissions so we can persist without lock 7659 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7660 synchronized (this) { 7661 final int size = mGrantedUriPermissions.size(); 7662 for (int i = 0; i < size; i++) { 7663 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7664 for (UriPermission perm : perms.values()) { 7665 if (perm.persistedModeFlags != 0) { 7666 persist.add(perm.snapshot()); 7667 } 7668 } 7669 } 7670 } 7671 7672 FileOutputStream fos = null; 7673 try { 7674 fos = mGrantFile.startWrite(); 7675 7676 XmlSerializer out = new FastXmlSerializer(); 7677 out.setOutput(fos, "utf-8"); 7678 out.startDocument(null, true); 7679 out.startTag(null, TAG_URI_GRANTS); 7680 for (UriPermission.Snapshot perm : persist) { 7681 out.startTag(null, TAG_URI_GRANT); 7682 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7683 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7684 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7685 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7686 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7687 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7688 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7689 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7690 out.endTag(null, TAG_URI_GRANT); 7691 } 7692 out.endTag(null, TAG_URI_GRANTS); 7693 out.endDocument(); 7694 7695 mGrantFile.finishWrite(fos); 7696 } catch (IOException e) { 7697 if (fos != null) { 7698 mGrantFile.failWrite(fos); 7699 } 7700 } 7701 } 7702 7703 private void readGrantedUriPermissionsLocked() { 7704 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7705 7706 final long now = System.currentTimeMillis(); 7707 7708 FileInputStream fis = null; 7709 try { 7710 fis = mGrantFile.openRead(); 7711 final XmlPullParser in = Xml.newPullParser(); 7712 in.setInput(fis, null); 7713 7714 int type; 7715 while ((type = in.next()) != END_DOCUMENT) { 7716 final String tag = in.getName(); 7717 if (type == START_TAG) { 7718 if (TAG_URI_GRANT.equals(tag)) { 7719 final int sourceUserId; 7720 final int targetUserId; 7721 final int userHandle = readIntAttribute(in, 7722 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7723 if (userHandle != UserHandle.USER_NULL) { 7724 // For backwards compatibility. 7725 sourceUserId = userHandle; 7726 targetUserId = userHandle; 7727 } else { 7728 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7729 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7730 } 7731 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7732 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7733 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7734 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7735 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7736 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7737 7738 // Sanity check that provider still belongs to source package 7739 final ProviderInfo pi = getProviderInfoLocked( 7740 uri.getAuthority(), sourceUserId); 7741 if (pi != null && sourcePkg.equals(pi.packageName)) { 7742 int targetUid = -1; 7743 try { 7744 targetUid = AppGlobals.getPackageManager() 7745 .getPackageUid(targetPkg, targetUserId); 7746 } catch (RemoteException e) { 7747 } 7748 if (targetUid != -1) { 7749 final UriPermission perm = findOrCreateUriPermissionLocked( 7750 sourcePkg, targetPkg, targetUid, 7751 new GrantUri(sourceUserId, uri, prefix)); 7752 perm.initPersistedModes(modeFlags, createdTime); 7753 } 7754 } else { 7755 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7756 + " but instead found " + pi); 7757 } 7758 } 7759 } 7760 } 7761 } catch (FileNotFoundException e) { 7762 // Missing grants is okay 7763 } catch (IOException e) { 7764 Log.wtf(TAG, "Failed reading Uri grants", e); 7765 } catch (XmlPullParserException e) { 7766 Log.wtf(TAG, "Failed reading Uri grants", e); 7767 } finally { 7768 IoUtils.closeQuietly(fis); 7769 } 7770 } 7771 7772 /** 7773 * @param uri This uri must NOT contain an embedded userId. 7774 * @param userId The userId in which the uri is to be resolved. 7775 */ 7776 @Override 7777 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7778 enforceNotIsolatedCaller("takePersistableUriPermission"); 7779 7780 Preconditions.checkFlagsArgument(modeFlags, 7781 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7782 7783 synchronized (this) { 7784 final int callingUid = Binder.getCallingUid(); 7785 boolean persistChanged = false; 7786 GrantUri grantUri = new GrantUri(userId, uri, false); 7787 7788 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7789 new GrantUri(userId, uri, false)); 7790 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7791 new GrantUri(userId, uri, true)); 7792 7793 final boolean exactValid = (exactPerm != null) 7794 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7795 final boolean prefixValid = (prefixPerm != null) 7796 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7797 7798 if (!(exactValid || prefixValid)) { 7799 throw new SecurityException("No persistable permission grants found for UID " 7800 + callingUid + " and Uri " + grantUri.toSafeString()); 7801 } 7802 7803 if (exactValid) { 7804 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7805 } 7806 if (prefixValid) { 7807 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7808 } 7809 7810 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7811 7812 if (persistChanged) { 7813 schedulePersistUriGrants(); 7814 } 7815 } 7816 } 7817 7818 /** 7819 * @param uri This uri must NOT contain an embedded userId. 7820 * @param userId The userId in which the uri is to be resolved. 7821 */ 7822 @Override 7823 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7824 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7825 7826 Preconditions.checkFlagsArgument(modeFlags, 7827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7828 7829 synchronized (this) { 7830 final int callingUid = Binder.getCallingUid(); 7831 boolean persistChanged = false; 7832 7833 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7834 new GrantUri(userId, uri, false)); 7835 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7836 new GrantUri(userId, uri, true)); 7837 if (exactPerm == null && prefixPerm == null) { 7838 throw new SecurityException("No permission grants found for UID " + callingUid 7839 + " and Uri " + uri.toSafeString()); 7840 } 7841 7842 if (exactPerm != null) { 7843 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7844 removeUriPermissionIfNeededLocked(exactPerm); 7845 } 7846 if (prefixPerm != null) { 7847 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7848 removeUriPermissionIfNeededLocked(prefixPerm); 7849 } 7850 7851 if (persistChanged) { 7852 schedulePersistUriGrants(); 7853 } 7854 } 7855 } 7856 7857 /** 7858 * Prune any older {@link UriPermission} for the given UID until outstanding 7859 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7860 * 7861 * @return if any mutations occured that require persisting. 7862 */ 7863 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7864 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7865 if (perms == null) return false; 7866 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7867 7868 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7869 for (UriPermission perm : perms.values()) { 7870 if (perm.persistedModeFlags != 0) { 7871 persisted.add(perm); 7872 } 7873 } 7874 7875 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7876 if (trimCount <= 0) return false; 7877 7878 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7879 for (int i = 0; i < trimCount; i++) { 7880 final UriPermission perm = persisted.get(i); 7881 7882 if (DEBUG_URI_PERMISSION) { 7883 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7884 } 7885 7886 perm.releasePersistableModes(~0); 7887 removeUriPermissionIfNeededLocked(perm); 7888 } 7889 7890 return true; 7891 } 7892 7893 @Override 7894 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7895 String packageName, boolean incoming) { 7896 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7897 Preconditions.checkNotNull(packageName, "packageName"); 7898 7899 final int callingUid = Binder.getCallingUid(); 7900 final IPackageManager pm = AppGlobals.getPackageManager(); 7901 try { 7902 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7903 if (packageUid != callingUid) { 7904 throw new SecurityException( 7905 "Package " + packageName + " does not belong to calling UID " + callingUid); 7906 } 7907 } catch (RemoteException e) { 7908 throw new SecurityException("Failed to verify package name ownership"); 7909 } 7910 7911 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7912 synchronized (this) { 7913 if (incoming) { 7914 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7915 callingUid); 7916 if (perms == null) { 7917 Slog.w(TAG, "No permission grants found for " + packageName); 7918 } else { 7919 for (UriPermission perm : perms.values()) { 7920 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7921 result.add(perm.buildPersistedPublicApiObject()); 7922 } 7923 } 7924 } 7925 } else { 7926 final int size = mGrantedUriPermissions.size(); 7927 for (int i = 0; i < size; i++) { 7928 final ArrayMap<GrantUri, UriPermission> perms = 7929 mGrantedUriPermissions.valueAt(i); 7930 for (UriPermission perm : perms.values()) { 7931 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7932 result.add(perm.buildPersistedPublicApiObject()); 7933 } 7934 } 7935 } 7936 } 7937 } 7938 return new ParceledListSlice<android.content.UriPermission>(result); 7939 } 7940 7941 @Override 7942 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7943 synchronized (this) { 7944 ProcessRecord app = 7945 who != null ? getRecordForAppLocked(who) : null; 7946 if (app == null) return; 7947 7948 Message msg = Message.obtain(); 7949 msg.what = WAIT_FOR_DEBUGGER_MSG; 7950 msg.obj = app; 7951 msg.arg1 = waiting ? 1 : 0; 7952 mHandler.sendMessage(msg); 7953 } 7954 } 7955 7956 @Override 7957 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7958 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7959 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7960 outInfo.availMem = Process.getFreeMemory(); 7961 outInfo.totalMem = Process.getTotalMemory(); 7962 outInfo.threshold = homeAppMem; 7963 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7964 outInfo.hiddenAppThreshold = cachedAppMem; 7965 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7966 ProcessList.SERVICE_ADJ); 7967 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7968 ProcessList.VISIBLE_APP_ADJ); 7969 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7970 ProcessList.FOREGROUND_APP_ADJ); 7971 } 7972 7973 // ========================================================= 7974 // TASK MANAGEMENT 7975 // ========================================================= 7976 7977 @Override 7978 public List<IAppTask> getAppTasks(String callingPackage) { 7979 int callingUid = Binder.getCallingUid(); 7980 long ident = Binder.clearCallingIdentity(); 7981 7982 synchronized(this) { 7983 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7984 try { 7985 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7986 7987 final int N = mRecentTasks.size(); 7988 for (int i = 0; i < N; i++) { 7989 TaskRecord tr = mRecentTasks.get(i); 7990 // Skip tasks that do not match the caller. We don't need to verify 7991 // callingPackage, because we are also limiting to callingUid and know 7992 // that will limit to the correct security sandbox. 7993 if (tr.effectiveUid != callingUid) { 7994 continue; 7995 } 7996 Intent intent = tr.getBaseIntent(); 7997 if (intent == null || 7998 !callingPackage.equals(intent.getComponent().getPackageName())) { 7999 continue; 8000 } 8001 ActivityManager.RecentTaskInfo taskInfo = 8002 createRecentTaskInfoFromTaskRecord(tr); 8003 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8004 list.add(taskImpl); 8005 } 8006 } finally { 8007 Binder.restoreCallingIdentity(ident); 8008 } 8009 return list; 8010 } 8011 } 8012 8013 @Override 8014 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8015 final int callingUid = Binder.getCallingUid(); 8016 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8017 8018 synchronized(this) { 8019 if (localLOGV) Slog.v( 8020 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8021 8022 final boolean allowed = checkCallingPermission( 8023 android.Manifest.permission.GET_TASKS) 8024 == PackageManager.PERMISSION_GRANTED; 8025 if (!allowed) { 8026 Slog.w(TAG, "getTasks: caller " + callingUid 8027 + " does not hold GET_TASKS; limiting output"); 8028 } 8029 8030 // TODO: Improve with MRU list from all ActivityStacks. 8031 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8032 } 8033 8034 return list; 8035 } 8036 8037 TaskRecord getMostRecentTask() { 8038 return mRecentTasks.get(0); 8039 } 8040 8041 /** 8042 * Creates a new RecentTaskInfo from a TaskRecord. 8043 */ 8044 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8045 // Update the task description to reflect any changes in the task stack 8046 tr.updateTaskDescription(); 8047 8048 // Compose the recent task info 8049 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8050 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8051 rti.persistentId = tr.taskId; 8052 rti.baseIntent = new Intent(tr.getBaseIntent()); 8053 rti.origActivity = tr.origActivity; 8054 rti.description = tr.lastDescription; 8055 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8056 rti.userId = tr.userId; 8057 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8058 rti.firstActiveTime = tr.firstActiveTime; 8059 rti.lastActiveTime = tr.lastActiveTime; 8060 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8061 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8062 return rti; 8063 } 8064 8065 @Override 8066 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8067 final int callingUid = Binder.getCallingUid(); 8068 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8069 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8070 8071 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8072 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8073 synchronized (this) { 8074 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8075 == PackageManager.PERMISSION_GRANTED; 8076 if (!allowed) { 8077 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8078 + " does not hold GET_TASKS; limiting output"); 8079 } 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.taskDescription = td; 8276 r.task.updateTaskDescription(); 8277 } 8278 } 8279 } 8280 8281 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8282 mRecentTasks.remove(tr); 8283 tr.removedFromRecents(mTaskPersister); 8284 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8285 Intent baseIntent = new Intent( 8286 tr.intent != null ? tr.intent : tr.affinityIntent); 8287 ComponentName component = baseIntent.getComponent(); 8288 if (component == null) { 8289 Slog.w(TAG, "Now component for base intent of task: " + tr); 8290 return; 8291 } 8292 8293 // Find any running services associated with this app. 8294 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8295 8296 if (killProcesses) { 8297 // Find any running processes associated with this app. 8298 final String pkg = component.getPackageName(); 8299 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8300 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8301 for (int i=0; i<pmap.size(); i++) { 8302 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8303 for (int j=0; j<uids.size(); j++) { 8304 ProcessRecord proc = uids.valueAt(j); 8305 if (proc.userId != tr.userId) { 8306 continue; 8307 } 8308 if (!proc.pkgList.containsKey(pkg)) { 8309 continue; 8310 } 8311 procs.add(proc); 8312 } 8313 } 8314 8315 // Kill the running processes. 8316 for (int i=0; i<procs.size(); i++) { 8317 ProcessRecord pr = procs.get(i); 8318 if (pr == mHomeProcess) { 8319 // Don't kill the home process along with tasks from the same package. 8320 continue; 8321 } 8322 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8323 pr.kill("remove task", true); 8324 } else { 8325 pr.waitingToKill = "remove task"; 8326 } 8327 } 8328 } 8329 } 8330 8331 /** 8332 * Removes the task with the specified task id. 8333 * 8334 * @param taskId Identifier of the task to be removed. 8335 * @param flags Additional operational flags. May be 0 or 8336 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8337 * @return Returns true if the given task was found and removed. 8338 */ 8339 private boolean removeTaskByIdLocked(int taskId, int flags) { 8340 TaskRecord tr = recentTaskForIdLocked(taskId); 8341 if (tr != null) { 8342 tr.removeTaskActivitiesLocked(); 8343 cleanUpRemovedTaskLocked(tr, flags); 8344 if (tr.isPersistable) { 8345 notifyTaskPersisterLocked(null, true); 8346 } 8347 return true; 8348 } 8349 return false; 8350 } 8351 8352 @Override 8353 public boolean removeTask(int taskId, int flags) { 8354 synchronized (this) { 8355 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8356 "removeTask()"); 8357 long ident = Binder.clearCallingIdentity(); 8358 try { 8359 return removeTaskByIdLocked(taskId, flags); 8360 } finally { 8361 Binder.restoreCallingIdentity(ident); 8362 } 8363 } 8364 } 8365 8366 /** 8367 * TODO: Add mController hook 8368 */ 8369 @Override 8370 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8371 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8372 "moveTaskToFront()"); 8373 8374 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8375 synchronized(this) { 8376 moveTaskToFrontLocked(taskId, flags, options); 8377 } 8378 } 8379 8380 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8381 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8382 Binder.getCallingUid(), "Task to front")) { 8383 ActivityOptions.abort(options); 8384 return; 8385 } 8386 final long origId = Binder.clearCallingIdentity(); 8387 try { 8388 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8389 if (task == null) { 8390 return; 8391 } 8392 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8393 mStackSupervisor.showLockTaskToast(); 8394 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8395 return; 8396 } 8397 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8398 if (prev != null && prev.isRecentsActivity()) { 8399 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8400 } 8401 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8402 } finally { 8403 Binder.restoreCallingIdentity(origId); 8404 } 8405 ActivityOptions.abort(options); 8406 } 8407 8408 @Override 8409 public void moveTaskToBack(int taskId) { 8410 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8411 "moveTaskToBack()"); 8412 8413 synchronized(this) { 8414 TaskRecord tr = recentTaskForIdLocked(taskId); 8415 if (tr != null) { 8416 if (tr == mStackSupervisor.mLockTaskModeTask) { 8417 mStackSupervisor.showLockTaskToast(); 8418 return; 8419 } 8420 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8421 ActivityStack stack = tr.stack; 8422 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8423 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8424 Binder.getCallingUid(), "Task to back")) { 8425 return; 8426 } 8427 } 8428 final long origId = Binder.clearCallingIdentity(); 8429 try { 8430 stack.moveTaskToBackLocked(taskId, null); 8431 } finally { 8432 Binder.restoreCallingIdentity(origId); 8433 } 8434 } 8435 } 8436 } 8437 8438 /** 8439 * Moves an activity, and all of the other activities within the same task, to the bottom 8440 * of the history stack. The activity's order within the task is unchanged. 8441 * 8442 * @param token A reference to the activity we wish to move 8443 * @param nonRoot If false then this only works if the activity is the root 8444 * of a task; if true it will work for any activity in a task. 8445 * @return Returns true if the move completed, false if not. 8446 */ 8447 @Override 8448 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8449 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8450 synchronized(this) { 8451 final long origId = Binder.clearCallingIdentity(); 8452 try { 8453 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8454 if (taskId >= 0) { 8455 if ((mStackSupervisor.mLockTaskModeTask != null) 8456 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8457 mStackSupervisor.showLockTaskToast(); 8458 return false; 8459 } 8460 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8461 } 8462 } finally { 8463 Binder.restoreCallingIdentity(origId); 8464 } 8465 } 8466 return false; 8467 } 8468 8469 @Override 8470 public void moveTaskBackwards(int task) { 8471 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8472 "moveTaskBackwards()"); 8473 8474 synchronized(this) { 8475 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8476 Binder.getCallingUid(), "Task backwards")) { 8477 return; 8478 } 8479 final long origId = Binder.clearCallingIdentity(); 8480 moveTaskBackwardsLocked(task); 8481 Binder.restoreCallingIdentity(origId); 8482 } 8483 } 8484 8485 private final void moveTaskBackwardsLocked(int task) { 8486 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8487 } 8488 8489 @Override 8490 public IBinder getHomeActivityToken() throws RemoteException { 8491 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8492 "getHomeActivityToken()"); 8493 synchronized (this) { 8494 return mStackSupervisor.getHomeActivityToken(); 8495 } 8496 } 8497 8498 @Override 8499 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8500 IActivityContainerCallback callback) throws RemoteException { 8501 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8502 "createActivityContainer()"); 8503 synchronized (this) { 8504 if (parentActivityToken == null) { 8505 throw new IllegalArgumentException("parent token must not be null"); 8506 } 8507 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8508 if (r == null) { 8509 return null; 8510 } 8511 if (callback == null) { 8512 throw new IllegalArgumentException("callback must not be null"); 8513 } 8514 return mStackSupervisor.createActivityContainer(r, callback); 8515 } 8516 } 8517 8518 @Override 8519 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8520 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8521 "deleteActivityContainer()"); 8522 synchronized (this) { 8523 mStackSupervisor.deleteActivityContainer(container); 8524 } 8525 } 8526 8527 @Override 8528 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8529 throws RemoteException { 8530 synchronized (this) { 8531 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8532 if (stack != null) { 8533 return stack.mActivityContainer; 8534 } 8535 return null; 8536 } 8537 } 8538 8539 @Override 8540 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8541 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8542 "moveTaskToStack()"); 8543 if (stackId == HOME_STACK_ID) { 8544 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8545 new RuntimeException("here").fillInStackTrace()); 8546 } 8547 synchronized (this) { 8548 long ident = Binder.clearCallingIdentity(); 8549 try { 8550 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8551 + stackId + " toTop=" + toTop); 8552 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8553 } finally { 8554 Binder.restoreCallingIdentity(ident); 8555 } 8556 } 8557 } 8558 8559 @Override 8560 public void resizeStack(int stackBoxId, Rect bounds) { 8561 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8562 "resizeStackBox()"); 8563 long ident = Binder.clearCallingIdentity(); 8564 try { 8565 mWindowManager.resizeStack(stackBoxId, bounds); 8566 } finally { 8567 Binder.restoreCallingIdentity(ident); 8568 } 8569 } 8570 8571 @Override 8572 public List<StackInfo> getAllStackInfos() { 8573 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8574 "getAllStackInfos()"); 8575 long ident = Binder.clearCallingIdentity(); 8576 try { 8577 synchronized (this) { 8578 return mStackSupervisor.getAllStackInfosLocked(); 8579 } 8580 } finally { 8581 Binder.restoreCallingIdentity(ident); 8582 } 8583 } 8584 8585 @Override 8586 public StackInfo getStackInfo(int stackId) { 8587 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8588 "getStackInfo()"); 8589 long ident = Binder.clearCallingIdentity(); 8590 try { 8591 synchronized (this) { 8592 return mStackSupervisor.getStackInfoLocked(stackId); 8593 } 8594 } finally { 8595 Binder.restoreCallingIdentity(ident); 8596 } 8597 } 8598 8599 @Override 8600 public boolean isInHomeStack(int taskId) { 8601 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8602 "getStackInfo()"); 8603 long ident = Binder.clearCallingIdentity(); 8604 try { 8605 synchronized (this) { 8606 TaskRecord tr = recentTaskForIdLocked(taskId); 8607 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8608 } 8609 } finally { 8610 Binder.restoreCallingIdentity(ident); 8611 } 8612 } 8613 8614 @Override 8615 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8616 synchronized(this) { 8617 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8618 } 8619 } 8620 8621 private boolean isLockTaskAuthorized(String pkg) { 8622 final DevicePolicyManager dpm = (DevicePolicyManager) 8623 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8624 try { 8625 int uid = mContext.getPackageManager().getPackageUid(pkg, 8626 Binder.getCallingUserHandle().getIdentifier()); 8627 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8628 } catch (NameNotFoundException e) { 8629 return false; 8630 } 8631 } 8632 8633 void startLockTaskMode(TaskRecord task) { 8634 final String pkg; 8635 synchronized (this) { 8636 pkg = task.intent.getComponent().getPackageName(); 8637 } 8638 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8639 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8640 final TaskRecord taskRecord = task; 8641 mHandler.post(new Runnable() { 8642 @Override 8643 public void run() { 8644 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8645 } 8646 }); 8647 return; 8648 } 8649 long ident = Binder.clearCallingIdentity(); 8650 try { 8651 synchronized (this) { 8652 // Since we lost lock on task, make sure it is still there. 8653 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8654 if (task != null) { 8655 if (!isSystemInitiated 8656 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8657 throw new IllegalArgumentException("Invalid task, not in foreground"); 8658 } 8659 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8660 } 8661 } 8662 } finally { 8663 Binder.restoreCallingIdentity(ident); 8664 } 8665 } 8666 8667 @Override 8668 public void startLockTaskMode(int taskId) { 8669 final TaskRecord task; 8670 long ident = Binder.clearCallingIdentity(); 8671 try { 8672 synchronized (this) { 8673 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8674 } 8675 } finally { 8676 Binder.restoreCallingIdentity(ident); 8677 } 8678 if (task != null) { 8679 startLockTaskMode(task); 8680 } 8681 } 8682 8683 @Override 8684 public void startLockTaskMode(IBinder token) { 8685 final TaskRecord task; 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 synchronized (this) { 8689 final ActivityRecord r = ActivityRecord.forToken(token); 8690 if (r == null) { 8691 return; 8692 } 8693 task = r.task; 8694 } 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 if (task != null) { 8699 startLockTaskMode(task); 8700 } 8701 } 8702 8703 @Override 8704 public void startLockTaskModeOnCurrent() throws RemoteException { 8705 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8706 "startLockTaskModeOnCurrent"); 8707 ActivityRecord r = null; 8708 synchronized (this) { 8709 r = mStackSupervisor.topRunningActivityLocked(); 8710 } 8711 startLockTaskMode(r.task); 8712 } 8713 8714 @Override 8715 public void stopLockTaskMode() { 8716 // Verify that the user matches the package of the intent for the TaskRecord 8717 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8718 // and stopLockTaskMode. 8719 final int callingUid = Binder.getCallingUid(); 8720 if (callingUid != Process.SYSTEM_UID) { 8721 try { 8722 String pkg = 8723 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8724 int uid = mContext.getPackageManager().getPackageUid(pkg, 8725 Binder.getCallingUserHandle().getIdentifier()); 8726 if (uid != callingUid) { 8727 throw new SecurityException("Invalid uid, expected " + uid); 8728 } 8729 } catch (NameNotFoundException e) { 8730 Log.d(TAG, "stopLockTaskMode " + e); 8731 return; 8732 } 8733 } 8734 long ident = Binder.clearCallingIdentity(); 8735 try { 8736 Log.d(TAG, "stopLockTaskMode"); 8737 // Stop lock task 8738 synchronized (this) { 8739 mStackSupervisor.setLockTaskModeLocked(null, false); 8740 } 8741 } finally { 8742 Binder.restoreCallingIdentity(ident); 8743 } 8744 } 8745 8746 @Override 8747 public void stopLockTaskModeOnCurrent() throws RemoteException { 8748 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8749 "stopLockTaskModeOnCurrent"); 8750 long ident = Binder.clearCallingIdentity(); 8751 try { 8752 stopLockTaskMode(); 8753 } finally { 8754 Binder.restoreCallingIdentity(ident); 8755 } 8756 } 8757 8758 @Override 8759 public boolean isInLockTaskMode() { 8760 synchronized (this) { 8761 return mStackSupervisor.isInLockTaskMode(); 8762 } 8763 } 8764 8765 // ========================================================= 8766 // CONTENT PROVIDERS 8767 // ========================================================= 8768 8769 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8770 List<ProviderInfo> providers = null; 8771 try { 8772 providers = AppGlobals.getPackageManager(). 8773 queryContentProviders(app.processName, app.uid, 8774 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8775 } catch (RemoteException ex) { 8776 } 8777 if (DEBUG_MU) 8778 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8779 int userId = app.userId; 8780 if (providers != null) { 8781 int N = providers.size(); 8782 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8783 for (int i=0; i<N; i++) { 8784 ProviderInfo cpi = 8785 (ProviderInfo)providers.get(i); 8786 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8787 cpi.name, cpi.flags); 8788 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8789 // This is a singleton provider, but a user besides the 8790 // default user is asking to initialize a process it runs 8791 // in... well, no, it doesn't actually run in this process, 8792 // it runs in the process of the default user. Get rid of it. 8793 providers.remove(i); 8794 N--; 8795 i--; 8796 continue; 8797 } 8798 8799 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8800 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8801 if (cpr == null) { 8802 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8803 mProviderMap.putProviderByClass(comp, cpr); 8804 } 8805 if (DEBUG_MU) 8806 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8807 app.pubProviders.put(cpi.name, cpr); 8808 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8809 // Don't add this if it is a platform component that is marked 8810 // to run in multiple processes, because this is actually 8811 // part of the framework so doesn't make sense to track as a 8812 // separate apk in the process. 8813 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8814 mProcessStats); 8815 } 8816 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8817 } 8818 } 8819 return providers; 8820 } 8821 8822 /** 8823 * Check if {@link ProcessRecord} has a possible chance at accessing the 8824 * given {@link ProviderInfo}. Final permission checking is always done 8825 * in {@link ContentProvider}. 8826 */ 8827 private final String checkContentProviderPermissionLocked( 8828 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8829 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8830 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8831 boolean checkedGrants = false; 8832 if (checkUser) { 8833 // Looking for cross-user grants before enforcing the typical cross-users permissions 8834 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8835 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8836 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8837 return null; 8838 } 8839 checkedGrants = true; 8840 } 8841 userId = handleIncomingUser(callingPid, callingUid, userId, 8842 false, ALLOW_NON_FULL, 8843 "checkContentProviderPermissionLocked " + cpi.authority, null); 8844 if (userId != tmpTargetUserId) { 8845 // When we actually went to determine the final targer user ID, this ended 8846 // up different than our initial check for the authority. This is because 8847 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8848 // SELF. So we need to re-check the grants again. 8849 checkedGrants = false; 8850 } 8851 } 8852 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8853 cpi.applicationInfo.uid, cpi.exported) 8854 == PackageManager.PERMISSION_GRANTED) { 8855 return null; 8856 } 8857 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8858 cpi.applicationInfo.uid, cpi.exported) 8859 == PackageManager.PERMISSION_GRANTED) { 8860 return null; 8861 } 8862 8863 PathPermission[] pps = cpi.pathPermissions; 8864 if (pps != null) { 8865 int i = pps.length; 8866 while (i > 0) { 8867 i--; 8868 PathPermission pp = pps[i]; 8869 String pprperm = pp.getReadPermission(); 8870 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8871 cpi.applicationInfo.uid, cpi.exported) 8872 == PackageManager.PERMISSION_GRANTED) { 8873 return null; 8874 } 8875 String ppwperm = pp.getWritePermission(); 8876 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8877 cpi.applicationInfo.uid, cpi.exported) 8878 == PackageManager.PERMISSION_GRANTED) { 8879 return null; 8880 } 8881 } 8882 } 8883 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8884 return null; 8885 } 8886 8887 String msg; 8888 if (!cpi.exported) { 8889 msg = "Permission Denial: opening provider " + cpi.name 8890 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8891 + ", uid=" + callingUid + ") that is not exported from uid " 8892 + cpi.applicationInfo.uid; 8893 } else { 8894 msg = "Permission Denial: opening provider " + cpi.name 8895 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8896 + ", uid=" + callingUid + ") requires " 8897 + cpi.readPermission + " or " + cpi.writePermission; 8898 } 8899 Slog.w(TAG, msg); 8900 return msg; 8901 } 8902 8903 /** 8904 * Returns if the ContentProvider has granted a uri to callingUid 8905 */ 8906 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8907 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8908 if (perms != null) { 8909 for (int i=perms.size()-1; i>=0; i--) { 8910 GrantUri grantUri = perms.keyAt(i); 8911 if (grantUri.sourceUserId == userId || !checkUser) { 8912 if (matchesProvider(grantUri.uri, cpi)) { 8913 return true; 8914 } 8915 } 8916 } 8917 } 8918 return false; 8919 } 8920 8921 /** 8922 * Returns true if the uri authority is one of the authorities specified in the provider. 8923 */ 8924 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8925 String uriAuth = uri.getAuthority(); 8926 String cpiAuth = cpi.authority; 8927 if (cpiAuth.indexOf(';') == -1) { 8928 return cpiAuth.equals(uriAuth); 8929 } 8930 String[] cpiAuths = cpiAuth.split(";"); 8931 int length = cpiAuths.length; 8932 for (int i = 0; i < length; i++) { 8933 if (cpiAuths[i].equals(uriAuth)) return true; 8934 } 8935 return false; 8936 } 8937 8938 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8939 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8940 if (r != null) { 8941 for (int i=0; i<r.conProviders.size(); i++) { 8942 ContentProviderConnection conn = r.conProviders.get(i); 8943 if (conn.provider == cpr) { 8944 if (DEBUG_PROVIDER) Slog.v(TAG, 8945 "Adding provider requested by " 8946 + r.processName + " from process " 8947 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8948 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8949 if (stable) { 8950 conn.stableCount++; 8951 conn.numStableIncs++; 8952 } else { 8953 conn.unstableCount++; 8954 conn.numUnstableIncs++; 8955 } 8956 return conn; 8957 } 8958 } 8959 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8960 if (stable) { 8961 conn.stableCount = 1; 8962 conn.numStableIncs = 1; 8963 } else { 8964 conn.unstableCount = 1; 8965 conn.numUnstableIncs = 1; 8966 } 8967 cpr.connections.add(conn); 8968 r.conProviders.add(conn); 8969 return conn; 8970 } 8971 cpr.addExternalProcessHandleLocked(externalProcessToken); 8972 return null; 8973 } 8974 8975 boolean decProviderCountLocked(ContentProviderConnection conn, 8976 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8977 if (conn != null) { 8978 cpr = conn.provider; 8979 if (DEBUG_PROVIDER) Slog.v(TAG, 8980 "Removing provider requested by " 8981 + conn.client.processName + " from process " 8982 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8983 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8984 if (stable) { 8985 conn.stableCount--; 8986 } else { 8987 conn.unstableCount--; 8988 } 8989 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8990 cpr.connections.remove(conn); 8991 conn.client.conProviders.remove(conn); 8992 return true; 8993 } 8994 return false; 8995 } 8996 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8997 return false; 8998 } 8999 9000 private void checkTime(long startTime, String where) { 9001 long now = SystemClock.elapsedRealtime(); 9002 if ((now-startTime) > 1000) { 9003 // If we are taking more than a second, log about it. 9004 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9005 } 9006 } 9007 9008 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9009 String name, IBinder token, boolean stable, int userId) { 9010 ContentProviderRecord cpr; 9011 ContentProviderConnection conn = null; 9012 ProviderInfo cpi = null; 9013 9014 synchronized(this) { 9015 long startTime = SystemClock.elapsedRealtime(); 9016 9017 ProcessRecord r = null; 9018 if (caller != null) { 9019 r = getRecordForAppLocked(caller); 9020 if (r == null) { 9021 throw new SecurityException( 9022 "Unable to find app for caller " + caller 9023 + " (pid=" + Binder.getCallingPid() 9024 + ") when getting content provider " + name); 9025 } 9026 } 9027 9028 boolean checkCrossUser = true; 9029 9030 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9031 9032 // First check if this content provider has been published... 9033 cpr = mProviderMap.getProviderByName(name, userId); 9034 // If that didn't work, check if it exists for user 0 and then 9035 // verify that it's a singleton provider before using it. 9036 if (cpr == null && userId != UserHandle.USER_OWNER) { 9037 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9038 if (cpr != null) { 9039 cpi = cpr.info; 9040 if (isSingleton(cpi.processName, cpi.applicationInfo, 9041 cpi.name, cpi.flags) 9042 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9043 userId = UserHandle.USER_OWNER; 9044 checkCrossUser = false; 9045 } else { 9046 cpr = null; 9047 cpi = null; 9048 } 9049 } 9050 } 9051 9052 boolean providerRunning = cpr != null; 9053 if (providerRunning) { 9054 cpi = cpr.info; 9055 String msg; 9056 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9057 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9058 != null) { 9059 throw new SecurityException(msg); 9060 } 9061 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9062 9063 if (r != null && cpr.canRunHere(r)) { 9064 // This provider has been published or is in the process 9065 // of being published... but it is also allowed to run 9066 // in the caller's process, so don't make a connection 9067 // and just let the caller instantiate its own instance. 9068 ContentProviderHolder holder = cpr.newHolder(null); 9069 // don't give caller the provider object, it needs 9070 // to make its own. 9071 holder.provider = null; 9072 return holder; 9073 } 9074 9075 final long origId = Binder.clearCallingIdentity(); 9076 9077 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9078 9079 // In this case the provider instance already exists, so we can 9080 // return it right away. 9081 conn = incProviderCountLocked(r, cpr, token, stable); 9082 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9083 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9084 // If this is a perceptible app accessing the provider, 9085 // make sure to count it as being accessed and thus 9086 // back up on the LRU list. This is good because 9087 // content providers are often expensive to start. 9088 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9089 updateLruProcessLocked(cpr.proc, false, null); 9090 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9091 } 9092 } 9093 9094 if (cpr.proc != null) { 9095 if (false) { 9096 if (cpr.name.flattenToShortString().equals( 9097 "com.android.providers.calendar/.CalendarProvider2")) { 9098 Slog.v(TAG, "****************** KILLING " 9099 + cpr.name.flattenToShortString()); 9100 Process.killProcess(cpr.proc.pid); 9101 } 9102 } 9103 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9104 boolean success = updateOomAdjLocked(cpr.proc); 9105 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9106 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9107 // NOTE: there is still a race here where a signal could be 9108 // pending on the process even though we managed to update its 9109 // adj level. Not sure what to do about this, but at least 9110 // the race is now smaller. 9111 if (!success) { 9112 // Uh oh... it looks like the provider's process 9113 // has been killed on us. We need to wait for a new 9114 // process to be started, and make sure its death 9115 // doesn't kill our process. 9116 Slog.i(TAG, 9117 "Existing provider " + cpr.name.flattenToShortString() 9118 + " is crashing; detaching " + r); 9119 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9120 checkTime(startTime, "getContentProviderImpl: before appDied"); 9121 appDiedLocked(cpr.proc); 9122 checkTime(startTime, "getContentProviderImpl: after appDied"); 9123 if (!lastRef) { 9124 // This wasn't the last ref our process had on 9125 // the provider... we have now been killed, bail. 9126 return null; 9127 } 9128 providerRunning = false; 9129 conn = null; 9130 } 9131 } 9132 9133 Binder.restoreCallingIdentity(origId); 9134 } 9135 9136 boolean singleton; 9137 if (!providerRunning) { 9138 try { 9139 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9140 cpi = AppGlobals.getPackageManager(). 9141 resolveContentProvider(name, 9142 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9143 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9144 } catch (RemoteException ex) { 9145 } 9146 if (cpi == null) { 9147 return null; 9148 } 9149 // If the provider is a singleton AND 9150 // (it's a call within the same user || the provider is a 9151 // privileged app) 9152 // Then allow connecting to the singleton provider 9153 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9154 cpi.name, cpi.flags) 9155 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9156 if (singleton) { 9157 userId = UserHandle.USER_OWNER; 9158 } 9159 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9160 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9161 9162 String msg; 9163 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9164 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9165 != null) { 9166 throw new SecurityException(msg); 9167 } 9168 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9169 9170 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9171 && !cpi.processName.equals("system")) { 9172 // If this content provider does not run in the system 9173 // process, and the system is not yet ready to run other 9174 // processes, then fail fast instead of hanging. 9175 throw new IllegalArgumentException( 9176 "Attempt to launch content provider before system ready"); 9177 } 9178 9179 // Make sure that the user who owns this provider is started. If not, 9180 // we don't want to allow it to run. 9181 if (mStartedUsers.get(userId) == null) { 9182 Slog.w(TAG, "Unable to launch app " 9183 + cpi.applicationInfo.packageName + "/" 9184 + cpi.applicationInfo.uid + " for provider " 9185 + name + ": user " + userId + " is stopped"); 9186 return null; 9187 } 9188 9189 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9190 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9191 cpr = mProviderMap.getProviderByClass(comp, userId); 9192 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9193 final boolean firstClass = cpr == null; 9194 if (firstClass) { 9195 try { 9196 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9197 ApplicationInfo ai = 9198 AppGlobals.getPackageManager(). 9199 getApplicationInfo( 9200 cpi.applicationInfo.packageName, 9201 STOCK_PM_FLAGS, userId); 9202 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9203 if (ai == null) { 9204 Slog.w(TAG, "No package info for content provider " 9205 + cpi.name); 9206 return null; 9207 } 9208 ai = getAppInfoForUser(ai, userId); 9209 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9210 } catch (RemoteException ex) { 9211 // pm is in same process, this will never happen. 9212 } 9213 } 9214 9215 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9216 9217 if (r != null && cpr.canRunHere(r)) { 9218 // If this is a multiprocess provider, then just return its 9219 // info and allow the caller to instantiate it. Only do 9220 // this if the provider is the same user as the caller's 9221 // process, or can run as root (so can be in any process). 9222 return cpr.newHolder(null); 9223 } 9224 9225 if (DEBUG_PROVIDER) { 9226 RuntimeException e = new RuntimeException("here"); 9227 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9228 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9229 } 9230 9231 // This is single process, and our app is now connecting to it. 9232 // See if we are already in the process of launching this 9233 // provider. 9234 final int N = mLaunchingProviders.size(); 9235 int i; 9236 for (i=0; i<N; i++) { 9237 if (mLaunchingProviders.get(i) == cpr) { 9238 break; 9239 } 9240 } 9241 9242 // If the provider is not already being launched, then get it 9243 // started. 9244 if (i >= N) { 9245 final long origId = Binder.clearCallingIdentity(); 9246 9247 try { 9248 // Content provider is now in use, its package can't be stopped. 9249 try { 9250 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9251 AppGlobals.getPackageManager().setPackageStoppedState( 9252 cpr.appInfo.packageName, false, userId); 9253 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9254 } catch (RemoteException e) { 9255 } catch (IllegalArgumentException e) { 9256 Slog.w(TAG, "Failed trying to unstop package " 9257 + cpr.appInfo.packageName + ": " + e); 9258 } 9259 9260 // Use existing process if already started 9261 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9262 ProcessRecord proc = getProcessRecordLocked( 9263 cpi.processName, cpr.appInfo.uid, false); 9264 if (proc != null && proc.thread != null) { 9265 if (DEBUG_PROVIDER) { 9266 Slog.d(TAG, "Installing in existing process " + proc); 9267 } 9268 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9269 proc.pubProviders.put(cpi.name, cpr); 9270 try { 9271 proc.thread.scheduleInstallProvider(cpi); 9272 } catch (RemoteException e) { 9273 } 9274 } else { 9275 checkTime(startTime, "getContentProviderImpl: before start process"); 9276 proc = startProcessLocked(cpi.processName, 9277 cpr.appInfo, false, 0, "content provider", 9278 new ComponentName(cpi.applicationInfo.packageName, 9279 cpi.name), false, false, false); 9280 checkTime(startTime, "getContentProviderImpl: after start process"); 9281 if (proc == null) { 9282 Slog.w(TAG, "Unable to launch app " 9283 + cpi.applicationInfo.packageName + "/" 9284 + cpi.applicationInfo.uid + " for provider " 9285 + name + ": process is bad"); 9286 return null; 9287 } 9288 } 9289 cpr.launchingApp = proc; 9290 mLaunchingProviders.add(cpr); 9291 } finally { 9292 Binder.restoreCallingIdentity(origId); 9293 } 9294 } 9295 9296 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9297 9298 // Make sure the provider is published (the same provider class 9299 // may be published under multiple names). 9300 if (firstClass) { 9301 mProviderMap.putProviderByClass(comp, cpr); 9302 } 9303 9304 mProviderMap.putProviderByName(name, cpr); 9305 conn = incProviderCountLocked(r, cpr, token, stable); 9306 if (conn != null) { 9307 conn.waiting = true; 9308 } 9309 } 9310 checkTime(startTime, "getContentProviderImpl: done!"); 9311 } 9312 9313 // Wait for the provider to be published... 9314 synchronized (cpr) { 9315 while (cpr.provider == null) { 9316 if (cpr.launchingApp == null) { 9317 Slog.w(TAG, "Unable to launch app " 9318 + cpi.applicationInfo.packageName + "/" 9319 + cpi.applicationInfo.uid + " for provider " 9320 + name + ": launching app became null"); 9321 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9322 UserHandle.getUserId(cpi.applicationInfo.uid), 9323 cpi.applicationInfo.packageName, 9324 cpi.applicationInfo.uid, name); 9325 return null; 9326 } 9327 try { 9328 if (DEBUG_MU) { 9329 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9330 + cpr.launchingApp); 9331 } 9332 if (conn != null) { 9333 conn.waiting = true; 9334 } 9335 cpr.wait(); 9336 } catch (InterruptedException ex) { 9337 } finally { 9338 if (conn != null) { 9339 conn.waiting = false; 9340 } 9341 } 9342 } 9343 } 9344 return cpr != null ? cpr.newHolder(conn) : null; 9345 } 9346 9347 @Override 9348 public final ContentProviderHolder getContentProvider( 9349 IApplicationThread caller, String name, int userId, boolean stable) { 9350 enforceNotIsolatedCaller("getContentProvider"); 9351 if (caller == null) { 9352 String msg = "null IApplicationThread when getting content provider " 9353 + name; 9354 Slog.w(TAG, msg); 9355 throw new SecurityException(msg); 9356 } 9357 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9358 // with cross-user grant. 9359 return getContentProviderImpl(caller, name, null, stable, userId); 9360 } 9361 9362 public ContentProviderHolder getContentProviderExternal( 9363 String name, int userId, IBinder token) { 9364 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9365 "Do not have permission in call getContentProviderExternal()"); 9366 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9367 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9368 return getContentProviderExternalUnchecked(name, token, userId); 9369 } 9370 9371 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9372 IBinder token, int userId) { 9373 return getContentProviderImpl(null, name, token, true, userId); 9374 } 9375 9376 /** 9377 * Drop a content provider from a ProcessRecord's bookkeeping 9378 */ 9379 public void removeContentProvider(IBinder connection, boolean stable) { 9380 enforceNotIsolatedCaller("removeContentProvider"); 9381 long ident = Binder.clearCallingIdentity(); 9382 try { 9383 synchronized (this) { 9384 ContentProviderConnection conn; 9385 try { 9386 conn = (ContentProviderConnection)connection; 9387 } catch (ClassCastException e) { 9388 String msg ="removeContentProvider: " + connection 9389 + " not a ContentProviderConnection"; 9390 Slog.w(TAG, msg); 9391 throw new IllegalArgumentException(msg); 9392 } 9393 if (conn == null) { 9394 throw new NullPointerException("connection is null"); 9395 } 9396 if (decProviderCountLocked(conn, null, null, stable)) { 9397 updateOomAdjLocked(); 9398 } 9399 } 9400 } finally { 9401 Binder.restoreCallingIdentity(ident); 9402 } 9403 } 9404 9405 public void removeContentProviderExternal(String name, IBinder token) { 9406 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9407 "Do not have permission in call removeContentProviderExternal()"); 9408 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9409 } 9410 9411 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9412 synchronized (this) { 9413 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9414 if(cpr == null) { 9415 //remove from mProvidersByClass 9416 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9417 return; 9418 } 9419 9420 //update content provider record entry info 9421 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9422 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9423 if (localCpr.hasExternalProcessHandles()) { 9424 if (localCpr.removeExternalProcessHandleLocked(token)) { 9425 updateOomAdjLocked(); 9426 } else { 9427 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9428 + " with no external reference for token: " 9429 + token + "."); 9430 } 9431 } else { 9432 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9433 + " with no external references."); 9434 } 9435 } 9436 } 9437 9438 public final void publishContentProviders(IApplicationThread caller, 9439 List<ContentProviderHolder> providers) { 9440 if (providers == null) { 9441 return; 9442 } 9443 9444 enforceNotIsolatedCaller("publishContentProviders"); 9445 synchronized (this) { 9446 final ProcessRecord r = getRecordForAppLocked(caller); 9447 if (DEBUG_MU) 9448 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9449 if (r == null) { 9450 throw new SecurityException( 9451 "Unable to find app for caller " + caller 9452 + " (pid=" + Binder.getCallingPid() 9453 + ") when publishing content providers"); 9454 } 9455 9456 final long origId = Binder.clearCallingIdentity(); 9457 9458 final int N = providers.size(); 9459 for (int i=0; i<N; i++) { 9460 ContentProviderHolder src = providers.get(i); 9461 if (src == null || src.info == null || src.provider == null) { 9462 continue; 9463 } 9464 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9465 if (DEBUG_MU) 9466 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9467 if (dst != null) { 9468 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9469 mProviderMap.putProviderByClass(comp, dst); 9470 String names[] = dst.info.authority.split(";"); 9471 for (int j = 0; j < names.length; j++) { 9472 mProviderMap.putProviderByName(names[j], dst); 9473 } 9474 9475 int NL = mLaunchingProviders.size(); 9476 int j; 9477 for (j=0; j<NL; j++) { 9478 if (mLaunchingProviders.get(j) == dst) { 9479 mLaunchingProviders.remove(j); 9480 j--; 9481 NL--; 9482 } 9483 } 9484 synchronized (dst) { 9485 dst.provider = src.provider; 9486 dst.proc = r; 9487 dst.notifyAll(); 9488 } 9489 updateOomAdjLocked(r); 9490 } 9491 } 9492 9493 Binder.restoreCallingIdentity(origId); 9494 } 9495 } 9496 9497 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9498 ContentProviderConnection conn; 9499 try { 9500 conn = (ContentProviderConnection)connection; 9501 } catch (ClassCastException e) { 9502 String msg ="refContentProvider: " + connection 9503 + " not a ContentProviderConnection"; 9504 Slog.w(TAG, msg); 9505 throw new IllegalArgumentException(msg); 9506 } 9507 if (conn == null) { 9508 throw new NullPointerException("connection is null"); 9509 } 9510 9511 synchronized (this) { 9512 if (stable > 0) { 9513 conn.numStableIncs += stable; 9514 } 9515 stable = conn.stableCount + stable; 9516 if (stable < 0) { 9517 throw new IllegalStateException("stableCount < 0: " + stable); 9518 } 9519 9520 if (unstable > 0) { 9521 conn.numUnstableIncs += unstable; 9522 } 9523 unstable = conn.unstableCount + unstable; 9524 if (unstable < 0) { 9525 throw new IllegalStateException("unstableCount < 0: " + unstable); 9526 } 9527 9528 if ((stable+unstable) <= 0) { 9529 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9530 + stable + " unstable=" + unstable); 9531 } 9532 conn.stableCount = stable; 9533 conn.unstableCount = unstable; 9534 return !conn.dead; 9535 } 9536 } 9537 9538 public void unstableProviderDied(IBinder connection) { 9539 ContentProviderConnection conn; 9540 try { 9541 conn = (ContentProviderConnection)connection; 9542 } catch (ClassCastException e) { 9543 String msg ="refContentProvider: " + connection 9544 + " not a ContentProviderConnection"; 9545 Slog.w(TAG, msg); 9546 throw new IllegalArgumentException(msg); 9547 } 9548 if (conn == null) { 9549 throw new NullPointerException("connection is null"); 9550 } 9551 9552 // Safely retrieve the content provider associated with the connection. 9553 IContentProvider provider; 9554 synchronized (this) { 9555 provider = conn.provider.provider; 9556 } 9557 9558 if (provider == null) { 9559 // Um, yeah, we're way ahead of you. 9560 return; 9561 } 9562 9563 // Make sure the caller is being honest with us. 9564 if (provider.asBinder().pingBinder()) { 9565 // Er, no, still looks good to us. 9566 synchronized (this) { 9567 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9568 + " says " + conn + " died, but we don't agree"); 9569 return; 9570 } 9571 } 9572 9573 // Well look at that! It's dead! 9574 synchronized (this) { 9575 if (conn.provider.provider != provider) { 9576 // But something changed... good enough. 9577 return; 9578 } 9579 9580 ProcessRecord proc = conn.provider.proc; 9581 if (proc == null || proc.thread == null) { 9582 // Seems like the process is already cleaned up. 9583 return; 9584 } 9585 9586 // As far as we're concerned, this is just like receiving a 9587 // death notification... just a bit prematurely. 9588 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9589 + ") early provider death"); 9590 final long ident = Binder.clearCallingIdentity(); 9591 try { 9592 appDiedLocked(proc); 9593 } finally { 9594 Binder.restoreCallingIdentity(ident); 9595 } 9596 } 9597 } 9598 9599 @Override 9600 public void appNotRespondingViaProvider(IBinder connection) { 9601 enforceCallingPermission( 9602 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9603 9604 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9605 if (conn == null) { 9606 Slog.w(TAG, "ContentProviderConnection is null"); 9607 return; 9608 } 9609 9610 final ProcessRecord host = conn.provider.proc; 9611 if (host == null) { 9612 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9613 return; 9614 } 9615 9616 final long token = Binder.clearCallingIdentity(); 9617 try { 9618 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9619 } finally { 9620 Binder.restoreCallingIdentity(token); 9621 } 9622 } 9623 9624 public final void installSystemProviders() { 9625 List<ProviderInfo> providers; 9626 synchronized (this) { 9627 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9628 providers = generateApplicationProvidersLocked(app); 9629 if (providers != null) { 9630 for (int i=providers.size()-1; i>=0; i--) { 9631 ProviderInfo pi = (ProviderInfo)providers.get(i); 9632 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9633 Slog.w(TAG, "Not installing system proc provider " + pi.name 9634 + ": not system .apk"); 9635 providers.remove(i); 9636 } 9637 } 9638 } 9639 } 9640 if (providers != null) { 9641 mSystemThread.installSystemProviders(providers); 9642 } 9643 9644 mCoreSettingsObserver = new CoreSettingsObserver(this); 9645 9646 //mUsageStatsService.monitorPackages(); 9647 } 9648 9649 /** 9650 * Allows apps to retrieve the MIME type of a URI. 9651 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9652 * users, then it does not need permission to access the ContentProvider. 9653 * Either, it needs cross-user uri grants. 9654 * 9655 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9656 * 9657 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9658 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9659 */ 9660 public String getProviderMimeType(Uri uri, int userId) { 9661 enforceNotIsolatedCaller("getProviderMimeType"); 9662 final String name = uri.getAuthority(); 9663 int callingUid = Binder.getCallingUid(); 9664 int callingPid = Binder.getCallingPid(); 9665 long ident = 0; 9666 boolean clearedIdentity = false; 9667 userId = unsafeConvertIncomingUser(userId); 9668 if (UserHandle.getUserId(callingUid) != userId) { 9669 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9670 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9671 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9672 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9673 clearedIdentity = true; 9674 ident = Binder.clearCallingIdentity(); 9675 } 9676 } 9677 ContentProviderHolder holder = null; 9678 try { 9679 holder = getContentProviderExternalUnchecked(name, null, userId); 9680 if (holder != null) { 9681 return holder.provider.getType(uri); 9682 } 9683 } catch (RemoteException e) { 9684 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9685 return null; 9686 } finally { 9687 // We need to clear the identity to call removeContentProviderExternalUnchecked 9688 if (!clearedIdentity) { 9689 ident = Binder.clearCallingIdentity(); 9690 } 9691 try { 9692 if (holder != null) { 9693 removeContentProviderExternalUnchecked(name, null, userId); 9694 } 9695 } finally { 9696 Binder.restoreCallingIdentity(ident); 9697 } 9698 } 9699 9700 return null; 9701 } 9702 9703 // ========================================================= 9704 // GLOBAL MANAGEMENT 9705 // ========================================================= 9706 9707 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9708 boolean isolated, int isolatedUid) { 9709 String proc = customProcess != null ? customProcess : info.processName; 9710 BatteryStatsImpl.Uid.Proc ps = null; 9711 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9712 int uid = info.uid; 9713 if (isolated) { 9714 if (isolatedUid == 0) { 9715 int userId = UserHandle.getUserId(uid); 9716 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9717 while (true) { 9718 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9719 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9720 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9721 } 9722 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9723 mNextIsolatedProcessUid++; 9724 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9725 // No process for this uid, use it. 9726 break; 9727 } 9728 stepsLeft--; 9729 if (stepsLeft <= 0) { 9730 return null; 9731 } 9732 } 9733 } else { 9734 // Special case for startIsolatedProcess (internal only), where 9735 // the uid of the isolated process is specified by the caller. 9736 uid = isolatedUid; 9737 } 9738 } 9739 return new ProcessRecord(stats, info, proc, uid); 9740 } 9741 9742 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9743 String abiOverride) { 9744 ProcessRecord app; 9745 if (!isolated) { 9746 app = getProcessRecordLocked(info.processName, info.uid, true); 9747 } else { 9748 app = null; 9749 } 9750 9751 if (app == null) { 9752 app = newProcessRecordLocked(info, null, isolated, 0); 9753 mProcessNames.put(info.processName, app.uid, app); 9754 if (isolated) { 9755 mIsolatedProcesses.put(app.uid, app); 9756 } 9757 updateLruProcessLocked(app, false, null); 9758 updateOomAdjLocked(); 9759 } 9760 9761 // This package really, really can not be stopped. 9762 try { 9763 AppGlobals.getPackageManager().setPackageStoppedState( 9764 info.packageName, false, UserHandle.getUserId(app.uid)); 9765 } catch (RemoteException e) { 9766 } catch (IllegalArgumentException e) { 9767 Slog.w(TAG, "Failed trying to unstop package " 9768 + info.packageName + ": " + e); 9769 } 9770 9771 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9772 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9773 app.persistent = true; 9774 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9775 } 9776 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9777 mPersistentStartingProcesses.add(app); 9778 startProcessLocked(app, "added application", app.processName, abiOverride, 9779 null /* entryPoint */, null /* entryPointArgs */); 9780 } 9781 9782 return app; 9783 } 9784 9785 public void unhandledBack() { 9786 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9787 "unhandledBack()"); 9788 9789 synchronized(this) { 9790 final long origId = Binder.clearCallingIdentity(); 9791 try { 9792 getFocusedStack().unhandledBackLocked(); 9793 } finally { 9794 Binder.restoreCallingIdentity(origId); 9795 } 9796 } 9797 } 9798 9799 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9800 enforceNotIsolatedCaller("openContentUri"); 9801 final int userId = UserHandle.getCallingUserId(); 9802 String name = uri.getAuthority(); 9803 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9804 ParcelFileDescriptor pfd = null; 9805 if (cph != null) { 9806 // We record the binder invoker's uid in thread-local storage before 9807 // going to the content provider to open the file. Later, in the code 9808 // that handles all permissions checks, we look for this uid and use 9809 // that rather than the Activity Manager's own uid. The effect is that 9810 // we do the check against the caller's permissions even though it looks 9811 // to the content provider like the Activity Manager itself is making 9812 // the request. 9813 sCallerIdentity.set(new Identity( 9814 Binder.getCallingPid(), Binder.getCallingUid())); 9815 try { 9816 pfd = cph.provider.openFile(null, uri, "r", null); 9817 } catch (FileNotFoundException e) { 9818 // do nothing; pfd will be returned null 9819 } finally { 9820 // Ensure that whatever happens, we clean up the identity state 9821 sCallerIdentity.remove(); 9822 } 9823 9824 // We've got the fd now, so we're done with the provider. 9825 removeContentProviderExternalUnchecked(name, null, userId); 9826 } else { 9827 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9828 } 9829 return pfd; 9830 } 9831 9832 // Actually is sleeping or shutting down or whatever else in the future 9833 // is an inactive state. 9834 public boolean isSleepingOrShuttingDown() { 9835 return mSleeping || mShuttingDown; 9836 } 9837 9838 public boolean isSleeping() { 9839 return mSleeping; 9840 } 9841 9842 void goingToSleep() { 9843 synchronized(this) { 9844 mWentToSleep = true; 9845 updateEventDispatchingLocked(); 9846 goToSleepIfNeededLocked(); 9847 } 9848 } 9849 9850 void finishRunningVoiceLocked() { 9851 if (mRunningVoice) { 9852 mRunningVoice = false; 9853 goToSleepIfNeededLocked(); 9854 } 9855 } 9856 9857 void goToSleepIfNeededLocked() { 9858 if (mWentToSleep && !mRunningVoice) { 9859 if (!mSleeping) { 9860 mSleeping = true; 9861 mStackSupervisor.goingToSleepLocked(); 9862 9863 // Initialize the wake times of all processes. 9864 checkExcessivePowerUsageLocked(false); 9865 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9866 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9867 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9868 } 9869 } 9870 } 9871 9872 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9873 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9874 // Never persist the home stack. 9875 return; 9876 } 9877 mTaskPersister.wakeup(task, flush); 9878 } 9879 9880 @Override 9881 public boolean shutdown(int timeout) { 9882 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9883 != PackageManager.PERMISSION_GRANTED) { 9884 throw new SecurityException("Requires permission " 9885 + android.Manifest.permission.SHUTDOWN); 9886 } 9887 9888 boolean timedout = false; 9889 9890 synchronized(this) { 9891 mShuttingDown = true; 9892 updateEventDispatchingLocked(); 9893 timedout = mStackSupervisor.shutdownLocked(timeout); 9894 } 9895 9896 mAppOpsService.shutdown(); 9897 if (mUsageStatsService != null) { 9898 mUsageStatsService.prepareShutdown(); 9899 } 9900 mBatteryStatsService.shutdown(); 9901 synchronized (this) { 9902 mProcessStats.shutdownLocked(); 9903 } 9904 notifyTaskPersisterLocked(null, true); 9905 9906 return timedout; 9907 } 9908 9909 public final void activitySlept(IBinder token) { 9910 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9911 9912 final long origId = Binder.clearCallingIdentity(); 9913 9914 synchronized (this) { 9915 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9916 if (r != null) { 9917 mStackSupervisor.activitySleptLocked(r); 9918 } 9919 } 9920 9921 Binder.restoreCallingIdentity(origId); 9922 } 9923 9924 void logLockScreen(String msg) { 9925 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9926 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9927 mWentToSleep + " mSleeping=" + mSleeping); 9928 } 9929 9930 private void comeOutOfSleepIfNeededLocked() { 9931 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9932 if (mSleeping) { 9933 mSleeping = false; 9934 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9935 } 9936 } 9937 } 9938 9939 void wakingUp() { 9940 synchronized(this) { 9941 mWentToSleep = false; 9942 updateEventDispatchingLocked(); 9943 comeOutOfSleepIfNeededLocked(); 9944 } 9945 } 9946 9947 void startRunningVoiceLocked() { 9948 if (!mRunningVoice) { 9949 mRunningVoice = true; 9950 comeOutOfSleepIfNeededLocked(); 9951 } 9952 } 9953 9954 private void updateEventDispatchingLocked() { 9955 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9956 } 9957 9958 public void setLockScreenShown(boolean shown) { 9959 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9960 != PackageManager.PERMISSION_GRANTED) { 9961 throw new SecurityException("Requires permission " 9962 + android.Manifest.permission.DEVICE_POWER); 9963 } 9964 9965 synchronized(this) { 9966 long ident = Binder.clearCallingIdentity(); 9967 try { 9968 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9969 mLockScreenShown = shown; 9970 comeOutOfSleepIfNeededLocked(); 9971 } finally { 9972 Binder.restoreCallingIdentity(ident); 9973 } 9974 } 9975 } 9976 9977 @Override 9978 public void stopAppSwitches() { 9979 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9980 != PackageManager.PERMISSION_GRANTED) { 9981 throw new SecurityException("Requires permission " 9982 + android.Manifest.permission.STOP_APP_SWITCHES); 9983 } 9984 9985 synchronized(this) { 9986 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9987 + APP_SWITCH_DELAY_TIME; 9988 mDidAppSwitch = false; 9989 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9990 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9991 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9992 } 9993 } 9994 9995 public void resumeAppSwitches() { 9996 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9997 != PackageManager.PERMISSION_GRANTED) { 9998 throw new SecurityException("Requires permission " 9999 + android.Manifest.permission.STOP_APP_SWITCHES); 10000 } 10001 10002 synchronized(this) { 10003 // Note that we don't execute any pending app switches... we will 10004 // let those wait until either the timeout, or the next start 10005 // activity request. 10006 mAppSwitchesAllowedTime = 0; 10007 } 10008 } 10009 10010 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10011 String name) { 10012 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10013 return true; 10014 } 10015 10016 final int perm = checkComponentPermission( 10017 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10018 callingUid, -1, true); 10019 if (perm == PackageManager.PERMISSION_GRANTED) { 10020 return true; 10021 } 10022 10023 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10024 return false; 10025 } 10026 10027 public void setDebugApp(String packageName, boolean waitForDebugger, 10028 boolean persistent) { 10029 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10030 "setDebugApp()"); 10031 10032 long ident = Binder.clearCallingIdentity(); 10033 try { 10034 // Note that this is not really thread safe if there are multiple 10035 // callers into it at the same time, but that's not a situation we 10036 // care about. 10037 if (persistent) { 10038 final ContentResolver resolver = mContext.getContentResolver(); 10039 Settings.Global.putString( 10040 resolver, Settings.Global.DEBUG_APP, 10041 packageName); 10042 Settings.Global.putInt( 10043 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10044 waitForDebugger ? 1 : 0); 10045 } 10046 10047 synchronized (this) { 10048 if (!persistent) { 10049 mOrigDebugApp = mDebugApp; 10050 mOrigWaitForDebugger = mWaitForDebugger; 10051 } 10052 mDebugApp = packageName; 10053 mWaitForDebugger = waitForDebugger; 10054 mDebugTransient = !persistent; 10055 if (packageName != null) { 10056 forceStopPackageLocked(packageName, -1, false, false, true, true, 10057 false, UserHandle.USER_ALL, "set debug app"); 10058 } 10059 } 10060 } finally { 10061 Binder.restoreCallingIdentity(ident); 10062 } 10063 } 10064 10065 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10066 synchronized (this) { 10067 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10068 if (!isDebuggable) { 10069 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10070 throw new SecurityException("Process not debuggable: " + app.packageName); 10071 } 10072 } 10073 10074 mOpenGlTraceApp = processName; 10075 } 10076 } 10077 10078 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10079 synchronized (this) { 10080 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10081 if (!isDebuggable) { 10082 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10083 throw new SecurityException("Process not debuggable: " + app.packageName); 10084 } 10085 } 10086 mProfileApp = processName; 10087 mProfileFile = profilerInfo.profileFile; 10088 if (mProfileFd != null) { 10089 try { 10090 mProfileFd.close(); 10091 } catch (IOException e) { 10092 } 10093 mProfileFd = null; 10094 } 10095 mProfileFd = profilerInfo.profileFd; 10096 mSamplingInterval = profilerInfo.samplingInterval; 10097 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10098 mProfileType = 0; 10099 } 10100 } 10101 10102 @Override 10103 public void setAlwaysFinish(boolean enabled) { 10104 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10105 "setAlwaysFinish()"); 10106 10107 Settings.Global.putInt( 10108 mContext.getContentResolver(), 10109 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10110 10111 synchronized (this) { 10112 mAlwaysFinishActivities = enabled; 10113 } 10114 } 10115 10116 @Override 10117 public void setActivityController(IActivityController controller) { 10118 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10119 "setActivityController()"); 10120 synchronized (this) { 10121 mController = controller; 10122 Watchdog.getInstance().setActivityController(controller); 10123 } 10124 } 10125 10126 @Override 10127 public void setUserIsMonkey(boolean userIsMonkey) { 10128 synchronized (this) { 10129 synchronized (mPidsSelfLocked) { 10130 final int callingPid = Binder.getCallingPid(); 10131 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10132 if (precessRecord == null) { 10133 throw new SecurityException("Unknown process: " + callingPid); 10134 } 10135 if (precessRecord.instrumentationUiAutomationConnection == null) { 10136 throw new SecurityException("Only an instrumentation process " 10137 + "with a UiAutomation can call setUserIsMonkey"); 10138 } 10139 } 10140 mUserIsMonkey = userIsMonkey; 10141 } 10142 } 10143 10144 @Override 10145 public boolean isUserAMonkey() { 10146 synchronized (this) { 10147 // If there is a controller also implies the user is a monkey. 10148 return (mUserIsMonkey || mController != null); 10149 } 10150 } 10151 10152 public void requestBugReport() { 10153 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10154 SystemProperties.set("ctl.start", "bugreport"); 10155 } 10156 10157 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10158 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10159 } 10160 10161 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10162 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10163 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10164 } 10165 return KEY_DISPATCHING_TIMEOUT; 10166 } 10167 10168 @Override 10169 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10170 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10171 != PackageManager.PERMISSION_GRANTED) { 10172 throw new SecurityException("Requires permission " 10173 + android.Manifest.permission.FILTER_EVENTS); 10174 } 10175 ProcessRecord proc; 10176 long timeout; 10177 synchronized (this) { 10178 synchronized (mPidsSelfLocked) { 10179 proc = mPidsSelfLocked.get(pid); 10180 } 10181 timeout = getInputDispatchingTimeoutLocked(proc); 10182 } 10183 10184 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10185 return -1; 10186 } 10187 10188 return timeout; 10189 } 10190 10191 /** 10192 * Handle input dispatching timeouts. 10193 * Returns whether input dispatching should be aborted or not. 10194 */ 10195 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10196 final ActivityRecord activity, final ActivityRecord parent, 10197 final boolean aboveSystem, String reason) { 10198 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10199 != PackageManager.PERMISSION_GRANTED) { 10200 throw new SecurityException("Requires permission " 10201 + android.Manifest.permission.FILTER_EVENTS); 10202 } 10203 10204 final String annotation; 10205 if (reason == null) { 10206 annotation = "Input dispatching timed out"; 10207 } else { 10208 annotation = "Input dispatching timed out (" + reason + ")"; 10209 } 10210 10211 if (proc != null) { 10212 synchronized (this) { 10213 if (proc.debugging) { 10214 return false; 10215 } 10216 10217 if (mDidDexOpt) { 10218 // Give more time since we were dexopting. 10219 mDidDexOpt = false; 10220 return false; 10221 } 10222 10223 if (proc.instrumentationClass != null) { 10224 Bundle info = new Bundle(); 10225 info.putString("shortMsg", "keyDispatchingTimedOut"); 10226 info.putString("longMsg", annotation); 10227 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10228 return true; 10229 } 10230 } 10231 mHandler.post(new Runnable() { 10232 @Override 10233 public void run() { 10234 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10235 } 10236 }); 10237 } 10238 10239 return true; 10240 } 10241 10242 public Bundle getAssistContextExtras(int requestType) { 10243 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10244 "getAssistContextExtras()"); 10245 PendingAssistExtras pae; 10246 Bundle extras = new Bundle(); 10247 synchronized (this) { 10248 ActivityRecord activity = getFocusedStack().mResumedActivity; 10249 if (activity == null) { 10250 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10251 return null; 10252 } 10253 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10254 if (activity.app == null || activity.app.thread == null) { 10255 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10256 return extras; 10257 } 10258 if (activity.app.pid == Binder.getCallingPid()) { 10259 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10260 return extras; 10261 } 10262 pae = new PendingAssistExtras(activity); 10263 try { 10264 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10265 requestType); 10266 mPendingAssistExtras.add(pae); 10267 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10268 } catch (RemoteException e) { 10269 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10270 return extras; 10271 } 10272 } 10273 synchronized (pae) { 10274 while (!pae.haveResult) { 10275 try { 10276 pae.wait(); 10277 } catch (InterruptedException e) { 10278 } 10279 } 10280 if (pae.result != null) { 10281 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10282 } 10283 } 10284 synchronized (this) { 10285 mPendingAssistExtras.remove(pae); 10286 mHandler.removeCallbacks(pae); 10287 } 10288 return extras; 10289 } 10290 10291 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10292 PendingAssistExtras pae = (PendingAssistExtras)token; 10293 synchronized (pae) { 10294 pae.result = extras; 10295 pae.haveResult = true; 10296 pae.notifyAll(); 10297 } 10298 } 10299 10300 public void registerProcessObserver(IProcessObserver observer) { 10301 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10302 "registerProcessObserver()"); 10303 synchronized (this) { 10304 mProcessObservers.register(observer); 10305 } 10306 } 10307 10308 @Override 10309 public void unregisterProcessObserver(IProcessObserver observer) { 10310 synchronized (this) { 10311 mProcessObservers.unregister(observer); 10312 } 10313 } 10314 10315 @Override 10316 public boolean convertFromTranslucent(IBinder token) { 10317 final long origId = Binder.clearCallingIdentity(); 10318 try { 10319 synchronized (this) { 10320 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10321 if (r == null) { 10322 return false; 10323 } 10324 final boolean translucentChanged = r.changeWindowTranslucency(true); 10325 if (translucentChanged) { 10326 r.task.stack.releaseBackgroundResources(); 10327 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10328 } 10329 mWindowManager.setAppFullscreen(token, true); 10330 return translucentChanged; 10331 } 10332 } finally { 10333 Binder.restoreCallingIdentity(origId); 10334 } 10335 } 10336 10337 @Override 10338 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10339 final long origId = Binder.clearCallingIdentity(); 10340 try { 10341 synchronized (this) { 10342 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10343 if (r == null) { 10344 return false; 10345 } 10346 int index = r.task.mActivities.lastIndexOf(r); 10347 if (index > 0) { 10348 ActivityRecord under = r.task.mActivities.get(index - 1); 10349 under.returningOptions = options; 10350 } 10351 final boolean translucentChanged = r.changeWindowTranslucency(false); 10352 if (translucentChanged) { 10353 r.task.stack.convertToTranslucent(r); 10354 } 10355 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10356 mWindowManager.setAppFullscreen(token, false); 10357 return translucentChanged; 10358 } 10359 } finally { 10360 Binder.restoreCallingIdentity(origId); 10361 } 10362 } 10363 10364 @Override 10365 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10366 final long origId = Binder.clearCallingIdentity(); 10367 try { 10368 synchronized (this) { 10369 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10370 if (r != null) { 10371 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10372 } 10373 } 10374 return false; 10375 } finally { 10376 Binder.restoreCallingIdentity(origId); 10377 } 10378 } 10379 10380 @Override 10381 public boolean isBackgroundVisibleBehind(IBinder token) { 10382 final long origId = Binder.clearCallingIdentity(); 10383 try { 10384 synchronized (this) { 10385 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10386 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10387 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10388 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10389 return visible; 10390 } 10391 } finally { 10392 Binder.restoreCallingIdentity(origId); 10393 } 10394 } 10395 10396 @Override 10397 public ActivityOptions getActivityOptions(IBinder token) { 10398 final long origId = Binder.clearCallingIdentity(); 10399 try { 10400 synchronized (this) { 10401 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10402 if (r != null) { 10403 final ActivityOptions activityOptions = r.pendingOptions; 10404 r.pendingOptions = null; 10405 return activityOptions; 10406 } 10407 return null; 10408 } 10409 } finally { 10410 Binder.restoreCallingIdentity(origId); 10411 } 10412 } 10413 10414 @Override 10415 public void setImmersive(IBinder token, boolean immersive) { 10416 synchronized(this) { 10417 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10418 if (r == null) { 10419 throw new IllegalArgumentException(); 10420 } 10421 r.immersive = immersive; 10422 10423 // update associated state if we're frontmost 10424 if (r == mFocusedActivity) { 10425 if (DEBUG_IMMERSIVE) { 10426 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10427 } 10428 applyUpdateLockStateLocked(r); 10429 } 10430 } 10431 } 10432 10433 @Override 10434 public boolean isImmersive(IBinder token) { 10435 synchronized (this) { 10436 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10437 if (r == null) { 10438 throw new IllegalArgumentException(); 10439 } 10440 return r.immersive; 10441 } 10442 } 10443 10444 public boolean isTopActivityImmersive() { 10445 enforceNotIsolatedCaller("startActivity"); 10446 synchronized (this) { 10447 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10448 return (r != null) ? r.immersive : false; 10449 } 10450 } 10451 10452 @Override 10453 public boolean isTopOfTask(IBinder token) { 10454 synchronized (this) { 10455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10456 if (r == null) { 10457 throw new IllegalArgumentException(); 10458 } 10459 return r.task.getTopActivity() == r; 10460 } 10461 } 10462 10463 public final void enterSafeMode() { 10464 synchronized(this) { 10465 // It only makes sense to do this before the system is ready 10466 // and started launching other packages. 10467 if (!mSystemReady) { 10468 try { 10469 AppGlobals.getPackageManager().enterSafeMode(); 10470 } catch (RemoteException e) { 10471 } 10472 } 10473 10474 mSafeMode = true; 10475 } 10476 } 10477 10478 public final void showSafeModeOverlay() { 10479 View v = LayoutInflater.from(mContext).inflate( 10480 com.android.internal.R.layout.safe_mode, null); 10481 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10482 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10483 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10484 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10485 lp.gravity = Gravity.BOTTOM | Gravity.START; 10486 lp.format = v.getBackground().getOpacity(); 10487 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10488 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10489 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10490 ((WindowManager)mContext.getSystemService( 10491 Context.WINDOW_SERVICE)).addView(v, lp); 10492 } 10493 10494 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10495 if (!(sender instanceof PendingIntentRecord)) { 10496 return; 10497 } 10498 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10499 synchronized (stats) { 10500 if (mBatteryStatsService.isOnBattery()) { 10501 mBatteryStatsService.enforceCallingPermission(); 10502 PendingIntentRecord rec = (PendingIntentRecord)sender; 10503 int MY_UID = Binder.getCallingUid(); 10504 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10505 BatteryStatsImpl.Uid.Pkg pkg = 10506 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10507 sourcePkg != null ? sourcePkg : rec.key.packageName); 10508 pkg.incWakeupsLocked(); 10509 } 10510 } 10511 } 10512 10513 public boolean killPids(int[] pids, String pReason, boolean secure) { 10514 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10515 throw new SecurityException("killPids only available to the system"); 10516 } 10517 String reason = (pReason == null) ? "Unknown" : pReason; 10518 // XXX Note: don't acquire main activity lock here, because the window 10519 // manager calls in with its locks held. 10520 10521 boolean killed = false; 10522 synchronized (mPidsSelfLocked) { 10523 int[] types = new int[pids.length]; 10524 int worstType = 0; 10525 for (int i=0; i<pids.length; i++) { 10526 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10527 if (proc != null) { 10528 int type = proc.setAdj; 10529 types[i] = type; 10530 if (type > worstType) { 10531 worstType = type; 10532 } 10533 } 10534 } 10535 10536 // If the worst oom_adj is somewhere in the cached proc LRU range, 10537 // then constrain it so we will kill all cached procs. 10538 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10539 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10540 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10541 } 10542 10543 // If this is not a secure call, don't let it kill processes that 10544 // are important. 10545 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10546 worstType = ProcessList.SERVICE_ADJ; 10547 } 10548 10549 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10550 for (int i=0; i<pids.length; i++) { 10551 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10552 if (proc == null) { 10553 continue; 10554 } 10555 int adj = proc.setAdj; 10556 if (adj >= worstType && !proc.killedByAm) { 10557 proc.kill(reason, true); 10558 killed = true; 10559 } 10560 } 10561 } 10562 return killed; 10563 } 10564 10565 @Override 10566 public void killUid(int uid, String reason) { 10567 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10568 throw new SecurityException("killUid only available to the system"); 10569 } 10570 synchronized (this) { 10571 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10572 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10573 reason != null ? reason : "kill uid"); 10574 } 10575 } 10576 10577 @Override 10578 public boolean killProcessesBelowForeground(String reason) { 10579 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10580 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10581 } 10582 10583 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10584 } 10585 10586 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10587 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10588 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10589 } 10590 10591 boolean killed = false; 10592 synchronized (mPidsSelfLocked) { 10593 final int size = mPidsSelfLocked.size(); 10594 for (int i = 0; i < size; i++) { 10595 final int pid = mPidsSelfLocked.keyAt(i); 10596 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10597 if (proc == null) continue; 10598 10599 final int adj = proc.setAdj; 10600 if (adj > belowAdj && !proc.killedByAm) { 10601 proc.kill(reason, true); 10602 killed = true; 10603 } 10604 } 10605 } 10606 return killed; 10607 } 10608 10609 @Override 10610 public void hang(final IBinder who, boolean allowRestart) { 10611 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10612 != PackageManager.PERMISSION_GRANTED) { 10613 throw new SecurityException("Requires permission " 10614 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10615 } 10616 10617 final IBinder.DeathRecipient death = new DeathRecipient() { 10618 @Override 10619 public void binderDied() { 10620 synchronized (this) { 10621 notifyAll(); 10622 } 10623 } 10624 }; 10625 10626 try { 10627 who.linkToDeath(death, 0); 10628 } catch (RemoteException e) { 10629 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10630 return; 10631 } 10632 10633 synchronized (this) { 10634 Watchdog.getInstance().setAllowRestart(allowRestart); 10635 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10636 synchronized (death) { 10637 while (who.isBinderAlive()) { 10638 try { 10639 death.wait(); 10640 } catch (InterruptedException e) { 10641 } 10642 } 10643 } 10644 Watchdog.getInstance().setAllowRestart(true); 10645 } 10646 } 10647 10648 @Override 10649 public void restart() { 10650 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10651 != PackageManager.PERMISSION_GRANTED) { 10652 throw new SecurityException("Requires permission " 10653 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10654 } 10655 10656 Log.i(TAG, "Sending shutdown broadcast..."); 10657 10658 BroadcastReceiver br = new BroadcastReceiver() { 10659 @Override public void onReceive(Context context, Intent intent) { 10660 // Now the broadcast is done, finish up the low-level shutdown. 10661 Log.i(TAG, "Shutting down activity manager..."); 10662 shutdown(10000); 10663 Log.i(TAG, "Shutdown complete, restarting!"); 10664 Process.killProcess(Process.myPid()); 10665 System.exit(10); 10666 } 10667 }; 10668 10669 // First send the high-level shut down broadcast. 10670 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10671 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10672 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10673 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10674 mContext.sendOrderedBroadcastAsUser(intent, 10675 UserHandle.ALL, null, br, mHandler, 0, null, null); 10676 */ 10677 br.onReceive(mContext, intent); 10678 } 10679 10680 private long getLowRamTimeSinceIdle(long now) { 10681 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10682 } 10683 10684 @Override 10685 public void performIdleMaintenance() { 10686 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10687 != PackageManager.PERMISSION_GRANTED) { 10688 throw new SecurityException("Requires permission " 10689 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10690 } 10691 10692 synchronized (this) { 10693 final long now = SystemClock.uptimeMillis(); 10694 final long timeSinceLastIdle = now - mLastIdleTime; 10695 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10696 mLastIdleTime = now; 10697 mLowRamTimeSinceLastIdle = 0; 10698 if (mLowRamStartTime != 0) { 10699 mLowRamStartTime = now; 10700 } 10701 10702 StringBuilder sb = new StringBuilder(128); 10703 sb.append("Idle maintenance over "); 10704 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10705 sb.append(" low RAM for "); 10706 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10707 Slog.i(TAG, sb.toString()); 10708 10709 // If at least 1/3 of our time since the last idle period has been spent 10710 // with RAM low, then we want to kill processes. 10711 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10712 10713 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10714 ProcessRecord proc = mLruProcesses.get(i); 10715 if (proc.notCachedSinceIdle) { 10716 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10717 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10718 if (doKilling && proc.initialIdlePss != 0 10719 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10720 proc.kill("idle maint (pss " + proc.lastPss 10721 + " from " + proc.initialIdlePss + ")", true); 10722 } 10723 } 10724 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10725 proc.notCachedSinceIdle = true; 10726 proc.initialIdlePss = 0; 10727 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10728 isSleeping(), now); 10729 } 10730 } 10731 10732 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10733 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10734 } 10735 } 10736 10737 private void retrieveSettings() { 10738 final ContentResolver resolver = mContext.getContentResolver(); 10739 String debugApp = Settings.Global.getString( 10740 resolver, Settings.Global.DEBUG_APP); 10741 boolean waitForDebugger = Settings.Global.getInt( 10742 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10743 boolean alwaysFinishActivities = Settings.Global.getInt( 10744 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10745 boolean forceRtl = Settings.Global.getInt( 10746 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10747 // Transfer any global setting for forcing RTL layout, into a System Property 10748 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10749 10750 Configuration configuration = new Configuration(); 10751 Settings.System.getConfiguration(resolver, configuration); 10752 if (forceRtl) { 10753 // This will take care of setting the correct layout direction flags 10754 configuration.setLayoutDirection(configuration.locale); 10755 } 10756 10757 synchronized (this) { 10758 mDebugApp = mOrigDebugApp = debugApp; 10759 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10760 mAlwaysFinishActivities = alwaysFinishActivities; 10761 // This happens before any activities are started, so we can 10762 // change mConfiguration in-place. 10763 updateConfigurationLocked(configuration, null, false, true); 10764 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10765 } 10766 } 10767 10768 /** Loads resources after the current configuration has been set. */ 10769 private void loadResourcesOnSystemReady() { 10770 final Resources res = mContext.getResources(); 10771 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10772 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10773 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10774 } 10775 10776 public boolean testIsSystemReady() { 10777 // no need to synchronize(this) just to read & return the value 10778 return mSystemReady; 10779 } 10780 10781 private static File getCalledPreBootReceiversFile() { 10782 File dataDir = Environment.getDataDirectory(); 10783 File systemDir = new File(dataDir, "system"); 10784 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10785 return fname; 10786 } 10787 10788 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10789 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10790 File file = getCalledPreBootReceiversFile(); 10791 FileInputStream fis = null; 10792 try { 10793 fis = new FileInputStream(file); 10794 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10795 int fvers = dis.readInt(); 10796 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10797 String vers = dis.readUTF(); 10798 String codename = dis.readUTF(); 10799 String build = dis.readUTF(); 10800 if (android.os.Build.VERSION.RELEASE.equals(vers) 10801 && android.os.Build.VERSION.CODENAME.equals(codename) 10802 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10803 int num = dis.readInt(); 10804 while (num > 0) { 10805 num--; 10806 String pkg = dis.readUTF(); 10807 String cls = dis.readUTF(); 10808 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10809 } 10810 } 10811 } 10812 } catch (FileNotFoundException e) { 10813 } catch (IOException e) { 10814 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10815 } finally { 10816 if (fis != null) { 10817 try { 10818 fis.close(); 10819 } catch (IOException e) { 10820 } 10821 } 10822 } 10823 return lastDoneReceivers; 10824 } 10825 10826 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10827 File file = getCalledPreBootReceiversFile(); 10828 FileOutputStream fos = null; 10829 DataOutputStream dos = null; 10830 try { 10831 fos = new FileOutputStream(file); 10832 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10833 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10834 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10835 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10836 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10837 dos.writeInt(list.size()); 10838 for (int i=0; i<list.size(); i++) { 10839 dos.writeUTF(list.get(i).getPackageName()); 10840 dos.writeUTF(list.get(i).getClassName()); 10841 } 10842 } catch (IOException e) { 10843 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10844 file.delete(); 10845 } finally { 10846 FileUtils.sync(fos); 10847 if (dos != null) { 10848 try { 10849 dos.close(); 10850 } catch (IOException e) { 10851 // TODO Auto-generated catch block 10852 e.printStackTrace(); 10853 } 10854 } 10855 } 10856 } 10857 10858 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10859 ArrayList<ComponentName> doneReceivers, int userId) { 10860 boolean waitingUpdate = false; 10861 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10862 List<ResolveInfo> ris = null; 10863 try { 10864 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10865 intent, null, 0, userId); 10866 } catch (RemoteException e) { 10867 } 10868 if (ris != null) { 10869 for (int i=ris.size()-1; i>=0; i--) { 10870 if ((ris.get(i).activityInfo.applicationInfo.flags 10871 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10872 ris.remove(i); 10873 } 10874 } 10875 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10876 10877 // For User 0, load the version number. When delivering to a new user, deliver 10878 // to all receivers. 10879 if (userId == UserHandle.USER_OWNER) { 10880 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10881 for (int i=0; i<ris.size(); i++) { 10882 ActivityInfo ai = ris.get(i).activityInfo; 10883 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10884 if (lastDoneReceivers.contains(comp)) { 10885 // We already did the pre boot receiver for this app with the current 10886 // platform version, so don't do it again... 10887 ris.remove(i); 10888 i--; 10889 // ...however, do keep it as one that has been done, so we don't 10890 // forget about it when rewriting the file of last done receivers. 10891 doneReceivers.add(comp); 10892 } 10893 } 10894 } 10895 10896 // If primary user, send broadcast to all available users, else just to userId 10897 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10898 : new int[] { userId }; 10899 for (int i = 0; i < ris.size(); i++) { 10900 ActivityInfo ai = ris.get(i).activityInfo; 10901 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10902 doneReceivers.add(comp); 10903 intent.setComponent(comp); 10904 for (int j=0; j<users.length; j++) { 10905 IIntentReceiver finisher = null; 10906 // On last receiver and user, set up a completion callback 10907 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10908 finisher = new IIntentReceiver.Stub() { 10909 public void performReceive(Intent intent, int resultCode, 10910 String data, Bundle extras, boolean ordered, 10911 boolean sticky, int sendingUser) { 10912 // The raw IIntentReceiver interface is called 10913 // with the AM lock held, so redispatch to 10914 // execute our code without the lock. 10915 mHandler.post(onFinishCallback); 10916 } 10917 }; 10918 } 10919 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10920 + " for user " + users[j]); 10921 broadcastIntentLocked(null, null, intent, null, finisher, 10922 0, null, null, null, AppOpsManager.OP_NONE, 10923 true, false, MY_PID, Process.SYSTEM_UID, 10924 users[j]); 10925 if (finisher != null) { 10926 waitingUpdate = true; 10927 } 10928 } 10929 } 10930 } 10931 10932 return waitingUpdate; 10933 } 10934 10935 public void systemReady(final Runnable goingCallback) { 10936 synchronized(this) { 10937 if (mSystemReady) { 10938 // If we're done calling all the receivers, run the next "boot phase" passed in 10939 // by the SystemServer 10940 if (goingCallback != null) { 10941 goingCallback.run(); 10942 } 10943 return; 10944 } 10945 10946 // Make sure we have the current profile info, since it is needed for 10947 // security checks. 10948 updateCurrentProfileIdsLocked(); 10949 10950 if (mRecentTasks == null) { 10951 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10952 if (!mRecentTasks.isEmpty()) { 10953 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10954 } 10955 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10956 mTaskPersister.startPersisting(); 10957 } 10958 10959 // Check to see if there are any update receivers to run. 10960 if (!mDidUpdate) { 10961 if (mWaitingUpdate) { 10962 return; 10963 } 10964 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10965 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10966 public void run() { 10967 synchronized (ActivityManagerService.this) { 10968 mDidUpdate = true; 10969 } 10970 writeLastDonePreBootReceivers(doneReceivers); 10971 showBootMessage(mContext.getText( 10972 R.string.android_upgrading_complete), 10973 false); 10974 systemReady(goingCallback); 10975 } 10976 }, doneReceivers, UserHandle.USER_OWNER); 10977 10978 if (mWaitingUpdate) { 10979 return; 10980 } 10981 mDidUpdate = true; 10982 } 10983 10984 mAppOpsService.systemReady(); 10985 mSystemReady = true; 10986 } 10987 10988 ArrayList<ProcessRecord> procsToKill = null; 10989 synchronized(mPidsSelfLocked) { 10990 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10991 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10992 if (!isAllowedWhileBooting(proc.info)){ 10993 if (procsToKill == null) { 10994 procsToKill = new ArrayList<ProcessRecord>(); 10995 } 10996 procsToKill.add(proc); 10997 } 10998 } 10999 } 11000 11001 synchronized(this) { 11002 if (procsToKill != null) { 11003 for (int i=procsToKill.size()-1; i>=0; i--) { 11004 ProcessRecord proc = procsToKill.get(i); 11005 Slog.i(TAG, "Removing system update proc: " + proc); 11006 removeProcessLocked(proc, true, false, "system update done"); 11007 } 11008 } 11009 11010 // Now that we have cleaned up any update processes, we 11011 // are ready to start launching real processes and know that 11012 // we won't trample on them any more. 11013 mProcessesReady = true; 11014 } 11015 11016 Slog.i(TAG, "System now ready"); 11017 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11018 SystemClock.uptimeMillis()); 11019 11020 synchronized(this) { 11021 // Make sure we have no pre-ready processes sitting around. 11022 11023 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11024 ResolveInfo ri = mContext.getPackageManager() 11025 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11026 STOCK_PM_FLAGS); 11027 CharSequence errorMsg = null; 11028 if (ri != null) { 11029 ActivityInfo ai = ri.activityInfo; 11030 ApplicationInfo app = ai.applicationInfo; 11031 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11032 mTopAction = Intent.ACTION_FACTORY_TEST; 11033 mTopData = null; 11034 mTopComponent = new ComponentName(app.packageName, 11035 ai.name); 11036 } else { 11037 errorMsg = mContext.getResources().getText( 11038 com.android.internal.R.string.factorytest_not_system); 11039 } 11040 } else { 11041 errorMsg = mContext.getResources().getText( 11042 com.android.internal.R.string.factorytest_no_action); 11043 } 11044 if (errorMsg != null) { 11045 mTopAction = null; 11046 mTopData = null; 11047 mTopComponent = null; 11048 Message msg = Message.obtain(); 11049 msg.what = SHOW_FACTORY_ERROR_MSG; 11050 msg.getData().putCharSequence("msg", errorMsg); 11051 mHandler.sendMessage(msg); 11052 } 11053 } 11054 } 11055 11056 retrieveSettings(); 11057 loadResourcesOnSystemReady(); 11058 11059 synchronized (this) { 11060 readGrantedUriPermissionsLocked(); 11061 } 11062 11063 if (goingCallback != null) goingCallback.run(); 11064 11065 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11066 Integer.toString(mCurrentUserId), mCurrentUserId); 11067 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11068 Integer.toString(mCurrentUserId), mCurrentUserId); 11069 mSystemServiceManager.startUser(mCurrentUserId); 11070 11071 synchronized (this) { 11072 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11073 try { 11074 List apps = AppGlobals.getPackageManager(). 11075 getPersistentApplications(STOCK_PM_FLAGS); 11076 if (apps != null) { 11077 int N = apps.size(); 11078 int i; 11079 for (i=0; i<N; i++) { 11080 ApplicationInfo info 11081 = (ApplicationInfo)apps.get(i); 11082 if (info != null && 11083 !info.packageName.equals("android")) { 11084 addAppLocked(info, false, null /* ABI override */); 11085 } 11086 } 11087 } 11088 } catch (RemoteException ex) { 11089 // pm is in same process, this will never happen. 11090 } 11091 } 11092 11093 // Start up initial activity. 11094 mBooting = true; 11095 11096 try { 11097 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11098 Message msg = Message.obtain(); 11099 msg.what = SHOW_UID_ERROR_MSG; 11100 mHandler.sendMessage(msg); 11101 } 11102 } catch (RemoteException e) { 11103 } 11104 11105 long ident = Binder.clearCallingIdentity(); 11106 try { 11107 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11108 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11109 | Intent.FLAG_RECEIVER_FOREGROUND); 11110 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11111 broadcastIntentLocked(null, null, intent, 11112 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11113 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11114 intent = new Intent(Intent.ACTION_USER_STARTING); 11115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11116 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11117 broadcastIntentLocked(null, null, intent, 11118 null, new IIntentReceiver.Stub() { 11119 @Override 11120 public void performReceive(Intent intent, int resultCode, String data, 11121 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11122 throws RemoteException { 11123 } 11124 }, 0, null, null, 11125 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11126 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11127 } catch (Throwable t) { 11128 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11129 } finally { 11130 Binder.restoreCallingIdentity(ident); 11131 } 11132 mStackSupervisor.resumeTopActivitiesLocked(); 11133 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11134 } 11135 } 11136 11137 private boolean makeAppCrashingLocked(ProcessRecord app, 11138 String shortMsg, String longMsg, String stackTrace) { 11139 app.crashing = true; 11140 app.crashingReport = generateProcessError(app, 11141 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11142 startAppProblemLocked(app); 11143 app.stopFreezingAllLocked(); 11144 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11145 } 11146 11147 private void makeAppNotRespondingLocked(ProcessRecord app, 11148 String activity, String shortMsg, String longMsg) { 11149 app.notResponding = true; 11150 app.notRespondingReport = generateProcessError(app, 11151 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11152 activity, shortMsg, longMsg, null); 11153 startAppProblemLocked(app); 11154 app.stopFreezingAllLocked(); 11155 } 11156 11157 /** 11158 * Generate a process error record, suitable for attachment to a ProcessRecord. 11159 * 11160 * @param app The ProcessRecord in which the error occurred. 11161 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11162 * ActivityManager.AppErrorStateInfo 11163 * @param activity The activity associated with the crash, if known. 11164 * @param shortMsg Short message describing the crash. 11165 * @param longMsg Long message describing the crash. 11166 * @param stackTrace Full crash stack trace, may be null. 11167 * 11168 * @return Returns a fully-formed AppErrorStateInfo record. 11169 */ 11170 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11171 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11172 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11173 11174 report.condition = condition; 11175 report.processName = app.processName; 11176 report.pid = app.pid; 11177 report.uid = app.info.uid; 11178 report.tag = activity; 11179 report.shortMsg = shortMsg; 11180 report.longMsg = longMsg; 11181 report.stackTrace = stackTrace; 11182 11183 return report; 11184 } 11185 11186 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11187 synchronized (this) { 11188 app.crashing = false; 11189 app.crashingReport = null; 11190 app.notResponding = false; 11191 app.notRespondingReport = null; 11192 if (app.anrDialog == fromDialog) { 11193 app.anrDialog = null; 11194 } 11195 if (app.waitDialog == fromDialog) { 11196 app.waitDialog = null; 11197 } 11198 if (app.pid > 0 && app.pid != MY_PID) { 11199 handleAppCrashLocked(app, null, null, null); 11200 app.kill("user request after error", true); 11201 } 11202 } 11203 } 11204 11205 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11206 String stackTrace) { 11207 long now = SystemClock.uptimeMillis(); 11208 11209 Long crashTime; 11210 if (!app.isolated) { 11211 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11212 } else { 11213 crashTime = null; 11214 } 11215 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11216 // This process loses! 11217 Slog.w(TAG, "Process " + app.info.processName 11218 + " has crashed too many times: killing!"); 11219 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11220 app.userId, app.info.processName, app.uid); 11221 mStackSupervisor.handleAppCrashLocked(app); 11222 if (!app.persistent) { 11223 // We don't want to start this process again until the user 11224 // explicitly does so... but for persistent process, we really 11225 // need to keep it running. If a persistent process is actually 11226 // repeatedly crashing, then badness for everyone. 11227 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11228 app.info.processName); 11229 if (!app.isolated) { 11230 // XXX We don't have a way to mark isolated processes 11231 // as bad, since they don't have a peristent identity. 11232 mBadProcesses.put(app.info.processName, app.uid, 11233 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11234 mProcessCrashTimes.remove(app.info.processName, app.uid); 11235 } 11236 app.bad = true; 11237 app.removed = true; 11238 // Don't let services in this process be restarted and potentially 11239 // annoy the user repeatedly. Unless it is persistent, since those 11240 // processes run critical code. 11241 removeProcessLocked(app, false, false, "crash"); 11242 mStackSupervisor.resumeTopActivitiesLocked(); 11243 return false; 11244 } 11245 mStackSupervisor.resumeTopActivitiesLocked(); 11246 } else { 11247 mStackSupervisor.finishTopRunningActivityLocked(app); 11248 } 11249 11250 // Bump up the crash count of any services currently running in the proc. 11251 for (int i=app.services.size()-1; i>=0; i--) { 11252 // Any services running in the application need to be placed 11253 // back in the pending list. 11254 ServiceRecord sr = app.services.valueAt(i); 11255 sr.crashCount++; 11256 } 11257 11258 // If the crashing process is what we consider to be the "home process" and it has been 11259 // replaced by a third-party app, clear the package preferred activities from packages 11260 // with a home activity running in the process to prevent a repeatedly crashing app 11261 // from blocking the user to manually clear the list. 11262 final ArrayList<ActivityRecord> activities = app.activities; 11263 if (app == mHomeProcess && activities.size() > 0 11264 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11265 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11266 final ActivityRecord r = activities.get(activityNdx); 11267 if (r.isHomeActivity()) { 11268 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11269 try { 11270 ActivityThread.getPackageManager() 11271 .clearPackagePreferredActivities(r.packageName); 11272 } catch (RemoteException c) { 11273 // pm is in same process, this will never happen. 11274 } 11275 } 11276 } 11277 } 11278 11279 if (!app.isolated) { 11280 // XXX Can't keep track of crash times for isolated processes, 11281 // because they don't have a perisistent identity. 11282 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11283 } 11284 11285 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11286 return true; 11287 } 11288 11289 void startAppProblemLocked(ProcessRecord app) { 11290 // If this app is not running under the current user, then we 11291 // can't give it a report button because that would require 11292 // launching the report UI under a different user. 11293 app.errorReportReceiver = null; 11294 11295 for (int userId : mCurrentProfileIds) { 11296 if (app.userId == userId) { 11297 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11298 mContext, app.info.packageName, app.info.flags); 11299 } 11300 } 11301 skipCurrentReceiverLocked(app); 11302 } 11303 11304 void skipCurrentReceiverLocked(ProcessRecord app) { 11305 for (BroadcastQueue queue : mBroadcastQueues) { 11306 queue.skipCurrentReceiverLocked(app); 11307 } 11308 } 11309 11310 /** 11311 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11312 * The application process will exit immediately after this call returns. 11313 * @param app object of the crashing app, null for the system server 11314 * @param crashInfo describing the exception 11315 */ 11316 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11317 ProcessRecord r = findAppProcess(app, "Crash"); 11318 final String processName = app == null ? "system_server" 11319 : (r == null ? "unknown" : r.processName); 11320 11321 handleApplicationCrashInner("crash", r, processName, crashInfo); 11322 } 11323 11324 /* Native crash reporting uses this inner version because it needs to be somewhat 11325 * decoupled from the AM-managed cleanup lifecycle 11326 */ 11327 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11328 ApplicationErrorReport.CrashInfo crashInfo) { 11329 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11330 UserHandle.getUserId(Binder.getCallingUid()), processName, 11331 r == null ? -1 : r.info.flags, 11332 crashInfo.exceptionClassName, 11333 crashInfo.exceptionMessage, 11334 crashInfo.throwFileName, 11335 crashInfo.throwLineNumber); 11336 11337 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11338 11339 crashApplication(r, crashInfo); 11340 } 11341 11342 public void handleApplicationStrictModeViolation( 11343 IBinder app, 11344 int violationMask, 11345 StrictMode.ViolationInfo info) { 11346 ProcessRecord r = findAppProcess(app, "StrictMode"); 11347 if (r == null) { 11348 return; 11349 } 11350 11351 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11352 Integer stackFingerprint = info.hashCode(); 11353 boolean logIt = true; 11354 synchronized (mAlreadyLoggedViolatedStacks) { 11355 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11356 logIt = false; 11357 // TODO: sub-sample into EventLog for these, with 11358 // the info.durationMillis? Then we'd get 11359 // the relative pain numbers, without logging all 11360 // the stack traces repeatedly. We'd want to do 11361 // likewise in the client code, which also does 11362 // dup suppression, before the Binder call. 11363 } else { 11364 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11365 mAlreadyLoggedViolatedStacks.clear(); 11366 } 11367 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11368 } 11369 } 11370 if (logIt) { 11371 logStrictModeViolationToDropBox(r, info); 11372 } 11373 } 11374 11375 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11376 AppErrorResult result = new AppErrorResult(); 11377 synchronized (this) { 11378 final long origId = Binder.clearCallingIdentity(); 11379 11380 Message msg = Message.obtain(); 11381 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11382 HashMap<String, Object> data = new HashMap<String, Object>(); 11383 data.put("result", result); 11384 data.put("app", r); 11385 data.put("violationMask", violationMask); 11386 data.put("info", info); 11387 msg.obj = data; 11388 mHandler.sendMessage(msg); 11389 11390 Binder.restoreCallingIdentity(origId); 11391 } 11392 int res = result.get(); 11393 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11394 } 11395 } 11396 11397 // Depending on the policy in effect, there could be a bunch of 11398 // these in quick succession so we try to batch these together to 11399 // minimize disk writes, number of dropbox entries, and maximize 11400 // compression, by having more fewer, larger records. 11401 private void logStrictModeViolationToDropBox( 11402 ProcessRecord process, 11403 StrictMode.ViolationInfo info) { 11404 if (info == null) { 11405 return; 11406 } 11407 final boolean isSystemApp = process == null || 11408 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11409 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11410 final String processName = process == null ? "unknown" : process.processName; 11411 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11412 final DropBoxManager dbox = (DropBoxManager) 11413 mContext.getSystemService(Context.DROPBOX_SERVICE); 11414 11415 // Exit early if the dropbox isn't configured to accept this report type. 11416 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11417 11418 boolean bufferWasEmpty; 11419 boolean needsFlush; 11420 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11421 synchronized (sb) { 11422 bufferWasEmpty = sb.length() == 0; 11423 appendDropBoxProcessHeaders(process, processName, sb); 11424 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11425 sb.append("System-App: ").append(isSystemApp).append("\n"); 11426 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11427 if (info.violationNumThisLoop != 0) { 11428 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11429 } 11430 if (info.numAnimationsRunning != 0) { 11431 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11432 } 11433 if (info.broadcastIntentAction != null) { 11434 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11435 } 11436 if (info.durationMillis != -1) { 11437 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11438 } 11439 if (info.numInstances != -1) { 11440 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11441 } 11442 if (info.tags != null) { 11443 for (String tag : info.tags) { 11444 sb.append("Span-Tag: ").append(tag).append("\n"); 11445 } 11446 } 11447 sb.append("\n"); 11448 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11449 sb.append(info.crashInfo.stackTrace); 11450 } 11451 sb.append("\n"); 11452 11453 // Only buffer up to ~64k. Various logging bits truncate 11454 // things at 128k. 11455 needsFlush = (sb.length() > 64 * 1024); 11456 } 11457 11458 // Flush immediately if the buffer's grown too large, or this 11459 // is a non-system app. Non-system apps are isolated with a 11460 // different tag & policy and not batched. 11461 // 11462 // Batching is useful during internal testing with 11463 // StrictMode settings turned up high. Without batching, 11464 // thousands of separate files could be created on boot. 11465 if (!isSystemApp || needsFlush) { 11466 new Thread("Error dump: " + dropboxTag) { 11467 @Override 11468 public void run() { 11469 String report; 11470 synchronized (sb) { 11471 report = sb.toString(); 11472 sb.delete(0, sb.length()); 11473 sb.trimToSize(); 11474 } 11475 if (report.length() != 0) { 11476 dbox.addText(dropboxTag, report); 11477 } 11478 } 11479 }.start(); 11480 return; 11481 } 11482 11483 // System app batching: 11484 if (!bufferWasEmpty) { 11485 // An existing dropbox-writing thread is outstanding, so 11486 // we don't need to start it up. The existing thread will 11487 // catch the buffer appends we just did. 11488 return; 11489 } 11490 11491 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11492 // (After this point, we shouldn't access AMS internal data structures.) 11493 new Thread("Error dump: " + dropboxTag) { 11494 @Override 11495 public void run() { 11496 // 5 second sleep to let stacks arrive and be batched together 11497 try { 11498 Thread.sleep(5000); // 5 seconds 11499 } catch (InterruptedException e) {} 11500 11501 String errorReport; 11502 synchronized (mStrictModeBuffer) { 11503 errorReport = mStrictModeBuffer.toString(); 11504 if (errorReport.length() == 0) { 11505 return; 11506 } 11507 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11508 mStrictModeBuffer.trimToSize(); 11509 } 11510 dbox.addText(dropboxTag, errorReport); 11511 } 11512 }.start(); 11513 } 11514 11515 /** 11516 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11517 * @param app object of the crashing app, null for the system server 11518 * @param tag reported by the caller 11519 * @param system whether this wtf is coming from the system 11520 * @param crashInfo describing the context of the error 11521 * @return true if the process should exit immediately (WTF is fatal) 11522 */ 11523 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11524 final ApplicationErrorReport.CrashInfo crashInfo) { 11525 final ProcessRecord r = findAppProcess(app, "WTF"); 11526 final String processName = app == null ? "system_server" 11527 : (r == null ? "unknown" : r.processName); 11528 11529 EventLog.writeEvent(EventLogTags.AM_WTF, 11530 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11531 processName, 11532 r == null ? -1 : r.info.flags, 11533 tag, crashInfo.exceptionMessage); 11534 11535 if (system) { 11536 // If this is coming from the system, we could very well have low-level 11537 // system locks held, so we want to do this all asynchronously. And we 11538 // never want this to become fatal, so there is that too. 11539 mHandler.post(new Runnable() { 11540 @Override public void run() { 11541 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11542 crashInfo); 11543 } 11544 }); 11545 return false; 11546 } 11547 11548 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11549 11550 if (r != null && r.pid != Process.myPid() && 11551 Settings.Global.getInt(mContext.getContentResolver(), 11552 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11553 crashApplication(r, crashInfo); 11554 return true; 11555 } else { 11556 return false; 11557 } 11558 } 11559 11560 /** 11561 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11562 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11563 */ 11564 private ProcessRecord findAppProcess(IBinder app, String reason) { 11565 if (app == null) { 11566 return null; 11567 } 11568 11569 synchronized (this) { 11570 final int NP = mProcessNames.getMap().size(); 11571 for (int ip=0; ip<NP; ip++) { 11572 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11573 final int NA = apps.size(); 11574 for (int ia=0; ia<NA; ia++) { 11575 ProcessRecord p = apps.valueAt(ia); 11576 if (p.thread != null && p.thread.asBinder() == app) { 11577 return p; 11578 } 11579 } 11580 } 11581 11582 Slog.w(TAG, "Can't find mystery application for " + reason 11583 + " from pid=" + Binder.getCallingPid() 11584 + " uid=" + Binder.getCallingUid() + ": " + app); 11585 return null; 11586 } 11587 } 11588 11589 /** 11590 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11591 * to append various headers to the dropbox log text. 11592 */ 11593 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11594 StringBuilder sb) { 11595 // Watchdog thread ends up invoking this function (with 11596 // a null ProcessRecord) to add the stack file to dropbox. 11597 // Do not acquire a lock on this (am) in such cases, as it 11598 // could cause a potential deadlock, if and when watchdog 11599 // is invoked due to unavailability of lock on am and it 11600 // would prevent watchdog from killing system_server. 11601 if (process == null) { 11602 sb.append("Process: ").append(processName).append("\n"); 11603 return; 11604 } 11605 // Note: ProcessRecord 'process' is guarded by the service 11606 // instance. (notably process.pkgList, which could otherwise change 11607 // concurrently during execution of this method) 11608 synchronized (this) { 11609 sb.append("Process: ").append(processName).append("\n"); 11610 int flags = process.info.flags; 11611 IPackageManager pm = AppGlobals.getPackageManager(); 11612 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11613 for (int ip=0; ip<process.pkgList.size(); ip++) { 11614 String pkg = process.pkgList.keyAt(ip); 11615 sb.append("Package: ").append(pkg); 11616 try { 11617 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11618 if (pi != null) { 11619 sb.append(" v").append(pi.versionCode); 11620 if (pi.versionName != null) { 11621 sb.append(" (").append(pi.versionName).append(")"); 11622 } 11623 } 11624 } catch (RemoteException e) { 11625 Slog.e(TAG, "Error getting package info: " + pkg, e); 11626 } 11627 sb.append("\n"); 11628 } 11629 } 11630 } 11631 11632 private static String processClass(ProcessRecord process) { 11633 if (process == null || process.pid == MY_PID) { 11634 return "system_server"; 11635 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11636 return "system_app"; 11637 } else { 11638 return "data_app"; 11639 } 11640 } 11641 11642 /** 11643 * Write a description of an error (crash, WTF, ANR) to the drop box. 11644 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11645 * @param process which caused the error, null means the system server 11646 * @param activity which triggered the error, null if unknown 11647 * @param parent activity related to the error, null if unknown 11648 * @param subject line related to the error, null if absent 11649 * @param report in long form describing the error, null if absent 11650 * @param logFile to include in the report, null if none 11651 * @param crashInfo giving an application stack trace, null if absent 11652 */ 11653 public void addErrorToDropBox(String eventType, 11654 ProcessRecord process, String processName, ActivityRecord activity, 11655 ActivityRecord parent, String subject, 11656 final String report, final File logFile, 11657 final ApplicationErrorReport.CrashInfo crashInfo) { 11658 // NOTE -- this must never acquire the ActivityManagerService lock, 11659 // otherwise the watchdog may be prevented from resetting the system. 11660 11661 final String dropboxTag = processClass(process) + "_" + eventType; 11662 final DropBoxManager dbox = (DropBoxManager) 11663 mContext.getSystemService(Context.DROPBOX_SERVICE); 11664 11665 // Exit early if the dropbox isn't configured to accept this report type. 11666 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11667 11668 final StringBuilder sb = new StringBuilder(1024); 11669 appendDropBoxProcessHeaders(process, processName, sb); 11670 if (activity != null) { 11671 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11672 } 11673 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11674 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11675 } 11676 if (parent != null && parent != activity) { 11677 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11678 } 11679 if (subject != null) { 11680 sb.append("Subject: ").append(subject).append("\n"); 11681 } 11682 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11683 if (Debug.isDebuggerConnected()) { 11684 sb.append("Debugger: Connected\n"); 11685 } 11686 sb.append("\n"); 11687 11688 // Do the rest in a worker thread to avoid blocking the caller on I/O 11689 // (After this point, we shouldn't access AMS internal data structures.) 11690 Thread worker = new Thread("Error dump: " + dropboxTag) { 11691 @Override 11692 public void run() { 11693 if (report != null) { 11694 sb.append(report); 11695 } 11696 if (logFile != null) { 11697 try { 11698 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11699 "\n\n[[TRUNCATED]]")); 11700 } catch (IOException e) { 11701 Slog.e(TAG, "Error reading " + logFile, e); 11702 } 11703 } 11704 if (crashInfo != null && crashInfo.stackTrace != null) { 11705 sb.append(crashInfo.stackTrace); 11706 } 11707 11708 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11709 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11710 if (lines > 0) { 11711 sb.append("\n"); 11712 11713 // Merge several logcat streams, and take the last N lines 11714 InputStreamReader input = null; 11715 try { 11716 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11717 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11718 "-b", "crash", 11719 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11720 11721 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11722 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11723 input = new InputStreamReader(logcat.getInputStream()); 11724 11725 int num; 11726 char[] buf = new char[8192]; 11727 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11728 } catch (IOException e) { 11729 Slog.e(TAG, "Error running logcat", e); 11730 } finally { 11731 if (input != null) try { input.close(); } catch (IOException e) {} 11732 } 11733 } 11734 11735 dbox.addText(dropboxTag, sb.toString()); 11736 } 11737 }; 11738 11739 if (process == null) { 11740 // If process is null, we are being called from some internal code 11741 // and may be about to die -- run this synchronously. 11742 worker.run(); 11743 } else { 11744 worker.start(); 11745 } 11746 } 11747 11748 /** 11749 * Bring up the "unexpected error" dialog box for a crashing app. 11750 * Deal with edge cases (intercepts from instrumented applications, 11751 * ActivityController, error intent receivers, that sort of thing). 11752 * @param r the application crashing 11753 * @param crashInfo describing the failure 11754 */ 11755 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11756 long timeMillis = System.currentTimeMillis(); 11757 String shortMsg = crashInfo.exceptionClassName; 11758 String longMsg = crashInfo.exceptionMessage; 11759 String stackTrace = crashInfo.stackTrace; 11760 if (shortMsg != null && longMsg != null) { 11761 longMsg = shortMsg + ": " + longMsg; 11762 } else if (shortMsg != null) { 11763 longMsg = shortMsg; 11764 } 11765 11766 AppErrorResult result = new AppErrorResult(); 11767 synchronized (this) { 11768 if (mController != null) { 11769 try { 11770 String name = r != null ? r.processName : null; 11771 int pid = r != null ? r.pid : Binder.getCallingPid(); 11772 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11773 if (!mController.appCrashed(name, pid, 11774 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11775 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11776 && "Native crash".equals(crashInfo.exceptionClassName)) { 11777 Slog.w(TAG, "Skip killing native crashed app " + name 11778 + "(" + pid + ") during testing"); 11779 } else { 11780 Slog.w(TAG, "Force-killing crashed app " + name 11781 + " at watcher's request"); 11782 if (r != null) { 11783 r.kill("crash", true); 11784 } else { 11785 // Huh. 11786 Process.killProcess(pid); 11787 Process.killProcessGroup(uid, pid); 11788 } 11789 } 11790 return; 11791 } 11792 } catch (RemoteException e) { 11793 mController = null; 11794 Watchdog.getInstance().setActivityController(null); 11795 } 11796 } 11797 11798 final long origId = Binder.clearCallingIdentity(); 11799 11800 // If this process is running instrumentation, finish it. 11801 if (r != null && r.instrumentationClass != null) { 11802 Slog.w(TAG, "Error in app " + r.processName 11803 + " running instrumentation " + r.instrumentationClass + ":"); 11804 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11805 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11806 Bundle info = new Bundle(); 11807 info.putString("shortMsg", shortMsg); 11808 info.putString("longMsg", longMsg); 11809 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11810 Binder.restoreCallingIdentity(origId); 11811 return; 11812 } 11813 11814 // If we can't identify the process or it's already exceeded its crash quota, 11815 // quit right away without showing a crash dialog. 11816 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11817 Binder.restoreCallingIdentity(origId); 11818 return; 11819 } 11820 11821 Message msg = Message.obtain(); 11822 msg.what = SHOW_ERROR_MSG; 11823 HashMap data = new HashMap(); 11824 data.put("result", result); 11825 data.put("app", r); 11826 msg.obj = data; 11827 mHandler.sendMessage(msg); 11828 11829 Binder.restoreCallingIdentity(origId); 11830 } 11831 11832 int res = result.get(); 11833 11834 Intent appErrorIntent = null; 11835 synchronized (this) { 11836 if (r != null && !r.isolated) { 11837 // XXX Can't keep track of crash time for isolated processes, 11838 // since they don't have a persistent identity. 11839 mProcessCrashTimes.put(r.info.processName, r.uid, 11840 SystemClock.uptimeMillis()); 11841 } 11842 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11843 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11844 } 11845 } 11846 11847 if (appErrorIntent != null) { 11848 try { 11849 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11850 } catch (ActivityNotFoundException e) { 11851 Slog.w(TAG, "bug report receiver dissappeared", e); 11852 } 11853 } 11854 } 11855 11856 Intent createAppErrorIntentLocked(ProcessRecord r, 11857 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11858 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11859 if (report == null) { 11860 return null; 11861 } 11862 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11863 result.setComponent(r.errorReportReceiver); 11864 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11865 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11866 return result; 11867 } 11868 11869 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11870 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11871 if (r.errorReportReceiver == null) { 11872 return null; 11873 } 11874 11875 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11876 return null; 11877 } 11878 11879 ApplicationErrorReport report = new ApplicationErrorReport(); 11880 report.packageName = r.info.packageName; 11881 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11882 report.processName = r.processName; 11883 report.time = timeMillis; 11884 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11885 11886 if (r.crashing || r.forceCrashReport) { 11887 report.type = ApplicationErrorReport.TYPE_CRASH; 11888 report.crashInfo = crashInfo; 11889 } else if (r.notResponding) { 11890 report.type = ApplicationErrorReport.TYPE_ANR; 11891 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11892 11893 report.anrInfo.activity = r.notRespondingReport.tag; 11894 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11895 report.anrInfo.info = r.notRespondingReport.longMsg; 11896 } 11897 11898 return report; 11899 } 11900 11901 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11902 enforceNotIsolatedCaller("getProcessesInErrorState"); 11903 // assume our apps are happy - lazy create the list 11904 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11905 11906 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11907 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11908 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11909 11910 synchronized (this) { 11911 11912 // iterate across all processes 11913 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11914 ProcessRecord app = mLruProcesses.get(i); 11915 if (!allUsers && app.userId != userId) { 11916 continue; 11917 } 11918 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11919 // This one's in trouble, so we'll generate a report for it 11920 // crashes are higher priority (in case there's a crash *and* an anr) 11921 ActivityManager.ProcessErrorStateInfo report = null; 11922 if (app.crashing) { 11923 report = app.crashingReport; 11924 } else if (app.notResponding) { 11925 report = app.notRespondingReport; 11926 } 11927 11928 if (report != null) { 11929 if (errList == null) { 11930 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11931 } 11932 errList.add(report); 11933 } else { 11934 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11935 " crashing = " + app.crashing + 11936 " notResponding = " + app.notResponding); 11937 } 11938 } 11939 } 11940 } 11941 11942 return errList; 11943 } 11944 11945 static int procStateToImportance(int procState, int memAdj, 11946 ActivityManager.RunningAppProcessInfo currApp) { 11947 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11948 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11949 currApp.lru = memAdj; 11950 } else { 11951 currApp.lru = 0; 11952 } 11953 return imp; 11954 } 11955 11956 private void fillInProcMemInfo(ProcessRecord app, 11957 ActivityManager.RunningAppProcessInfo outInfo) { 11958 outInfo.pid = app.pid; 11959 outInfo.uid = app.info.uid; 11960 if (mHeavyWeightProcess == app) { 11961 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11962 } 11963 if (app.persistent) { 11964 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11965 } 11966 if (app.activities.size() > 0) { 11967 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11968 } 11969 outInfo.lastTrimLevel = app.trimMemoryLevel; 11970 int adj = app.curAdj; 11971 int procState = app.curProcState; 11972 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11973 outInfo.importanceReasonCode = app.adjTypeCode; 11974 outInfo.processState = app.curProcState; 11975 } 11976 11977 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11978 enforceNotIsolatedCaller("getRunningAppProcesses"); 11979 // Lazy instantiation of list 11980 List<ActivityManager.RunningAppProcessInfo> runList = null; 11981 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11982 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11983 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11984 synchronized (this) { 11985 // Iterate across all processes 11986 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11987 ProcessRecord app = mLruProcesses.get(i); 11988 if (!allUsers && app.userId != userId) { 11989 continue; 11990 } 11991 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11992 // Generate process state info for running application 11993 ActivityManager.RunningAppProcessInfo currApp = 11994 new ActivityManager.RunningAppProcessInfo(app.processName, 11995 app.pid, app.getPackageList()); 11996 fillInProcMemInfo(app, currApp); 11997 if (app.adjSource instanceof ProcessRecord) { 11998 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11999 currApp.importanceReasonImportance = 12000 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12001 app.adjSourceProcState); 12002 } else if (app.adjSource instanceof ActivityRecord) { 12003 ActivityRecord r = (ActivityRecord)app.adjSource; 12004 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12005 } 12006 if (app.adjTarget instanceof ComponentName) { 12007 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12008 } 12009 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12010 // + " lru=" + currApp.lru); 12011 if (runList == null) { 12012 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12013 } 12014 runList.add(currApp); 12015 } 12016 } 12017 } 12018 return runList; 12019 } 12020 12021 public List<ApplicationInfo> getRunningExternalApplications() { 12022 enforceNotIsolatedCaller("getRunningExternalApplications"); 12023 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12024 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12025 if (runningApps != null && runningApps.size() > 0) { 12026 Set<String> extList = new HashSet<String>(); 12027 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12028 if (app.pkgList != null) { 12029 for (String pkg : app.pkgList) { 12030 extList.add(pkg); 12031 } 12032 } 12033 } 12034 IPackageManager pm = AppGlobals.getPackageManager(); 12035 for (String pkg : extList) { 12036 try { 12037 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12038 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12039 retList.add(info); 12040 } 12041 } catch (RemoteException e) { 12042 } 12043 } 12044 } 12045 return retList; 12046 } 12047 12048 @Override 12049 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12050 enforceNotIsolatedCaller("getMyMemoryState"); 12051 synchronized (this) { 12052 ProcessRecord proc; 12053 synchronized (mPidsSelfLocked) { 12054 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12055 } 12056 fillInProcMemInfo(proc, outInfo); 12057 } 12058 } 12059 12060 @Override 12061 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12062 if (checkCallingPermission(android.Manifest.permission.DUMP) 12063 != PackageManager.PERMISSION_GRANTED) { 12064 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12065 + Binder.getCallingPid() 12066 + ", uid=" + Binder.getCallingUid() 12067 + " without permission " 12068 + android.Manifest.permission.DUMP); 12069 return; 12070 } 12071 12072 boolean dumpAll = false; 12073 boolean dumpClient = false; 12074 String dumpPackage = null; 12075 12076 int opti = 0; 12077 while (opti < args.length) { 12078 String opt = args[opti]; 12079 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12080 break; 12081 } 12082 opti++; 12083 if ("-a".equals(opt)) { 12084 dumpAll = true; 12085 } else if ("-c".equals(opt)) { 12086 dumpClient = true; 12087 } else if ("-h".equals(opt)) { 12088 pw.println("Activity manager dump options:"); 12089 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12090 pw.println(" cmd may be one of:"); 12091 pw.println(" a[ctivities]: activity stack state"); 12092 pw.println(" r[recents]: recent activities state"); 12093 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12094 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12095 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12096 pw.println(" o[om]: out of memory management"); 12097 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12098 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12099 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12100 pw.println(" service [COMP_SPEC]: service client-side state"); 12101 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12102 pw.println(" all: dump all activities"); 12103 pw.println(" top: dump the top activity"); 12104 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12105 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12106 pw.println(" a partial substring in a component name, a"); 12107 pw.println(" hex object identifier."); 12108 pw.println(" -a: include all available server state."); 12109 pw.println(" -c: include client state."); 12110 return; 12111 } else { 12112 pw.println("Unknown argument: " + opt + "; use -h for help"); 12113 } 12114 } 12115 12116 long origId = Binder.clearCallingIdentity(); 12117 boolean more = false; 12118 // Is the caller requesting to dump a particular piece of data? 12119 if (opti < args.length) { 12120 String cmd = args[opti]; 12121 opti++; 12122 if ("activities".equals(cmd) || "a".equals(cmd)) { 12123 synchronized (this) { 12124 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12125 } 12126 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12127 synchronized (this) { 12128 dumpRecentsLocked(fd, pw, args, opti, true, null); 12129 } 12130 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12131 String[] newArgs; 12132 String name; 12133 if (opti >= args.length) { 12134 name = null; 12135 newArgs = EMPTY_STRING_ARRAY; 12136 } else { 12137 name = args[opti]; 12138 opti++; 12139 newArgs = new String[args.length - opti]; 12140 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12141 args.length - opti); 12142 } 12143 synchronized (this) { 12144 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12145 } 12146 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12147 String[] newArgs; 12148 String name; 12149 if (opti >= args.length) { 12150 name = null; 12151 newArgs = EMPTY_STRING_ARRAY; 12152 } else { 12153 name = args[opti]; 12154 opti++; 12155 newArgs = new String[args.length - opti]; 12156 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12157 args.length - opti); 12158 } 12159 synchronized (this) { 12160 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12161 } 12162 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12163 String[] newArgs; 12164 String name; 12165 if (opti >= args.length) { 12166 name = null; 12167 newArgs = EMPTY_STRING_ARRAY; 12168 } else { 12169 name = args[opti]; 12170 opti++; 12171 newArgs = new String[args.length - opti]; 12172 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12173 args.length - opti); 12174 } 12175 synchronized (this) { 12176 dumpProcessesLocked(fd, pw, args, opti, true, name); 12177 } 12178 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12179 synchronized (this) { 12180 dumpOomLocked(fd, pw, args, opti, true); 12181 } 12182 } else if ("provider".equals(cmd)) { 12183 String[] newArgs; 12184 String name; 12185 if (opti >= args.length) { 12186 name = null; 12187 newArgs = EMPTY_STRING_ARRAY; 12188 } else { 12189 name = args[opti]; 12190 opti++; 12191 newArgs = new String[args.length - opti]; 12192 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12193 } 12194 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12195 pw.println("No providers match: " + name); 12196 pw.println("Use -h for help."); 12197 } 12198 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12199 synchronized (this) { 12200 dumpProvidersLocked(fd, pw, args, opti, true, null); 12201 } 12202 } else if ("service".equals(cmd)) { 12203 String[] newArgs; 12204 String name; 12205 if (opti >= args.length) { 12206 name = null; 12207 newArgs = EMPTY_STRING_ARRAY; 12208 } else { 12209 name = args[opti]; 12210 opti++; 12211 newArgs = new String[args.length - opti]; 12212 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12213 args.length - opti); 12214 } 12215 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12216 pw.println("No services match: " + name); 12217 pw.println("Use -h for help."); 12218 } 12219 } else if ("package".equals(cmd)) { 12220 String[] newArgs; 12221 if (opti >= args.length) { 12222 pw.println("package: no package name specified"); 12223 pw.println("Use -h for help."); 12224 } else { 12225 dumpPackage = args[opti]; 12226 opti++; 12227 newArgs = new String[args.length - opti]; 12228 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12229 args.length - opti); 12230 args = newArgs; 12231 opti = 0; 12232 more = true; 12233 } 12234 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12235 synchronized (this) { 12236 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12237 } 12238 } else { 12239 // Dumping a single activity? 12240 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12241 pw.println("Bad activity command, or no activities match: " + cmd); 12242 pw.println("Use -h for help."); 12243 } 12244 } 12245 if (!more) { 12246 Binder.restoreCallingIdentity(origId); 12247 return; 12248 } 12249 } 12250 12251 // No piece of data specified, dump everything. 12252 synchronized (this) { 12253 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12254 pw.println(); 12255 if (dumpAll) { 12256 pw.println("-------------------------------------------------------------------------------"); 12257 } 12258 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12259 pw.println(); 12260 if (dumpAll) { 12261 pw.println("-------------------------------------------------------------------------------"); 12262 } 12263 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12264 pw.println(); 12265 if (dumpAll) { 12266 pw.println("-------------------------------------------------------------------------------"); 12267 } 12268 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12269 pw.println(); 12270 if (dumpAll) { 12271 pw.println("-------------------------------------------------------------------------------"); 12272 } 12273 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12274 pw.println(); 12275 if (dumpAll) { 12276 pw.println("-------------------------------------------------------------------------------"); 12277 } 12278 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12279 pw.println(); 12280 if (dumpAll) { 12281 pw.println("-------------------------------------------------------------------------------"); 12282 } 12283 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12284 } 12285 Binder.restoreCallingIdentity(origId); 12286 } 12287 12288 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12289 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12290 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12291 12292 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12293 dumpPackage); 12294 boolean needSep = printedAnything; 12295 12296 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12297 dumpPackage, needSep, " mFocusedActivity: "); 12298 if (printed) { 12299 printedAnything = true; 12300 needSep = false; 12301 } 12302 12303 if (dumpPackage == null) { 12304 if (needSep) { 12305 pw.println(); 12306 } 12307 needSep = true; 12308 printedAnything = true; 12309 mStackSupervisor.dump(pw, " "); 12310 } 12311 12312 if (!printedAnything) { 12313 pw.println(" (nothing)"); 12314 } 12315 } 12316 12317 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12318 int opti, boolean dumpAll, String dumpPackage) { 12319 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12320 12321 boolean printedAnything = false; 12322 12323 if (mRecentTasks.size() > 0) { 12324 boolean printedHeader = false; 12325 12326 final int N = mRecentTasks.size(); 12327 for (int i=0; i<N; i++) { 12328 TaskRecord tr = mRecentTasks.get(i); 12329 if (dumpPackage != null) { 12330 if (tr.realActivity == null || 12331 !dumpPackage.equals(tr.realActivity)) { 12332 continue; 12333 } 12334 } 12335 if (!printedHeader) { 12336 pw.println(" Recent tasks:"); 12337 printedHeader = true; 12338 printedAnything = true; 12339 } 12340 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12341 pw.println(tr); 12342 if (dumpAll) { 12343 mRecentTasks.get(i).dump(pw, " "); 12344 } 12345 } 12346 } 12347 12348 if (!printedAnything) { 12349 pw.println(" (nothing)"); 12350 } 12351 } 12352 12353 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12354 int opti, boolean dumpAll, String dumpPackage) { 12355 boolean needSep = false; 12356 boolean printedAnything = false; 12357 int numPers = 0; 12358 12359 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12360 12361 if (dumpAll) { 12362 final int NP = mProcessNames.getMap().size(); 12363 for (int ip=0; ip<NP; ip++) { 12364 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12365 final int NA = procs.size(); 12366 for (int ia=0; ia<NA; ia++) { 12367 ProcessRecord r = procs.valueAt(ia); 12368 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12369 continue; 12370 } 12371 if (!needSep) { 12372 pw.println(" All known processes:"); 12373 needSep = true; 12374 printedAnything = true; 12375 } 12376 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12377 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12378 pw.print(" "); pw.println(r); 12379 r.dump(pw, " "); 12380 if (r.persistent) { 12381 numPers++; 12382 } 12383 } 12384 } 12385 } 12386 12387 if (mIsolatedProcesses.size() > 0) { 12388 boolean printed = false; 12389 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12390 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12391 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12392 continue; 12393 } 12394 if (!printed) { 12395 if (needSep) { 12396 pw.println(); 12397 } 12398 pw.println(" Isolated process list (sorted by uid):"); 12399 printedAnything = true; 12400 printed = true; 12401 needSep = true; 12402 } 12403 pw.println(String.format("%sIsolated #%2d: %s", 12404 " ", i, r.toString())); 12405 } 12406 } 12407 12408 if (mLruProcesses.size() > 0) { 12409 if (needSep) { 12410 pw.println(); 12411 } 12412 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12413 pw.print(" total, non-act at "); 12414 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12415 pw.print(", non-svc at "); 12416 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12417 pw.println("):"); 12418 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12419 needSep = true; 12420 printedAnything = true; 12421 } 12422 12423 if (dumpAll || dumpPackage != null) { 12424 synchronized (mPidsSelfLocked) { 12425 boolean printed = false; 12426 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12427 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12428 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12429 continue; 12430 } 12431 if (!printed) { 12432 if (needSep) pw.println(); 12433 needSep = true; 12434 pw.println(" PID mappings:"); 12435 printed = true; 12436 printedAnything = true; 12437 } 12438 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12439 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12440 } 12441 } 12442 } 12443 12444 if (mForegroundProcesses.size() > 0) { 12445 synchronized (mPidsSelfLocked) { 12446 boolean printed = false; 12447 for (int i=0; i<mForegroundProcesses.size(); i++) { 12448 ProcessRecord r = mPidsSelfLocked.get( 12449 mForegroundProcesses.valueAt(i).pid); 12450 if (dumpPackage != null && (r == null 12451 || !r.pkgList.containsKey(dumpPackage))) { 12452 continue; 12453 } 12454 if (!printed) { 12455 if (needSep) pw.println(); 12456 needSep = true; 12457 pw.println(" Foreground Processes:"); 12458 printed = true; 12459 printedAnything = true; 12460 } 12461 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12462 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12463 } 12464 } 12465 } 12466 12467 if (mPersistentStartingProcesses.size() > 0) { 12468 if (needSep) pw.println(); 12469 needSep = true; 12470 printedAnything = true; 12471 pw.println(" Persisent processes that are starting:"); 12472 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12473 "Starting Norm", "Restarting PERS", dumpPackage); 12474 } 12475 12476 if (mRemovedProcesses.size() > 0) { 12477 if (needSep) pw.println(); 12478 needSep = true; 12479 printedAnything = true; 12480 pw.println(" Processes that are being removed:"); 12481 dumpProcessList(pw, this, mRemovedProcesses, " ", 12482 "Removed Norm", "Removed PERS", dumpPackage); 12483 } 12484 12485 if (mProcessesOnHold.size() > 0) { 12486 if (needSep) pw.println(); 12487 needSep = true; 12488 printedAnything = true; 12489 pw.println(" Processes that are on old until the system is ready:"); 12490 dumpProcessList(pw, this, mProcessesOnHold, " ", 12491 "OnHold Norm", "OnHold PERS", dumpPackage); 12492 } 12493 12494 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12495 12496 if (mProcessCrashTimes.getMap().size() > 0) { 12497 boolean printed = false; 12498 long now = SystemClock.uptimeMillis(); 12499 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12500 final int NP = pmap.size(); 12501 for (int ip=0; ip<NP; ip++) { 12502 String pname = pmap.keyAt(ip); 12503 SparseArray<Long> uids = pmap.valueAt(ip); 12504 final int N = uids.size(); 12505 for (int i=0; i<N; i++) { 12506 int puid = uids.keyAt(i); 12507 ProcessRecord r = mProcessNames.get(pname, puid); 12508 if (dumpPackage != null && (r == null 12509 || !r.pkgList.containsKey(dumpPackage))) { 12510 continue; 12511 } 12512 if (!printed) { 12513 if (needSep) pw.println(); 12514 needSep = true; 12515 pw.println(" Time since processes crashed:"); 12516 printed = true; 12517 printedAnything = true; 12518 } 12519 pw.print(" Process "); pw.print(pname); 12520 pw.print(" uid "); pw.print(puid); 12521 pw.print(": last crashed "); 12522 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12523 pw.println(" ago"); 12524 } 12525 } 12526 } 12527 12528 if (mBadProcesses.getMap().size() > 0) { 12529 boolean printed = false; 12530 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12531 final int NP = pmap.size(); 12532 for (int ip=0; ip<NP; ip++) { 12533 String pname = pmap.keyAt(ip); 12534 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12535 final int N = uids.size(); 12536 for (int i=0; i<N; i++) { 12537 int puid = uids.keyAt(i); 12538 ProcessRecord r = mProcessNames.get(pname, puid); 12539 if (dumpPackage != null && (r == null 12540 || !r.pkgList.containsKey(dumpPackage))) { 12541 continue; 12542 } 12543 if (!printed) { 12544 if (needSep) pw.println(); 12545 needSep = true; 12546 pw.println(" Bad processes:"); 12547 printedAnything = true; 12548 } 12549 BadProcessInfo info = uids.valueAt(i); 12550 pw.print(" Bad process "); pw.print(pname); 12551 pw.print(" uid "); pw.print(puid); 12552 pw.print(": crashed at time "); pw.println(info.time); 12553 if (info.shortMsg != null) { 12554 pw.print(" Short msg: "); pw.println(info.shortMsg); 12555 } 12556 if (info.longMsg != null) { 12557 pw.print(" Long msg: "); pw.println(info.longMsg); 12558 } 12559 if (info.stack != null) { 12560 pw.println(" Stack:"); 12561 int lastPos = 0; 12562 for (int pos=0; pos<info.stack.length(); pos++) { 12563 if (info.stack.charAt(pos) == '\n') { 12564 pw.print(" "); 12565 pw.write(info.stack, lastPos, pos-lastPos); 12566 pw.println(); 12567 lastPos = pos+1; 12568 } 12569 } 12570 if (lastPos < info.stack.length()) { 12571 pw.print(" "); 12572 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12573 pw.println(); 12574 } 12575 } 12576 } 12577 } 12578 } 12579 12580 if (dumpPackage == null) { 12581 pw.println(); 12582 needSep = false; 12583 pw.println(" mStartedUsers:"); 12584 for (int i=0; i<mStartedUsers.size(); i++) { 12585 UserStartedState uss = mStartedUsers.valueAt(i); 12586 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12587 pw.print(": "); uss.dump("", pw); 12588 } 12589 pw.print(" mStartedUserArray: ["); 12590 for (int i=0; i<mStartedUserArray.length; i++) { 12591 if (i > 0) pw.print(", "); 12592 pw.print(mStartedUserArray[i]); 12593 } 12594 pw.println("]"); 12595 pw.print(" mUserLru: ["); 12596 for (int i=0; i<mUserLru.size(); i++) { 12597 if (i > 0) pw.print(", "); 12598 pw.print(mUserLru.get(i)); 12599 } 12600 pw.println("]"); 12601 if (dumpAll) { 12602 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12603 } 12604 synchronized (mUserProfileGroupIdsSelfLocked) { 12605 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12606 pw.println(" mUserProfileGroupIds:"); 12607 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12608 pw.print(" User #"); 12609 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12610 pw.print(" -> profile #"); 12611 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12612 } 12613 } 12614 } 12615 } 12616 if (mHomeProcess != null && (dumpPackage == null 12617 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12618 if (needSep) { 12619 pw.println(); 12620 needSep = false; 12621 } 12622 pw.println(" mHomeProcess: " + mHomeProcess); 12623 } 12624 if (mPreviousProcess != null && (dumpPackage == null 12625 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12626 if (needSep) { 12627 pw.println(); 12628 needSep = false; 12629 } 12630 pw.println(" mPreviousProcess: " + mPreviousProcess); 12631 } 12632 if (dumpAll) { 12633 StringBuilder sb = new StringBuilder(128); 12634 sb.append(" mPreviousProcessVisibleTime: "); 12635 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12636 pw.println(sb); 12637 } 12638 if (mHeavyWeightProcess != null && (dumpPackage == null 12639 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12640 if (needSep) { 12641 pw.println(); 12642 needSep = false; 12643 } 12644 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12645 } 12646 if (dumpPackage == null) { 12647 pw.println(" mConfiguration: " + mConfiguration); 12648 } 12649 if (dumpAll) { 12650 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12651 if (mCompatModePackages.getPackages().size() > 0) { 12652 boolean printed = false; 12653 for (Map.Entry<String, Integer> entry 12654 : mCompatModePackages.getPackages().entrySet()) { 12655 String pkg = entry.getKey(); 12656 int mode = entry.getValue(); 12657 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12658 continue; 12659 } 12660 if (!printed) { 12661 pw.println(" mScreenCompatPackages:"); 12662 printed = true; 12663 } 12664 pw.print(" "); pw.print(pkg); pw.print(": "); 12665 pw.print(mode); pw.println(); 12666 } 12667 } 12668 } 12669 if (dumpPackage == null) { 12670 if (mSleeping || mWentToSleep || mLockScreenShown) { 12671 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12672 + " mLockScreenShown " + mLockScreenShown); 12673 } 12674 if (mShuttingDown || mRunningVoice) { 12675 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12676 } 12677 } 12678 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12679 || mOrigWaitForDebugger) { 12680 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12681 || dumpPackage.equals(mOrigDebugApp)) { 12682 if (needSep) { 12683 pw.println(); 12684 needSep = false; 12685 } 12686 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12687 + " mDebugTransient=" + mDebugTransient 12688 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12689 } 12690 } 12691 if (mOpenGlTraceApp != null) { 12692 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12693 if (needSep) { 12694 pw.println(); 12695 needSep = false; 12696 } 12697 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12698 } 12699 } 12700 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12701 || mProfileFd != null) { 12702 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12703 if (needSep) { 12704 pw.println(); 12705 needSep = false; 12706 } 12707 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12708 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12709 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12710 + mAutoStopProfiler); 12711 pw.println(" mProfileType=" + mProfileType); 12712 } 12713 } 12714 if (dumpPackage == null) { 12715 if (mAlwaysFinishActivities || mController != null) { 12716 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12717 + " mController=" + mController); 12718 } 12719 if (dumpAll) { 12720 pw.println(" Total persistent processes: " + numPers); 12721 pw.println(" mProcessesReady=" + mProcessesReady 12722 + " mSystemReady=" + mSystemReady); 12723 pw.println(" mBooting=" + mBooting 12724 + " mBooted=" + mBooted 12725 + " mFactoryTest=" + mFactoryTest); 12726 pw.print(" mLastPowerCheckRealtime="); 12727 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12728 pw.println(""); 12729 pw.print(" mLastPowerCheckUptime="); 12730 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12731 pw.println(""); 12732 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12733 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12734 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12735 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12736 + " (" + mLruProcesses.size() + " total)" 12737 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12738 + " mNumServiceProcs=" + mNumServiceProcs 12739 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12740 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12741 + " mLastMemoryLevel" + mLastMemoryLevel 12742 + " mLastNumProcesses" + mLastNumProcesses); 12743 long now = SystemClock.uptimeMillis(); 12744 pw.print(" mLastIdleTime="); 12745 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12746 pw.print(" mLowRamSinceLastIdle="); 12747 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12748 pw.println(); 12749 } 12750 } 12751 12752 if (!printedAnything) { 12753 pw.println(" (nothing)"); 12754 } 12755 } 12756 12757 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12758 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12759 if (mProcessesToGc.size() > 0) { 12760 boolean printed = false; 12761 long now = SystemClock.uptimeMillis(); 12762 for (int i=0; i<mProcessesToGc.size(); i++) { 12763 ProcessRecord proc = mProcessesToGc.get(i); 12764 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12765 continue; 12766 } 12767 if (!printed) { 12768 if (needSep) pw.println(); 12769 needSep = true; 12770 pw.println(" Processes that are waiting to GC:"); 12771 printed = true; 12772 } 12773 pw.print(" Process "); pw.println(proc); 12774 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12775 pw.print(", last gced="); 12776 pw.print(now-proc.lastRequestedGc); 12777 pw.print(" ms ago, last lowMem="); 12778 pw.print(now-proc.lastLowMemory); 12779 pw.println(" ms ago"); 12780 12781 } 12782 } 12783 return needSep; 12784 } 12785 12786 void printOomLevel(PrintWriter pw, String name, int adj) { 12787 pw.print(" "); 12788 if (adj >= 0) { 12789 pw.print(' '); 12790 if (adj < 10) pw.print(' '); 12791 } else { 12792 if (adj > -10) pw.print(' '); 12793 } 12794 pw.print(adj); 12795 pw.print(": "); 12796 pw.print(name); 12797 pw.print(" ("); 12798 pw.print(mProcessList.getMemLevel(adj)/1024); 12799 pw.println(" kB)"); 12800 } 12801 12802 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12803 int opti, boolean dumpAll) { 12804 boolean needSep = false; 12805 12806 if (mLruProcesses.size() > 0) { 12807 if (needSep) pw.println(); 12808 needSep = true; 12809 pw.println(" OOM levels:"); 12810 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12811 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12812 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12813 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12814 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12815 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12816 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12817 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12818 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12819 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12820 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12821 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12822 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12823 12824 if (needSep) pw.println(); 12825 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12826 pw.print(" total, non-act at "); 12827 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12828 pw.print(", non-svc at "); 12829 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12830 pw.println("):"); 12831 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12832 needSep = true; 12833 } 12834 12835 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12836 12837 pw.println(); 12838 pw.println(" mHomeProcess: " + mHomeProcess); 12839 pw.println(" mPreviousProcess: " + mPreviousProcess); 12840 if (mHeavyWeightProcess != null) { 12841 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12842 } 12843 12844 return true; 12845 } 12846 12847 /** 12848 * There are three ways to call this: 12849 * - no provider specified: dump all the providers 12850 * - a flattened component name that matched an existing provider was specified as the 12851 * first arg: dump that one provider 12852 * - the first arg isn't the flattened component name of an existing provider: 12853 * dump all providers whose component contains the first arg as a substring 12854 */ 12855 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12856 int opti, boolean dumpAll) { 12857 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12858 } 12859 12860 static class ItemMatcher { 12861 ArrayList<ComponentName> components; 12862 ArrayList<String> strings; 12863 ArrayList<Integer> objects; 12864 boolean all; 12865 12866 ItemMatcher() { 12867 all = true; 12868 } 12869 12870 void build(String name) { 12871 ComponentName componentName = ComponentName.unflattenFromString(name); 12872 if (componentName != null) { 12873 if (components == null) { 12874 components = new ArrayList<ComponentName>(); 12875 } 12876 components.add(componentName); 12877 all = false; 12878 } else { 12879 int objectId = 0; 12880 // Not a '/' separated full component name; maybe an object ID? 12881 try { 12882 objectId = Integer.parseInt(name, 16); 12883 if (objects == null) { 12884 objects = new ArrayList<Integer>(); 12885 } 12886 objects.add(objectId); 12887 all = false; 12888 } catch (RuntimeException e) { 12889 // Not an integer; just do string match. 12890 if (strings == null) { 12891 strings = new ArrayList<String>(); 12892 } 12893 strings.add(name); 12894 all = false; 12895 } 12896 } 12897 } 12898 12899 int build(String[] args, int opti) { 12900 for (; opti<args.length; opti++) { 12901 String name = args[opti]; 12902 if ("--".equals(name)) { 12903 return opti+1; 12904 } 12905 build(name); 12906 } 12907 return opti; 12908 } 12909 12910 boolean match(Object object, ComponentName comp) { 12911 if (all) { 12912 return true; 12913 } 12914 if (components != null) { 12915 for (int i=0; i<components.size(); i++) { 12916 if (components.get(i).equals(comp)) { 12917 return true; 12918 } 12919 } 12920 } 12921 if (objects != null) { 12922 for (int i=0; i<objects.size(); i++) { 12923 if (System.identityHashCode(object) == objects.get(i)) { 12924 return true; 12925 } 12926 } 12927 } 12928 if (strings != null) { 12929 String flat = comp.flattenToString(); 12930 for (int i=0; i<strings.size(); i++) { 12931 if (flat.contains(strings.get(i))) { 12932 return true; 12933 } 12934 } 12935 } 12936 return false; 12937 } 12938 } 12939 12940 /** 12941 * There are three things that cmd can be: 12942 * - a flattened component name that matches an existing activity 12943 * - the cmd arg isn't the flattened component name of an existing activity: 12944 * dump all activity whose component contains the cmd as a substring 12945 * - A hex number of the ActivityRecord object instance. 12946 */ 12947 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12948 int opti, boolean dumpAll) { 12949 ArrayList<ActivityRecord> activities; 12950 12951 synchronized (this) { 12952 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12953 } 12954 12955 if (activities.size() <= 0) { 12956 return false; 12957 } 12958 12959 String[] newArgs = new String[args.length - opti]; 12960 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12961 12962 TaskRecord lastTask = null; 12963 boolean needSep = false; 12964 for (int i=activities.size()-1; i>=0; i--) { 12965 ActivityRecord r = activities.get(i); 12966 if (needSep) { 12967 pw.println(); 12968 } 12969 needSep = true; 12970 synchronized (this) { 12971 if (lastTask != r.task) { 12972 lastTask = r.task; 12973 pw.print("TASK "); pw.print(lastTask.affinity); 12974 pw.print(" id="); pw.println(lastTask.taskId); 12975 if (dumpAll) { 12976 lastTask.dump(pw, " "); 12977 } 12978 } 12979 } 12980 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12981 } 12982 return true; 12983 } 12984 12985 /** 12986 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12987 * there is a thread associated with the activity. 12988 */ 12989 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12990 final ActivityRecord r, String[] args, boolean dumpAll) { 12991 String innerPrefix = prefix + " "; 12992 synchronized (this) { 12993 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12994 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12995 pw.print(" pid="); 12996 if (r.app != null) pw.println(r.app.pid); 12997 else pw.println("(not running)"); 12998 if (dumpAll) { 12999 r.dump(pw, innerPrefix); 13000 } 13001 } 13002 if (r.app != null && r.app.thread != null) { 13003 // flush anything that is already in the PrintWriter since the thread is going 13004 // to write to the file descriptor directly 13005 pw.flush(); 13006 try { 13007 TransferPipe tp = new TransferPipe(); 13008 try { 13009 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13010 r.appToken, innerPrefix, args); 13011 tp.go(fd); 13012 } finally { 13013 tp.kill(); 13014 } 13015 } catch (IOException e) { 13016 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13017 } catch (RemoteException e) { 13018 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13019 } 13020 } 13021 } 13022 13023 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13024 int opti, boolean dumpAll, String dumpPackage) { 13025 boolean needSep = false; 13026 boolean onlyHistory = false; 13027 boolean printedAnything = false; 13028 13029 if ("history".equals(dumpPackage)) { 13030 if (opti < args.length && "-s".equals(args[opti])) { 13031 dumpAll = false; 13032 } 13033 onlyHistory = true; 13034 dumpPackage = null; 13035 } 13036 13037 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13038 if (!onlyHistory && dumpAll) { 13039 if (mRegisteredReceivers.size() > 0) { 13040 boolean printed = false; 13041 Iterator it = mRegisteredReceivers.values().iterator(); 13042 while (it.hasNext()) { 13043 ReceiverList r = (ReceiverList)it.next(); 13044 if (dumpPackage != null && (r.app == null || 13045 !dumpPackage.equals(r.app.info.packageName))) { 13046 continue; 13047 } 13048 if (!printed) { 13049 pw.println(" Registered Receivers:"); 13050 needSep = true; 13051 printed = true; 13052 printedAnything = true; 13053 } 13054 pw.print(" * "); pw.println(r); 13055 r.dump(pw, " "); 13056 } 13057 } 13058 13059 if (mReceiverResolver.dump(pw, needSep ? 13060 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13061 " ", dumpPackage, false)) { 13062 needSep = true; 13063 printedAnything = true; 13064 } 13065 } 13066 13067 for (BroadcastQueue q : mBroadcastQueues) { 13068 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13069 printedAnything |= needSep; 13070 } 13071 13072 needSep = true; 13073 13074 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13075 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13076 if (needSep) { 13077 pw.println(); 13078 } 13079 needSep = true; 13080 printedAnything = true; 13081 pw.print(" Sticky broadcasts for user "); 13082 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13083 StringBuilder sb = new StringBuilder(128); 13084 for (Map.Entry<String, ArrayList<Intent>> ent 13085 : mStickyBroadcasts.valueAt(user).entrySet()) { 13086 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13087 if (dumpAll) { 13088 pw.println(":"); 13089 ArrayList<Intent> intents = ent.getValue(); 13090 final int N = intents.size(); 13091 for (int i=0; i<N; i++) { 13092 sb.setLength(0); 13093 sb.append(" Intent: "); 13094 intents.get(i).toShortString(sb, false, true, false, false); 13095 pw.println(sb.toString()); 13096 Bundle bundle = intents.get(i).getExtras(); 13097 if (bundle != null) { 13098 pw.print(" "); 13099 pw.println(bundle.toString()); 13100 } 13101 } 13102 } else { 13103 pw.println(""); 13104 } 13105 } 13106 } 13107 } 13108 13109 if (!onlyHistory && dumpAll) { 13110 pw.println(); 13111 for (BroadcastQueue queue : mBroadcastQueues) { 13112 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13113 + queue.mBroadcastsScheduled); 13114 } 13115 pw.println(" mHandler:"); 13116 mHandler.dump(new PrintWriterPrinter(pw), " "); 13117 needSep = true; 13118 printedAnything = true; 13119 } 13120 13121 if (!printedAnything) { 13122 pw.println(" (nothing)"); 13123 } 13124 } 13125 13126 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13127 int opti, boolean dumpAll, String dumpPackage) { 13128 boolean needSep; 13129 boolean printedAnything = false; 13130 13131 ItemMatcher matcher = new ItemMatcher(); 13132 matcher.build(args, opti); 13133 13134 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13135 13136 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13137 printedAnything |= needSep; 13138 13139 if (mLaunchingProviders.size() > 0) { 13140 boolean printed = false; 13141 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13142 ContentProviderRecord r = mLaunchingProviders.get(i); 13143 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13144 continue; 13145 } 13146 if (!printed) { 13147 if (needSep) pw.println(); 13148 needSep = true; 13149 pw.println(" Launching content providers:"); 13150 printed = true; 13151 printedAnything = true; 13152 } 13153 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13154 pw.println(r); 13155 } 13156 } 13157 13158 if (mGrantedUriPermissions.size() > 0) { 13159 boolean printed = false; 13160 int dumpUid = -2; 13161 if (dumpPackage != null) { 13162 try { 13163 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13164 } catch (NameNotFoundException e) { 13165 dumpUid = -1; 13166 } 13167 } 13168 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13169 int uid = mGrantedUriPermissions.keyAt(i); 13170 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13171 continue; 13172 } 13173 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13174 if (!printed) { 13175 if (needSep) pw.println(); 13176 needSep = true; 13177 pw.println(" Granted Uri Permissions:"); 13178 printed = true; 13179 printedAnything = true; 13180 } 13181 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13182 for (UriPermission perm : perms.values()) { 13183 pw.print(" "); pw.println(perm); 13184 if (dumpAll) { 13185 perm.dump(pw, " "); 13186 } 13187 } 13188 } 13189 } 13190 13191 if (!printedAnything) { 13192 pw.println(" (nothing)"); 13193 } 13194 } 13195 13196 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13197 int opti, boolean dumpAll, String dumpPackage) { 13198 boolean printed = false; 13199 13200 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13201 13202 if (mIntentSenderRecords.size() > 0) { 13203 Iterator<WeakReference<PendingIntentRecord>> it 13204 = mIntentSenderRecords.values().iterator(); 13205 while (it.hasNext()) { 13206 WeakReference<PendingIntentRecord> ref = it.next(); 13207 PendingIntentRecord rec = ref != null ? ref.get(): null; 13208 if (dumpPackage != null && (rec == null 13209 || !dumpPackage.equals(rec.key.packageName))) { 13210 continue; 13211 } 13212 printed = true; 13213 if (rec != null) { 13214 pw.print(" * "); pw.println(rec); 13215 if (dumpAll) { 13216 rec.dump(pw, " "); 13217 } 13218 } else { 13219 pw.print(" * "); pw.println(ref); 13220 } 13221 } 13222 } 13223 13224 if (!printed) { 13225 pw.println(" (nothing)"); 13226 } 13227 } 13228 13229 private static final int dumpProcessList(PrintWriter pw, 13230 ActivityManagerService service, List list, 13231 String prefix, String normalLabel, String persistentLabel, 13232 String dumpPackage) { 13233 int numPers = 0; 13234 final int N = list.size()-1; 13235 for (int i=N; i>=0; i--) { 13236 ProcessRecord r = (ProcessRecord)list.get(i); 13237 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13238 continue; 13239 } 13240 pw.println(String.format("%s%s #%2d: %s", 13241 prefix, (r.persistent ? persistentLabel : normalLabel), 13242 i, r.toString())); 13243 if (r.persistent) { 13244 numPers++; 13245 } 13246 } 13247 return numPers; 13248 } 13249 13250 private static final boolean dumpProcessOomList(PrintWriter pw, 13251 ActivityManagerService service, List<ProcessRecord> origList, 13252 String prefix, String normalLabel, String persistentLabel, 13253 boolean inclDetails, String dumpPackage) { 13254 13255 ArrayList<Pair<ProcessRecord, Integer>> list 13256 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13257 for (int i=0; i<origList.size(); i++) { 13258 ProcessRecord r = origList.get(i); 13259 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13260 continue; 13261 } 13262 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13263 } 13264 13265 if (list.size() <= 0) { 13266 return false; 13267 } 13268 13269 Comparator<Pair<ProcessRecord, Integer>> comparator 13270 = new Comparator<Pair<ProcessRecord, Integer>>() { 13271 @Override 13272 public int compare(Pair<ProcessRecord, Integer> object1, 13273 Pair<ProcessRecord, Integer> object2) { 13274 if (object1.first.setAdj != object2.first.setAdj) { 13275 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13276 } 13277 if (object1.second.intValue() != object2.second.intValue()) { 13278 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13279 } 13280 return 0; 13281 } 13282 }; 13283 13284 Collections.sort(list, comparator); 13285 13286 final long curRealtime = SystemClock.elapsedRealtime(); 13287 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13288 final long curUptime = SystemClock.uptimeMillis(); 13289 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13290 13291 for (int i=list.size()-1; i>=0; i--) { 13292 ProcessRecord r = list.get(i).first; 13293 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13294 char schedGroup; 13295 switch (r.setSchedGroup) { 13296 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13297 schedGroup = 'B'; 13298 break; 13299 case Process.THREAD_GROUP_DEFAULT: 13300 schedGroup = 'F'; 13301 break; 13302 default: 13303 schedGroup = '?'; 13304 break; 13305 } 13306 char foreground; 13307 if (r.foregroundActivities) { 13308 foreground = 'A'; 13309 } else if (r.foregroundServices) { 13310 foreground = 'S'; 13311 } else { 13312 foreground = ' '; 13313 } 13314 String procState = ProcessList.makeProcStateString(r.curProcState); 13315 pw.print(prefix); 13316 pw.print(r.persistent ? persistentLabel : normalLabel); 13317 pw.print(" #"); 13318 int num = (origList.size()-1)-list.get(i).second; 13319 if (num < 10) pw.print(' '); 13320 pw.print(num); 13321 pw.print(": "); 13322 pw.print(oomAdj); 13323 pw.print(' '); 13324 pw.print(schedGroup); 13325 pw.print('/'); 13326 pw.print(foreground); 13327 pw.print('/'); 13328 pw.print(procState); 13329 pw.print(" trm:"); 13330 if (r.trimMemoryLevel < 10) pw.print(' '); 13331 pw.print(r.trimMemoryLevel); 13332 pw.print(' '); 13333 pw.print(r.toShortString()); 13334 pw.print(" ("); 13335 pw.print(r.adjType); 13336 pw.println(')'); 13337 if (r.adjSource != null || r.adjTarget != null) { 13338 pw.print(prefix); 13339 pw.print(" "); 13340 if (r.adjTarget instanceof ComponentName) { 13341 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13342 } else if (r.adjTarget != null) { 13343 pw.print(r.adjTarget.toString()); 13344 } else { 13345 pw.print("{null}"); 13346 } 13347 pw.print("<="); 13348 if (r.adjSource instanceof ProcessRecord) { 13349 pw.print("Proc{"); 13350 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13351 pw.println("}"); 13352 } else if (r.adjSource != null) { 13353 pw.println(r.adjSource.toString()); 13354 } else { 13355 pw.println("{null}"); 13356 } 13357 } 13358 if (inclDetails) { 13359 pw.print(prefix); 13360 pw.print(" "); 13361 pw.print("oom: max="); pw.print(r.maxAdj); 13362 pw.print(" curRaw="); pw.print(r.curRawAdj); 13363 pw.print(" setRaw="); pw.print(r.setRawAdj); 13364 pw.print(" cur="); pw.print(r.curAdj); 13365 pw.print(" set="); pw.println(r.setAdj); 13366 pw.print(prefix); 13367 pw.print(" "); 13368 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13369 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13370 pw.print(" lastPss="); pw.print(r.lastPss); 13371 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13372 pw.print(prefix); 13373 pw.print(" "); 13374 pw.print("cached="); pw.print(r.cached); 13375 pw.print(" empty="); pw.print(r.empty); 13376 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13377 13378 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13379 if (r.lastWakeTime != 0) { 13380 long wtime; 13381 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13382 synchronized (stats) { 13383 wtime = stats.getProcessWakeTime(r.info.uid, 13384 r.pid, curRealtime); 13385 } 13386 long timeUsed = wtime - r.lastWakeTime; 13387 pw.print(prefix); 13388 pw.print(" "); 13389 pw.print("keep awake over "); 13390 TimeUtils.formatDuration(realtimeSince, pw); 13391 pw.print(" used "); 13392 TimeUtils.formatDuration(timeUsed, pw); 13393 pw.print(" ("); 13394 pw.print((timeUsed*100)/realtimeSince); 13395 pw.println("%)"); 13396 } 13397 if (r.lastCpuTime != 0) { 13398 long timeUsed = r.curCpuTime - r.lastCpuTime; 13399 pw.print(prefix); 13400 pw.print(" "); 13401 pw.print("run cpu over "); 13402 TimeUtils.formatDuration(uptimeSince, pw); 13403 pw.print(" used "); 13404 TimeUtils.formatDuration(timeUsed, pw); 13405 pw.print(" ("); 13406 pw.print((timeUsed*100)/uptimeSince); 13407 pw.println("%)"); 13408 } 13409 } 13410 } 13411 } 13412 return true; 13413 } 13414 13415 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13416 ArrayList<ProcessRecord> procs; 13417 synchronized (this) { 13418 if (args != null && args.length > start 13419 && args[start].charAt(0) != '-') { 13420 procs = new ArrayList<ProcessRecord>(); 13421 int pid = -1; 13422 try { 13423 pid = Integer.parseInt(args[start]); 13424 } catch (NumberFormatException e) { 13425 } 13426 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13427 ProcessRecord proc = mLruProcesses.get(i); 13428 if (proc.pid == pid) { 13429 procs.add(proc); 13430 } else if (proc.processName.equals(args[start])) { 13431 procs.add(proc); 13432 } 13433 } 13434 if (procs.size() <= 0) { 13435 return null; 13436 } 13437 } else { 13438 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13439 } 13440 } 13441 return procs; 13442 } 13443 13444 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13445 PrintWriter pw, String[] args) { 13446 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13447 if (procs == null) { 13448 pw.println("No process found for: " + args[0]); 13449 return; 13450 } 13451 13452 long uptime = SystemClock.uptimeMillis(); 13453 long realtime = SystemClock.elapsedRealtime(); 13454 pw.println("Applications Graphics Acceleration Info:"); 13455 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13456 13457 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13458 ProcessRecord r = procs.get(i); 13459 if (r.thread != null) { 13460 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13461 pw.flush(); 13462 try { 13463 TransferPipe tp = new TransferPipe(); 13464 try { 13465 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13466 tp.go(fd); 13467 } finally { 13468 tp.kill(); 13469 } 13470 } catch (IOException e) { 13471 pw.println("Failure while dumping the app: " + r); 13472 pw.flush(); 13473 } catch (RemoteException e) { 13474 pw.println("Got a RemoteException while dumping the app " + r); 13475 pw.flush(); 13476 } 13477 } 13478 } 13479 } 13480 13481 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13482 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13483 if (procs == null) { 13484 pw.println("No process found for: " + args[0]); 13485 return; 13486 } 13487 13488 pw.println("Applications Database Info:"); 13489 13490 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13491 ProcessRecord r = procs.get(i); 13492 if (r.thread != null) { 13493 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13494 pw.flush(); 13495 try { 13496 TransferPipe tp = new TransferPipe(); 13497 try { 13498 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13499 tp.go(fd); 13500 } finally { 13501 tp.kill(); 13502 } 13503 } catch (IOException e) { 13504 pw.println("Failure while dumping the app: " + r); 13505 pw.flush(); 13506 } catch (RemoteException e) { 13507 pw.println("Got a RemoteException while dumping the app " + r); 13508 pw.flush(); 13509 } 13510 } 13511 } 13512 } 13513 13514 final static class MemItem { 13515 final boolean isProc; 13516 final String label; 13517 final String shortLabel; 13518 final long pss; 13519 final int id; 13520 final boolean hasActivities; 13521 ArrayList<MemItem> subitems; 13522 13523 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13524 boolean _hasActivities) { 13525 isProc = true; 13526 label = _label; 13527 shortLabel = _shortLabel; 13528 pss = _pss; 13529 id = _id; 13530 hasActivities = _hasActivities; 13531 } 13532 13533 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13534 isProc = false; 13535 label = _label; 13536 shortLabel = _shortLabel; 13537 pss = _pss; 13538 id = _id; 13539 hasActivities = false; 13540 } 13541 } 13542 13543 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13544 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13545 if (sort && !isCompact) { 13546 Collections.sort(items, new Comparator<MemItem>() { 13547 @Override 13548 public int compare(MemItem lhs, MemItem rhs) { 13549 if (lhs.pss < rhs.pss) { 13550 return 1; 13551 } else if (lhs.pss > rhs.pss) { 13552 return -1; 13553 } 13554 return 0; 13555 } 13556 }); 13557 } 13558 13559 for (int i=0; i<items.size(); i++) { 13560 MemItem mi = items.get(i); 13561 if (!isCompact) { 13562 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13563 } else if (mi.isProc) { 13564 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13565 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13566 pw.println(mi.hasActivities ? ",a" : ",e"); 13567 } else { 13568 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13569 pw.println(mi.pss); 13570 } 13571 if (mi.subitems != null) { 13572 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13573 true, isCompact); 13574 } 13575 } 13576 } 13577 13578 // These are in KB. 13579 static final long[] DUMP_MEM_BUCKETS = new long[] { 13580 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13581 120*1024, 160*1024, 200*1024, 13582 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13583 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13584 }; 13585 13586 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13587 boolean stackLike) { 13588 int start = label.lastIndexOf('.'); 13589 if (start >= 0) start++; 13590 else start = 0; 13591 int end = label.length(); 13592 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13593 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13594 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13595 out.append(bucket); 13596 out.append(stackLike ? "MB." : "MB "); 13597 out.append(label, start, end); 13598 return; 13599 } 13600 } 13601 out.append(memKB/1024); 13602 out.append(stackLike ? "MB." : "MB "); 13603 out.append(label, start, end); 13604 } 13605 13606 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13607 ProcessList.NATIVE_ADJ, 13608 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13609 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13610 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13611 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13612 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13613 }; 13614 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13615 "Native", 13616 "System", "Persistent", "Foreground", 13617 "Visible", "Perceptible", 13618 "Heavy Weight", "Backup", 13619 "A Services", "Home", 13620 "Previous", "B Services", "Cached" 13621 }; 13622 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13623 "native", 13624 "sys", "pers", "fore", 13625 "vis", "percept", 13626 "heavy", "backup", 13627 "servicea", "home", 13628 "prev", "serviceb", "cached" 13629 }; 13630 13631 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13632 long realtime, boolean isCheckinRequest, boolean isCompact) { 13633 if (isCheckinRequest || isCompact) { 13634 // short checkin version 13635 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13636 } else { 13637 pw.println("Applications Memory Usage (kB):"); 13638 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13639 } 13640 } 13641 13642 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13643 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13644 boolean dumpDetails = false; 13645 boolean dumpFullDetails = false; 13646 boolean dumpDalvik = false; 13647 boolean oomOnly = false; 13648 boolean isCompact = false; 13649 boolean localOnly = false; 13650 13651 int opti = 0; 13652 while (opti < args.length) { 13653 String opt = args[opti]; 13654 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13655 break; 13656 } 13657 opti++; 13658 if ("-a".equals(opt)) { 13659 dumpDetails = true; 13660 dumpFullDetails = true; 13661 dumpDalvik = true; 13662 } else if ("-d".equals(opt)) { 13663 dumpDalvik = true; 13664 } else if ("-c".equals(opt)) { 13665 isCompact = true; 13666 } else if ("--oom".equals(opt)) { 13667 oomOnly = true; 13668 } else if ("--local".equals(opt)) { 13669 localOnly = true; 13670 } else if ("-h".equals(opt)) { 13671 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13672 pw.println(" -a: include all available information for each process."); 13673 pw.println(" -d: include dalvik details when dumping process details."); 13674 pw.println(" -c: dump in a compact machine-parseable representation."); 13675 pw.println(" --oom: only show processes organized by oom adj."); 13676 pw.println(" --local: only collect details locally, don't call process."); 13677 pw.println("If [process] is specified it can be the name or "); 13678 pw.println("pid of a specific process to dump."); 13679 return; 13680 } else { 13681 pw.println("Unknown argument: " + opt + "; use -h for help"); 13682 } 13683 } 13684 13685 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13686 long uptime = SystemClock.uptimeMillis(); 13687 long realtime = SystemClock.elapsedRealtime(); 13688 final long[] tmpLong = new long[1]; 13689 13690 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13691 if (procs == null) { 13692 // No Java processes. Maybe they want to print a native process. 13693 if (args != null && args.length > opti 13694 && args[opti].charAt(0) != '-') { 13695 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13696 = new ArrayList<ProcessCpuTracker.Stats>(); 13697 updateCpuStatsNow(); 13698 int findPid = -1; 13699 try { 13700 findPid = Integer.parseInt(args[opti]); 13701 } catch (NumberFormatException e) { 13702 } 13703 synchronized (mProcessCpuThread) { 13704 final int N = mProcessCpuTracker.countStats(); 13705 for (int i=0; i<N; i++) { 13706 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13707 if (st.pid == findPid || (st.baseName != null 13708 && st.baseName.equals(args[opti]))) { 13709 nativeProcs.add(st); 13710 } 13711 } 13712 } 13713 if (nativeProcs.size() > 0) { 13714 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13715 isCompact); 13716 Debug.MemoryInfo mi = null; 13717 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13718 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13719 final int pid = r.pid; 13720 if (!isCheckinRequest && dumpDetails) { 13721 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13722 } 13723 if (mi == null) { 13724 mi = new Debug.MemoryInfo(); 13725 } 13726 if (dumpDetails || (!brief && !oomOnly)) { 13727 Debug.getMemoryInfo(pid, mi); 13728 } else { 13729 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13730 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13731 } 13732 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13733 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13734 if (isCheckinRequest) { 13735 pw.println(); 13736 } 13737 } 13738 return; 13739 } 13740 } 13741 pw.println("No process found for: " + args[opti]); 13742 return; 13743 } 13744 13745 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13746 dumpDetails = true; 13747 } 13748 13749 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13750 13751 String[] innerArgs = new String[args.length-opti]; 13752 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13753 13754 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13755 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13756 long nativePss=0, dalvikPss=0, otherPss=0; 13757 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13758 13759 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13760 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13761 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13762 13763 long totalPss = 0; 13764 long cachedPss = 0; 13765 13766 Debug.MemoryInfo mi = null; 13767 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13768 final ProcessRecord r = procs.get(i); 13769 final IApplicationThread thread; 13770 final int pid; 13771 final int oomAdj; 13772 final boolean hasActivities; 13773 synchronized (this) { 13774 thread = r.thread; 13775 pid = r.pid; 13776 oomAdj = r.getSetAdjWithServices(); 13777 hasActivities = r.activities.size() > 0; 13778 } 13779 if (thread != null) { 13780 if (!isCheckinRequest && dumpDetails) { 13781 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13782 } 13783 if (mi == null) { 13784 mi = new Debug.MemoryInfo(); 13785 } 13786 if (dumpDetails || (!brief && !oomOnly)) { 13787 Debug.getMemoryInfo(pid, mi); 13788 } else { 13789 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13790 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13791 } 13792 if (dumpDetails) { 13793 if (localOnly) { 13794 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13795 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13796 if (isCheckinRequest) { 13797 pw.println(); 13798 } 13799 } else { 13800 try { 13801 pw.flush(); 13802 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13803 dumpDalvik, innerArgs); 13804 } catch (RemoteException e) { 13805 if (!isCheckinRequest) { 13806 pw.println("Got RemoteException!"); 13807 pw.flush(); 13808 } 13809 } 13810 } 13811 } 13812 13813 final long myTotalPss = mi.getTotalPss(); 13814 final long myTotalUss = mi.getTotalUss(); 13815 13816 synchronized (this) { 13817 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13818 // Record this for posterity if the process has been stable. 13819 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13820 } 13821 } 13822 13823 if (!isCheckinRequest && mi != null) { 13824 totalPss += myTotalPss; 13825 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13826 (hasActivities ? " / activities)" : ")"), 13827 r.processName, myTotalPss, pid, hasActivities); 13828 procMems.add(pssItem); 13829 procMemsMap.put(pid, pssItem); 13830 13831 nativePss += mi.nativePss; 13832 dalvikPss += mi.dalvikPss; 13833 otherPss += mi.otherPss; 13834 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13835 long mem = mi.getOtherPss(j); 13836 miscPss[j] += mem; 13837 otherPss -= mem; 13838 } 13839 13840 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13841 cachedPss += myTotalPss; 13842 } 13843 13844 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13845 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13846 || oomIndex == (oomPss.length-1)) { 13847 oomPss[oomIndex] += myTotalPss; 13848 if (oomProcs[oomIndex] == null) { 13849 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13850 } 13851 oomProcs[oomIndex].add(pssItem); 13852 break; 13853 } 13854 } 13855 } 13856 } 13857 } 13858 13859 long nativeProcTotalPss = 0; 13860 13861 if (!isCheckinRequest && procs.size() > 1) { 13862 // If we are showing aggregations, also look for native processes to 13863 // include so that our aggregations are more accurate. 13864 updateCpuStatsNow(); 13865 synchronized (mProcessCpuThread) { 13866 final int N = mProcessCpuTracker.countStats(); 13867 for (int i=0; i<N; i++) { 13868 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13869 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13870 if (mi == null) { 13871 mi = new Debug.MemoryInfo(); 13872 } 13873 if (!brief && !oomOnly) { 13874 Debug.getMemoryInfo(st.pid, mi); 13875 } else { 13876 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13877 mi.nativePrivateDirty = (int)tmpLong[0]; 13878 } 13879 13880 final long myTotalPss = mi.getTotalPss(); 13881 totalPss += myTotalPss; 13882 nativeProcTotalPss += myTotalPss; 13883 13884 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13885 st.name, myTotalPss, st.pid, false); 13886 procMems.add(pssItem); 13887 13888 nativePss += mi.nativePss; 13889 dalvikPss += mi.dalvikPss; 13890 otherPss += mi.otherPss; 13891 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13892 long mem = mi.getOtherPss(j); 13893 miscPss[j] += mem; 13894 otherPss -= mem; 13895 } 13896 oomPss[0] += myTotalPss; 13897 if (oomProcs[0] == null) { 13898 oomProcs[0] = new ArrayList<MemItem>(); 13899 } 13900 oomProcs[0].add(pssItem); 13901 } 13902 } 13903 } 13904 13905 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13906 13907 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13908 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13909 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13910 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13911 String label = Debug.MemoryInfo.getOtherLabel(j); 13912 catMems.add(new MemItem(label, label, miscPss[j], j)); 13913 } 13914 13915 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13916 for (int j=0; j<oomPss.length; j++) { 13917 if (oomPss[j] != 0) { 13918 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13919 : DUMP_MEM_OOM_LABEL[j]; 13920 MemItem item = new MemItem(label, label, oomPss[j], 13921 DUMP_MEM_OOM_ADJ[j]); 13922 item.subitems = oomProcs[j]; 13923 oomMems.add(item); 13924 } 13925 } 13926 13927 if (!brief && !oomOnly && !isCompact) { 13928 pw.println(); 13929 pw.println("Total PSS by process:"); 13930 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13931 pw.println(); 13932 } 13933 if (!isCompact) { 13934 pw.println("Total PSS by OOM adjustment:"); 13935 } 13936 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13937 if (!brief && !oomOnly) { 13938 PrintWriter out = categoryPw != null ? categoryPw : pw; 13939 if (!isCompact) { 13940 out.println(); 13941 out.println("Total PSS by category:"); 13942 } 13943 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13944 } 13945 if (!isCompact) { 13946 pw.println(); 13947 } 13948 MemInfoReader memInfo = new MemInfoReader(); 13949 memInfo.readMemInfo(); 13950 if (nativeProcTotalPss > 0) { 13951 synchronized (this) { 13952 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13953 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13954 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13955 nativeProcTotalPss); 13956 } 13957 } 13958 if (!brief) { 13959 if (!isCompact) { 13960 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13961 pw.print(" kB (status "); 13962 switch (mLastMemoryLevel) { 13963 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13964 pw.println("normal)"); 13965 break; 13966 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13967 pw.println("moderate)"); 13968 break; 13969 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13970 pw.println("low)"); 13971 break; 13972 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13973 pw.println("critical)"); 13974 break; 13975 default: 13976 pw.print(mLastMemoryLevel); 13977 pw.println(")"); 13978 break; 13979 } 13980 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13981 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13982 pw.print(cachedPss); pw.print(" cached pss + "); 13983 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13984 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13985 } else { 13986 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13987 pw.print(cachedPss + memInfo.getCachedSizeKb() 13988 + memInfo.getFreeSizeKb()); pw.print(","); 13989 pw.println(totalPss - cachedPss); 13990 } 13991 } 13992 if (!isCompact) { 13993 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13994 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13995 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13996 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13997 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13998 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13999 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14000 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14001 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14002 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14003 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14004 } 14005 if (!brief) { 14006 if (memInfo.getZramTotalSizeKb() != 0) { 14007 if (!isCompact) { 14008 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14009 pw.print(" kB physical used for "); 14010 pw.print(memInfo.getSwapTotalSizeKb() 14011 - memInfo.getSwapFreeSizeKb()); 14012 pw.print(" kB in swap ("); 14013 pw.print(memInfo.getSwapTotalSizeKb()); 14014 pw.println(" kB total swap)"); 14015 } else { 14016 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14017 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14018 pw.println(memInfo.getSwapFreeSizeKb()); 14019 } 14020 } 14021 final int[] SINGLE_LONG_FORMAT = new int[] { 14022 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14023 }; 14024 long[] longOut = new long[1]; 14025 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14026 SINGLE_LONG_FORMAT, null, longOut, null); 14027 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14028 longOut[0] = 0; 14029 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14030 SINGLE_LONG_FORMAT, null, longOut, null); 14031 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14032 longOut[0] = 0; 14033 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14034 SINGLE_LONG_FORMAT, null, longOut, null); 14035 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14036 longOut[0] = 0; 14037 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14038 SINGLE_LONG_FORMAT, null, longOut, null); 14039 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14040 if (!isCompact) { 14041 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14042 pw.print(" KSM: "); pw.print(sharing); 14043 pw.print(" kB saved from shared "); 14044 pw.print(shared); pw.println(" kB"); 14045 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14046 pw.print(voltile); pw.println(" kB volatile"); 14047 } 14048 pw.print(" Tuning: "); 14049 pw.print(ActivityManager.staticGetMemoryClass()); 14050 pw.print(" (large "); 14051 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14052 pw.print("), oom "); 14053 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14054 pw.print(" kB"); 14055 pw.print(", restore limit "); 14056 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14057 pw.print(" kB"); 14058 if (ActivityManager.isLowRamDeviceStatic()) { 14059 pw.print(" (low-ram)"); 14060 } 14061 if (ActivityManager.isHighEndGfx()) { 14062 pw.print(" (high-end-gfx)"); 14063 } 14064 pw.println(); 14065 } else { 14066 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14067 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14068 pw.println(voltile); 14069 pw.print("tuning,"); 14070 pw.print(ActivityManager.staticGetMemoryClass()); 14071 pw.print(','); 14072 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14073 pw.print(','); 14074 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14075 if (ActivityManager.isLowRamDeviceStatic()) { 14076 pw.print(",low-ram"); 14077 } 14078 if (ActivityManager.isHighEndGfx()) { 14079 pw.print(",high-end-gfx"); 14080 } 14081 pw.println(); 14082 } 14083 } 14084 } 14085 } 14086 14087 /** 14088 * Searches array of arguments for the specified string 14089 * @param args array of argument strings 14090 * @param value value to search for 14091 * @return true if the value is contained in the array 14092 */ 14093 private static boolean scanArgs(String[] args, String value) { 14094 if (args != null) { 14095 for (String arg : args) { 14096 if (value.equals(arg)) { 14097 return true; 14098 } 14099 } 14100 } 14101 return false; 14102 } 14103 14104 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14105 ContentProviderRecord cpr, boolean always) { 14106 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14107 14108 if (!inLaunching || always) { 14109 synchronized (cpr) { 14110 cpr.launchingApp = null; 14111 cpr.notifyAll(); 14112 } 14113 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14114 String names[] = cpr.info.authority.split(";"); 14115 for (int j = 0; j < names.length; j++) { 14116 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14117 } 14118 } 14119 14120 for (int i=0; i<cpr.connections.size(); i++) { 14121 ContentProviderConnection conn = cpr.connections.get(i); 14122 if (conn.waiting) { 14123 // If this connection is waiting for the provider, then we don't 14124 // need to mess with its process unless we are always removing 14125 // or for some reason the provider is not currently launching. 14126 if (inLaunching && !always) { 14127 continue; 14128 } 14129 } 14130 ProcessRecord capp = conn.client; 14131 conn.dead = true; 14132 if (conn.stableCount > 0) { 14133 if (!capp.persistent && capp.thread != null 14134 && capp.pid != 0 14135 && capp.pid != MY_PID) { 14136 capp.kill("depends on provider " 14137 + cpr.name.flattenToShortString() 14138 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14139 } 14140 } else if (capp.thread != null && conn.provider.provider != null) { 14141 try { 14142 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14143 } catch (RemoteException e) { 14144 } 14145 // In the protocol here, we don't expect the client to correctly 14146 // clean up this connection, we'll just remove it. 14147 cpr.connections.remove(i); 14148 conn.client.conProviders.remove(conn); 14149 } 14150 } 14151 14152 if (inLaunching && always) { 14153 mLaunchingProviders.remove(cpr); 14154 } 14155 return inLaunching; 14156 } 14157 14158 /** 14159 * Main code for cleaning up a process when it has gone away. This is 14160 * called both as a result of the process dying, or directly when stopping 14161 * a process when running in single process mode. 14162 */ 14163 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14164 boolean restarting, boolean allowRestart, int index) { 14165 if (index >= 0) { 14166 removeLruProcessLocked(app); 14167 ProcessList.remove(app.pid); 14168 } 14169 14170 mProcessesToGc.remove(app); 14171 mPendingPssProcesses.remove(app); 14172 14173 // Dismiss any open dialogs. 14174 if (app.crashDialog != null && !app.forceCrashReport) { 14175 app.crashDialog.dismiss(); 14176 app.crashDialog = null; 14177 } 14178 if (app.anrDialog != null) { 14179 app.anrDialog.dismiss(); 14180 app.anrDialog = null; 14181 } 14182 if (app.waitDialog != null) { 14183 app.waitDialog.dismiss(); 14184 app.waitDialog = null; 14185 } 14186 14187 app.crashing = false; 14188 app.notResponding = false; 14189 14190 app.resetPackageList(mProcessStats); 14191 app.unlinkDeathRecipient(); 14192 app.makeInactive(mProcessStats); 14193 app.waitingToKill = null; 14194 app.forcingToForeground = null; 14195 updateProcessForegroundLocked(app, false, false); 14196 app.foregroundActivities = false; 14197 app.hasShownUi = false; 14198 app.treatLikeActivity = false; 14199 app.hasAboveClient = false; 14200 app.hasClientActivities = false; 14201 14202 mServices.killServicesLocked(app, allowRestart); 14203 14204 boolean restart = false; 14205 14206 // Remove published content providers. 14207 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14208 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14209 final boolean always = app.bad || !allowRestart; 14210 if (removeDyingProviderLocked(app, cpr, always) || always) { 14211 // We left the provider in the launching list, need to 14212 // restart it. 14213 restart = true; 14214 } 14215 14216 cpr.provider = null; 14217 cpr.proc = null; 14218 } 14219 app.pubProviders.clear(); 14220 14221 // Take care of any launching providers waiting for this process. 14222 if (checkAppInLaunchingProvidersLocked(app, false)) { 14223 restart = true; 14224 } 14225 14226 // Unregister from connected content providers. 14227 if (!app.conProviders.isEmpty()) { 14228 for (int i=0; i<app.conProviders.size(); i++) { 14229 ContentProviderConnection conn = app.conProviders.get(i); 14230 conn.provider.connections.remove(conn); 14231 } 14232 app.conProviders.clear(); 14233 } 14234 14235 // At this point there may be remaining entries in mLaunchingProviders 14236 // where we were the only one waiting, so they are no longer of use. 14237 // Look for these and clean up if found. 14238 // XXX Commented out for now. Trying to figure out a way to reproduce 14239 // the actual situation to identify what is actually going on. 14240 if (false) { 14241 for (int i=0; i<mLaunchingProviders.size(); i++) { 14242 ContentProviderRecord cpr = (ContentProviderRecord) 14243 mLaunchingProviders.get(i); 14244 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14245 synchronized (cpr) { 14246 cpr.launchingApp = null; 14247 cpr.notifyAll(); 14248 } 14249 } 14250 } 14251 } 14252 14253 skipCurrentReceiverLocked(app); 14254 14255 // Unregister any receivers. 14256 for (int i=app.receivers.size()-1; i>=0; i--) { 14257 removeReceiverLocked(app.receivers.valueAt(i)); 14258 } 14259 app.receivers.clear(); 14260 14261 // If the app is undergoing backup, tell the backup manager about it 14262 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14263 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14264 + mBackupTarget.appInfo + " died during backup"); 14265 try { 14266 IBackupManager bm = IBackupManager.Stub.asInterface( 14267 ServiceManager.getService(Context.BACKUP_SERVICE)); 14268 bm.agentDisconnected(app.info.packageName); 14269 } catch (RemoteException e) { 14270 // can't happen; backup manager is local 14271 } 14272 } 14273 14274 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14275 ProcessChangeItem item = mPendingProcessChanges.get(i); 14276 if (item.pid == app.pid) { 14277 mPendingProcessChanges.remove(i); 14278 mAvailProcessChanges.add(item); 14279 } 14280 } 14281 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14282 14283 // If the caller is restarting this app, then leave it in its 14284 // current lists and let the caller take care of it. 14285 if (restarting) { 14286 return; 14287 } 14288 14289 if (!app.persistent || app.isolated) { 14290 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14291 "Removing non-persistent process during cleanup: " + app); 14292 mProcessNames.remove(app.processName, app.uid); 14293 mIsolatedProcesses.remove(app.uid); 14294 if (mHeavyWeightProcess == app) { 14295 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14296 mHeavyWeightProcess.userId, 0)); 14297 mHeavyWeightProcess = null; 14298 } 14299 } else if (!app.removed) { 14300 // This app is persistent, so we need to keep its record around. 14301 // If it is not already on the pending app list, add it there 14302 // and start a new process for it. 14303 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14304 mPersistentStartingProcesses.add(app); 14305 restart = true; 14306 } 14307 } 14308 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14309 "Clean-up removing on hold: " + app); 14310 mProcessesOnHold.remove(app); 14311 14312 if (app == mHomeProcess) { 14313 mHomeProcess = null; 14314 } 14315 if (app == mPreviousProcess) { 14316 mPreviousProcess = null; 14317 } 14318 14319 if (restart && !app.isolated) { 14320 // We have components that still need to be running in the 14321 // process, so re-launch it. 14322 mProcessNames.put(app.processName, app.uid, app); 14323 startProcessLocked(app, "restart", app.processName); 14324 } else if (app.pid > 0 && app.pid != MY_PID) { 14325 // Goodbye! 14326 boolean removed; 14327 synchronized (mPidsSelfLocked) { 14328 mPidsSelfLocked.remove(app.pid); 14329 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14330 } 14331 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14332 if (app.isolated) { 14333 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14334 } 14335 app.setPid(0); 14336 } 14337 } 14338 14339 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14340 // Look through the content providers we are waiting to have launched, 14341 // and if any run in this process then either schedule a restart of 14342 // the process or kill the client waiting for it if this process has 14343 // gone bad. 14344 int NL = mLaunchingProviders.size(); 14345 boolean restart = false; 14346 for (int i=0; i<NL; i++) { 14347 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14348 if (cpr.launchingApp == app) { 14349 if (!alwaysBad && !app.bad) { 14350 restart = true; 14351 } else { 14352 removeDyingProviderLocked(app, cpr, true); 14353 // cpr should have been removed from mLaunchingProviders 14354 NL = mLaunchingProviders.size(); 14355 i--; 14356 } 14357 } 14358 } 14359 return restart; 14360 } 14361 14362 // ========================================================= 14363 // SERVICES 14364 // ========================================================= 14365 14366 @Override 14367 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14368 int flags) { 14369 enforceNotIsolatedCaller("getServices"); 14370 synchronized (this) { 14371 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14372 } 14373 } 14374 14375 @Override 14376 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14377 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14378 synchronized (this) { 14379 return mServices.getRunningServiceControlPanelLocked(name); 14380 } 14381 } 14382 14383 @Override 14384 public ComponentName startService(IApplicationThread caller, Intent service, 14385 String resolvedType, int userId) { 14386 enforceNotIsolatedCaller("startService"); 14387 // Refuse possible leaked file descriptors 14388 if (service != null && service.hasFileDescriptors() == true) { 14389 throw new IllegalArgumentException("File descriptors passed in Intent"); 14390 } 14391 14392 if (DEBUG_SERVICE) 14393 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14394 synchronized(this) { 14395 final int callingPid = Binder.getCallingPid(); 14396 final int callingUid = Binder.getCallingUid(); 14397 final long origId = Binder.clearCallingIdentity(); 14398 ComponentName res = mServices.startServiceLocked(caller, service, 14399 resolvedType, callingPid, callingUid, userId); 14400 Binder.restoreCallingIdentity(origId); 14401 return res; 14402 } 14403 } 14404 14405 ComponentName startServiceInPackage(int uid, 14406 Intent service, String resolvedType, int userId) { 14407 synchronized(this) { 14408 if (DEBUG_SERVICE) 14409 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14410 final long origId = Binder.clearCallingIdentity(); 14411 ComponentName res = mServices.startServiceLocked(null, service, 14412 resolvedType, -1, uid, userId); 14413 Binder.restoreCallingIdentity(origId); 14414 return res; 14415 } 14416 } 14417 14418 @Override 14419 public int stopService(IApplicationThread caller, Intent service, 14420 String resolvedType, int userId) { 14421 enforceNotIsolatedCaller("stopService"); 14422 // Refuse possible leaked file descriptors 14423 if (service != null && service.hasFileDescriptors() == true) { 14424 throw new IllegalArgumentException("File descriptors passed in Intent"); 14425 } 14426 14427 synchronized(this) { 14428 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14429 } 14430 } 14431 14432 @Override 14433 public IBinder peekService(Intent service, String resolvedType) { 14434 enforceNotIsolatedCaller("peekService"); 14435 // Refuse possible leaked file descriptors 14436 if (service != null && service.hasFileDescriptors() == true) { 14437 throw new IllegalArgumentException("File descriptors passed in Intent"); 14438 } 14439 synchronized(this) { 14440 return mServices.peekServiceLocked(service, resolvedType); 14441 } 14442 } 14443 14444 @Override 14445 public boolean stopServiceToken(ComponentName className, IBinder token, 14446 int startId) { 14447 synchronized(this) { 14448 return mServices.stopServiceTokenLocked(className, token, startId); 14449 } 14450 } 14451 14452 @Override 14453 public void setServiceForeground(ComponentName className, IBinder token, 14454 int id, Notification notification, boolean removeNotification) { 14455 synchronized(this) { 14456 mServices.setServiceForegroundLocked(className, token, id, notification, 14457 removeNotification); 14458 } 14459 } 14460 14461 @Override 14462 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14463 boolean requireFull, String name, String callerPackage) { 14464 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14465 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14466 } 14467 14468 int unsafeConvertIncomingUser(int userId) { 14469 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14470 ? mCurrentUserId : userId; 14471 } 14472 14473 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14474 int allowMode, String name, String callerPackage) { 14475 final int callingUserId = UserHandle.getUserId(callingUid); 14476 if (callingUserId == userId) { 14477 return userId; 14478 } 14479 14480 // Note that we may be accessing mCurrentUserId outside of a lock... 14481 // shouldn't be a big deal, if this is being called outside 14482 // of a locked context there is intrinsically a race with 14483 // the value the caller will receive and someone else changing it. 14484 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14485 // we will switch to the calling user if access to the current user fails. 14486 int targetUserId = unsafeConvertIncomingUser(userId); 14487 14488 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14489 final boolean allow; 14490 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14491 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14492 // If the caller has this permission, they always pass go. And collect $200. 14493 allow = true; 14494 } else if (allowMode == ALLOW_FULL_ONLY) { 14495 // We require full access, sucks to be you. 14496 allow = false; 14497 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14498 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14499 // If the caller does not have either permission, they are always doomed. 14500 allow = false; 14501 } else if (allowMode == ALLOW_NON_FULL) { 14502 // We are blanket allowing non-full access, you lucky caller! 14503 allow = true; 14504 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14505 // We may or may not allow this depending on whether the two users are 14506 // in the same profile. 14507 synchronized (mUserProfileGroupIdsSelfLocked) { 14508 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14509 UserInfo.NO_PROFILE_GROUP_ID); 14510 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14511 UserInfo.NO_PROFILE_GROUP_ID); 14512 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14513 && callingProfile == targetProfile; 14514 } 14515 } else { 14516 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14517 } 14518 if (!allow) { 14519 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14520 // In this case, they would like to just execute as their 14521 // owner user instead of failing. 14522 targetUserId = callingUserId; 14523 } else { 14524 StringBuilder builder = new StringBuilder(128); 14525 builder.append("Permission Denial: "); 14526 builder.append(name); 14527 if (callerPackage != null) { 14528 builder.append(" from "); 14529 builder.append(callerPackage); 14530 } 14531 builder.append(" asks to run as user "); 14532 builder.append(userId); 14533 builder.append(" but is calling from user "); 14534 builder.append(UserHandle.getUserId(callingUid)); 14535 builder.append("; this requires "); 14536 builder.append(INTERACT_ACROSS_USERS_FULL); 14537 if (allowMode != ALLOW_FULL_ONLY) { 14538 builder.append(" or "); 14539 builder.append(INTERACT_ACROSS_USERS); 14540 } 14541 String msg = builder.toString(); 14542 Slog.w(TAG, msg); 14543 throw new SecurityException(msg); 14544 } 14545 } 14546 } 14547 if (!allowAll && targetUserId < 0) { 14548 throw new IllegalArgumentException( 14549 "Call does not support special user #" + targetUserId); 14550 } 14551 return targetUserId; 14552 } 14553 14554 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14555 String className, int flags) { 14556 boolean result = false; 14557 // For apps that don't have pre-defined UIDs, check for permission 14558 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14559 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14560 if (ActivityManager.checkUidPermission( 14561 INTERACT_ACROSS_USERS, 14562 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14563 ComponentName comp = new ComponentName(aInfo.packageName, className); 14564 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14565 + " requests FLAG_SINGLE_USER, but app does not hold " 14566 + INTERACT_ACROSS_USERS; 14567 Slog.w(TAG, msg); 14568 throw new SecurityException(msg); 14569 } 14570 // Permission passed 14571 result = true; 14572 } 14573 } else if ("system".equals(componentProcessName)) { 14574 result = true; 14575 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14576 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14577 // Phone app is allowed to export singleuser providers. 14578 result = true; 14579 } else { 14580 // App with pre-defined UID, check if it's a persistent app 14581 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14582 } 14583 if (DEBUG_MU) { 14584 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14585 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14586 } 14587 return result; 14588 } 14589 14590 /** 14591 * Checks to see if the caller is in the same app as the singleton 14592 * component, or the component is in a special app. It allows special apps 14593 * to export singleton components but prevents exporting singleton 14594 * components for regular apps. 14595 */ 14596 boolean isValidSingletonCall(int callingUid, int componentUid) { 14597 int componentAppId = UserHandle.getAppId(componentUid); 14598 return UserHandle.isSameApp(callingUid, componentUid) 14599 || componentAppId == Process.SYSTEM_UID 14600 || componentAppId == Process.PHONE_UID 14601 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14602 == PackageManager.PERMISSION_GRANTED; 14603 } 14604 14605 public int bindService(IApplicationThread caller, IBinder token, 14606 Intent service, String resolvedType, 14607 IServiceConnection connection, int flags, int userId) { 14608 enforceNotIsolatedCaller("bindService"); 14609 // Refuse possible leaked file descriptors 14610 if (service != null && service.hasFileDescriptors() == true) { 14611 throw new IllegalArgumentException("File descriptors passed in Intent"); 14612 } 14613 14614 synchronized(this) { 14615 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14616 connection, flags, userId); 14617 } 14618 } 14619 14620 public boolean unbindService(IServiceConnection connection) { 14621 synchronized (this) { 14622 return mServices.unbindServiceLocked(connection); 14623 } 14624 } 14625 14626 public void publishService(IBinder token, Intent intent, IBinder service) { 14627 // Refuse possible leaked file descriptors 14628 if (intent != null && intent.hasFileDescriptors() == true) { 14629 throw new IllegalArgumentException("File descriptors passed in Intent"); 14630 } 14631 14632 synchronized(this) { 14633 if (!(token instanceof ServiceRecord)) { 14634 throw new IllegalArgumentException("Invalid service token"); 14635 } 14636 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14637 } 14638 } 14639 14640 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14641 // Refuse possible leaked file descriptors 14642 if (intent != null && intent.hasFileDescriptors() == true) { 14643 throw new IllegalArgumentException("File descriptors passed in Intent"); 14644 } 14645 14646 synchronized(this) { 14647 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14648 } 14649 } 14650 14651 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14652 synchronized(this) { 14653 if (!(token instanceof ServiceRecord)) { 14654 throw new IllegalArgumentException("Invalid service token"); 14655 } 14656 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14657 } 14658 } 14659 14660 // ========================================================= 14661 // BACKUP AND RESTORE 14662 // ========================================================= 14663 14664 // Cause the target app to be launched if necessary and its backup agent 14665 // instantiated. The backup agent will invoke backupAgentCreated() on the 14666 // activity manager to announce its creation. 14667 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14668 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14669 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14670 14671 synchronized(this) { 14672 // !!! TODO: currently no check here that we're already bound 14673 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14674 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14675 synchronized (stats) { 14676 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14677 } 14678 14679 // Backup agent is now in use, its package can't be stopped. 14680 try { 14681 AppGlobals.getPackageManager().setPackageStoppedState( 14682 app.packageName, false, UserHandle.getUserId(app.uid)); 14683 } catch (RemoteException e) { 14684 } catch (IllegalArgumentException e) { 14685 Slog.w(TAG, "Failed trying to unstop package " 14686 + app.packageName + ": " + e); 14687 } 14688 14689 BackupRecord r = new BackupRecord(ss, app, backupMode); 14690 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14691 ? new ComponentName(app.packageName, app.backupAgentName) 14692 : new ComponentName("android", "FullBackupAgent"); 14693 // startProcessLocked() returns existing proc's record if it's already running 14694 ProcessRecord proc = startProcessLocked(app.processName, app, 14695 false, 0, "backup", hostingName, false, false, false); 14696 if (proc == null) { 14697 Slog.e(TAG, "Unable to start backup agent process " + r); 14698 return false; 14699 } 14700 14701 r.app = proc; 14702 mBackupTarget = r; 14703 mBackupAppName = app.packageName; 14704 14705 // Try not to kill the process during backup 14706 updateOomAdjLocked(proc); 14707 14708 // If the process is already attached, schedule the creation of the backup agent now. 14709 // If it is not yet live, this will be done when it attaches to the framework. 14710 if (proc.thread != null) { 14711 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14712 try { 14713 proc.thread.scheduleCreateBackupAgent(app, 14714 compatibilityInfoForPackageLocked(app), backupMode); 14715 } catch (RemoteException e) { 14716 // Will time out on the backup manager side 14717 } 14718 } else { 14719 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14720 } 14721 // Invariants: at this point, the target app process exists and the application 14722 // is either already running or in the process of coming up. mBackupTarget and 14723 // mBackupAppName describe the app, so that when it binds back to the AM we 14724 // know that it's scheduled for a backup-agent operation. 14725 } 14726 14727 return true; 14728 } 14729 14730 @Override 14731 public void clearPendingBackup() { 14732 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14733 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14734 14735 synchronized (this) { 14736 mBackupTarget = null; 14737 mBackupAppName = null; 14738 } 14739 } 14740 14741 // A backup agent has just come up 14742 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14743 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14744 + " = " + agent); 14745 14746 synchronized(this) { 14747 if (!agentPackageName.equals(mBackupAppName)) { 14748 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14749 return; 14750 } 14751 } 14752 14753 long oldIdent = Binder.clearCallingIdentity(); 14754 try { 14755 IBackupManager bm = IBackupManager.Stub.asInterface( 14756 ServiceManager.getService(Context.BACKUP_SERVICE)); 14757 bm.agentConnected(agentPackageName, agent); 14758 } catch (RemoteException e) { 14759 // can't happen; the backup manager service is local 14760 } catch (Exception e) { 14761 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14762 e.printStackTrace(); 14763 } finally { 14764 Binder.restoreCallingIdentity(oldIdent); 14765 } 14766 } 14767 14768 // done with this agent 14769 public void unbindBackupAgent(ApplicationInfo appInfo) { 14770 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14771 if (appInfo == null) { 14772 Slog.w(TAG, "unbind backup agent for null app"); 14773 return; 14774 } 14775 14776 synchronized(this) { 14777 try { 14778 if (mBackupAppName == null) { 14779 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14780 return; 14781 } 14782 14783 if (!mBackupAppName.equals(appInfo.packageName)) { 14784 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14785 return; 14786 } 14787 14788 // Not backing this app up any more; reset its OOM adjustment 14789 final ProcessRecord proc = mBackupTarget.app; 14790 updateOomAdjLocked(proc); 14791 14792 // If the app crashed during backup, 'thread' will be null here 14793 if (proc.thread != null) { 14794 try { 14795 proc.thread.scheduleDestroyBackupAgent(appInfo, 14796 compatibilityInfoForPackageLocked(appInfo)); 14797 } catch (Exception e) { 14798 Slog.e(TAG, "Exception when unbinding backup agent:"); 14799 e.printStackTrace(); 14800 } 14801 } 14802 } finally { 14803 mBackupTarget = null; 14804 mBackupAppName = null; 14805 } 14806 } 14807 } 14808 // ========================================================= 14809 // BROADCASTS 14810 // ========================================================= 14811 14812 private final List getStickiesLocked(String action, IntentFilter filter, 14813 List cur, int userId) { 14814 final ContentResolver resolver = mContext.getContentResolver(); 14815 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14816 if (stickies == null) { 14817 return cur; 14818 } 14819 final ArrayList<Intent> list = stickies.get(action); 14820 if (list == null) { 14821 return cur; 14822 } 14823 int N = list.size(); 14824 for (int i=0; i<N; i++) { 14825 Intent intent = list.get(i); 14826 if (filter.match(resolver, intent, true, TAG) >= 0) { 14827 if (cur == null) { 14828 cur = new ArrayList<Intent>(); 14829 } 14830 cur.add(intent); 14831 } 14832 } 14833 return cur; 14834 } 14835 14836 boolean isPendingBroadcastProcessLocked(int pid) { 14837 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14838 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14839 } 14840 14841 void skipPendingBroadcastLocked(int pid) { 14842 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14843 for (BroadcastQueue queue : mBroadcastQueues) { 14844 queue.skipPendingBroadcastLocked(pid); 14845 } 14846 } 14847 14848 // The app just attached; send any pending broadcasts that it should receive 14849 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14850 boolean didSomething = false; 14851 for (BroadcastQueue queue : mBroadcastQueues) { 14852 didSomething |= queue.sendPendingBroadcastsLocked(app); 14853 } 14854 return didSomething; 14855 } 14856 14857 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14858 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14859 enforceNotIsolatedCaller("registerReceiver"); 14860 int callingUid; 14861 int callingPid; 14862 synchronized(this) { 14863 ProcessRecord callerApp = null; 14864 if (caller != null) { 14865 callerApp = getRecordForAppLocked(caller); 14866 if (callerApp == null) { 14867 throw new SecurityException( 14868 "Unable to find app for caller " + caller 14869 + " (pid=" + Binder.getCallingPid() 14870 + ") when registering receiver " + receiver); 14871 } 14872 if (callerApp.info.uid != Process.SYSTEM_UID && 14873 !callerApp.pkgList.containsKey(callerPackage) && 14874 !"android".equals(callerPackage)) { 14875 throw new SecurityException("Given caller package " + callerPackage 14876 + " is not running in process " + callerApp); 14877 } 14878 callingUid = callerApp.info.uid; 14879 callingPid = callerApp.pid; 14880 } else { 14881 callerPackage = null; 14882 callingUid = Binder.getCallingUid(); 14883 callingPid = Binder.getCallingPid(); 14884 } 14885 14886 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14887 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14888 14889 List allSticky = null; 14890 14891 // Look for any matching sticky broadcasts... 14892 Iterator actions = filter.actionsIterator(); 14893 if (actions != null) { 14894 while (actions.hasNext()) { 14895 String action = (String)actions.next(); 14896 allSticky = getStickiesLocked(action, filter, allSticky, 14897 UserHandle.USER_ALL); 14898 allSticky = getStickiesLocked(action, filter, allSticky, 14899 UserHandle.getUserId(callingUid)); 14900 } 14901 } else { 14902 allSticky = getStickiesLocked(null, filter, allSticky, 14903 UserHandle.USER_ALL); 14904 allSticky = getStickiesLocked(null, filter, allSticky, 14905 UserHandle.getUserId(callingUid)); 14906 } 14907 14908 // The first sticky in the list is returned directly back to 14909 // the client. 14910 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14911 14912 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14913 + ": " + sticky); 14914 14915 if (receiver == null) { 14916 return sticky; 14917 } 14918 14919 ReceiverList rl 14920 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14921 if (rl == null) { 14922 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14923 userId, receiver); 14924 if (rl.app != null) { 14925 rl.app.receivers.add(rl); 14926 } else { 14927 try { 14928 receiver.asBinder().linkToDeath(rl, 0); 14929 } catch (RemoteException e) { 14930 return sticky; 14931 } 14932 rl.linkedToDeath = true; 14933 } 14934 mRegisteredReceivers.put(receiver.asBinder(), rl); 14935 } else if (rl.uid != callingUid) { 14936 throw new IllegalArgumentException( 14937 "Receiver requested to register for uid " + callingUid 14938 + " was previously registered for uid " + rl.uid); 14939 } else if (rl.pid != callingPid) { 14940 throw new IllegalArgumentException( 14941 "Receiver requested to register for pid " + callingPid 14942 + " was previously registered for pid " + rl.pid); 14943 } else if (rl.userId != userId) { 14944 throw new IllegalArgumentException( 14945 "Receiver requested to register for user " + userId 14946 + " was previously registered for user " + rl.userId); 14947 } 14948 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14949 permission, callingUid, userId); 14950 rl.add(bf); 14951 if (!bf.debugCheck()) { 14952 Slog.w(TAG, "==> For Dynamic broadast"); 14953 } 14954 mReceiverResolver.addFilter(bf); 14955 14956 // Enqueue broadcasts for all existing stickies that match 14957 // this filter. 14958 if (allSticky != null) { 14959 ArrayList receivers = new ArrayList(); 14960 receivers.add(bf); 14961 14962 int N = allSticky.size(); 14963 for (int i=0; i<N; i++) { 14964 Intent intent = (Intent)allSticky.get(i); 14965 BroadcastQueue queue = broadcastQueueForIntent(intent); 14966 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14967 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14968 null, null, false, true, true, -1); 14969 queue.enqueueParallelBroadcastLocked(r); 14970 queue.scheduleBroadcastsLocked(); 14971 } 14972 } 14973 14974 return sticky; 14975 } 14976 } 14977 14978 public void unregisterReceiver(IIntentReceiver receiver) { 14979 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14980 14981 final long origId = Binder.clearCallingIdentity(); 14982 try { 14983 boolean doTrim = false; 14984 14985 synchronized(this) { 14986 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14987 if (rl != null) { 14988 if (rl.curBroadcast != null) { 14989 BroadcastRecord r = rl.curBroadcast; 14990 final boolean doNext = finishReceiverLocked( 14991 receiver.asBinder(), r.resultCode, r.resultData, 14992 r.resultExtras, r.resultAbort); 14993 if (doNext) { 14994 doTrim = true; 14995 r.queue.processNextBroadcast(false); 14996 } 14997 } 14998 14999 if (rl.app != null) { 15000 rl.app.receivers.remove(rl); 15001 } 15002 removeReceiverLocked(rl); 15003 if (rl.linkedToDeath) { 15004 rl.linkedToDeath = false; 15005 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15006 } 15007 } 15008 } 15009 15010 // If we actually concluded any broadcasts, we might now be able 15011 // to trim the recipients' apps from our working set 15012 if (doTrim) { 15013 trimApplications(); 15014 return; 15015 } 15016 15017 } finally { 15018 Binder.restoreCallingIdentity(origId); 15019 } 15020 } 15021 15022 void removeReceiverLocked(ReceiverList rl) { 15023 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15024 int N = rl.size(); 15025 for (int i=0; i<N; i++) { 15026 mReceiverResolver.removeFilter(rl.get(i)); 15027 } 15028 } 15029 15030 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15031 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15032 ProcessRecord r = mLruProcesses.get(i); 15033 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15034 try { 15035 r.thread.dispatchPackageBroadcast(cmd, packages); 15036 } catch (RemoteException ex) { 15037 } 15038 } 15039 } 15040 } 15041 15042 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15043 int[] users) { 15044 List<ResolveInfo> receivers = null; 15045 try { 15046 HashSet<ComponentName> singleUserReceivers = null; 15047 boolean scannedFirstReceivers = false; 15048 for (int user : users) { 15049 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15050 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15051 if (user != 0 && newReceivers != null) { 15052 // If this is not the primary user, we need to check for 15053 // any receivers that should be filtered out. 15054 for (int i=0; i<newReceivers.size(); i++) { 15055 ResolveInfo ri = newReceivers.get(i); 15056 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15057 newReceivers.remove(i); 15058 i--; 15059 } 15060 } 15061 } 15062 if (newReceivers != null && newReceivers.size() == 0) { 15063 newReceivers = null; 15064 } 15065 if (receivers == null) { 15066 receivers = newReceivers; 15067 } else if (newReceivers != null) { 15068 // We need to concatenate the additional receivers 15069 // found with what we have do far. This would be easy, 15070 // but we also need to de-dup any receivers that are 15071 // singleUser. 15072 if (!scannedFirstReceivers) { 15073 // Collect any single user receivers we had already retrieved. 15074 scannedFirstReceivers = true; 15075 for (int i=0; i<receivers.size(); i++) { 15076 ResolveInfo ri = receivers.get(i); 15077 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15078 ComponentName cn = new ComponentName( 15079 ri.activityInfo.packageName, ri.activityInfo.name); 15080 if (singleUserReceivers == null) { 15081 singleUserReceivers = new HashSet<ComponentName>(); 15082 } 15083 singleUserReceivers.add(cn); 15084 } 15085 } 15086 } 15087 // Add the new results to the existing results, tracking 15088 // and de-dupping single user receivers. 15089 for (int i=0; i<newReceivers.size(); i++) { 15090 ResolveInfo ri = newReceivers.get(i); 15091 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15092 ComponentName cn = new ComponentName( 15093 ri.activityInfo.packageName, ri.activityInfo.name); 15094 if (singleUserReceivers == null) { 15095 singleUserReceivers = new HashSet<ComponentName>(); 15096 } 15097 if (!singleUserReceivers.contains(cn)) { 15098 singleUserReceivers.add(cn); 15099 receivers.add(ri); 15100 } 15101 } else { 15102 receivers.add(ri); 15103 } 15104 } 15105 } 15106 } 15107 } catch (RemoteException ex) { 15108 // pm is in same process, this will never happen. 15109 } 15110 return receivers; 15111 } 15112 15113 private final int broadcastIntentLocked(ProcessRecord callerApp, 15114 String callerPackage, Intent intent, String resolvedType, 15115 IIntentReceiver resultTo, int resultCode, String resultData, 15116 Bundle map, String requiredPermission, int appOp, 15117 boolean ordered, boolean sticky, int callingPid, int callingUid, 15118 int userId) { 15119 intent = new Intent(intent); 15120 15121 // By default broadcasts do not go to stopped apps. 15122 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15123 15124 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15125 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15126 + " ordered=" + ordered + " userid=" + userId); 15127 if ((resultTo != null) && !ordered) { 15128 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15129 } 15130 15131 userId = handleIncomingUser(callingPid, callingUid, userId, 15132 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15133 15134 // Make sure that the user who is receiving this broadcast is started. 15135 // If not, we will just skip it. 15136 15137 15138 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15139 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15140 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15141 Slog.w(TAG, "Skipping broadcast of " + intent 15142 + ": user " + userId + " is stopped"); 15143 return ActivityManager.BROADCAST_SUCCESS; 15144 } 15145 } 15146 15147 /* 15148 * Prevent non-system code (defined here to be non-persistent 15149 * processes) from sending protected broadcasts. 15150 */ 15151 int callingAppId = UserHandle.getAppId(callingUid); 15152 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15153 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15154 || callingAppId == Process.NFC_UID || callingUid == 0) { 15155 // Always okay. 15156 } else if (callerApp == null || !callerApp.persistent) { 15157 try { 15158 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15159 intent.getAction())) { 15160 String msg = "Permission Denial: not allowed to send broadcast " 15161 + intent.getAction() + " from pid=" 15162 + callingPid + ", uid=" + callingUid; 15163 Slog.w(TAG, msg); 15164 throw new SecurityException(msg); 15165 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15166 // Special case for compatibility: we don't want apps to send this, 15167 // but historically it has not been protected and apps may be using it 15168 // to poke their own app widget. So, instead of making it protected, 15169 // just limit it to the caller. 15170 if (callerApp == null) { 15171 String msg = "Permission Denial: not allowed to send broadcast " 15172 + intent.getAction() + " from unknown caller."; 15173 Slog.w(TAG, msg); 15174 throw new SecurityException(msg); 15175 } else if (intent.getComponent() != null) { 15176 // They are good enough to send to an explicit component... verify 15177 // it is being sent to the calling app. 15178 if (!intent.getComponent().getPackageName().equals( 15179 callerApp.info.packageName)) { 15180 String msg = "Permission Denial: not allowed to send broadcast " 15181 + intent.getAction() + " to " 15182 + intent.getComponent().getPackageName() + " from " 15183 + callerApp.info.packageName; 15184 Slog.w(TAG, msg); 15185 throw new SecurityException(msg); 15186 } 15187 } else { 15188 // Limit broadcast to their own package. 15189 intent.setPackage(callerApp.info.packageName); 15190 } 15191 } 15192 } catch (RemoteException e) { 15193 Slog.w(TAG, "Remote exception", e); 15194 return ActivityManager.BROADCAST_SUCCESS; 15195 } 15196 } 15197 15198 // Handle special intents: if this broadcast is from the package 15199 // manager about a package being removed, we need to remove all of 15200 // its activities from the history stack. 15201 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15202 intent.getAction()); 15203 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15204 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15205 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15206 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15207 || uidRemoved) { 15208 if (checkComponentPermission( 15209 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15210 callingPid, callingUid, -1, true) 15211 == PackageManager.PERMISSION_GRANTED) { 15212 if (uidRemoved) { 15213 final Bundle intentExtras = intent.getExtras(); 15214 final int uid = intentExtras != null 15215 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15216 if (uid >= 0) { 15217 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15218 synchronized (bs) { 15219 bs.removeUidStatsLocked(uid); 15220 } 15221 mAppOpsService.uidRemoved(uid); 15222 } 15223 } else { 15224 // If resources are unavailable just force stop all 15225 // those packages and flush the attribute cache as well. 15226 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15227 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15228 if (list != null && (list.length > 0)) { 15229 for (String pkg : list) { 15230 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15231 "storage unmount"); 15232 } 15233 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15234 sendPackageBroadcastLocked( 15235 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15236 } 15237 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15238 intent.getAction())) { 15239 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15240 } else { 15241 Uri data = intent.getData(); 15242 String ssp; 15243 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15244 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15245 intent.getAction()); 15246 boolean fullUninstall = removed && 15247 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15248 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15249 forceStopPackageLocked(ssp, UserHandle.getAppId( 15250 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15251 false, fullUninstall, userId, 15252 removed ? "pkg removed" : "pkg changed"); 15253 } 15254 if (removed) { 15255 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15256 new String[] {ssp}, userId); 15257 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15258 mAppOpsService.packageRemoved( 15259 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15260 15261 // Remove all permissions granted from/to this package 15262 removeUriPermissionsForPackageLocked(ssp, userId, true); 15263 } 15264 } 15265 } 15266 } 15267 } 15268 } else { 15269 String msg = "Permission Denial: " + intent.getAction() 15270 + " broadcast from " + callerPackage + " (pid=" + callingPid 15271 + ", uid=" + callingUid + ")" 15272 + " requires " 15273 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15274 Slog.w(TAG, msg); 15275 throw new SecurityException(msg); 15276 } 15277 15278 // Special case for adding a package: by default turn on compatibility 15279 // mode. 15280 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15281 Uri data = intent.getData(); 15282 String ssp; 15283 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15284 mCompatModePackages.handlePackageAddedLocked(ssp, 15285 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15286 } 15287 } 15288 15289 /* 15290 * If this is the time zone changed action, queue up a message that will reset the timezone 15291 * of all currently running processes. This message will get queued up before the broadcast 15292 * happens. 15293 */ 15294 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15295 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15296 } 15297 15298 /* 15299 * If the user set the time, let all running processes know. 15300 */ 15301 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15302 final int is24Hour = intent.getBooleanExtra( 15303 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15304 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15305 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15306 synchronized (stats) { 15307 stats.noteCurrentTimeChangedLocked(); 15308 } 15309 } 15310 15311 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15312 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15313 } 15314 15315 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15316 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15317 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15318 } 15319 15320 // Add to the sticky list if requested. 15321 if (sticky) { 15322 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15323 callingPid, callingUid) 15324 != PackageManager.PERMISSION_GRANTED) { 15325 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15326 + callingPid + ", uid=" + callingUid 15327 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15328 Slog.w(TAG, msg); 15329 throw new SecurityException(msg); 15330 } 15331 if (requiredPermission != null) { 15332 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15333 + " and enforce permission " + requiredPermission); 15334 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15335 } 15336 if (intent.getComponent() != null) { 15337 throw new SecurityException( 15338 "Sticky broadcasts can't target a specific component"); 15339 } 15340 // We use userId directly here, since the "all" target is maintained 15341 // as a separate set of sticky broadcasts. 15342 if (userId != UserHandle.USER_ALL) { 15343 // But first, if this is not a broadcast to all users, then 15344 // make sure it doesn't conflict with an existing broadcast to 15345 // all users. 15346 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15347 UserHandle.USER_ALL); 15348 if (stickies != null) { 15349 ArrayList<Intent> list = stickies.get(intent.getAction()); 15350 if (list != null) { 15351 int N = list.size(); 15352 int i; 15353 for (i=0; i<N; i++) { 15354 if (intent.filterEquals(list.get(i))) { 15355 throw new IllegalArgumentException( 15356 "Sticky broadcast " + intent + " for user " 15357 + userId + " conflicts with existing global broadcast"); 15358 } 15359 } 15360 } 15361 } 15362 } 15363 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15364 if (stickies == null) { 15365 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15366 mStickyBroadcasts.put(userId, stickies); 15367 } 15368 ArrayList<Intent> list = stickies.get(intent.getAction()); 15369 if (list == null) { 15370 list = new ArrayList<Intent>(); 15371 stickies.put(intent.getAction(), list); 15372 } 15373 int N = list.size(); 15374 int i; 15375 for (i=0; i<N; i++) { 15376 if (intent.filterEquals(list.get(i))) { 15377 // This sticky already exists, replace it. 15378 list.set(i, new Intent(intent)); 15379 break; 15380 } 15381 } 15382 if (i >= N) { 15383 list.add(new Intent(intent)); 15384 } 15385 } 15386 15387 int[] users; 15388 if (userId == UserHandle.USER_ALL) { 15389 // Caller wants broadcast to go to all started users. 15390 users = mStartedUserArray; 15391 } else { 15392 // Caller wants broadcast to go to one specific user. 15393 users = new int[] {userId}; 15394 } 15395 15396 // Figure out who all will receive this broadcast. 15397 List receivers = null; 15398 List<BroadcastFilter> registeredReceivers = null; 15399 // Need to resolve the intent to interested receivers... 15400 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15401 == 0) { 15402 receivers = collectReceiverComponents(intent, resolvedType, users); 15403 } 15404 if (intent.getComponent() == null) { 15405 registeredReceivers = mReceiverResolver.queryIntent(intent, 15406 resolvedType, false, userId); 15407 } 15408 15409 final boolean replacePending = 15410 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15411 15412 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15413 + " replacePending=" + replacePending); 15414 15415 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15416 if (!ordered && NR > 0) { 15417 // If we are not serializing this broadcast, then send the 15418 // registered receivers separately so they don't wait for the 15419 // components to be launched. 15420 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15421 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15422 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15423 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15424 ordered, sticky, false, userId); 15425 if (DEBUG_BROADCAST) Slog.v( 15426 TAG, "Enqueueing parallel broadcast " + r); 15427 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15428 if (!replaced) { 15429 queue.enqueueParallelBroadcastLocked(r); 15430 queue.scheduleBroadcastsLocked(); 15431 } 15432 registeredReceivers = null; 15433 NR = 0; 15434 } 15435 15436 // Merge into one list. 15437 int ir = 0; 15438 if (receivers != null) { 15439 // A special case for PACKAGE_ADDED: do not allow the package 15440 // being added to see this broadcast. This prevents them from 15441 // using this as a back door to get run as soon as they are 15442 // installed. Maybe in the future we want to have a special install 15443 // broadcast or such for apps, but we'd like to deliberately make 15444 // this decision. 15445 String skipPackages[] = null; 15446 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15447 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15448 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15449 Uri data = intent.getData(); 15450 if (data != null) { 15451 String pkgName = data.getSchemeSpecificPart(); 15452 if (pkgName != null) { 15453 skipPackages = new String[] { pkgName }; 15454 } 15455 } 15456 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15457 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15458 } 15459 if (skipPackages != null && (skipPackages.length > 0)) { 15460 for (String skipPackage : skipPackages) { 15461 if (skipPackage != null) { 15462 int NT = receivers.size(); 15463 for (int it=0; it<NT; it++) { 15464 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15465 if (curt.activityInfo.packageName.equals(skipPackage)) { 15466 receivers.remove(it); 15467 it--; 15468 NT--; 15469 } 15470 } 15471 } 15472 } 15473 } 15474 15475 int NT = receivers != null ? receivers.size() : 0; 15476 int it = 0; 15477 ResolveInfo curt = null; 15478 BroadcastFilter curr = null; 15479 while (it < NT && ir < NR) { 15480 if (curt == null) { 15481 curt = (ResolveInfo)receivers.get(it); 15482 } 15483 if (curr == null) { 15484 curr = registeredReceivers.get(ir); 15485 } 15486 if (curr.getPriority() >= curt.priority) { 15487 // Insert this broadcast record into the final list. 15488 receivers.add(it, curr); 15489 ir++; 15490 curr = null; 15491 it++; 15492 NT++; 15493 } else { 15494 // Skip to the next ResolveInfo in the final list. 15495 it++; 15496 curt = null; 15497 } 15498 } 15499 } 15500 while (ir < NR) { 15501 if (receivers == null) { 15502 receivers = new ArrayList(); 15503 } 15504 receivers.add(registeredReceivers.get(ir)); 15505 ir++; 15506 } 15507 15508 if ((receivers != null && receivers.size() > 0) 15509 || resultTo != null) { 15510 BroadcastQueue queue = broadcastQueueForIntent(intent); 15511 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15512 callerPackage, callingPid, callingUid, resolvedType, 15513 requiredPermission, appOp, receivers, resultTo, resultCode, 15514 resultData, map, ordered, sticky, false, userId); 15515 if (DEBUG_BROADCAST) Slog.v( 15516 TAG, "Enqueueing ordered broadcast " + r 15517 + ": prev had " + queue.mOrderedBroadcasts.size()); 15518 if (DEBUG_BROADCAST) { 15519 int seq = r.intent.getIntExtra("seq", -1); 15520 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15521 } 15522 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15523 if (!replaced) { 15524 queue.enqueueOrderedBroadcastLocked(r); 15525 queue.scheduleBroadcastsLocked(); 15526 } 15527 } 15528 15529 return ActivityManager.BROADCAST_SUCCESS; 15530 } 15531 15532 final Intent verifyBroadcastLocked(Intent intent) { 15533 // Refuse possible leaked file descriptors 15534 if (intent != null && intent.hasFileDescriptors() == true) { 15535 throw new IllegalArgumentException("File descriptors passed in Intent"); 15536 } 15537 15538 int flags = intent.getFlags(); 15539 15540 if (!mProcessesReady) { 15541 // if the caller really truly claims to know what they're doing, go 15542 // ahead and allow the broadcast without launching any receivers 15543 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15544 intent = new Intent(intent); 15545 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15546 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15547 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15548 + " before boot completion"); 15549 throw new IllegalStateException("Cannot broadcast before boot completed"); 15550 } 15551 } 15552 15553 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15554 throw new IllegalArgumentException( 15555 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15556 } 15557 15558 return intent; 15559 } 15560 15561 public final int broadcastIntent(IApplicationThread caller, 15562 Intent intent, String resolvedType, IIntentReceiver resultTo, 15563 int resultCode, String resultData, Bundle map, 15564 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15565 enforceNotIsolatedCaller("broadcastIntent"); 15566 synchronized(this) { 15567 intent = verifyBroadcastLocked(intent); 15568 15569 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15570 final int callingPid = Binder.getCallingPid(); 15571 final int callingUid = Binder.getCallingUid(); 15572 final long origId = Binder.clearCallingIdentity(); 15573 int res = broadcastIntentLocked(callerApp, 15574 callerApp != null ? callerApp.info.packageName : null, 15575 intent, resolvedType, resultTo, 15576 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15577 callingPid, callingUid, userId); 15578 Binder.restoreCallingIdentity(origId); 15579 return res; 15580 } 15581 } 15582 15583 int broadcastIntentInPackage(String packageName, int uid, 15584 Intent intent, String resolvedType, IIntentReceiver resultTo, 15585 int resultCode, String resultData, Bundle map, 15586 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15587 synchronized(this) { 15588 intent = verifyBroadcastLocked(intent); 15589 15590 final long origId = Binder.clearCallingIdentity(); 15591 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15592 resultTo, resultCode, resultData, map, requiredPermission, 15593 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15594 Binder.restoreCallingIdentity(origId); 15595 return res; 15596 } 15597 } 15598 15599 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15600 // Refuse possible leaked file descriptors 15601 if (intent != null && intent.hasFileDescriptors() == true) { 15602 throw new IllegalArgumentException("File descriptors passed in Intent"); 15603 } 15604 15605 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15606 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15607 15608 synchronized(this) { 15609 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15610 != PackageManager.PERMISSION_GRANTED) { 15611 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15612 + Binder.getCallingPid() 15613 + ", uid=" + Binder.getCallingUid() 15614 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15615 Slog.w(TAG, msg); 15616 throw new SecurityException(msg); 15617 } 15618 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15619 if (stickies != null) { 15620 ArrayList<Intent> list = stickies.get(intent.getAction()); 15621 if (list != null) { 15622 int N = list.size(); 15623 int i; 15624 for (i=0; i<N; i++) { 15625 if (intent.filterEquals(list.get(i))) { 15626 list.remove(i); 15627 break; 15628 } 15629 } 15630 if (list.size() <= 0) { 15631 stickies.remove(intent.getAction()); 15632 } 15633 } 15634 if (stickies.size() <= 0) { 15635 mStickyBroadcasts.remove(userId); 15636 } 15637 } 15638 } 15639 } 15640 15641 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15642 String resultData, Bundle resultExtras, boolean resultAbort) { 15643 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15644 if (r == null) { 15645 Slog.w(TAG, "finishReceiver called but not found on queue"); 15646 return false; 15647 } 15648 15649 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15650 } 15651 15652 void backgroundServicesFinishedLocked(int userId) { 15653 for (BroadcastQueue queue : mBroadcastQueues) { 15654 queue.backgroundServicesFinishedLocked(userId); 15655 } 15656 } 15657 15658 public void finishReceiver(IBinder who, int resultCode, String resultData, 15659 Bundle resultExtras, boolean resultAbort) { 15660 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15661 15662 // Refuse possible leaked file descriptors 15663 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15664 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15665 } 15666 15667 final long origId = Binder.clearCallingIdentity(); 15668 try { 15669 boolean doNext = false; 15670 BroadcastRecord r; 15671 15672 synchronized(this) { 15673 r = broadcastRecordForReceiverLocked(who); 15674 if (r != null) { 15675 doNext = r.queue.finishReceiverLocked(r, resultCode, 15676 resultData, resultExtras, resultAbort, true); 15677 } 15678 } 15679 15680 if (doNext) { 15681 r.queue.processNextBroadcast(false); 15682 } 15683 trimApplications(); 15684 } finally { 15685 Binder.restoreCallingIdentity(origId); 15686 } 15687 } 15688 15689 // ========================================================= 15690 // INSTRUMENTATION 15691 // ========================================================= 15692 15693 public boolean startInstrumentation(ComponentName className, 15694 String profileFile, int flags, Bundle arguments, 15695 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15696 int userId, String abiOverride) { 15697 enforceNotIsolatedCaller("startInstrumentation"); 15698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15699 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15700 // Refuse possible leaked file descriptors 15701 if (arguments != null && arguments.hasFileDescriptors()) { 15702 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15703 } 15704 15705 synchronized(this) { 15706 InstrumentationInfo ii = null; 15707 ApplicationInfo ai = null; 15708 try { 15709 ii = mContext.getPackageManager().getInstrumentationInfo( 15710 className, STOCK_PM_FLAGS); 15711 ai = AppGlobals.getPackageManager().getApplicationInfo( 15712 ii.targetPackage, STOCK_PM_FLAGS, userId); 15713 } catch (PackageManager.NameNotFoundException e) { 15714 } catch (RemoteException e) { 15715 } 15716 if (ii == null) { 15717 reportStartInstrumentationFailure(watcher, className, 15718 "Unable to find instrumentation info for: " + className); 15719 return false; 15720 } 15721 if (ai == null) { 15722 reportStartInstrumentationFailure(watcher, className, 15723 "Unable to find instrumentation target package: " + ii.targetPackage); 15724 return false; 15725 } 15726 15727 int match = mContext.getPackageManager().checkSignatures( 15728 ii.targetPackage, ii.packageName); 15729 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15730 String msg = "Permission Denial: starting instrumentation " 15731 + className + " from pid=" 15732 + Binder.getCallingPid() 15733 + ", uid=" + Binder.getCallingPid() 15734 + " not allowed because package " + ii.packageName 15735 + " does not have a signature matching the target " 15736 + ii.targetPackage; 15737 reportStartInstrumentationFailure(watcher, className, msg); 15738 throw new SecurityException(msg); 15739 } 15740 15741 final long origId = Binder.clearCallingIdentity(); 15742 // Instrumentation can kill and relaunch even persistent processes 15743 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15744 "start instr"); 15745 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15746 app.instrumentationClass = className; 15747 app.instrumentationInfo = ai; 15748 app.instrumentationProfileFile = profileFile; 15749 app.instrumentationArguments = arguments; 15750 app.instrumentationWatcher = watcher; 15751 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15752 app.instrumentationResultClass = className; 15753 Binder.restoreCallingIdentity(origId); 15754 } 15755 15756 return true; 15757 } 15758 15759 /** 15760 * Report errors that occur while attempting to start Instrumentation. Always writes the 15761 * error to the logs, but if somebody is watching, send the report there too. This enables 15762 * the "am" command to report errors with more information. 15763 * 15764 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15765 * @param cn The component name of the instrumentation. 15766 * @param report The error report. 15767 */ 15768 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15769 ComponentName cn, String report) { 15770 Slog.w(TAG, report); 15771 try { 15772 if (watcher != null) { 15773 Bundle results = new Bundle(); 15774 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15775 results.putString("Error", report); 15776 watcher.instrumentationStatus(cn, -1, results); 15777 } 15778 } catch (RemoteException e) { 15779 Slog.w(TAG, e); 15780 } 15781 } 15782 15783 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15784 if (app.instrumentationWatcher != null) { 15785 try { 15786 // NOTE: IInstrumentationWatcher *must* be oneway here 15787 app.instrumentationWatcher.instrumentationFinished( 15788 app.instrumentationClass, 15789 resultCode, 15790 results); 15791 } catch (RemoteException e) { 15792 } 15793 } 15794 if (app.instrumentationUiAutomationConnection != null) { 15795 try { 15796 app.instrumentationUiAutomationConnection.shutdown(); 15797 } catch (RemoteException re) { 15798 /* ignore */ 15799 } 15800 // Only a UiAutomation can set this flag and now that 15801 // it is finished we make sure it is reset to its default. 15802 mUserIsMonkey = false; 15803 } 15804 app.instrumentationWatcher = null; 15805 app.instrumentationUiAutomationConnection = null; 15806 app.instrumentationClass = null; 15807 app.instrumentationInfo = null; 15808 app.instrumentationProfileFile = null; 15809 app.instrumentationArguments = null; 15810 15811 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15812 "finished inst"); 15813 } 15814 15815 public void finishInstrumentation(IApplicationThread target, 15816 int resultCode, Bundle results) { 15817 int userId = UserHandle.getCallingUserId(); 15818 // Refuse possible leaked file descriptors 15819 if (results != null && results.hasFileDescriptors()) { 15820 throw new IllegalArgumentException("File descriptors passed in Intent"); 15821 } 15822 15823 synchronized(this) { 15824 ProcessRecord app = getRecordForAppLocked(target); 15825 if (app == null) { 15826 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15827 return; 15828 } 15829 final long origId = Binder.clearCallingIdentity(); 15830 finishInstrumentationLocked(app, resultCode, results); 15831 Binder.restoreCallingIdentity(origId); 15832 } 15833 } 15834 15835 // ========================================================= 15836 // CONFIGURATION 15837 // ========================================================= 15838 15839 public ConfigurationInfo getDeviceConfigurationInfo() { 15840 ConfigurationInfo config = new ConfigurationInfo(); 15841 synchronized (this) { 15842 config.reqTouchScreen = mConfiguration.touchscreen; 15843 config.reqKeyboardType = mConfiguration.keyboard; 15844 config.reqNavigation = mConfiguration.navigation; 15845 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15846 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15847 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15848 } 15849 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15850 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15851 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15852 } 15853 config.reqGlEsVersion = GL_ES_VERSION; 15854 } 15855 return config; 15856 } 15857 15858 ActivityStack getFocusedStack() { 15859 return mStackSupervisor.getFocusedStack(); 15860 } 15861 15862 public Configuration getConfiguration() { 15863 Configuration ci; 15864 synchronized(this) { 15865 ci = new Configuration(mConfiguration); 15866 } 15867 return ci; 15868 } 15869 15870 public void updatePersistentConfiguration(Configuration values) { 15871 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15872 "updateConfiguration()"); 15873 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15874 "updateConfiguration()"); 15875 if (values == null) { 15876 throw new NullPointerException("Configuration must not be null"); 15877 } 15878 15879 synchronized(this) { 15880 final long origId = Binder.clearCallingIdentity(); 15881 updateConfigurationLocked(values, null, true, false); 15882 Binder.restoreCallingIdentity(origId); 15883 } 15884 } 15885 15886 public void updateConfiguration(Configuration values) { 15887 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15888 "updateConfiguration()"); 15889 15890 synchronized(this) { 15891 if (values == null && mWindowManager != null) { 15892 // sentinel: fetch the current configuration from the window manager 15893 values = mWindowManager.computeNewConfiguration(); 15894 } 15895 15896 if (mWindowManager != null) { 15897 mProcessList.applyDisplaySize(mWindowManager); 15898 } 15899 15900 final long origId = Binder.clearCallingIdentity(); 15901 if (values != null) { 15902 Settings.System.clearConfiguration(values); 15903 } 15904 updateConfigurationLocked(values, null, false, false); 15905 Binder.restoreCallingIdentity(origId); 15906 } 15907 } 15908 15909 /** 15910 * Do either or both things: (1) change the current configuration, and (2) 15911 * make sure the given activity is running with the (now) current 15912 * configuration. Returns true if the activity has been left running, or 15913 * false if <var>starting</var> is being destroyed to match the new 15914 * configuration. 15915 * @param persistent TODO 15916 */ 15917 boolean updateConfigurationLocked(Configuration values, 15918 ActivityRecord starting, boolean persistent, boolean initLocale) { 15919 int changes = 0; 15920 15921 if (values != null) { 15922 Configuration newConfig = new Configuration(mConfiguration); 15923 changes = newConfig.updateFrom(values); 15924 if (changes != 0) { 15925 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15926 Slog.i(TAG, "Updating configuration to: " + values); 15927 } 15928 15929 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15930 15931 if (values.locale != null && !initLocale) { 15932 saveLocaleLocked(values.locale, 15933 !values.locale.equals(mConfiguration.locale), 15934 values.userSetLocale); 15935 } 15936 15937 mConfigurationSeq++; 15938 if (mConfigurationSeq <= 0) { 15939 mConfigurationSeq = 1; 15940 } 15941 newConfig.seq = mConfigurationSeq; 15942 mConfiguration = newConfig; 15943 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15944 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15945 //mUsageStatsService.noteStartConfig(newConfig); 15946 15947 final Configuration configCopy = new Configuration(mConfiguration); 15948 15949 // TODO: If our config changes, should we auto dismiss any currently 15950 // showing dialogs? 15951 mShowDialogs = shouldShowDialogs(newConfig); 15952 15953 AttributeCache ac = AttributeCache.instance(); 15954 if (ac != null) { 15955 ac.updateConfiguration(configCopy); 15956 } 15957 15958 // Make sure all resources in our process are updated 15959 // right now, so that anyone who is going to retrieve 15960 // resource values after we return will be sure to get 15961 // the new ones. This is especially important during 15962 // boot, where the first config change needs to guarantee 15963 // all resources have that config before following boot 15964 // code is executed. 15965 mSystemThread.applyConfigurationToResources(configCopy); 15966 15967 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15968 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15969 msg.obj = new Configuration(configCopy); 15970 mHandler.sendMessage(msg); 15971 } 15972 15973 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15974 ProcessRecord app = mLruProcesses.get(i); 15975 try { 15976 if (app.thread != null) { 15977 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15978 + app.processName + " new config " + mConfiguration); 15979 app.thread.scheduleConfigurationChanged(configCopy); 15980 } 15981 } catch (Exception e) { 15982 } 15983 } 15984 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15985 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15986 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15987 | Intent.FLAG_RECEIVER_FOREGROUND); 15988 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15989 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15990 Process.SYSTEM_UID, UserHandle.USER_ALL); 15991 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15992 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15993 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15994 broadcastIntentLocked(null, null, intent, 15995 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15996 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15997 } 15998 } 15999 } 16000 16001 boolean kept = true; 16002 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16003 // mainStack is null during startup. 16004 if (mainStack != null) { 16005 if (changes != 0 && starting == null) { 16006 // If the configuration changed, and the caller is not already 16007 // in the process of starting an activity, then find the top 16008 // activity to check if its configuration needs to change. 16009 starting = mainStack.topRunningActivityLocked(null); 16010 } 16011 16012 if (starting != null) { 16013 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16014 // And we need to make sure at this point that all other activities 16015 // are made visible with the correct configuration. 16016 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16017 } 16018 } 16019 16020 if (values != null && mWindowManager != null) { 16021 mWindowManager.setNewConfiguration(mConfiguration); 16022 } 16023 16024 return kept; 16025 } 16026 16027 /** 16028 * Decide based on the configuration whether we should shouw the ANR, 16029 * crash, etc dialogs. The idea is that if there is no affordnace to 16030 * press the on-screen buttons, we shouldn't show the dialog. 16031 * 16032 * A thought: SystemUI might also want to get told about this, the Power 16033 * dialog / global actions also might want different behaviors. 16034 */ 16035 private static final boolean shouldShowDialogs(Configuration config) { 16036 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16037 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16038 } 16039 16040 /** 16041 * Save the locale. You must be inside a synchronized (this) block. 16042 */ 16043 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16044 if(isDiff) { 16045 SystemProperties.set("user.language", l.getLanguage()); 16046 SystemProperties.set("user.region", l.getCountry()); 16047 } 16048 16049 if(isPersist) { 16050 SystemProperties.set("persist.sys.language", l.getLanguage()); 16051 SystemProperties.set("persist.sys.country", l.getCountry()); 16052 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16053 } 16054 } 16055 16056 @Override 16057 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16058 synchronized (this) { 16059 ActivityRecord srec = ActivityRecord.forToken(token); 16060 if (srec.task != null && srec.task.stack != null) { 16061 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16062 } 16063 } 16064 return false; 16065 } 16066 16067 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16068 Intent resultData) { 16069 16070 synchronized (this) { 16071 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16072 if (stack != null) { 16073 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16074 } 16075 return false; 16076 } 16077 } 16078 16079 public int getLaunchedFromUid(IBinder activityToken) { 16080 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16081 if (srec == null) { 16082 return -1; 16083 } 16084 return srec.launchedFromUid; 16085 } 16086 16087 public String getLaunchedFromPackage(IBinder activityToken) { 16088 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16089 if (srec == null) { 16090 return null; 16091 } 16092 return srec.launchedFromPackage; 16093 } 16094 16095 // ========================================================= 16096 // LIFETIME MANAGEMENT 16097 // ========================================================= 16098 16099 // Returns which broadcast queue the app is the current [or imminent] receiver 16100 // on, or 'null' if the app is not an active broadcast recipient. 16101 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16102 BroadcastRecord r = app.curReceiver; 16103 if (r != null) { 16104 return r.queue; 16105 } 16106 16107 // It's not the current receiver, but it might be starting up to become one 16108 synchronized (this) { 16109 for (BroadcastQueue queue : mBroadcastQueues) { 16110 r = queue.mPendingBroadcast; 16111 if (r != null && r.curApp == app) { 16112 // found it; report which queue it's in 16113 return queue; 16114 } 16115 } 16116 } 16117 16118 return null; 16119 } 16120 16121 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16122 boolean doingAll, long now) { 16123 if (mAdjSeq == app.adjSeq) { 16124 // This adjustment has already been computed. 16125 return app.curRawAdj; 16126 } 16127 16128 if (app.thread == null) { 16129 app.adjSeq = mAdjSeq; 16130 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16131 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16132 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16133 } 16134 16135 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16136 app.adjSource = null; 16137 app.adjTarget = null; 16138 app.empty = false; 16139 app.cached = false; 16140 16141 final int activitiesSize = app.activities.size(); 16142 16143 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16144 // The max adjustment doesn't allow this app to be anything 16145 // below foreground, so it is not worth doing work for it. 16146 app.adjType = "fixed"; 16147 app.adjSeq = mAdjSeq; 16148 app.curRawAdj = app.maxAdj; 16149 app.foregroundActivities = false; 16150 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16151 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16152 // System processes can do UI, and when they do we want to have 16153 // them trim their memory after the user leaves the UI. To 16154 // facilitate this, here we need to determine whether or not it 16155 // is currently showing UI. 16156 app.systemNoUi = true; 16157 if (app == TOP_APP) { 16158 app.systemNoUi = false; 16159 } else if (activitiesSize > 0) { 16160 for (int j = 0; j < activitiesSize; j++) { 16161 final ActivityRecord r = app.activities.get(j); 16162 if (r.visible) { 16163 app.systemNoUi = false; 16164 } 16165 } 16166 } 16167 if (!app.systemNoUi) { 16168 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16169 } 16170 return (app.curAdj=app.maxAdj); 16171 } 16172 16173 app.systemNoUi = false; 16174 16175 // Determine the importance of the process, starting with most 16176 // important to least, and assign an appropriate OOM adjustment. 16177 int adj; 16178 int schedGroup; 16179 int procState; 16180 boolean foregroundActivities = false; 16181 BroadcastQueue queue; 16182 if (app == TOP_APP) { 16183 // The last app on the list is the foreground app. 16184 adj = ProcessList.FOREGROUND_APP_ADJ; 16185 schedGroup = Process.THREAD_GROUP_DEFAULT; 16186 app.adjType = "top-activity"; 16187 foregroundActivities = true; 16188 procState = ActivityManager.PROCESS_STATE_TOP; 16189 } else if (app.instrumentationClass != null) { 16190 // Don't want to kill running instrumentation. 16191 adj = ProcessList.FOREGROUND_APP_ADJ; 16192 schedGroup = Process.THREAD_GROUP_DEFAULT; 16193 app.adjType = "instrumentation"; 16194 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16195 } else if ((queue = isReceivingBroadcast(app)) != null) { 16196 // An app that is currently receiving a broadcast also 16197 // counts as being in the foreground for OOM killer purposes. 16198 // It's placed in a sched group based on the nature of the 16199 // broadcast as reflected by which queue it's active in. 16200 adj = ProcessList.FOREGROUND_APP_ADJ; 16201 schedGroup = (queue == mFgBroadcastQueue) 16202 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16203 app.adjType = "broadcast"; 16204 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16205 } else if (app.executingServices.size() > 0) { 16206 // An app that is currently executing a service callback also 16207 // counts as being in the foreground. 16208 adj = ProcessList.FOREGROUND_APP_ADJ; 16209 schedGroup = app.execServicesFg ? 16210 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16211 app.adjType = "exec-service"; 16212 procState = ActivityManager.PROCESS_STATE_SERVICE; 16213 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16214 } else { 16215 // As far as we know the process is empty. We may change our mind later. 16216 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16217 // At this point we don't actually know the adjustment. Use the cached adj 16218 // value that the caller wants us to. 16219 adj = cachedAdj; 16220 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16221 app.cached = true; 16222 app.empty = true; 16223 app.adjType = "cch-empty"; 16224 } 16225 16226 // Examine all activities if not already foreground. 16227 if (!foregroundActivities && activitiesSize > 0) { 16228 for (int j = 0; j < activitiesSize; j++) { 16229 final ActivityRecord r = app.activities.get(j); 16230 if (r.app != app) { 16231 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16232 + app + "?!?"); 16233 continue; 16234 } 16235 if (r.visible) { 16236 // App has a visible activity; only upgrade adjustment. 16237 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16238 adj = ProcessList.VISIBLE_APP_ADJ; 16239 app.adjType = "visible"; 16240 } 16241 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16242 procState = ActivityManager.PROCESS_STATE_TOP; 16243 } 16244 schedGroup = Process.THREAD_GROUP_DEFAULT; 16245 app.cached = false; 16246 app.empty = false; 16247 foregroundActivities = true; 16248 break; 16249 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16250 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16251 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16252 app.adjType = "pausing"; 16253 } 16254 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16255 procState = ActivityManager.PROCESS_STATE_TOP; 16256 } 16257 schedGroup = Process.THREAD_GROUP_DEFAULT; 16258 app.cached = false; 16259 app.empty = false; 16260 foregroundActivities = true; 16261 } else if (r.state == ActivityState.STOPPING) { 16262 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16263 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16264 app.adjType = "stopping"; 16265 } 16266 // For the process state, we will at this point consider the 16267 // process to be cached. It will be cached either as an activity 16268 // or empty depending on whether the activity is finishing. We do 16269 // this so that we can treat the process as cached for purposes of 16270 // memory trimming (determing current memory level, trim command to 16271 // send to process) since there can be an arbitrary number of stopping 16272 // processes and they should soon all go into the cached state. 16273 if (!r.finishing) { 16274 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16275 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16276 } 16277 } 16278 app.cached = false; 16279 app.empty = false; 16280 foregroundActivities = true; 16281 } else { 16282 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16283 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16284 app.adjType = "cch-act"; 16285 } 16286 } 16287 } 16288 } 16289 16290 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16291 if (app.foregroundServices) { 16292 // The user is aware of this app, so make it visible. 16293 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16294 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16295 app.cached = false; 16296 app.adjType = "fg-service"; 16297 schedGroup = Process.THREAD_GROUP_DEFAULT; 16298 } else if (app.forcingToForeground != null) { 16299 // The user is aware of this app, so make it visible. 16300 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16301 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16302 app.cached = false; 16303 app.adjType = "force-fg"; 16304 app.adjSource = app.forcingToForeground; 16305 schedGroup = Process.THREAD_GROUP_DEFAULT; 16306 } 16307 } 16308 16309 if (app == mHeavyWeightProcess) { 16310 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16311 // We don't want to kill the current heavy-weight process. 16312 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16313 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16314 app.cached = false; 16315 app.adjType = "heavy"; 16316 } 16317 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16318 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16319 } 16320 } 16321 16322 if (app == mHomeProcess) { 16323 if (adj > ProcessList.HOME_APP_ADJ) { 16324 // This process is hosting what we currently consider to be the 16325 // home app, so we don't want to let it go into the background. 16326 adj = ProcessList.HOME_APP_ADJ; 16327 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16328 app.cached = false; 16329 app.adjType = "home"; 16330 } 16331 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16332 procState = ActivityManager.PROCESS_STATE_HOME; 16333 } 16334 } 16335 16336 if (app == mPreviousProcess && app.activities.size() > 0) { 16337 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16338 // This was the previous process that showed UI to the user. 16339 // We want to try to keep it around more aggressively, to give 16340 // a good experience around switching between two apps. 16341 adj = ProcessList.PREVIOUS_APP_ADJ; 16342 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16343 app.cached = false; 16344 app.adjType = "previous"; 16345 } 16346 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16347 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16348 } 16349 } 16350 16351 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16352 + " reason=" + app.adjType); 16353 16354 // By default, we use the computed adjustment. It may be changed if 16355 // there are applications dependent on our services or providers, but 16356 // this gives us a baseline and makes sure we don't get into an 16357 // infinite recursion. 16358 app.adjSeq = mAdjSeq; 16359 app.curRawAdj = adj; 16360 app.hasStartedServices = false; 16361 16362 if (mBackupTarget != null && app == mBackupTarget.app) { 16363 // If possible we want to avoid killing apps while they're being backed up 16364 if (adj > ProcessList.BACKUP_APP_ADJ) { 16365 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16366 adj = ProcessList.BACKUP_APP_ADJ; 16367 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16368 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16369 } 16370 app.adjType = "backup"; 16371 app.cached = false; 16372 } 16373 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16374 procState = ActivityManager.PROCESS_STATE_BACKUP; 16375 } 16376 } 16377 16378 boolean mayBeTop = false; 16379 16380 for (int is = app.services.size()-1; 16381 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16382 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16383 || procState > ActivityManager.PROCESS_STATE_TOP); 16384 is--) { 16385 ServiceRecord s = app.services.valueAt(is); 16386 if (s.startRequested) { 16387 app.hasStartedServices = true; 16388 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16389 procState = ActivityManager.PROCESS_STATE_SERVICE; 16390 } 16391 if (app.hasShownUi && app != mHomeProcess) { 16392 // If this process has shown some UI, let it immediately 16393 // go to the LRU list because it may be pretty heavy with 16394 // UI stuff. We'll tag it with a label just to help 16395 // debug and understand what is going on. 16396 if (adj > ProcessList.SERVICE_ADJ) { 16397 app.adjType = "cch-started-ui-services"; 16398 } 16399 } else { 16400 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16401 // This service has seen some activity within 16402 // recent memory, so we will keep its process ahead 16403 // of the background processes. 16404 if (adj > ProcessList.SERVICE_ADJ) { 16405 adj = ProcessList.SERVICE_ADJ; 16406 app.adjType = "started-services"; 16407 app.cached = false; 16408 } 16409 } 16410 // If we have let the service slide into the background 16411 // state, still have some text describing what it is doing 16412 // even though the service no longer has an impact. 16413 if (adj > ProcessList.SERVICE_ADJ) { 16414 app.adjType = "cch-started-services"; 16415 } 16416 } 16417 } 16418 for (int conni = s.connections.size()-1; 16419 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16420 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16421 || procState > ActivityManager.PROCESS_STATE_TOP); 16422 conni--) { 16423 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16424 for (int i = 0; 16425 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16426 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16427 || procState > ActivityManager.PROCESS_STATE_TOP); 16428 i++) { 16429 // XXX should compute this based on the max of 16430 // all connected clients. 16431 ConnectionRecord cr = clist.get(i); 16432 if (cr.binding.client == app) { 16433 // Binding to ourself is not interesting. 16434 continue; 16435 } 16436 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16437 ProcessRecord client = cr.binding.client; 16438 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16439 TOP_APP, doingAll, now); 16440 int clientProcState = client.curProcState; 16441 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16442 // If the other app is cached for any reason, for purposes here 16443 // we are going to consider it empty. The specific cached state 16444 // doesn't propagate except under certain conditions. 16445 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16446 } 16447 String adjType = null; 16448 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16449 // Not doing bind OOM management, so treat 16450 // this guy more like a started service. 16451 if (app.hasShownUi && app != mHomeProcess) { 16452 // If this process has shown some UI, let it immediately 16453 // go to the LRU list because it may be pretty heavy with 16454 // UI stuff. We'll tag it with a label just to help 16455 // debug and understand what is going on. 16456 if (adj > clientAdj) { 16457 adjType = "cch-bound-ui-services"; 16458 } 16459 app.cached = false; 16460 clientAdj = adj; 16461 clientProcState = procState; 16462 } else { 16463 if (now >= (s.lastActivity 16464 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16465 // This service has not seen activity within 16466 // recent memory, so allow it to drop to the 16467 // LRU list if there is no other reason to keep 16468 // it around. We'll also tag it with a label just 16469 // to help debug and undertand what is going on. 16470 if (adj > clientAdj) { 16471 adjType = "cch-bound-services"; 16472 } 16473 clientAdj = adj; 16474 } 16475 } 16476 } 16477 if (adj > clientAdj) { 16478 // If this process has recently shown UI, and 16479 // the process that is binding to it is less 16480 // important than being visible, then we don't 16481 // care about the binding as much as we care 16482 // about letting this process get into the LRU 16483 // list to be killed and restarted if needed for 16484 // memory. 16485 if (app.hasShownUi && app != mHomeProcess 16486 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16487 adjType = "cch-bound-ui-services"; 16488 } else { 16489 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16490 |Context.BIND_IMPORTANT)) != 0) { 16491 adj = clientAdj; 16492 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16493 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16494 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16495 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16496 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16497 adj = clientAdj; 16498 } else { 16499 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16500 adj = ProcessList.VISIBLE_APP_ADJ; 16501 } 16502 } 16503 if (!client.cached) { 16504 app.cached = false; 16505 } 16506 adjType = "service"; 16507 } 16508 } 16509 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16510 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16511 schedGroup = Process.THREAD_GROUP_DEFAULT; 16512 } 16513 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16514 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16515 // Special handling of clients who are in the top state. 16516 // We *may* want to consider this process to be in the 16517 // top state as well, but only if there is not another 16518 // reason for it to be running. Being on the top is a 16519 // special state, meaning you are specifically running 16520 // for the current top app. If the process is already 16521 // running in the background for some other reason, it 16522 // is more important to continue considering it to be 16523 // in the background state. 16524 mayBeTop = true; 16525 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16526 } else { 16527 // Special handling for above-top states (persistent 16528 // processes). These should not bring the current process 16529 // into the top state, since they are not on top. Instead 16530 // give them the best state after that. 16531 clientProcState = 16532 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16533 } 16534 } 16535 } else { 16536 if (clientProcState < 16537 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16538 clientProcState = 16539 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16540 } 16541 } 16542 if (procState > clientProcState) { 16543 procState = clientProcState; 16544 } 16545 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16546 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16547 app.pendingUiClean = true; 16548 } 16549 if (adjType != null) { 16550 app.adjType = adjType; 16551 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16552 .REASON_SERVICE_IN_USE; 16553 app.adjSource = cr.binding.client; 16554 app.adjSourceProcState = clientProcState; 16555 app.adjTarget = s.name; 16556 } 16557 } 16558 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16559 app.treatLikeActivity = true; 16560 } 16561 final ActivityRecord a = cr.activity; 16562 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16563 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16564 (a.visible || a.state == ActivityState.RESUMED 16565 || a.state == ActivityState.PAUSING)) { 16566 adj = ProcessList.FOREGROUND_APP_ADJ; 16567 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16568 schedGroup = Process.THREAD_GROUP_DEFAULT; 16569 } 16570 app.cached = false; 16571 app.adjType = "service"; 16572 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16573 .REASON_SERVICE_IN_USE; 16574 app.adjSource = a; 16575 app.adjSourceProcState = procState; 16576 app.adjTarget = s.name; 16577 } 16578 } 16579 } 16580 } 16581 } 16582 16583 for (int provi = app.pubProviders.size()-1; 16584 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16585 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16586 || procState > ActivityManager.PROCESS_STATE_TOP); 16587 provi--) { 16588 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16589 for (int i = cpr.connections.size()-1; 16590 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16591 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16592 || procState > ActivityManager.PROCESS_STATE_TOP); 16593 i--) { 16594 ContentProviderConnection conn = cpr.connections.get(i); 16595 ProcessRecord client = conn.client; 16596 if (client == app) { 16597 // Being our own client is not interesting. 16598 continue; 16599 } 16600 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16601 int clientProcState = client.curProcState; 16602 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16603 // If the other app is cached for any reason, for purposes here 16604 // we are going to consider it empty. 16605 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16606 } 16607 if (adj > clientAdj) { 16608 if (app.hasShownUi && app != mHomeProcess 16609 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16610 app.adjType = "cch-ui-provider"; 16611 } else { 16612 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16613 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16614 app.adjType = "provider"; 16615 } 16616 app.cached &= client.cached; 16617 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16618 .REASON_PROVIDER_IN_USE; 16619 app.adjSource = client; 16620 app.adjSourceProcState = clientProcState; 16621 app.adjTarget = cpr.name; 16622 } 16623 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16624 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16625 // Special handling of clients who are in the top state. 16626 // We *may* want to consider this process to be in the 16627 // top state as well, but only if there is not another 16628 // reason for it to be running. Being on the top is a 16629 // special state, meaning you are specifically running 16630 // for the current top app. If the process is already 16631 // running in the background for some other reason, it 16632 // is more important to continue considering it to be 16633 // in the background state. 16634 mayBeTop = true; 16635 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16636 } else { 16637 // Special handling for above-top states (persistent 16638 // processes). These should not bring the current process 16639 // into the top state, since they are not on top. Instead 16640 // give them the best state after that. 16641 clientProcState = 16642 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16643 } 16644 } 16645 if (procState > clientProcState) { 16646 procState = clientProcState; 16647 } 16648 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16649 schedGroup = Process.THREAD_GROUP_DEFAULT; 16650 } 16651 } 16652 // If the provider has external (non-framework) process 16653 // dependencies, ensure that its adjustment is at least 16654 // FOREGROUND_APP_ADJ. 16655 if (cpr.hasExternalProcessHandles()) { 16656 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16657 adj = ProcessList.FOREGROUND_APP_ADJ; 16658 schedGroup = Process.THREAD_GROUP_DEFAULT; 16659 app.cached = false; 16660 app.adjType = "provider"; 16661 app.adjTarget = cpr.name; 16662 } 16663 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16664 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16665 } 16666 } 16667 } 16668 16669 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16670 // A client of one of our services or providers is in the top state. We 16671 // *may* want to be in the top state, but not if we are already running in 16672 // the background for some other reason. For the decision here, we are going 16673 // to pick out a few specific states that we want to remain in when a client 16674 // is top (states that tend to be longer-term) and otherwise allow it to go 16675 // to the top state. 16676 switch (procState) { 16677 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16678 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16679 case ActivityManager.PROCESS_STATE_SERVICE: 16680 // These all are longer-term states, so pull them up to the top 16681 // of the background states, but not all the way to the top state. 16682 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16683 break; 16684 default: 16685 // Otherwise, top is a better choice, so take it. 16686 procState = ActivityManager.PROCESS_STATE_TOP; 16687 break; 16688 } 16689 } 16690 16691 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16692 if (app.hasClientActivities) { 16693 // This is a cached process, but with client activities. Mark it so. 16694 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16695 app.adjType = "cch-client-act"; 16696 } else if (app.treatLikeActivity) { 16697 // This is a cached process, but somebody wants us to treat it like it has 16698 // an activity, okay! 16699 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16700 app.adjType = "cch-as-act"; 16701 } 16702 } 16703 16704 if (adj == ProcessList.SERVICE_ADJ) { 16705 if (doingAll) { 16706 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16707 mNewNumServiceProcs++; 16708 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16709 if (!app.serviceb) { 16710 // This service isn't far enough down on the LRU list to 16711 // normally be a B service, but if we are low on RAM and it 16712 // is large we want to force it down since we would prefer to 16713 // keep launcher over it. 16714 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16715 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16716 app.serviceHighRam = true; 16717 app.serviceb = true; 16718 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16719 } else { 16720 mNewNumAServiceProcs++; 16721 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16722 } 16723 } else { 16724 app.serviceHighRam = false; 16725 } 16726 } 16727 if (app.serviceb) { 16728 adj = ProcessList.SERVICE_B_ADJ; 16729 } 16730 } 16731 16732 app.curRawAdj = adj; 16733 16734 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16735 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16736 if (adj > app.maxAdj) { 16737 adj = app.maxAdj; 16738 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16739 schedGroup = Process.THREAD_GROUP_DEFAULT; 16740 } 16741 } 16742 16743 // Do final modification to adj. Everything we do between here and applying 16744 // the final setAdj must be done in this function, because we will also use 16745 // it when computing the final cached adj later. Note that we don't need to 16746 // worry about this for max adj above, since max adj will always be used to 16747 // keep it out of the cached vaues. 16748 app.curAdj = app.modifyRawOomAdj(adj); 16749 app.curSchedGroup = schedGroup; 16750 app.curProcState = procState; 16751 app.foregroundActivities = foregroundActivities; 16752 16753 return app.curRawAdj; 16754 } 16755 16756 /** 16757 * Schedule PSS collection of a process. 16758 */ 16759 void requestPssLocked(ProcessRecord proc, int procState) { 16760 if (mPendingPssProcesses.contains(proc)) { 16761 return; 16762 } 16763 if (mPendingPssProcesses.size() == 0) { 16764 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16765 } 16766 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16767 proc.pssProcState = procState; 16768 mPendingPssProcesses.add(proc); 16769 } 16770 16771 /** 16772 * Schedule PSS collection of all processes. 16773 */ 16774 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16775 if (!always) { 16776 if (now < (mLastFullPssTime + 16777 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16778 return; 16779 } 16780 } 16781 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16782 mLastFullPssTime = now; 16783 mFullPssPending = true; 16784 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16785 mPendingPssProcesses.clear(); 16786 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16787 ProcessRecord app = mLruProcesses.get(i); 16788 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16789 app.pssProcState = app.setProcState; 16790 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16791 isSleeping(), now); 16792 mPendingPssProcesses.add(app); 16793 } 16794 } 16795 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16796 } 16797 16798 /** 16799 * Ask a given process to GC right now. 16800 */ 16801 final void performAppGcLocked(ProcessRecord app) { 16802 try { 16803 app.lastRequestedGc = SystemClock.uptimeMillis(); 16804 if (app.thread != null) { 16805 if (app.reportLowMemory) { 16806 app.reportLowMemory = false; 16807 app.thread.scheduleLowMemory(); 16808 } else { 16809 app.thread.processInBackground(); 16810 } 16811 } 16812 } catch (Exception e) { 16813 // whatever. 16814 } 16815 } 16816 16817 /** 16818 * Returns true if things are idle enough to perform GCs. 16819 */ 16820 private final boolean canGcNowLocked() { 16821 boolean processingBroadcasts = false; 16822 for (BroadcastQueue q : mBroadcastQueues) { 16823 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16824 processingBroadcasts = true; 16825 } 16826 } 16827 return !processingBroadcasts 16828 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16829 } 16830 16831 /** 16832 * Perform GCs on all processes that are waiting for it, but only 16833 * if things are idle. 16834 */ 16835 final void performAppGcsLocked() { 16836 final int N = mProcessesToGc.size(); 16837 if (N <= 0) { 16838 return; 16839 } 16840 if (canGcNowLocked()) { 16841 while (mProcessesToGc.size() > 0) { 16842 ProcessRecord proc = mProcessesToGc.remove(0); 16843 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16844 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16845 <= SystemClock.uptimeMillis()) { 16846 // To avoid spamming the system, we will GC processes one 16847 // at a time, waiting a few seconds between each. 16848 performAppGcLocked(proc); 16849 scheduleAppGcsLocked(); 16850 return; 16851 } else { 16852 // It hasn't been long enough since we last GCed this 16853 // process... put it in the list to wait for its time. 16854 addProcessToGcListLocked(proc); 16855 break; 16856 } 16857 } 16858 } 16859 16860 scheduleAppGcsLocked(); 16861 } 16862 } 16863 16864 /** 16865 * If all looks good, perform GCs on all processes waiting for them. 16866 */ 16867 final void performAppGcsIfAppropriateLocked() { 16868 if (canGcNowLocked()) { 16869 performAppGcsLocked(); 16870 return; 16871 } 16872 // Still not idle, wait some more. 16873 scheduleAppGcsLocked(); 16874 } 16875 16876 /** 16877 * Schedule the execution of all pending app GCs. 16878 */ 16879 final void scheduleAppGcsLocked() { 16880 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16881 16882 if (mProcessesToGc.size() > 0) { 16883 // Schedule a GC for the time to the next process. 16884 ProcessRecord proc = mProcessesToGc.get(0); 16885 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16886 16887 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16888 long now = SystemClock.uptimeMillis(); 16889 if (when < (now+GC_TIMEOUT)) { 16890 when = now + GC_TIMEOUT; 16891 } 16892 mHandler.sendMessageAtTime(msg, when); 16893 } 16894 } 16895 16896 /** 16897 * Add a process to the array of processes waiting to be GCed. Keeps the 16898 * list in sorted order by the last GC time. The process can't already be 16899 * on the list. 16900 */ 16901 final void addProcessToGcListLocked(ProcessRecord proc) { 16902 boolean added = false; 16903 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16904 if (mProcessesToGc.get(i).lastRequestedGc < 16905 proc.lastRequestedGc) { 16906 added = true; 16907 mProcessesToGc.add(i+1, proc); 16908 break; 16909 } 16910 } 16911 if (!added) { 16912 mProcessesToGc.add(0, proc); 16913 } 16914 } 16915 16916 /** 16917 * Set up to ask a process to GC itself. This will either do it 16918 * immediately, or put it on the list of processes to gc the next 16919 * time things are idle. 16920 */ 16921 final void scheduleAppGcLocked(ProcessRecord app) { 16922 long now = SystemClock.uptimeMillis(); 16923 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16924 return; 16925 } 16926 if (!mProcessesToGc.contains(app)) { 16927 addProcessToGcListLocked(app); 16928 scheduleAppGcsLocked(); 16929 } 16930 } 16931 16932 final void checkExcessivePowerUsageLocked(boolean doKills) { 16933 updateCpuStatsNow(); 16934 16935 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16936 boolean doWakeKills = doKills; 16937 boolean doCpuKills = doKills; 16938 if (mLastPowerCheckRealtime == 0) { 16939 doWakeKills = false; 16940 } 16941 if (mLastPowerCheckUptime == 0) { 16942 doCpuKills = false; 16943 } 16944 if (stats.isScreenOn()) { 16945 doWakeKills = false; 16946 } 16947 final long curRealtime = SystemClock.elapsedRealtime(); 16948 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16949 final long curUptime = SystemClock.uptimeMillis(); 16950 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16951 mLastPowerCheckRealtime = curRealtime; 16952 mLastPowerCheckUptime = curUptime; 16953 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16954 doWakeKills = false; 16955 } 16956 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16957 doCpuKills = false; 16958 } 16959 int i = mLruProcesses.size(); 16960 while (i > 0) { 16961 i--; 16962 ProcessRecord app = mLruProcesses.get(i); 16963 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16964 long wtime; 16965 synchronized (stats) { 16966 wtime = stats.getProcessWakeTime(app.info.uid, 16967 app.pid, curRealtime); 16968 } 16969 long wtimeUsed = wtime - app.lastWakeTime; 16970 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16971 if (DEBUG_POWER) { 16972 StringBuilder sb = new StringBuilder(128); 16973 sb.append("Wake for "); 16974 app.toShortString(sb); 16975 sb.append(": over "); 16976 TimeUtils.formatDuration(realtimeSince, sb); 16977 sb.append(" used "); 16978 TimeUtils.formatDuration(wtimeUsed, sb); 16979 sb.append(" ("); 16980 sb.append((wtimeUsed*100)/realtimeSince); 16981 sb.append("%)"); 16982 Slog.i(TAG, sb.toString()); 16983 sb.setLength(0); 16984 sb.append("CPU for "); 16985 app.toShortString(sb); 16986 sb.append(": over "); 16987 TimeUtils.formatDuration(uptimeSince, sb); 16988 sb.append(" used "); 16989 TimeUtils.formatDuration(cputimeUsed, sb); 16990 sb.append(" ("); 16991 sb.append((cputimeUsed*100)/uptimeSince); 16992 sb.append("%)"); 16993 Slog.i(TAG, sb.toString()); 16994 } 16995 // If a process has held a wake lock for more 16996 // than 50% of the time during this period, 16997 // that sounds bad. Kill! 16998 if (doWakeKills && realtimeSince > 0 16999 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17000 synchronized (stats) { 17001 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17002 realtimeSince, wtimeUsed); 17003 } 17004 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17005 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17006 } else if (doCpuKills && uptimeSince > 0 17007 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17008 synchronized (stats) { 17009 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17010 uptimeSince, cputimeUsed); 17011 } 17012 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17013 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17014 } else { 17015 app.lastWakeTime = wtime; 17016 app.lastCpuTime = app.curCpuTime; 17017 } 17018 } 17019 } 17020 } 17021 17022 private final boolean applyOomAdjLocked(ProcessRecord app, 17023 ProcessRecord TOP_APP, boolean doingAll, long now) { 17024 boolean success = true; 17025 17026 if (app.curRawAdj != app.setRawAdj) { 17027 app.setRawAdj = app.curRawAdj; 17028 } 17029 17030 int changes = 0; 17031 17032 if (app.curAdj != app.setAdj) { 17033 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17034 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17035 TAG, "Set " + app.pid + " " + app.processName + 17036 " adj " + app.curAdj + ": " + app.adjType); 17037 app.setAdj = app.curAdj; 17038 } 17039 17040 if (app.setSchedGroup != app.curSchedGroup) { 17041 app.setSchedGroup = app.curSchedGroup; 17042 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17043 "Setting process group of " + app.processName 17044 + " to " + app.curSchedGroup); 17045 if (app.waitingToKill != null && 17046 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17047 app.kill(app.waitingToKill, true); 17048 success = false; 17049 } else { 17050 if (true) { 17051 long oldId = Binder.clearCallingIdentity(); 17052 try { 17053 Process.setProcessGroup(app.pid, app.curSchedGroup); 17054 } catch (Exception e) { 17055 Slog.w(TAG, "Failed setting process group of " + app.pid 17056 + " to " + app.curSchedGroup); 17057 e.printStackTrace(); 17058 } finally { 17059 Binder.restoreCallingIdentity(oldId); 17060 } 17061 } else { 17062 if (app.thread != null) { 17063 try { 17064 app.thread.setSchedulingGroup(app.curSchedGroup); 17065 } catch (RemoteException e) { 17066 } 17067 } 17068 } 17069 Process.setSwappiness(app.pid, 17070 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17071 } 17072 } 17073 if (app.repForegroundActivities != app.foregroundActivities) { 17074 app.repForegroundActivities = app.foregroundActivities; 17075 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17076 } 17077 if (app.repProcState != app.curProcState) { 17078 app.repProcState = app.curProcState; 17079 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17080 if (app.thread != null) { 17081 try { 17082 if (false) { 17083 //RuntimeException h = new RuntimeException("here"); 17084 Slog.i(TAG, "Sending new process state " + app.repProcState 17085 + " to " + app /*, h*/); 17086 } 17087 app.thread.setProcessState(app.repProcState); 17088 } catch (RemoteException e) { 17089 } 17090 } 17091 } 17092 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17093 app.setProcState)) { 17094 app.lastStateTime = now; 17095 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17096 isSleeping(), now); 17097 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17098 + ProcessList.makeProcStateString(app.setProcState) + " to " 17099 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17100 + (app.nextPssTime-now) + ": " + app); 17101 } else { 17102 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17103 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17104 requestPssLocked(app, app.setProcState); 17105 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17106 isSleeping(), now); 17107 } else if (false && DEBUG_PSS) { 17108 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17109 } 17110 } 17111 if (app.setProcState != app.curProcState) { 17112 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17113 "Proc state change of " + app.processName 17114 + " to " + app.curProcState); 17115 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17116 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17117 if (setImportant && !curImportant) { 17118 // This app is no longer something we consider important enough to allow to 17119 // use arbitrary amounts of battery power. Note 17120 // its current wake lock time to later know to kill it if 17121 // it is not behaving well. 17122 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17123 synchronized (stats) { 17124 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17125 app.pid, SystemClock.elapsedRealtime()); 17126 } 17127 app.lastCpuTime = app.curCpuTime; 17128 17129 } 17130 app.setProcState = app.curProcState; 17131 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17132 app.notCachedSinceIdle = false; 17133 } 17134 if (!doingAll) { 17135 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17136 } else { 17137 app.procStateChanged = true; 17138 } 17139 } 17140 17141 if (changes != 0) { 17142 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17143 int i = mPendingProcessChanges.size()-1; 17144 ProcessChangeItem item = null; 17145 while (i >= 0) { 17146 item = mPendingProcessChanges.get(i); 17147 if (item.pid == app.pid) { 17148 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17149 break; 17150 } 17151 i--; 17152 } 17153 if (i < 0) { 17154 // No existing item in pending changes; need a new one. 17155 final int NA = mAvailProcessChanges.size(); 17156 if (NA > 0) { 17157 item = mAvailProcessChanges.remove(NA-1); 17158 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17159 } else { 17160 item = new ProcessChangeItem(); 17161 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17162 } 17163 item.changes = 0; 17164 item.pid = app.pid; 17165 item.uid = app.info.uid; 17166 if (mPendingProcessChanges.size() == 0) { 17167 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17168 "*** Enqueueing dispatch processes changed!"); 17169 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17170 } 17171 mPendingProcessChanges.add(item); 17172 } 17173 item.changes |= changes; 17174 item.processState = app.repProcState; 17175 item.foregroundActivities = app.repForegroundActivities; 17176 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17177 + Integer.toHexString(System.identityHashCode(item)) 17178 + " " + app.toShortString() + ": changes=" + item.changes 17179 + " procState=" + item.processState 17180 + " foreground=" + item.foregroundActivities 17181 + " type=" + app.adjType + " source=" + app.adjSource 17182 + " target=" + app.adjTarget); 17183 } 17184 17185 return success; 17186 } 17187 17188 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17189 if (proc.thread != null) { 17190 if (proc.baseProcessTracker != null) { 17191 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17192 } 17193 if (proc.repProcState >= 0) { 17194 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17195 proc.repProcState); 17196 } 17197 } 17198 } 17199 17200 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17201 ProcessRecord TOP_APP, boolean doingAll, long now) { 17202 if (app.thread == null) { 17203 return false; 17204 } 17205 17206 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17207 17208 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17209 } 17210 17211 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17212 boolean oomAdj) { 17213 if (isForeground != proc.foregroundServices) { 17214 proc.foregroundServices = isForeground; 17215 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17216 proc.info.uid); 17217 if (isForeground) { 17218 if (curProcs == null) { 17219 curProcs = new ArrayList<ProcessRecord>(); 17220 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17221 } 17222 if (!curProcs.contains(proc)) { 17223 curProcs.add(proc); 17224 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17225 proc.info.packageName, proc.info.uid); 17226 } 17227 } else { 17228 if (curProcs != null) { 17229 if (curProcs.remove(proc)) { 17230 mBatteryStatsService.noteEvent( 17231 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17232 proc.info.packageName, proc.info.uid); 17233 if (curProcs.size() <= 0) { 17234 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17235 } 17236 } 17237 } 17238 } 17239 if (oomAdj) { 17240 updateOomAdjLocked(); 17241 } 17242 } 17243 } 17244 17245 private final ActivityRecord resumedAppLocked() { 17246 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17247 String pkg; 17248 int uid; 17249 if (act != null) { 17250 pkg = act.packageName; 17251 uid = act.info.applicationInfo.uid; 17252 } else { 17253 pkg = null; 17254 uid = -1; 17255 } 17256 // Has the UID or resumed package name changed? 17257 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17258 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17259 if (mCurResumedPackage != null) { 17260 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17261 mCurResumedPackage, mCurResumedUid); 17262 } 17263 mCurResumedPackage = pkg; 17264 mCurResumedUid = uid; 17265 if (mCurResumedPackage != null) { 17266 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17267 mCurResumedPackage, mCurResumedUid); 17268 } 17269 } 17270 return act; 17271 } 17272 17273 final boolean updateOomAdjLocked(ProcessRecord app) { 17274 final ActivityRecord TOP_ACT = resumedAppLocked(); 17275 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17276 final boolean wasCached = app.cached; 17277 17278 mAdjSeq++; 17279 17280 // This is the desired cached adjusment we want to tell it to use. 17281 // If our app is currently cached, we know it, and that is it. Otherwise, 17282 // we don't know it yet, and it needs to now be cached we will then 17283 // need to do a complete oom adj. 17284 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17285 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17286 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17287 SystemClock.uptimeMillis()); 17288 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17289 // Changed to/from cached state, so apps after it in the LRU 17290 // list may also be changed. 17291 updateOomAdjLocked(); 17292 } 17293 return success; 17294 } 17295 17296 final void updateOomAdjLocked() { 17297 final ActivityRecord TOP_ACT = resumedAppLocked(); 17298 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17299 final long now = SystemClock.uptimeMillis(); 17300 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17301 final int N = mLruProcesses.size(); 17302 17303 if (false) { 17304 RuntimeException e = new RuntimeException(); 17305 e.fillInStackTrace(); 17306 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17307 } 17308 17309 mAdjSeq++; 17310 mNewNumServiceProcs = 0; 17311 mNewNumAServiceProcs = 0; 17312 17313 final int emptyProcessLimit; 17314 final int cachedProcessLimit; 17315 if (mProcessLimit <= 0) { 17316 emptyProcessLimit = cachedProcessLimit = 0; 17317 } else if (mProcessLimit == 1) { 17318 emptyProcessLimit = 1; 17319 cachedProcessLimit = 0; 17320 } else { 17321 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17322 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17323 } 17324 17325 // Let's determine how many processes we have running vs. 17326 // how many slots we have for background processes; we may want 17327 // to put multiple processes in a slot of there are enough of 17328 // them. 17329 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17330 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17331 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17332 if (numEmptyProcs > cachedProcessLimit) { 17333 // If there are more empty processes than our limit on cached 17334 // processes, then use the cached process limit for the factor. 17335 // This ensures that the really old empty processes get pushed 17336 // down to the bottom, so if we are running low on memory we will 17337 // have a better chance at keeping around more cached processes 17338 // instead of a gazillion empty processes. 17339 numEmptyProcs = cachedProcessLimit; 17340 } 17341 int emptyFactor = numEmptyProcs/numSlots; 17342 if (emptyFactor < 1) emptyFactor = 1; 17343 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17344 if (cachedFactor < 1) cachedFactor = 1; 17345 int stepCached = 0; 17346 int stepEmpty = 0; 17347 int numCached = 0; 17348 int numEmpty = 0; 17349 int numTrimming = 0; 17350 17351 mNumNonCachedProcs = 0; 17352 mNumCachedHiddenProcs = 0; 17353 17354 // First update the OOM adjustment for each of the 17355 // application processes based on their current state. 17356 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17357 int nextCachedAdj = curCachedAdj+1; 17358 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17359 int nextEmptyAdj = curEmptyAdj+2; 17360 for (int i=N-1; i>=0; i--) { 17361 ProcessRecord app = mLruProcesses.get(i); 17362 if (!app.killedByAm && app.thread != null) { 17363 app.procStateChanged = false; 17364 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17365 17366 // If we haven't yet assigned the final cached adj 17367 // to the process, do that now. 17368 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17369 switch (app.curProcState) { 17370 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17371 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17372 // This process is a cached process holding activities... 17373 // assign it the next cached value for that type, and then 17374 // step that cached level. 17375 app.curRawAdj = curCachedAdj; 17376 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17377 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17378 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17379 + ")"); 17380 if (curCachedAdj != nextCachedAdj) { 17381 stepCached++; 17382 if (stepCached >= cachedFactor) { 17383 stepCached = 0; 17384 curCachedAdj = nextCachedAdj; 17385 nextCachedAdj += 2; 17386 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17387 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17388 } 17389 } 17390 } 17391 break; 17392 default: 17393 // For everything else, assign next empty cached process 17394 // level and bump that up. Note that this means that 17395 // long-running services that have dropped down to the 17396 // cached level will be treated as empty (since their process 17397 // state is still as a service), which is what we want. 17398 app.curRawAdj = curEmptyAdj; 17399 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17400 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17401 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17402 + ")"); 17403 if (curEmptyAdj != nextEmptyAdj) { 17404 stepEmpty++; 17405 if (stepEmpty >= emptyFactor) { 17406 stepEmpty = 0; 17407 curEmptyAdj = nextEmptyAdj; 17408 nextEmptyAdj += 2; 17409 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17410 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17411 } 17412 } 17413 } 17414 break; 17415 } 17416 } 17417 17418 applyOomAdjLocked(app, TOP_APP, true, now); 17419 17420 // Count the number of process types. 17421 switch (app.curProcState) { 17422 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17423 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17424 mNumCachedHiddenProcs++; 17425 numCached++; 17426 if (numCached > cachedProcessLimit) { 17427 app.kill("cached #" + numCached, true); 17428 } 17429 break; 17430 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17431 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17432 && app.lastActivityTime < oldTime) { 17433 app.kill("empty for " 17434 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17435 / 1000) + "s", true); 17436 } else { 17437 numEmpty++; 17438 if (numEmpty > emptyProcessLimit) { 17439 app.kill("empty #" + numEmpty, true); 17440 } 17441 } 17442 break; 17443 default: 17444 mNumNonCachedProcs++; 17445 break; 17446 } 17447 17448 if (app.isolated && app.services.size() <= 0) { 17449 // If this is an isolated process, and there are no 17450 // services running in it, then the process is no longer 17451 // needed. We agressively kill these because we can by 17452 // definition not re-use the same process again, and it is 17453 // good to avoid having whatever code was running in them 17454 // left sitting around after no longer needed. 17455 app.kill("isolated not needed", true); 17456 } 17457 17458 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17459 && !app.killedByAm) { 17460 numTrimming++; 17461 } 17462 } 17463 } 17464 17465 mNumServiceProcs = mNewNumServiceProcs; 17466 17467 // Now determine the memory trimming level of background processes. 17468 // Unfortunately we need to start at the back of the list to do this 17469 // properly. We only do this if the number of background apps we 17470 // are managing to keep around is less than half the maximum we desire; 17471 // if we are keeping a good number around, we'll let them use whatever 17472 // memory they want. 17473 final int numCachedAndEmpty = numCached + numEmpty; 17474 int memFactor; 17475 if (numCached <= ProcessList.TRIM_CACHED_APPS 17476 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17477 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17478 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17479 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17480 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17481 } else { 17482 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17483 } 17484 } else { 17485 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17486 } 17487 // We always allow the memory level to go up (better). We only allow it to go 17488 // down if we are in a state where that is allowed, *and* the total number of processes 17489 // has gone down since last time. 17490 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17491 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17492 + " last=" + mLastNumProcesses); 17493 if (memFactor > mLastMemoryLevel) { 17494 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17495 memFactor = mLastMemoryLevel; 17496 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17497 } 17498 } 17499 mLastMemoryLevel = memFactor; 17500 mLastNumProcesses = mLruProcesses.size(); 17501 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17502 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17503 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17504 if (mLowRamStartTime == 0) { 17505 mLowRamStartTime = now; 17506 } 17507 int step = 0; 17508 int fgTrimLevel; 17509 switch (memFactor) { 17510 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17511 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17512 break; 17513 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17514 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17515 break; 17516 default: 17517 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17518 break; 17519 } 17520 int factor = numTrimming/3; 17521 int minFactor = 2; 17522 if (mHomeProcess != null) minFactor++; 17523 if (mPreviousProcess != null) minFactor++; 17524 if (factor < minFactor) factor = minFactor; 17525 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17526 for (int i=N-1; i>=0; i--) { 17527 ProcessRecord app = mLruProcesses.get(i); 17528 if (allChanged || app.procStateChanged) { 17529 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17530 app.procStateChanged = false; 17531 } 17532 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17533 && !app.killedByAm) { 17534 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17535 try { 17536 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17537 "Trimming memory of " + app.processName 17538 + " to " + curLevel); 17539 app.thread.scheduleTrimMemory(curLevel); 17540 } catch (RemoteException e) { 17541 } 17542 if (false) { 17543 // For now we won't do this; our memory trimming seems 17544 // to be good enough at this point that destroying 17545 // activities causes more harm than good. 17546 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17547 && app != mHomeProcess && app != mPreviousProcess) { 17548 // Need to do this on its own message because the stack may not 17549 // be in a consistent state at this point. 17550 // For these apps we will also finish their activities 17551 // to help them free memory. 17552 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17553 } 17554 } 17555 } 17556 app.trimMemoryLevel = curLevel; 17557 step++; 17558 if (step >= factor) { 17559 step = 0; 17560 switch (curLevel) { 17561 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17562 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17563 break; 17564 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17565 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17566 break; 17567 } 17568 } 17569 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17570 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17571 && app.thread != null) { 17572 try { 17573 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17574 "Trimming memory of heavy-weight " + app.processName 17575 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17576 app.thread.scheduleTrimMemory( 17577 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17578 } catch (RemoteException e) { 17579 } 17580 } 17581 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17582 } else { 17583 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17584 || app.systemNoUi) && app.pendingUiClean) { 17585 // If this application is now in the background and it 17586 // had done UI, then give it the special trim level to 17587 // have it free UI resources. 17588 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17589 if (app.trimMemoryLevel < level && app.thread != null) { 17590 try { 17591 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17592 "Trimming memory of bg-ui " + app.processName 17593 + " to " + level); 17594 app.thread.scheduleTrimMemory(level); 17595 } catch (RemoteException e) { 17596 } 17597 } 17598 app.pendingUiClean = false; 17599 } 17600 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17601 try { 17602 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17603 "Trimming memory of fg " + app.processName 17604 + " to " + fgTrimLevel); 17605 app.thread.scheduleTrimMemory(fgTrimLevel); 17606 } catch (RemoteException e) { 17607 } 17608 } 17609 app.trimMemoryLevel = fgTrimLevel; 17610 } 17611 } 17612 } else { 17613 if (mLowRamStartTime != 0) { 17614 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17615 mLowRamStartTime = 0; 17616 } 17617 for (int i=N-1; i>=0; i--) { 17618 ProcessRecord app = mLruProcesses.get(i); 17619 if (allChanged || app.procStateChanged) { 17620 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17621 app.procStateChanged = false; 17622 } 17623 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17624 || app.systemNoUi) && app.pendingUiClean) { 17625 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17626 && app.thread != null) { 17627 try { 17628 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17629 "Trimming memory of ui hidden " + app.processName 17630 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17631 app.thread.scheduleTrimMemory( 17632 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17633 } catch (RemoteException e) { 17634 } 17635 } 17636 app.pendingUiClean = false; 17637 } 17638 app.trimMemoryLevel = 0; 17639 } 17640 } 17641 17642 if (mAlwaysFinishActivities) { 17643 // Need to do this on its own message because the stack may not 17644 // be in a consistent state at this point. 17645 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17646 } 17647 17648 if (allChanged) { 17649 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17650 } 17651 17652 if (mProcessStats.shouldWriteNowLocked(now)) { 17653 mHandler.post(new Runnable() { 17654 @Override public void run() { 17655 synchronized (ActivityManagerService.this) { 17656 mProcessStats.writeStateAsyncLocked(); 17657 } 17658 } 17659 }); 17660 } 17661 17662 if (DEBUG_OOM_ADJ) { 17663 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17664 } 17665 } 17666 17667 final void trimApplications() { 17668 synchronized (this) { 17669 int i; 17670 17671 // First remove any unused application processes whose package 17672 // has been removed. 17673 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17674 final ProcessRecord app = mRemovedProcesses.get(i); 17675 if (app.activities.size() == 0 17676 && app.curReceiver == null && app.services.size() == 0) { 17677 Slog.i( 17678 TAG, "Exiting empty application process " 17679 + app.processName + " (" 17680 + (app.thread != null ? app.thread.asBinder() : null) 17681 + ")\n"); 17682 if (app.pid > 0 && app.pid != MY_PID) { 17683 app.kill("empty", false); 17684 } else { 17685 try { 17686 app.thread.scheduleExit(); 17687 } catch (Exception e) { 17688 // Ignore exceptions. 17689 } 17690 } 17691 cleanUpApplicationRecordLocked(app, false, true, -1); 17692 mRemovedProcesses.remove(i); 17693 17694 if (app.persistent) { 17695 addAppLocked(app.info, false, null /* ABI override */); 17696 } 17697 } 17698 } 17699 17700 // Now update the oom adj for all processes. 17701 updateOomAdjLocked(); 17702 } 17703 } 17704 17705 /** This method sends the specified signal to each of the persistent apps */ 17706 public void signalPersistentProcesses(int sig) throws RemoteException { 17707 if (sig != Process.SIGNAL_USR1) { 17708 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17709 } 17710 17711 synchronized (this) { 17712 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17713 != PackageManager.PERMISSION_GRANTED) { 17714 throw new SecurityException("Requires permission " 17715 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17716 } 17717 17718 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17719 ProcessRecord r = mLruProcesses.get(i); 17720 if (r.thread != null && r.persistent) { 17721 Process.sendSignal(r.pid, sig); 17722 } 17723 } 17724 } 17725 } 17726 17727 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17728 if (proc == null || proc == mProfileProc) { 17729 proc = mProfileProc; 17730 profileType = mProfileType; 17731 clearProfilerLocked(); 17732 } 17733 if (proc == null) { 17734 return; 17735 } 17736 try { 17737 proc.thread.profilerControl(false, null, profileType); 17738 } catch (RemoteException e) { 17739 throw new IllegalStateException("Process disappeared"); 17740 } 17741 } 17742 17743 private void clearProfilerLocked() { 17744 if (mProfileFd != null) { 17745 try { 17746 mProfileFd.close(); 17747 } catch (IOException e) { 17748 } 17749 } 17750 mProfileApp = null; 17751 mProfileProc = null; 17752 mProfileFile = null; 17753 mProfileType = 0; 17754 mAutoStopProfiler = false; 17755 mSamplingInterval = 0; 17756 } 17757 17758 public boolean profileControl(String process, int userId, boolean start, 17759 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17760 17761 try { 17762 synchronized (this) { 17763 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17764 // its own permission. 17765 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17766 != PackageManager.PERMISSION_GRANTED) { 17767 throw new SecurityException("Requires permission " 17768 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17769 } 17770 17771 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17772 throw new IllegalArgumentException("null profile info or fd"); 17773 } 17774 17775 ProcessRecord proc = null; 17776 if (process != null) { 17777 proc = findProcessLocked(process, userId, "profileControl"); 17778 } 17779 17780 if (start && (proc == null || proc.thread == null)) { 17781 throw new IllegalArgumentException("Unknown process: " + process); 17782 } 17783 17784 if (start) { 17785 stopProfilerLocked(null, 0); 17786 setProfileApp(proc.info, proc.processName, profilerInfo); 17787 mProfileProc = proc; 17788 mProfileType = profileType; 17789 ParcelFileDescriptor fd = profilerInfo.profileFd; 17790 try { 17791 fd = fd.dup(); 17792 } catch (IOException e) { 17793 fd = null; 17794 } 17795 profilerInfo.profileFd = fd; 17796 proc.thread.profilerControl(start, profilerInfo, profileType); 17797 fd = null; 17798 mProfileFd = null; 17799 } else { 17800 stopProfilerLocked(proc, profileType); 17801 if (profilerInfo != null && profilerInfo.profileFd != null) { 17802 try { 17803 profilerInfo.profileFd.close(); 17804 } catch (IOException e) { 17805 } 17806 } 17807 } 17808 17809 return true; 17810 } 17811 } catch (RemoteException e) { 17812 throw new IllegalStateException("Process disappeared"); 17813 } finally { 17814 if (profilerInfo != null && profilerInfo.profileFd != null) { 17815 try { 17816 profilerInfo.profileFd.close(); 17817 } catch (IOException e) { 17818 } 17819 } 17820 } 17821 } 17822 17823 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17824 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17825 userId, true, ALLOW_FULL_ONLY, callName, null); 17826 ProcessRecord proc = null; 17827 try { 17828 int pid = Integer.parseInt(process); 17829 synchronized (mPidsSelfLocked) { 17830 proc = mPidsSelfLocked.get(pid); 17831 } 17832 } catch (NumberFormatException e) { 17833 } 17834 17835 if (proc == null) { 17836 ArrayMap<String, SparseArray<ProcessRecord>> all 17837 = mProcessNames.getMap(); 17838 SparseArray<ProcessRecord> procs = all.get(process); 17839 if (procs != null && procs.size() > 0) { 17840 proc = procs.valueAt(0); 17841 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17842 for (int i=1; i<procs.size(); i++) { 17843 ProcessRecord thisProc = procs.valueAt(i); 17844 if (thisProc.userId == userId) { 17845 proc = thisProc; 17846 break; 17847 } 17848 } 17849 } 17850 } 17851 } 17852 17853 return proc; 17854 } 17855 17856 public boolean dumpHeap(String process, int userId, boolean managed, 17857 String path, ParcelFileDescriptor fd) throws RemoteException { 17858 17859 try { 17860 synchronized (this) { 17861 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17862 // its own permission (same as profileControl). 17863 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17864 != PackageManager.PERMISSION_GRANTED) { 17865 throw new SecurityException("Requires permission " 17866 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17867 } 17868 17869 if (fd == null) { 17870 throw new IllegalArgumentException("null fd"); 17871 } 17872 17873 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17874 if (proc == null || proc.thread == null) { 17875 throw new IllegalArgumentException("Unknown process: " + process); 17876 } 17877 17878 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17879 if (!isDebuggable) { 17880 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17881 throw new SecurityException("Process not debuggable: " + proc); 17882 } 17883 } 17884 17885 proc.thread.dumpHeap(managed, path, fd); 17886 fd = null; 17887 return true; 17888 } 17889 } catch (RemoteException e) { 17890 throw new IllegalStateException("Process disappeared"); 17891 } finally { 17892 if (fd != null) { 17893 try { 17894 fd.close(); 17895 } catch (IOException e) { 17896 } 17897 } 17898 } 17899 } 17900 17901 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17902 public void monitor() { 17903 synchronized (this) { } 17904 } 17905 17906 void onCoreSettingsChange(Bundle settings) { 17907 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17908 ProcessRecord processRecord = mLruProcesses.get(i); 17909 try { 17910 if (processRecord.thread != null) { 17911 processRecord.thread.setCoreSettings(settings); 17912 } 17913 } catch (RemoteException re) { 17914 /* ignore */ 17915 } 17916 } 17917 } 17918 17919 // Multi-user methods 17920 17921 /** 17922 * Start user, if its not already running, but don't bring it to foreground. 17923 */ 17924 @Override 17925 public boolean startUserInBackground(final int userId) { 17926 return startUser(userId, /* foreground */ false); 17927 } 17928 17929 /** 17930 * Start user, if its not already running, and bring it to foreground. 17931 */ 17932 boolean startUserInForeground(final int userId, Dialog dlg) { 17933 boolean result = startUser(userId, /* foreground */ true); 17934 dlg.dismiss(); 17935 return result; 17936 } 17937 17938 /** 17939 * Refreshes the list of users related to the current user when either a 17940 * user switch happens or when a new related user is started in the 17941 * background. 17942 */ 17943 private void updateCurrentProfileIdsLocked() { 17944 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17945 mCurrentUserId, false /* enabledOnly */); 17946 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17947 for (int i = 0; i < currentProfileIds.length; i++) { 17948 currentProfileIds[i] = profiles.get(i).id; 17949 } 17950 mCurrentProfileIds = currentProfileIds; 17951 17952 synchronized (mUserProfileGroupIdsSelfLocked) { 17953 mUserProfileGroupIdsSelfLocked.clear(); 17954 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17955 for (int i = 0; i < users.size(); i++) { 17956 UserInfo user = users.get(i); 17957 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17958 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17959 } 17960 } 17961 } 17962 } 17963 17964 private Set getProfileIdsLocked(int userId) { 17965 Set userIds = new HashSet<Integer>(); 17966 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17967 userId, false /* enabledOnly */); 17968 for (UserInfo user : profiles) { 17969 userIds.add(Integer.valueOf(user.id)); 17970 } 17971 return userIds; 17972 } 17973 17974 @Override 17975 public boolean switchUser(final int userId) { 17976 String userName; 17977 synchronized (this) { 17978 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17979 if (userInfo == null) { 17980 Slog.w(TAG, "No user info for user #" + userId); 17981 return false; 17982 } 17983 if (userInfo.isManagedProfile()) { 17984 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17985 return false; 17986 } 17987 userName = userInfo.name; 17988 mTargetUserId = userId; 17989 } 17990 mHandler.removeMessages(START_USER_SWITCH_MSG); 17991 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17992 return true; 17993 } 17994 17995 private void showUserSwitchDialog(int userId, String userName) { 17996 // The dialog will show and then initiate the user switch by calling startUserInForeground 17997 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17998 true /* above system */); 17999 d.show(); 18000 } 18001 18002 private boolean startUser(final int userId, final boolean foreground) { 18003 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18004 != PackageManager.PERMISSION_GRANTED) { 18005 String msg = "Permission Denial: switchUser() from pid=" 18006 + Binder.getCallingPid() 18007 + ", uid=" + Binder.getCallingUid() 18008 + " requires " + INTERACT_ACROSS_USERS_FULL; 18009 Slog.w(TAG, msg); 18010 throw new SecurityException(msg); 18011 } 18012 18013 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18014 18015 final long ident = Binder.clearCallingIdentity(); 18016 try { 18017 synchronized (this) { 18018 final int oldUserId = mCurrentUserId; 18019 if (oldUserId == userId) { 18020 return true; 18021 } 18022 18023 mStackSupervisor.setLockTaskModeLocked(null, false); 18024 18025 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18026 if (userInfo == null) { 18027 Slog.w(TAG, "No user info for user #" + userId); 18028 return false; 18029 } 18030 if (foreground && userInfo.isManagedProfile()) { 18031 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18032 return false; 18033 } 18034 18035 if (foreground) { 18036 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18037 R.anim.screen_user_enter); 18038 } 18039 18040 boolean needStart = false; 18041 18042 // If the user we are switching to is not currently started, then 18043 // we need to start it now. 18044 if (mStartedUsers.get(userId) == null) { 18045 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18046 updateStartedUserArrayLocked(); 18047 needStart = true; 18048 } 18049 18050 final Integer userIdInt = Integer.valueOf(userId); 18051 mUserLru.remove(userIdInt); 18052 mUserLru.add(userIdInt); 18053 18054 if (foreground) { 18055 mCurrentUserId = userId; 18056 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18057 updateCurrentProfileIdsLocked(); 18058 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18059 // Once the internal notion of the active user has switched, we lock the device 18060 // with the option to show the user switcher on the keyguard. 18061 mWindowManager.lockNow(null); 18062 } else { 18063 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18064 updateCurrentProfileIdsLocked(); 18065 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18066 mUserLru.remove(currentUserIdInt); 18067 mUserLru.add(currentUserIdInt); 18068 } 18069 18070 final UserStartedState uss = mStartedUsers.get(userId); 18071 18072 // Make sure user is in the started state. If it is currently 18073 // stopping, we need to knock that off. 18074 if (uss.mState == UserStartedState.STATE_STOPPING) { 18075 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18076 // so we can just fairly silently bring the user back from 18077 // the almost-dead. 18078 uss.mState = UserStartedState.STATE_RUNNING; 18079 updateStartedUserArrayLocked(); 18080 needStart = true; 18081 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18082 // This means ACTION_SHUTDOWN has been sent, so we will 18083 // need to treat this as a new boot of the user. 18084 uss.mState = UserStartedState.STATE_BOOTING; 18085 updateStartedUserArrayLocked(); 18086 needStart = true; 18087 } 18088 18089 if (uss.mState == UserStartedState.STATE_BOOTING) { 18090 // Booting up a new user, need to tell system services about it. 18091 // Note that this is on the same handler as scheduling of broadcasts, 18092 // which is important because it needs to go first. 18093 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18094 } 18095 18096 if (foreground) { 18097 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18098 oldUserId)); 18099 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18100 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18101 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18102 oldUserId, userId, uss)); 18103 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18104 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18105 } 18106 18107 if (needStart) { 18108 // Send USER_STARTED broadcast 18109 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18110 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18111 | Intent.FLAG_RECEIVER_FOREGROUND); 18112 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18113 broadcastIntentLocked(null, null, intent, 18114 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18115 false, false, MY_PID, Process.SYSTEM_UID, userId); 18116 } 18117 18118 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18119 if (userId != UserHandle.USER_OWNER) { 18120 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18121 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18122 broadcastIntentLocked(null, null, intent, null, 18123 new IIntentReceiver.Stub() { 18124 public void performReceive(Intent intent, int resultCode, 18125 String data, Bundle extras, boolean ordered, 18126 boolean sticky, int sendingUser) { 18127 onUserInitialized(uss, foreground, oldUserId, userId); 18128 } 18129 }, 0, null, null, null, AppOpsManager.OP_NONE, 18130 true, false, MY_PID, Process.SYSTEM_UID, 18131 userId); 18132 uss.initializing = true; 18133 } else { 18134 getUserManagerLocked().makeInitialized(userInfo.id); 18135 } 18136 } 18137 18138 if (foreground) { 18139 if (!uss.initializing) { 18140 moveUserToForeground(uss, oldUserId, userId); 18141 } 18142 } else { 18143 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18144 } 18145 18146 if (needStart) { 18147 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18148 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18149 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18150 broadcastIntentLocked(null, null, intent, 18151 null, new IIntentReceiver.Stub() { 18152 @Override 18153 public void performReceive(Intent intent, int resultCode, String data, 18154 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18155 throws RemoteException { 18156 } 18157 }, 0, null, null, 18158 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18159 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18160 } 18161 } 18162 } finally { 18163 Binder.restoreCallingIdentity(ident); 18164 } 18165 18166 return true; 18167 } 18168 18169 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18170 long ident = Binder.clearCallingIdentity(); 18171 try { 18172 Intent intent; 18173 if (oldUserId >= 0) { 18174 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18175 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18176 int count = profiles.size(); 18177 for (int i = 0; i < count; i++) { 18178 int profileUserId = profiles.get(i).id; 18179 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18180 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18181 | Intent.FLAG_RECEIVER_FOREGROUND); 18182 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18183 broadcastIntentLocked(null, null, intent, 18184 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18185 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18186 } 18187 } 18188 if (newUserId >= 0) { 18189 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18190 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18191 int count = profiles.size(); 18192 for (int i = 0; i < count; i++) { 18193 int profileUserId = profiles.get(i).id; 18194 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18195 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18196 | Intent.FLAG_RECEIVER_FOREGROUND); 18197 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18198 broadcastIntentLocked(null, null, intent, 18199 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18200 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18201 } 18202 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18204 | Intent.FLAG_RECEIVER_FOREGROUND); 18205 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18206 broadcastIntentLocked(null, null, intent, 18207 null, null, 0, null, null, 18208 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18209 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18210 } 18211 } finally { 18212 Binder.restoreCallingIdentity(ident); 18213 } 18214 } 18215 18216 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18217 final int newUserId) { 18218 final int N = mUserSwitchObservers.beginBroadcast(); 18219 if (N > 0) { 18220 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18221 int mCount = 0; 18222 @Override 18223 public void sendResult(Bundle data) throws RemoteException { 18224 synchronized (ActivityManagerService.this) { 18225 if (mCurUserSwitchCallback == this) { 18226 mCount++; 18227 if (mCount == N) { 18228 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18229 } 18230 } 18231 } 18232 } 18233 }; 18234 synchronized (this) { 18235 uss.switching = true; 18236 mCurUserSwitchCallback = callback; 18237 } 18238 for (int i=0; i<N; i++) { 18239 try { 18240 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18241 newUserId, callback); 18242 } catch (RemoteException e) { 18243 } 18244 } 18245 } else { 18246 synchronized (this) { 18247 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18248 } 18249 } 18250 mUserSwitchObservers.finishBroadcast(); 18251 } 18252 18253 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18254 synchronized (this) { 18255 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18256 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18257 } 18258 } 18259 18260 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18261 mCurUserSwitchCallback = null; 18262 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18263 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18264 oldUserId, newUserId, uss)); 18265 } 18266 18267 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18268 synchronized (this) { 18269 if (foreground) { 18270 moveUserToForeground(uss, oldUserId, newUserId); 18271 } 18272 } 18273 18274 completeSwitchAndInitalize(uss, newUserId, true, false); 18275 } 18276 18277 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18278 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18279 if (homeInFront) { 18280 startHomeActivityLocked(newUserId); 18281 } else { 18282 mStackSupervisor.resumeTopActivitiesLocked(); 18283 } 18284 EventLogTags.writeAmSwitchUser(newUserId); 18285 getUserManagerLocked().userForeground(newUserId); 18286 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18287 } 18288 18289 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18290 completeSwitchAndInitalize(uss, newUserId, false, true); 18291 } 18292 18293 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18294 boolean clearInitializing, boolean clearSwitching) { 18295 boolean unfrozen = false; 18296 synchronized (this) { 18297 if (clearInitializing) { 18298 uss.initializing = false; 18299 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18300 } 18301 if (clearSwitching) { 18302 uss.switching = false; 18303 } 18304 if (!uss.switching && !uss.initializing) { 18305 mWindowManager.stopFreezingScreen(); 18306 unfrozen = true; 18307 } 18308 } 18309 if (unfrozen) { 18310 final int N = mUserSwitchObservers.beginBroadcast(); 18311 for (int i=0; i<N; i++) { 18312 try { 18313 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18314 } catch (RemoteException e) { 18315 } 18316 } 18317 mUserSwitchObservers.finishBroadcast(); 18318 } 18319 } 18320 18321 void scheduleStartProfilesLocked() { 18322 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18323 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18324 DateUtils.SECOND_IN_MILLIS); 18325 } 18326 } 18327 18328 void startProfilesLocked() { 18329 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18330 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18331 mCurrentUserId, false /* enabledOnly */); 18332 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18333 for (UserInfo user : profiles) { 18334 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18335 && user.id != mCurrentUserId) { 18336 toStart.add(user); 18337 } 18338 } 18339 final int n = toStart.size(); 18340 int i = 0; 18341 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18342 startUserInBackground(toStart.get(i).id); 18343 } 18344 if (i < n) { 18345 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18346 } 18347 } 18348 18349 void finishUserBoot(UserStartedState uss) { 18350 synchronized (this) { 18351 if (uss.mState == UserStartedState.STATE_BOOTING 18352 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18353 uss.mState = UserStartedState.STATE_RUNNING; 18354 final int userId = uss.mHandle.getIdentifier(); 18355 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18356 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18357 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18358 broadcastIntentLocked(null, null, intent, 18359 null, null, 0, null, null, 18360 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18361 true, false, MY_PID, Process.SYSTEM_UID, userId); 18362 } 18363 } 18364 } 18365 18366 void finishUserSwitch(UserStartedState uss) { 18367 synchronized (this) { 18368 finishUserBoot(uss); 18369 18370 startProfilesLocked(); 18371 18372 int num = mUserLru.size(); 18373 int i = 0; 18374 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18375 Integer oldUserId = mUserLru.get(i); 18376 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18377 if (oldUss == null) { 18378 // Shouldn't happen, but be sane if it does. 18379 mUserLru.remove(i); 18380 num--; 18381 continue; 18382 } 18383 if (oldUss.mState == UserStartedState.STATE_STOPPING 18384 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18385 // This user is already stopping, doesn't count. 18386 num--; 18387 i++; 18388 continue; 18389 } 18390 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18391 // Owner and current can't be stopped, but count as running. 18392 i++; 18393 continue; 18394 } 18395 // This is a user to be stopped. 18396 stopUserLocked(oldUserId, null); 18397 num--; 18398 i++; 18399 } 18400 } 18401 } 18402 18403 @Override 18404 public int stopUser(final int userId, final IStopUserCallback callback) { 18405 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18406 != PackageManager.PERMISSION_GRANTED) { 18407 String msg = "Permission Denial: switchUser() from pid=" 18408 + Binder.getCallingPid() 18409 + ", uid=" + Binder.getCallingUid() 18410 + " requires " + INTERACT_ACROSS_USERS_FULL; 18411 Slog.w(TAG, msg); 18412 throw new SecurityException(msg); 18413 } 18414 if (userId <= 0) { 18415 throw new IllegalArgumentException("Can't stop primary user " + userId); 18416 } 18417 synchronized (this) { 18418 return stopUserLocked(userId, callback); 18419 } 18420 } 18421 18422 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18423 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18424 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18425 return ActivityManager.USER_OP_IS_CURRENT; 18426 } 18427 18428 final UserStartedState uss = mStartedUsers.get(userId); 18429 if (uss == null) { 18430 // User is not started, nothing to do... but we do need to 18431 // callback if requested. 18432 if (callback != null) { 18433 mHandler.post(new Runnable() { 18434 @Override 18435 public void run() { 18436 try { 18437 callback.userStopped(userId); 18438 } catch (RemoteException e) { 18439 } 18440 } 18441 }); 18442 } 18443 return ActivityManager.USER_OP_SUCCESS; 18444 } 18445 18446 if (callback != null) { 18447 uss.mStopCallbacks.add(callback); 18448 } 18449 18450 if (uss.mState != UserStartedState.STATE_STOPPING 18451 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18452 uss.mState = UserStartedState.STATE_STOPPING; 18453 updateStartedUserArrayLocked(); 18454 18455 long ident = Binder.clearCallingIdentity(); 18456 try { 18457 // We are going to broadcast ACTION_USER_STOPPING and then 18458 // once that is done send a final ACTION_SHUTDOWN and then 18459 // stop the user. 18460 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18461 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18462 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18463 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18464 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18465 // This is the result receiver for the final shutdown broadcast. 18466 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18467 @Override 18468 public void performReceive(Intent intent, int resultCode, String data, 18469 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18470 finishUserStop(uss); 18471 } 18472 }; 18473 // This is the result receiver for the initial stopping broadcast. 18474 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18475 @Override 18476 public void performReceive(Intent intent, int resultCode, String data, 18477 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18478 // On to the next. 18479 synchronized (ActivityManagerService.this) { 18480 if (uss.mState != UserStartedState.STATE_STOPPING) { 18481 // Whoops, we are being started back up. Abort, abort! 18482 return; 18483 } 18484 uss.mState = UserStartedState.STATE_SHUTDOWN; 18485 } 18486 mBatteryStatsService.noteEvent( 18487 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18488 Integer.toString(userId), userId); 18489 mSystemServiceManager.stopUser(userId); 18490 broadcastIntentLocked(null, null, shutdownIntent, 18491 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18492 true, false, MY_PID, Process.SYSTEM_UID, userId); 18493 } 18494 }; 18495 // Kick things off. 18496 broadcastIntentLocked(null, null, stoppingIntent, 18497 null, stoppingReceiver, 0, null, null, 18498 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18499 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18500 } finally { 18501 Binder.restoreCallingIdentity(ident); 18502 } 18503 } 18504 18505 return ActivityManager.USER_OP_SUCCESS; 18506 } 18507 18508 void finishUserStop(UserStartedState uss) { 18509 final int userId = uss.mHandle.getIdentifier(); 18510 boolean stopped; 18511 ArrayList<IStopUserCallback> callbacks; 18512 synchronized (this) { 18513 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18514 if (mStartedUsers.get(userId) != uss) { 18515 stopped = false; 18516 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18517 stopped = false; 18518 } else { 18519 stopped = true; 18520 // User can no longer run. 18521 mStartedUsers.remove(userId); 18522 mUserLru.remove(Integer.valueOf(userId)); 18523 updateStartedUserArrayLocked(); 18524 18525 // Clean up all state and processes associated with the user. 18526 // Kill all the processes for the user. 18527 forceStopUserLocked(userId, "finish user"); 18528 } 18529 18530 // Explicitly remove the old information in mRecentTasks. 18531 removeRecentTasksForUserLocked(userId); 18532 } 18533 18534 for (int i=0; i<callbacks.size(); i++) { 18535 try { 18536 if (stopped) callbacks.get(i).userStopped(userId); 18537 else callbacks.get(i).userStopAborted(userId); 18538 } catch (RemoteException e) { 18539 } 18540 } 18541 18542 if (stopped) { 18543 mSystemServiceManager.cleanupUser(userId); 18544 synchronized (this) { 18545 mStackSupervisor.removeUserLocked(userId); 18546 } 18547 } 18548 } 18549 18550 @Override 18551 public UserInfo getCurrentUser() { 18552 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18553 != PackageManager.PERMISSION_GRANTED) && ( 18554 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18555 != PackageManager.PERMISSION_GRANTED)) { 18556 String msg = "Permission Denial: getCurrentUser() from pid=" 18557 + Binder.getCallingPid() 18558 + ", uid=" + Binder.getCallingUid() 18559 + " requires " + INTERACT_ACROSS_USERS; 18560 Slog.w(TAG, msg); 18561 throw new SecurityException(msg); 18562 } 18563 synchronized (this) { 18564 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18565 return getUserManagerLocked().getUserInfo(userId); 18566 } 18567 } 18568 18569 int getCurrentUserIdLocked() { 18570 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18571 } 18572 18573 @Override 18574 public boolean isUserRunning(int userId, boolean orStopped) { 18575 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18576 != PackageManager.PERMISSION_GRANTED) { 18577 String msg = "Permission Denial: isUserRunning() from pid=" 18578 + Binder.getCallingPid() 18579 + ", uid=" + Binder.getCallingUid() 18580 + " requires " + INTERACT_ACROSS_USERS; 18581 Slog.w(TAG, msg); 18582 throw new SecurityException(msg); 18583 } 18584 synchronized (this) { 18585 return isUserRunningLocked(userId, orStopped); 18586 } 18587 } 18588 18589 boolean isUserRunningLocked(int userId, boolean orStopped) { 18590 UserStartedState state = mStartedUsers.get(userId); 18591 if (state == null) { 18592 return false; 18593 } 18594 if (orStopped) { 18595 return true; 18596 } 18597 return state.mState != UserStartedState.STATE_STOPPING 18598 && state.mState != UserStartedState.STATE_SHUTDOWN; 18599 } 18600 18601 @Override 18602 public int[] getRunningUserIds() { 18603 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18604 != PackageManager.PERMISSION_GRANTED) { 18605 String msg = "Permission Denial: isUserRunning() from pid=" 18606 + Binder.getCallingPid() 18607 + ", uid=" + Binder.getCallingUid() 18608 + " requires " + INTERACT_ACROSS_USERS; 18609 Slog.w(TAG, msg); 18610 throw new SecurityException(msg); 18611 } 18612 synchronized (this) { 18613 return mStartedUserArray; 18614 } 18615 } 18616 18617 private void updateStartedUserArrayLocked() { 18618 int num = 0; 18619 for (int i=0; i<mStartedUsers.size(); i++) { 18620 UserStartedState uss = mStartedUsers.valueAt(i); 18621 // This list does not include stopping users. 18622 if (uss.mState != UserStartedState.STATE_STOPPING 18623 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18624 num++; 18625 } 18626 } 18627 mStartedUserArray = new int[num]; 18628 num = 0; 18629 for (int i=0; i<mStartedUsers.size(); i++) { 18630 UserStartedState uss = mStartedUsers.valueAt(i); 18631 if (uss.mState != UserStartedState.STATE_STOPPING 18632 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18633 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18634 num++; 18635 } 18636 } 18637 } 18638 18639 @Override 18640 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18641 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18642 != PackageManager.PERMISSION_GRANTED) { 18643 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18644 + Binder.getCallingPid() 18645 + ", uid=" + Binder.getCallingUid() 18646 + " requires " + INTERACT_ACROSS_USERS_FULL; 18647 Slog.w(TAG, msg); 18648 throw new SecurityException(msg); 18649 } 18650 18651 mUserSwitchObservers.register(observer); 18652 } 18653 18654 @Override 18655 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18656 mUserSwitchObservers.unregister(observer); 18657 } 18658 18659 private boolean userExists(int userId) { 18660 if (userId == 0) { 18661 return true; 18662 } 18663 UserManagerService ums = getUserManagerLocked(); 18664 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18665 } 18666 18667 int[] getUsersLocked() { 18668 UserManagerService ums = getUserManagerLocked(); 18669 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18670 } 18671 18672 UserManagerService getUserManagerLocked() { 18673 if (mUserManager == null) { 18674 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18675 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18676 } 18677 return mUserManager; 18678 } 18679 18680 private int applyUserId(int uid, int userId) { 18681 return UserHandle.getUid(userId, uid); 18682 } 18683 18684 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18685 if (info == null) return null; 18686 ApplicationInfo newInfo = new ApplicationInfo(info); 18687 newInfo.uid = applyUserId(info.uid, userId); 18688 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18689 + info.packageName; 18690 return newInfo; 18691 } 18692 18693 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18694 if (aInfo == null 18695 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18696 return aInfo; 18697 } 18698 18699 ActivityInfo info = new ActivityInfo(aInfo); 18700 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18701 return info; 18702 } 18703 18704 private final class LocalService extends ActivityManagerInternal { 18705 @Override 18706 public void goingToSleep() { 18707 ActivityManagerService.this.goingToSleep(); 18708 } 18709 18710 @Override 18711 public void wakingUp() { 18712 ActivityManagerService.this.wakingUp(); 18713 } 18714 18715 @Override 18716 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18717 String processName, String abiOverride, int uid, Runnable crashHandler) { 18718 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18719 processName, abiOverride, uid, crashHandler); 18720 } 18721 } 18722 18723 /** 18724 * An implementation of IAppTask, that allows an app to manage its own tasks via 18725 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18726 * only the process that calls getAppTasks() can call the AppTask methods. 18727 */ 18728 class AppTaskImpl extends IAppTask.Stub { 18729 private int mTaskId; 18730 private int mCallingUid; 18731 18732 public AppTaskImpl(int taskId, int callingUid) { 18733 mTaskId = taskId; 18734 mCallingUid = callingUid; 18735 } 18736 18737 private void checkCaller() { 18738 if (mCallingUid != Binder.getCallingUid()) { 18739 throw new SecurityException("Caller " + mCallingUid 18740 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18741 } 18742 } 18743 18744 @Override 18745 public void finishAndRemoveTask() { 18746 checkCaller(); 18747 18748 synchronized (ActivityManagerService.this) { 18749 long origId = Binder.clearCallingIdentity(); 18750 try { 18751 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18752 if (tr == null) { 18753 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18754 } 18755 // Only kill the process if we are not a new document 18756 int flags = tr.getBaseIntent().getFlags(); 18757 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18758 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18759 removeTaskByIdLocked(mTaskId, 18760 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18761 } finally { 18762 Binder.restoreCallingIdentity(origId); 18763 } 18764 } 18765 } 18766 18767 @Override 18768 public ActivityManager.RecentTaskInfo getTaskInfo() { 18769 checkCaller(); 18770 18771 synchronized (ActivityManagerService.this) { 18772 long origId = Binder.clearCallingIdentity(); 18773 try { 18774 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18775 if (tr == null) { 18776 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18777 } 18778 return createRecentTaskInfoFromTaskRecord(tr); 18779 } finally { 18780 Binder.restoreCallingIdentity(origId); 18781 } 18782 } 18783 } 18784 18785 @Override 18786 public void moveToFront() { 18787 checkCaller(); 18788 18789 final TaskRecord tr; 18790 synchronized (ActivityManagerService.this) { 18791 tr = recentTaskForIdLocked(mTaskId); 18792 if (tr == null) { 18793 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18794 } 18795 if (tr.getRootActivity() != null) { 18796 long origId = Binder.clearCallingIdentity(); 18797 try { 18798 moveTaskToFrontLocked(tr.taskId, 0, null); 18799 return; 18800 } finally { 18801 Binder.restoreCallingIdentity(origId); 18802 } 18803 } 18804 } 18805 18806 startActivityFromRecentsInner(tr.taskId, null); 18807 } 18808 18809 @Override 18810 public int startActivity(IBinder whoThread, String callingPackage, 18811 Intent intent, String resolvedType, Bundle options) { 18812 checkCaller(); 18813 18814 int callingUser = UserHandle.getCallingUserId(); 18815 TaskRecord tr; 18816 IApplicationThread appThread; 18817 synchronized (ActivityManagerService.this) { 18818 tr = recentTaskForIdLocked(mTaskId); 18819 if (tr == null) { 18820 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18821 } 18822 appThread = ApplicationThreadNative.asInterface(whoThread); 18823 if (appThread == null) { 18824 throw new IllegalArgumentException("Bad app thread " + appThread); 18825 } 18826 } 18827 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18828 resolvedType, null, null, null, null, 0, 0, null, null, 18829 null, options, callingUser, null, tr); 18830 } 18831 18832 @Override 18833 public void setExcludeFromRecents(boolean exclude) { 18834 checkCaller(); 18835 18836 synchronized (ActivityManagerService.this) { 18837 long origId = Binder.clearCallingIdentity(); 18838 try { 18839 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18840 if (tr == null) { 18841 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18842 } 18843 Intent intent = tr.getBaseIntent(); 18844 if (exclude) { 18845 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18846 } else { 18847 intent.setFlags(intent.getFlags() 18848 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18849 } 18850 } finally { 18851 Binder.restoreCallingIdentity(origId); 18852 } 18853 } 18854 } 18855 } 18856} 18857