ActivityManagerService.java revision ce0fd7665f297c5693ee23b3d6daf26baeed4e9d
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.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * Set while the keyguard is waiting for an activity to draw. 941 * In this state, if we are sleeping, we allow Activities to launch 942 * so that they can draw before Keyguard dismisses itself. 943 */ 944 private boolean mKeyguardWaitingForDraw = false; 945 946 /** 947 * State of external calls telling us if the device is asleep. 948 */ 949 private boolean mWentToSleep = false; 950 951 /** 952 * State of external call telling us if the lock screen is shown. 953 */ 954 private boolean mLockScreenShown = false; 955 956 /** 957 * Set if we are shutting down the system, similar to sleeping. 958 */ 959 boolean mShuttingDown = false; 960 961 /** 962 * Current sequence id for oom_adj computation traversal. 963 */ 964 int mAdjSeq = 0; 965 966 /** 967 * Current sequence id for process LRU updating. 968 */ 969 int mLruSeq = 0; 970 971 /** 972 * Keep track of the non-cached/empty process we last found, to help 973 * determine how to distribute cached/empty processes next time. 974 */ 975 int mNumNonCachedProcs = 0; 976 977 /** 978 * Keep track of the number of cached hidden procs, to balance oom adj 979 * distribution between those and empty procs. 980 */ 981 int mNumCachedHiddenProcs = 0; 982 983 /** 984 * Keep track of the number of service processes we last found, to 985 * determine on the next iteration which should be B services. 986 */ 987 int mNumServiceProcs = 0; 988 int mNewNumAServiceProcs = 0; 989 int mNewNumServiceProcs = 0; 990 991 /** 992 * Allow the current computed overall memory level of the system to go down? 993 * This is set to false when we are killing processes for reasons other than 994 * memory management, so that the now smaller process list will not be taken as 995 * an indication that memory is tighter. 996 */ 997 boolean mAllowLowerMemLevel = false; 998 999 /** 1000 * The last computed memory level, for holding when we are in a state that 1001 * processes are going away for other reasons. 1002 */ 1003 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1004 1005 /** 1006 * The last total number of process we have, to determine if changes actually look 1007 * like a shrinking number of process due to lower RAM. 1008 */ 1009 int mLastNumProcesses; 1010 1011 /** 1012 * The uptime of the last time we performed idle maintenance. 1013 */ 1014 long mLastIdleTime = SystemClock.uptimeMillis(); 1015 1016 /** 1017 * Total time spent with RAM that has been added in the past since the last idle time. 1018 */ 1019 long mLowRamTimeSinceLastIdle = 0; 1020 1021 /** 1022 * If RAM is currently low, when that horrible situation started. 1023 */ 1024 long mLowRamStartTime = 0; 1025 1026 /** 1027 * For reporting to battery stats the current top application. 1028 */ 1029 private String mCurResumedPackage = null; 1030 private int mCurResumedUid = -1; 1031 1032 /** 1033 * For reporting to battery stats the apps currently running foreground 1034 * service. The ProcessMap is package/uid tuples; each of these contain 1035 * an array of the currently foreground processes. 1036 */ 1037 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1038 = new ProcessMap<ArrayList<ProcessRecord>>(); 1039 1040 /** 1041 * This is set if we had to do a delayed dexopt of an app before launching 1042 * it, to increase the ANR timeouts in that case. 1043 */ 1044 boolean mDidDexOpt; 1045 1046 /** 1047 * Set if the systemServer made a call to enterSafeMode. 1048 */ 1049 boolean mSafeMode; 1050 1051 String mDebugApp = null; 1052 boolean mWaitForDebugger = false; 1053 boolean mDebugTransient = false; 1054 String mOrigDebugApp = null; 1055 boolean mOrigWaitForDebugger = false; 1056 boolean mAlwaysFinishActivities = false; 1057 IActivityController mController = null; 1058 String mProfileApp = null; 1059 ProcessRecord mProfileProc = null; 1060 String mProfileFile; 1061 ParcelFileDescriptor mProfileFd; 1062 int mSamplingInterval = 0; 1063 boolean mAutoStopProfiler = false; 1064 int mProfileType = 0; 1065 String mOpenGlTraceApp = null; 1066 1067 static class ProcessChangeItem { 1068 static final int CHANGE_ACTIVITIES = 1<<0; 1069 static final int CHANGE_PROCESS_STATE = 1<<1; 1070 int changes; 1071 int uid; 1072 int pid; 1073 int processState; 1074 boolean foregroundActivities; 1075 } 1076 1077 final RemoteCallbackList<IProcessObserver> mProcessObservers 1078 = new RemoteCallbackList<IProcessObserver>(); 1079 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1080 1081 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1082 = new ArrayList<ProcessChangeItem>(); 1083 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1084 = new ArrayList<ProcessChangeItem>(); 1085 1086 /** 1087 * Runtime CPU use collection thread. This object's lock is used to 1088 * perform synchronization with the thread (notifying it to run). 1089 */ 1090 final Thread mProcessCpuThread; 1091 1092 /** 1093 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1094 * Must acquire this object's lock when accessing it. 1095 * NOTE: this lock will be held while doing long operations (trawling 1096 * through all processes in /proc), so it should never be acquired by 1097 * any critical paths such as when holding the main activity manager lock. 1098 */ 1099 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1100 MONITOR_THREAD_CPU_USAGE); 1101 final AtomicLong mLastCpuTime = new AtomicLong(0); 1102 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1103 1104 long mLastWriteTime = 0; 1105 1106 /** 1107 * Used to retain an update lock when the foreground activity is in 1108 * immersive mode. 1109 */ 1110 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1111 1112 /** 1113 * Set to true after the system has finished booting. 1114 */ 1115 boolean mBooted = false; 1116 1117 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1118 int mProcessLimitOverride = -1; 1119 1120 WindowManagerService mWindowManager; 1121 1122 final ActivityThread mSystemThread; 1123 1124 // Holds the current foreground user's id 1125 int mCurrentUserId = 0; 1126 // Holds the target user's id during a user switch 1127 int mTargetUserId = UserHandle.USER_NULL; 1128 // If there are multiple profiles for the current user, their ids are here 1129 // Currently only the primary user can have managed profiles 1130 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1131 1132 /** 1133 * Mapping from each known user ID to the profile group ID it is associated with. 1134 */ 1135 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1136 1137 private UserManagerService mUserManager; 1138 1139 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1140 final ProcessRecord mApp; 1141 final int mPid; 1142 final IApplicationThread mAppThread; 1143 1144 AppDeathRecipient(ProcessRecord app, int pid, 1145 IApplicationThread thread) { 1146 if (localLOGV) Slog.v( 1147 TAG, "New death recipient " + this 1148 + " for thread " + thread.asBinder()); 1149 mApp = app; 1150 mPid = pid; 1151 mAppThread = thread; 1152 } 1153 1154 @Override 1155 public void binderDied() { 1156 if (localLOGV) Slog.v( 1157 TAG, "Death received in " + this 1158 + " for thread " + mAppThread.asBinder()); 1159 synchronized(ActivityManagerService.this) { 1160 appDiedLocked(mApp, mPid, mAppThread); 1161 } 1162 } 1163 } 1164 1165 static final int SHOW_ERROR_MSG = 1; 1166 static final int SHOW_NOT_RESPONDING_MSG = 2; 1167 static final int SHOW_FACTORY_ERROR_MSG = 3; 1168 static final int UPDATE_CONFIGURATION_MSG = 4; 1169 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1170 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1171 static final int SERVICE_TIMEOUT_MSG = 12; 1172 static final int UPDATE_TIME_ZONE = 13; 1173 static final int SHOW_UID_ERROR_MSG = 14; 1174 static final int IM_FEELING_LUCKY_MSG = 15; 1175 static final int PROC_START_TIMEOUT_MSG = 20; 1176 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1177 static final int KILL_APPLICATION_MSG = 22; 1178 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1179 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1180 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1181 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1182 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1183 static final int CLEAR_DNS_CACHE_MSG = 28; 1184 static final int UPDATE_HTTP_PROXY_MSG = 29; 1185 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1186 static final int DISPATCH_PROCESSES_CHANGED = 31; 1187 static final int DISPATCH_PROCESS_DIED = 32; 1188 static final int REPORT_MEM_USAGE_MSG = 33; 1189 static final int REPORT_USER_SWITCH_MSG = 34; 1190 static final int CONTINUE_USER_SWITCH_MSG = 35; 1191 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1192 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1193 static final int PERSIST_URI_GRANTS_MSG = 38; 1194 static final int REQUEST_ALL_PSS_MSG = 39; 1195 static final int START_PROFILES_MSG = 40; 1196 static final int UPDATE_TIME = 41; 1197 static final int SYSTEM_USER_START_MSG = 42; 1198 static final int SYSTEM_USER_CURRENT_MSG = 43; 1199 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1200 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1201 static final int START_USER_SWITCH_MSG = 46; 1202 1203 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1204 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1205 static final int FIRST_COMPAT_MODE_MSG = 300; 1206 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1207 1208 AlertDialog mUidAlert; 1209 CompatModeDialog mCompatModeDialog; 1210 long mLastMemUsageReportTime = 0; 1211 1212 private LockToAppRequestDialog mLockToAppRequest; 1213 1214 /** 1215 * Flag whether the current user is a "monkey", i.e. whether 1216 * the UI is driven by a UI automation tool. 1217 */ 1218 private boolean mUserIsMonkey; 1219 1220 /** Flag whether the device has a Recents UI */ 1221 boolean mHasRecents; 1222 1223 /** The dimensions of the thumbnails in the Recents UI. */ 1224 int mThumbnailWidth; 1225 int mThumbnailHeight; 1226 1227 final ServiceThread mHandlerThread; 1228 final MainHandler mHandler; 1229 1230 final class MainHandler extends Handler { 1231 public MainHandler(Looper looper) { 1232 super(looper, null, true); 1233 } 1234 1235 @Override 1236 public void handleMessage(Message msg) { 1237 switch (msg.what) { 1238 case SHOW_ERROR_MSG: { 1239 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1240 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1241 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1242 synchronized (ActivityManagerService.this) { 1243 ProcessRecord proc = (ProcessRecord)data.get("app"); 1244 AppErrorResult res = (AppErrorResult) data.get("result"); 1245 if (proc != null && proc.crashDialog != null) { 1246 Slog.e(TAG, "App already has crash dialog: " + proc); 1247 if (res != null) { 1248 res.set(0); 1249 } 1250 return; 1251 } 1252 boolean isBackground = (UserHandle.getAppId(proc.uid) 1253 >= Process.FIRST_APPLICATION_UID 1254 && proc.pid != MY_PID); 1255 for (int userId : mCurrentProfileIds) { 1256 isBackground &= (proc.userId != userId); 1257 } 1258 if (isBackground && !showBackground) { 1259 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1260 if (res != null) { 1261 res.set(0); 1262 } 1263 return; 1264 } 1265 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1266 Dialog d = new AppErrorDialog(mContext, 1267 ActivityManagerService.this, res, proc); 1268 d.show(); 1269 proc.crashDialog = d; 1270 } else { 1271 // The device is asleep, so just pretend that the user 1272 // saw a crash dialog and hit "force quit". 1273 if (res != null) { 1274 res.set(0); 1275 } 1276 } 1277 } 1278 1279 ensureBootCompleted(); 1280 } break; 1281 case SHOW_NOT_RESPONDING_MSG: { 1282 synchronized (ActivityManagerService.this) { 1283 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1284 ProcessRecord proc = (ProcessRecord)data.get("app"); 1285 if (proc != null && proc.anrDialog != null) { 1286 Slog.e(TAG, "App already has anr dialog: " + proc); 1287 return; 1288 } 1289 1290 Intent intent = new Intent("android.intent.action.ANR"); 1291 if (!mProcessesReady) { 1292 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1293 | Intent.FLAG_RECEIVER_FOREGROUND); 1294 } 1295 broadcastIntentLocked(null, null, intent, 1296 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1297 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1298 1299 if (mShowDialogs) { 1300 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1301 mContext, proc, (ActivityRecord)data.get("activity"), 1302 msg.arg1 != 0); 1303 d.show(); 1304 proc.anrDialog = d; 1305 } else { 1306 // Just kill the app if there is no dialog to be shown. 1307 killAppAtUsersRequest(proc, null); 1308 } 1309 } 1310 1311 ensureBootCompleted(); 1312 } break; 1313 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1314 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1315 synchronized (ActivityManagerService.this) { 1316 ProcessRecord proc = (ProcessRecord) data.get("app"); 1317 if (proc == null) { 1318 Slog.e(TAG, "App not found when showing strict mode dialog."); 1319 break; 1320 } 1321 if (proc.crashDialog != null) { 1322 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1323 return; 1324 } 1325 AppErrorResult res = (AppErrorResult) data.get("result"); 1326 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1327 Dialog d = new StrictModeViolationDialog(mContext, 1328 ActivityManagerService.this, res, proc); 1329 d.show(); 1330 proc.crashDialog = d; 1331 } else { 1332 // The device is asleep, so just pretend that the user 1333 // saw a crash dialog and hit "force quit". 1334 res.set(0); 1335 } 1336 } 1337 ensureBootCompleted(); 1338 } break; 1339 case SHOW_FACTORY_ERROR_MSG: { 1340 Dialog d = new FactoryErrorDialog( 1341 mContext, msg.getData().getCharSequence("msg")); 1342 d.show(); 1343 ensureBootCompleted(); 1344 } break; 1345 case UPDATE_CONFIGURATION_MSG: { 1346 final ContentResolver resolver = mContext.getContentResolver(); 1347 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1348 } break; 1349 case GC_BACKGROUND_PROCESSES_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 performAppGcsIfAppropriateLocked(); 1352 } 1353 } break; 1354 case WAIT_FOR_DEBUGGER_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 ProcessRecord app = (ProcessRecord)msg.obj; 1357 if (msg.arg1 != 0) { 1358 if (!app.waitedForDebugger) { 1359 Dialog d = new AppWaitingForDebuggerDialog( 1360 ActivityManagerService.this, 1361 mContext, app); 1362 app.waitDialog = d; 1363 app.waitedForDebugger = true; 1364 d.show(); 1365 } 1366 } else { 1367 if (app.waitDialog != null) { 1368 app.waitDialog.dismiss(); 1369 app.waitDialog = null; 1370 } 1371 } 1372 } 1373 } break; 1374 case SERVICE_TIMEOUT_MSG: { 1375 if (mDidDexOpt) { 1376 mDidDexOpt = false; 1377 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1378 nmsg.obj = msg.obj; 1379 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1380 return; 1381 } 1382 mServices.serviceTimeout((ProcessRecord)msg.obj); 1383 } break; 1384 case UPDATE_TIME_ZONE: { 1385 synchronized (ActivityManagerService.this) { 1386 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1387 ProcessRecord r = mLruProcesses.get(i); 1388 if (r.thread != null) { 1389 try { 1390 r.thread.updateTimeZone(); 1391 } catch (RemoteException ex) { 1392 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1393 } 1394 } 1395 } 1396 } 1397 } break; 1398 case CLEAR_DNS_CACHE_MSG: { 1399 synchronized (ActivityManagerService.this) { 1400 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1401 ProcessRecord r = mLruProcesses.get(i); 1402 if (r.thread != null) { 1403 try { 1404 r.thread.clearDnsCache(); 1405 } catch (RemoteException ex) { 1406 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1407 } 1408 } 1409 } 1410 } 1411 } break; 1412 case UPDATE_HTTP_PROXY_MSG: { 1413 ProxyInfo proxy = (ProxyInfo)msg.obj; 1414 String host = ""; 1415 String port = ""; 1416 String exclList = ""; 1417 Uri pacFileUrl = Uri.EMPTY; 1418 if (proxy != null) { 1419 host = proxy.getHost(); 1420 port = Integer.toString(proxy.getPort()); 1421 exclList = proxy.getExclusionListAsString(); 1422 pacFileUrl = proxy.getPacFileUrl(); 1423 } 1424 synchronized (ActivityManagerService.this) { 1425 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1426 ProcessRecord r = mLruProcesses.get(i); 1427 if (r.thread != null) { 1428 try { 1429 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1430 } catch (RemoteException ex) { 1431 Slog.w(TAG, "Failed to update http proxy for: " + 1432 r.info.processName); 1433 } 1434 } 1435 } 1436 } 1437 } break; 1438 case SHOW_UID_ERROR_MSG: { 1439 String title = "System UIDs Inconsistent"; 1440 String text = "UIDs on the system are inconsistent, you need to wipe your" 1441 + " data partition or your device will be unstable."; 1442 Log.e(TAG, title + ": " + text); 1443 if (mShowDialogs) { 1444 // XXX This is a temporary dialog, no need to localize. 1445 AlertDialog d = new BaseErrorDialog(mContext); 1446 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1447 d.setCancelable(false); 1448 d.setTitle(title); 1449 d.setMessage(text); 1450 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1451 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1452 mUidAlert = d; 1453 d.show(); 1454 } 1455 } break; 1456 case IM_FEELING_LUCKY_MSG: { 1457 if (mUidAlert != null) { 1458 mUidAlert.dismiss(); 1459 mUidAlert = null; 1460 } 1461 } break; 1462 case PROC_START_TIMEOUT_MSG: { 1463 if (mDidDexOpt) { 1464 mDidDexOpt = false; 1465 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1466 nmsg.obj = msg.obj; 1467 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1468 return; 1469 } 1470 ProcessRecord app = (ProcessRecord)msg.obj; 1471 synchronized (ActivityManagerService.this) { 1472 processStartTimedOutLocked(app); 1473 } 1474 } break; 1475 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1476 synchronized (ActivityManagerService.this) { 1477 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1478 } 1479 } break; 1480 case KILL_APPLICATION_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 int appid = msg.arg1; 1483 boolean restart = (msg.arg2 == 1); 1484 Bundle bundle = (Bundle)msg.obj; 1485 String pkg = bundle.getString("pkg"); 1486 String reason = bundle.getString("reason"); 1487 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1488 false, UserHandle.USER_ALL, reason); 1489 } 1490 } break; 1491 case FINALIZE_PENDING_INTENT_MSG: { 1492 ((PendingIntentRecord)msg.obj).completeFinalize(); 1493 } break; 1494 case POST_HEAVY_NOTIFICATION_MSG: { 1495 INotificationManager inm = NotificationManager.getService(); 1496 if (inm == null) { 1497 return; 1498 } 1499 1500 ActivityRecord root = (ActivityRecord)msg.obj; 1501 ProcessRecord process = root.app; 1502 if (process == null) { 1503 return; 1504 } 1505 1506 try { 1507 Context context = mContext.createPackageContext(process.info.packageName, 0); 1508 String text = mContext.getString(R.string.heavy_weight_notification, 1509 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1510 Notification notification = new Notification(); 1511 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1512 notification.when = 0; 1513 notification.flags = Notification.FLAG_ONGOING_EVENT; 1514 notification.tickerText = text; 1515 notification.defaults = 0; // please be quiet 1516 notification.sound = null; 1517 notification.vibrate = null; 1518 notification.color = mContext.getResources().getColor( 1519 com.android.internal.R.color.system_notification_accent_color); 1520 notification.setLatestEventInfo(context, text, 1521 mContext.getText(R.string.heavy_weight_notification_detail), 1522 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1523 PendingIntent.FLAG_CANCEL_CURRENT, null, 1524 new UserHandle(root.userId))); 1525 1526 try { 1527 int[] outId = new int[1]; 1528 inm.enqueueNotificationWithTag("android", "android", null, 1529 R.string.heavy_weight_notification, 1530 notification, outId, root.userId); 1531 } catch (RuntimeException e) { 1532 Slog.w(ActivityManagerService.TAG, 1533 "Error showing notification for heavy-weight app", e); 1534 } catch (RemoteException e) { 1535 } 1536 } catch (NameNotFoundException e) { 1537 Slog.w(TAG, "Unable to create context for heavy notification", e); 1538 } 1539 } break; 1540 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1541 INotificationManager inm = NotificationManager.getService(); 1542 if (inm == null) { 1543 return; 1544 } 1545 try { 1546 inm.cancelNotificationWithTag("android", null, 1547 R.string.heavy_weight_notification, msg.arg1); 1548 } catch (RuntimeException e) { 1549 Slog.w(ActivityManagerService.TAG, 1550 "Error canceling notification for service", e); 1551 } catch (RemoteException e) { 1552 } 1553 } break; 1554 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1555 synchronized (ActivityManagerService.this) { 1556 checkExcessivePowerUsageLocked(true); 1557 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1558 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1559 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1560 } 1561 } break; 1562 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1563 synchronized (ActivityManagerService.this) { 1564 ActivityRecord ar = (ActivityRecord)msg.obj; 1565 if (mCompatModeDialog != null) { 1566 if (mCompatModeDialog.mAppInfo.packageName.equals( 1567 ar.info.applicationInfo.packageName)) { 1568 return; 1569 } 1570 mCompatModeDialog.dismiss(); 1571 mCompatModeDialog = null; 1572 } 1573 if (ar != null && false) { 1574 if (mCompatModePackages.getPackageAskCompatModeLocked( 1575 ar.packageName)) { 1576 int mode = mCompatModePackages.computeCompatModeLocked( 1577 ar.info.applicationInfo); 1578 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1579 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1580 mCompatModeDialog = new CompatModeDialog( 1581 ActivityManagerService.this, mContext, 1582 ar.info.applicationInfo); 1583 mCompatModeDialog.show(); 1584 } 1585 } 1586 } 1587 } 1588 break; 1589 } 1590 case DISPATCH_PROCESSES_CHANGED: { 1591 dispatchProcessesChanged(); 1592 break; 1593 } 1594 case DISPATCH_PROCESS_DIED: { 1595 final int pid = msg.arg1; 1596 final int uid = msg.arg2; 1597 dispatchProcessDied(pid, uid); 1598 break; 1599 } 1600 case REPORT_MEM_USAGE_MSG: { 1601 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1602 Thread thread = new Thread() { 1603 @Override public void run() { 1604 final SparseArray<ProcessMemInfo> infoMap 1605 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1606 for (int i=0, N=memInfos.size(); i<N; i++) { 1607 ProcessMemInfo mi = memInfos.get(i); 1608 infoMap.put(mi.pid, mi); 1609 } 1610 updateCpuStatsNow(); 1611 synchronized (mProcessCpuTracker) { 1612 final int N = mProcessCpuTracker.countStats(); 1613 for (int i=0; i<N; i++) { 1614 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1615 if (st.vsize > 0) { 1616 long pss = Debug.getPss(st.pid, null); 1617 if (pss > 0) { 1618 if (infoMap.indexOfKey(st.pid) < 0) { 1619 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1620 ProcessList.NATIVE_ADJ, -1, "native", null); 1621 mi.pss = pss; 1622 memInfos.add(mi); 1623 } 1624 } 1625 } 1626 } 1627 } 1628 1629 long totalPss = 0; 1630 for (int i=0, N=memInfos.size(); i<N; i++) { 1631 ProcessMemInfo mi = memInfos.get(i); 1632 if (mi.pss == 0) { 1633 mi.pss = Debug.getPss(mi.pid, null); 1634 } 1635 totalPss += mi.pss; 1636 } 1637 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1638 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1639 if (lhs.oomAdj != rhs.oomAdj) { 1640 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1641 } 1642 if (lhs.pss != rhs.pss) { 1643 return lhs.pss < rhs.pss ? 1 : -1; 1644 } 1645 return 0; 1646 } 1647 }); 1648 1649 StringBuilder tag = new StringBuilder(128); 1650 StringBuilder stack = new StringBuilder(128); 1651 tag.append("Low on memory -- "); 1652 appendMemBucket(tag, totalPss, "total", false); 1653 appendMemBucket(stack, totalPss, "total", true); 1654 1655 StringBuilder logBuilder = new StringBuilder(1024); 1656 logBuilder.append("Low on memory:\n"); 1657 1658 boolean firstLine = true; 1659 int lastOomAdj = Integer.MIN_VALUE; 1660 for (int i=0, N=memInfos.size(); i<N; i++) { 1661 ProcessMemInfo mi = memInfos.get(i); 1662 1663 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1664 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1665 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1666 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1667 if (lastOomAdj != mi.oomAdj) { 1668 lastOomAdj = mi.oomAdj; 1669 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1670 tag.append(" / "); 1671 } 1672 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1673 if (firstLine) { 1674 stack.append(":"); 1675 firstLine = false; 1676 } 1677 stack.append("\n\t at "); 1678 } else { 1679 stack.append("$"); 1680 } 1681 } else { 1682 tag.append(" "); 1683 stack.append("$"); 1684 } 1685 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1686 appendMemBucket(tag, mi.pss, mi.name, false); 1687 } 1688 appendMemBucket(stack, mi.pss, mi.name, true); 1689 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1690 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1691 stack.append("("); 1692 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1693 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1694 stack.append(DUMP_MEM_OOM_LABEL[k]); 1695 stack.append(":"); 1696 stack.append(DUMP_MEM_OOM_ADJ[k]); 1697 } 1698 } 1699 stack.append(")"); 1700 } 1701 } 1702 1703 logBuilder.append(" "); 1704 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1705 logBuilder.append(' '); 1706 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1707 logBuilder.append(' '); 1708 ProcessList.appendRamKb(logBuilder, mi.pss); 1709 logBuilder.append(" kB: "); 1710 logBuilder.append(mi.name); 1711 logBuilder.append(" ("); 1712 logBuilder.append(mi.pid); 1713 logBuilder.append(") "); 1714 logBuilder.append(mi.adjType); 1715 logBuilder.append('\n'); 1716 if (mi.adjReason != null) { 1717 logBuilder.append(" "); 1718 logBuilder.append(mi.adjReason); 1719 logBuilder.append('\n'); 1720 } 1721 } 1722 1723 logBuilder.append(" "); 1724 ProcessList.appendRamKb(logBuilder, totalPss); 1725 logBuilder.append(" kB: TOTAL\n"); 1726 1727 long[] infos = new long[Debug.MEMINFO_COUNT]; 1728 Debug.getMemInfo(infos); 1729 logBuilder.append(" MemInfo: "); 1730 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1731 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1732 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1733 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1734 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1735 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1736 logBuilder.append(" ZRAM: "); 1737 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1738 logBuilder.append(" kB RAM, "); 1739 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1740 logBuilder.append(" kB swap total, "); 1741 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1742 logBuilder.append(" kB swap free\n"); 1743 } 1744 Slog.i(TAG, logBuilder.toString()); 1745 1746 StringBuilder dropBuilder = new StringBuilder(1024); 1747 /* 1748 StringWriter oomSw = new StringWriter(); 1749 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1750 StringWriter catSw = new StringWriter(); 1751 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1752 String[] emptyArgs = new String[] { }; 1753 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1754 oomPw.flush(); 1755 String oomString = oomSw.toString(); 1756 */ 1757 dropBuilder.append(stack); 1758 dropBuilder.append('\n'); 1759 dropBuilder.append('\n'); 1760 dropBuilder.append(logBuilder); 1761 dropBuilder.append('\n'); 1762 /* 1763 dropBuilder.append(oomString); 1764 dropBuilder.append('\n'); 1765 */ 1766 StringWriter catSw = new StringWriter(); 1767 synchronized (ActivityManagerService.this) { 1768 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1769 String[] emptyArgs = new String[] { }; 1770 catPw.println(); 1771 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1772 catPw.println(); 1773 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1774 false, false, null); 1775 catPw.println(); 1776 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1777 catPw.flush(); 1778 } 1779 dropBuilder.append(catSw.toString()); 1780 addErrorToDropBox("lowmem", null, "system_server", null, 1781 null, tag.toString(), dropBuilder.toString(), null, null); 1782 //Slog.i(TAG, "Sent to dropbox:"); 1783 //Slog.i(TAG, dropBuilder.toString()); 1784 synchronized (ActivityManagerService.this) { 1785 long now = SystemClock.uptimeMillis(); 1786 if (mLastMemUsageReportTime < now) { 1787 mLastMemUsageReportTime = now; 1788 } 1789 } 1790 } 1791 }; 1792 thread.start(); 1793 break; 1794 } 1795 case START_USER_SWITCH_MSG: { 1796 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1797 break; 1798 } 1799 case REPORT_USER_SWITCH_MSG: { 1800 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1801 break; 1802 } 1803 case CONTINUE_USER_SWITCH_MSG: { 1804 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1805 break; 1806 } 1807 case USER_SWITCH_TIMEOUT_MSG: { 1808 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1809 break; 1810 } 1811 case IMMERSIVE_MODE_LOCK_MSG: { 1812 final boolean nextState = (msg.arg1 != 0); 1813 if (mUpdateLock.isHeld() != nextState) { 1814 if (DEBUG_IMMERSIVE) { 1815 final ActivityRecord r = (ActivityRecord) msg.obj; 1816 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1817 } 1818 if (nextState) { 1819 mUpdateLock.acquire(); 1820 } else { 1821 mUpdateLock.release(); 1822 } 1823 } 1824 break; 1825 } 1826 case PERSIST_URI_GRANTS_MSG: { 1827 writeGrantedUriPermissions(); 1828 break; 1829 } 1830 case REQUEST_ALL_PSS_MSG: { 1831 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1832 break; 1833 } 1834 case START_PROFILES_MSG: { 1835 synchronized (ActivityManagerService.this) { 1836 startProfilesLocked(); 1837 } 1838 break; 1839 } 1840 case UPDATE_TIME: { 1841 synchronized (ActivityManagerService.this) { 1842 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1843 ProcessRecord r = mLruProcesses.get(i); 1844 if (r.thread != null) { 1845 try { 1846 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1847 } catch (RemoteException ex) { 1848 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1849 } 1850 } 1851 } 1852 } 1853 break; 1854 } 1855 case SYSTEM_USER_START_MSG: { 1856 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1857 Integer.toString(msg.arg1), msg.arg1); 1858 mSystemServiceManager.startUser(msg.arg1); 1859 break; 1860 } 1861 case SYSTEM_USER_CURRENT_MSG: { 1862 mBatteryStatsService.noteEvent( 1863 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1864 Integer.toString(msg.arg2), msg.arg2); 1865 mBatteryStatsService.noteEvent( 1866 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1867 Integer.toString(msg.arg1), msg.arg1); 1868 mSystemServiceManager.switchUser(msg.arg1); 1869 mLockToAppRequest.clearPrompt(); 1870 break; 1871 } 1872 case ENTER_ANIMATION_COMPLETE_MSG: { 1873 synchronized (ActivityManagerService.this) { 1874 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1875 if (r != null && r.app != null && r.app.thread != null) { 1876 try { 1877 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1878 } catch (RemoteException e) { 1879 } 1880 } 1881 } 1882 break; 1883 } 1884 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1885 enableScreenAfterBoot(); 1886 break; 1887 } 1888 } 1889 } 1890 }; 1891 1892 static final int COLLECT_PSS_BG_MSG = 1; 1893 1894 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1895 @Override 1896 public void handleMessage(Message msg) { 1897 switch (msg.what) { 1898 case COLLECT_PSS_BG_MSG: { 1899 long start = SystemClock.uptimeMillis(); 1900 MemInfoReader memInfo = null; 1901 synchronized (ActivityManagerService.this) { 1902 if (mFullPssPending) { 1903 mFullPssPending = false; 1904 memInfo = new MemInfoReader(); 1905 } 1906 } 1907 if (memInfo != null) { 1908 updateCpuStatsNow(); 1909 long nativeTotalPss = 0; 1910 synchronized (mProcessCpuTracker) { 1911 final int N = mProcessCpuTracker.countStats(); 1912 for (int j=0; j<N; j++) { 1913 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1914 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1915 // This is definitely an application process; skip it. 1916 continue; 1917 } 1918 synchronized (mPidsSelfLocked) { 1919 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1920 // This is one of our own processes; skip it. 1921 continue; 1922 } 1923 } 1924 nativeTotalPss += Debug.getPss(st.pid, null); 1925 } 1926 } 1927 memInfo.readMemInfo(); 1928 synchronized (ActivityManagerService.this) { 1929 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1930 + (SystemClock.uptimeMillis()-start) + "ms"); 1931 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1932 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1933 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1934 +memInfo.getSlabSizeKb(), 1935 nativeTotalPss); 1936 } 1937 } 1938 1939 int i=0, num=0; 1940 long[] tmp = new long[1]; 1941 do { 1942 ProcessRecord proc; 1943 int procState; 1944 int pid; 1945 synchronized (ActivityManagerService.this) { 1946 if (i >= mPendingPssProcesses.size()) { 1947 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1948 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1949 mPendingPssProcesses.clear(); 1950 return; 1951 } 1952 proc = mPendingPssProcesses.get(i); 1953 procState = proc.pssProcState; 1954 if (proc.thread != null && procState == proc.setProcState) { 1955 pid = proc.pid; 1956 } else { 1957 proc = null; 1958 pid = 0; 1959 } 1960 i++; 1961 } 1962 if (proc != null) { 1963 long pss = Debug.getPss(pid, tmp); 1964 synchronized (ActivityManagerService.this) { 1965 if (proc.thread != null && proc.setProcState == procState 1966 && proc.pid == pid) { 1967 num++; 1968 proc.lastPssTime = SystemClock.uptimeMillis(); 1969 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1970 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1971 + ": " + pss + " lastPss=" + proc.lastPss 1972 + " state=" + ProcessList.makeProcStateString(procState)); 1973 if (proc.initialIdlePss == 0) { 1974 proc.initialIdlePss = pss; 1975 } 1976 proc.lastPss = pss; 1977 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1978 proc.lastCachedPss = pss; 1979 } 1980 } 1981 } 1982 } 1983 } while (true); 1984 } 1985 } 1986 } 1987 }; 1988 1989 /** 1990 * Monitor for package changes and update our internal state. 1991 */ 1992 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1993 @Override 1994 public void onPackageRemoved(String packageName, int uid) { 1995 // Remove all tasks with activities in the specified package from the list of recent tasks 1996 synchronized (ActivityManagerService.this) { 1997 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1998 TaskRecord tr = mRecentTasks.get(i); 1999 ComponentName cn = tr.intent.getComponent(); 2000 if (cn != null && cn.getPackageName().equals(packageName)) { 2001 // If the package name matches, remove the task and kill the process 2002 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2003 } 2004 } 2005 } 2006 } 2007 2008 @Override 2009 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2010 onPackageModified(packageName); 2011 return true; 2012 } 2013 2014 @Override 2015 public void onPackageModified(String packageName) { 2016 final PackageManager pm = mContext.getPackageManager(); 2017 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2018 new ArrayList<Pair<Intent, Integer>>(); 2019 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2020 // Copy the list of recent tasks so that we don't hold onto the lock on 2021 // ActivityManagerService for long periods while checking if components exist. 2022 synchronized (ActivityManagerService.this) { 2023 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2024 TaskRecord tr = mRecentTasks.get(i); 2025 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2026 } 2027 } 2028 // Check the recent tasks and filter out all tasks with components that no longer exist. 2029 Intent tmpI = new Intent(); 2030 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2031 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2032 ComponentName cn = p.first.getComponent(); 2033 if (cn != null && cn.getPackageName().equals(packageName)) { 2034 try { 2035 // Add the task to the list to remove if the component no longer exists 2036 tmpI.setComponent(cn); 2037 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2038 tasksToRemove.add(p.second); 2039 } 2040 } catch (Exception e) {} 2041 } 2042 } 2043 // Prune all the tasks with removed components from the list of recent tasks 2044 synchronized (ActivityManagerService.this) { 2045 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2046 // Remove the task but don't kill the process (since other components in that 2047 // package may still be running and in the background) 2048 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2049 } 2050 } 2051 } 2052 2053 @Override 2054 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2055 // Force stop the specified packages 2056 if (packages != null) { 2057 for (String pkg : packages) { 2058 synchronized (ActivityManagerService.this) { 2059 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2060 "finished booting")) { 2061 return true; 2062 } 2063 } 2064 } 2065 } 2066 return false; 2067 } 2068 }; 2069 2070 public void setSystemProcess() { 2071 try { 2072 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2073 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2074 ServiceManager.addService("meminfo", new MemBinder(this)); 2075 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2076 ServiceManager.addService("dbinfo", new DbBinder(this)); 2077 if (MONITOR_CPU_USAGE) { 2078 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2079 } 2080 ServiceManager.addService("permission", new PermissionController(this)); 2081 2082 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2083 "android", STOCK_PM_FLAGS); 2084 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2085 2086 synchronized (this) { 2087 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2088 app.persistent = true; 2089 app.pid = MY_PID; 2090 app.maxAdj = ProcessList.SYSTEM_ADJ; 2091 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2092 mProcessNames.put(app.processName, app.uid, app); 2093 synchronized (mPidsSelfLocked) { 2094 mPidsSelfLocked.put(app.pid, app); 2095 } 2096 updateLruProcessLocked(app, false, null); 2097 updateOomAdjLocked(); 2098 } 2099 } catch (PackageManager.NameNotFoundException e) { 2100 throw new RuntimeException( 2101 "Unable to find android system package", e); 2102 } 2103 } 2104 2105 public void setWindowManager(WindowManagerService wm) { 2106 mWindowManager = wm; 2107 mStackSupervisor.setWindowManager(wm); 2108 } 2109 2110 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2111 mUsageStatsService = usageStatsManager; 2112 } 2113 2114 public void startObservingNativeCrashes() { 2115 final NativeCrashListener ncl = new NativeCrashListener(this); 2116 ncl.start(); 2117 } 2118 2119 public IAppOpsService getAppOpsService() { 2120 return mAppOpsService; 2121 } 2122 2123 static class MemBinder extends Binder { 2124 ActivityManagerService mActivityManagerService; 2125 MemBinder(ActivityManagerService activityManagerService) { 2126 mActivityManagerService = activityManagerService; 2127 } 2128 2129 @Override 2130 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2131 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2132 != PackageManager.PERMISSION_GRANTED) { 2133 pw.println("Permission Denial: can't dump meminfo from from pid=" 2134 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2135 + " without permission " + android.Manifest.permission.DUMP); 2136 return; 2137 } 2138 2139 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2140 } 2141 } 2142 2143 static class GraphicsBinder extends Binder { 2144 ActivityManagerService mActivityManagerService; 2145 GraphicsBinder(ActivityManagerService activityManagerService) { 2146 mActivityManagerService = activityManagerService; 2147 } 2148 2149 @Override 2150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2151 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2152 != PackageManager.PERMISSION_GRANTED) { 2153 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2154 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2155 + " without permission " + android.Manifest.permission.DUMP); 2156 return; 2157 } 2158 2159 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2160 } 2161 } 2162 2163 static class DbBinder extends Binder { 2164 ActivityManagerService mActivityManagerService; 2165 DbBinder(ActivityManagerService activityManagerService) { 2166 mActivityManagerService = activityManagerService; 2167 } 2168 2169 @Override 2170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2171 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2172 != PackageManager.PERMISSION_GRANTED) { 2173 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2174 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2175 + " without permission " + android.Manifest.permission.DUMP); 2176 return; 2177 } 2178 2179 mActivityManagerService.dumpDbInfo(fd, pw, args); 2180 } 2181 } 2182 2183 static class CpuBinder extends Binder { 2184 ActivityManagerService mActivityManagerService; 2185 CpuBinder(ActivityManagerService activityManagerService) { 2186 mActivityManagerService = activityManagerService; 2187 } 2188 2189 @Override 2190 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2191 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2192 != PackageManager.PERMISSION_GRANTED) { 2193 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2194 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2195 + " without permission " + android.Manifest.permission.DUMP); 2196 return; 2197 } 2198 2199 synchronized (mActivityManagerService.mProcessCpuTracker) { 2200 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2201 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2202 SystemClock.uptimeMillis())); 2203 } 2204 } 2205 } 2206 2207 public static final class Lifecycle extends SystemService { 2208 private final ActivityManagerService mService; 2209 2210 public Lifecycle(Context context) { 2211 super(context); 2212 mService = new ActivityManagerService(context); 2213 } 2214 2215 @Override 2216 public void onStart() { 2217 mService.start(); 2218 } 2219 2220 public ActivityManagerService getService() { 2221 return mService; 2222 } 2223 } 2224 2225 // Note: This method is invoked on the main thread but may need to attach various 2226 // handlers to other threads. So take care to be explicit about the looper. 2227 public ActivityManagerService(Context systemContext) { 2228 mContext = systemContext; 2229 mFactoryTest = FactoryTest.getMode(); 2230 mSystemThread = ActivityThread.currentActivityThread(); 2231 2232 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2233 2234 mHandlerThread = new ServiceThread(TAG, 2235 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2236 mHandlerThread.start(); 2237 mHandler = new MainHandler(mHandlerThread.getLooper()); 2238 2239 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2240 "foreground", BROADCAST_FG_TIMEOUT, false); 2241 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2242 "background", BROADCAST_BG_TIMEOUT, true); 2243 mBroadcastQueues[0] = mFgBroadcastQueue; 2244 mBroadcastQueues[1] = mBgBroadcastQueue; 2245 2246 mServices = new ActiveServices(this); 2247 mProviderMap = new ProviderMap(this); 2248 2249 // TODO: Move creation of battery stats service outside of activity manager service. 2250 File dataDir = Environment.getDataDirectory(); 2251 File systemDir = new File(dataDir, "system"); 2252 systemDir.mkdirs(); 2253 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2254 mBatteryStatsService.getActiveStatistics().readLocked(); 2255 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2256 mOnBattery = DEBUG_POWER ? true 2257 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2258 mBatteryStatsService.getActiveStatistics().setCallback(this); 2259 2260 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2261 2262 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2263 2264 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2265 2266 // User 0 is the first and only user that runs at boot. 2267 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2268 mUserLru.add(Integer.valueOf(0)); 2269 updateStartedUserArrayLocked(); 2270 2271 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2272 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2273 2274 mConfiguration.setToDefaults(); 2275 mConfiguration.setLocale(Locale.getDefault()); 2276 2277 mConfigurationSeq = mConfiguration.seq = 1; 2278 mProcessCpuTracker.init(); 2279 2280 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2281 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2282 mStackSupervisor = new ActivityStackSupervisor(this); 2283 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2284 2285 mProcessCpuThread = new Thread("CpuTracker") { 2286 @Override 2287 public void run() { 2288 while (true) { 2289 try { 2290 try { 2291 synchronized(this) { 2292 final long now = SystemClock.uptimeMillis(); 2293 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2294 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2295 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2296 // + ", write delay=" + nextWriteDelay); 2297 if (nextWriteDelay < nextCpuDelay) { 2298 nextCpuDelay = nextWriteDelay; 2299 } 2300 if (nextCpuDelay > 0) { 2301 mProcessCpuMutexFree.set(true); 2302 this.wait(nextCpuDelay); 2303 } 2304 } 2305 } catch (InterruptedException e) { 2306 } 2307 updateCpuStatsNow(); 2308 } catch (Exception e) { 2309 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2310 } 2311 } 2312 } 2313 }; 2314 2315 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2316 2317 Watchdog.getInstance().addMonitor(this); 2318 Watchdog.getInstance().addThread(mHandler); 2319 } 2320 2321 public void setSystemServiceManager(SystemServiceManager mgr) { 2322 mSystemServiceManager = mgr; 2323 } 2324 2325 private void start() { 2326 Process.removeAllProcessGroups(); 2327 mProcessCpuThread.start(); 2328 2329 mBatteryStatsService.publish(mContext); 2330 mAppOpsService.publish(mContext); 2331 Slog.d("AppOps", "AppOpsService published"); 2332 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2333 } 2334 2335 public void initPowerManagement() { 2336 mStackSupervisor.initPowerManagement(); 2337 mBatteryStatsService.initPowerManagement(); 2338 } 2339 2340 @Override 2341 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2342 throws RemoteException { 2343 if (code == SYSPROPS_TRANSACTION) { 2344 // We need to tell all apps about the system property change. 2345 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2346 synchronized(this) { 2347 final int NP = mProcessNames.getMap().size(); 2348 for (int ip=0; ip<NP; ip++) { 2349 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2350 final int NA = apps.size(); 2351 for (int ia=0; ia<NA; ia++) { 2352 ProcessRecord app = apps.valueAt(ia); 2353 if (app.thread != null) { 2354 procs.add(app.thread.asBinder()); 2355 } 2356 } 2357 } 2358 } 2359 2360 int N = procs.size(); 2361 for (int i=0; i<N; i++) { 2362 Parcel data2 = Parcel.obtain(); 2363 try { 2364 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2365 } catch (RemoteException e) { 2366 } 2367 data2.recycle(); 2368 } 2369 } 2370 try { 2371 return super.onTransact(code, data, reply, flags); 2372 } catch (RuntimeException e) { 2373 // The activity manager only throws security exceptions, so let's 2374 // log all others. 2375 if (!(e instanceof SecurityException)) { 2376 Slog.wtf(TAG, "Activity Manager Crash", e); 2377 } 2378 throw e; 2379 } 2380 } 2381 2382 void updateCpuStats() { 2383 final long now = SystemClock.uptimeMillis(); 2384 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2385 return; 2386 } 2387 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2388 synchronized (mProcessCpuThread) { 2389 mProcessCpuThread.notify(); 2390 } 2391 } 2392 } 2393 2394 void updateCpuStatsNow() { 2395 synchronized (mProcessCpuTracker) { 2396 mProcessCpuMutexFree.set(false); 2397 final long now = SystemClock.uptimeMillis(); 2398 boolean haveNewCpuStats = false; 2399 2400 if (MONITOR_CPU_USAGE && 2401 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2402 mLastCpuTime.set(now); 2403 haveNewCpuStats = true; 2404 mProcessCpuTracker.update(); 2405 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2406 //Slog.i(TAG, "Total CPU usage: " 2407 // + mProcessCpu.getTotalCpuPercent() + "%"); 2408 2409 // Slog the cpu usage if the property is set. 2410 if ("true".equals(SystemProperties.get("events.cpu"))) { 2411 int user = mProcessCpuTracker.getLastUserTime(); 2412 int system = mProcessCpuTracker.getLastSystemTime(); 2413 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2414 int irq = mProcessCpuTracker.getLastIrqTime(); 2415 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2416 int idle = mProcessCpuTracker.getLastIdleTime(); 2417 2418 int total = user + system + iowait + irq + softIrq + idle; 2419 if (total == 0) total = 1; 2420 2421 EventLog.writeEvent(EventLogTags.CPU, 2422 ((user+system+iowait+irq+softIrq) * 100) / total, 2423 (user * 100) / total, 2424 (system * 100) / total, 2425 (iowait * 100) / total, 2426 (irq * 100) / total, 2427 (softIrq * 100) / total); 2428 } 2429 } 2430 2431 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2432 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2433 synchronized(bstats) { 2434 synchronized(mPidsSelfLocked) { 2435 if (haveNewCpuStats) { 2436 if (mOnBattery) { 2437 int perc = bstats.startAddingCpuLocked(); 2438 int totalUTime = 0; 2439 int totalSTime = 0; 2440 final int N = mProcessCpuTracker.countStats(); 2441 for (int i=0; i<N; i++) { 2442 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2443 if (!st.working) { 2444 continue; 2445 } 2446 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2447 int otherUTime = (st.rel_utime*perc)/100; 2448 int otherSTime = (st.rel_stime*perc)/100; 2449 totalUTime += otherUTime; 2450 totalSTime += otherSTime; 2451 if (pr != null) { 2452 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2453 if (ps == null || !ps.isActive()) { 2454 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2455 pr.info.uid, pr.processName); 2456 } 2457 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2458 st.rel_stime-otherSTime); 2459 ps.addSpeedStepTimes(cpuSpeedTimes); 2460 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2461 } else { 2462 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2463 if (ps == null || !ps.isActive()) { 2464 st.batteryStats = ps = bstats.getProcessStatsLocked( 2465 bstats.mapUid(st.uid), st.name); 2466 } 2467 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2468 st.rel_stime-otherSTime); 2469 ps.addSpeedStepTimes(cpuSpeedTimes); 2470 } 2471 } 2472 bstats.finishAddingCpuLocked(perc, totalUTime, 2473 totalSTime, cpuSpeedTimes); 2474 } 2475 } 2476 } 2477 2478 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2479 mLastWriteTime = now; 2480 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2481 } 2482 } 2483 } 2484 } 2485 2486 @Override 2487 public void batteryNeedsCpuUpdate() { 2488 updateCpuStatsNow(); 2489 } 2490 2491 @Override 2492 public void batteryPowerChanged(boolean onBattery) { 2493 // When plugging in, update the CPU stats first before changing 2494 // the plug state. 2495 updateCpuStatsNow(); 2496 synchronized (this) { 2497 synchronized(mPidsSelfLocked) { 2498 mOnBattery = DEBUG_POWER ? true : onBattery; 2499 } 2500 } 2501 } 2502 2503 /** 2504 * Initialize the application bind args. These are passed to each 2505 * process when the bindApplication() IPC is sent to the process. They're 2506 * lazily setup to make sure the services are running when they're asked for. 2507 */ 2508 private HashMap<String, IBinder> getCommonServicesLocked() { 2509 if (mAppBindArgs == null) { 2510 mAppBindArgs = new HashMap<String, IBinder>(); 2511 2512 // Setup the application init args 2513 mAppBindArgs.put("package", ServiceManager.getService("package")); 2514 mAppBindArgs.put("window", ServiceManager.getService("window")); 2515 mAppBindArgs.put(Context.ALARM_SERVICE, 2516 ServiceManager.getService(Context.ALARM_SERVICE)); 2517 } 2518 return mAppBindArgs; 2519 } 2520 2521 final void setFocusedActivityLocked(ActivityRecord r) { 2522 if (mFocusedActivity != r) { 2523 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2524 mFocusedActivity = r; 2525 if (r.task != null && r.task.voiceInteractor != null) { 2526 startRunningVoiceLocked(); 2527 } else { 2528 finishRunningVoiceLocked(); 2529 } 2530 mStackSupervisor.setFocusedStack(r); 2531 if (r != null) { 2532 mWindowManager.setFocusedApp(r.appToken, true); 2533 } 2534 applyUpdateLockStateLocked(r); 2535 } 2536 } 2537 2538 final void clearFocusedActivity(ActivityRecord r) { 2539 if (mFocusedActivity == r) { 2540 mFocusedActivity = null; 2541 } 2542 } 2543 2544 @Override 2545 public void setFocusedStack(int stackId) { 2546 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2547 synchronized (ActivityManagerService.this) { 2548 ActivityStack stack = mStackSupervisor.getStack(stackId); 2549 if (stack != null) { 2550 ActivityRecord r = stack.topRunningActivityLocked(null); 2551 if (r != null) { 2552 setFocusedActivityLocked(r); 2553 } 2554 } 2555 } 2556 } 2557 2558 @Override 2559 public void notifyActivityDrawn(IBinder token) { 2560 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2561 synchronized (this) { 2562 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2563 if (r != null) { 2564 r.task.stack.notifyActivityDrawnLocked(r); 2565 } 2566 } 2567 } 2568 2569 final void applyUpdateLockStateLocked(ActivityRecord r) { 2570 // Modifications to the UpdateLock state are done on our handler, outside 2571 // the activity manager's locks. The new state is determined based on the 2572 // state *now* of the relevant activity record. The object is passed to 2573 // the handler solely for logging detail, not to be consulted/modified. 2574 final boolean nextState = r != null && r.immersive; 2575 mHandler.sendMessage( 2576 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2577 } 2578 2579 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2580 Message msg = Message.obtain(); 2581 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2582 msg.obj = r.task.askedCompatMode ? null : r; 2583 mHandler.sendMessage(msg); 2584 } 2585 2586 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2587 String what, Object obj, ProcessRecord srcApp) { 2588 app.lastActivityTime = now; 2589 2590 if (app.activities.size() > 0) { 2591 // Don't want to touch dependent processes that are hosting activities. 2592 return index; 2593 } 2594 2595 int lrui = mLruProcesses.lastIndexOf(app); 2596 if (lrui < 0) { 2597 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2598 + what + " " + obj + " from " + srcApp); 2599 return index; 2600 } 2601 2602 if (lrui >= index) { 2603 // Don't want to cause this to move dependent processes *back* in the 2604 // list as if they were less frequently used. 2605 return index; 2606 } 2607 2608 if (lrui >= mLruProcessActivityStart) { 2609 // Don't want to touch dependent processes that are hosting activities. 2610 return index; 2611 } 2612 2613 mLruProcesses.remove(lrui); 2614 if (index > 0) { 2615 index--; 2616 } 2617 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2618 + " in LRU list: " + app); 2619 mLruProcesses.add(index, app); 2620 return index; 2621 } 2622 2623 final void removeLruProcessLocked(ProcessRecord app) { 2624 int lrui = mLruProcesses.lastIndexOf(app); 2625 if (lrui >= 0) { 2626 if (lrui <= mLruProcessActivityStart) { 2627 mLruProcessActivityStart--; 2628 } 2629 if (lrui <= mLruProcessServiceStart) { 2630 mLruProcessServiceStart--; 2631 } 2632 mLruProcesses.remove(lrui); 2633 } 2634 } 2635 2636 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2637 ProcessRecord client) { 2638 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2639 || app.treatLikeActivity; 2640 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2641 if (!activityChange && hasActivity) { 2642 // The process has activities, so we are only allowing activity-based adjustments 2643 // to move it. It should be kept in the front of the list with other 2644 // processes that have activities, and we don't want those to change their 2645 // order except due to activity operations. 2646 return; 2647 } 2648 2649 mLruSeq++; 2650 final long now = SystemClock.uptimeMillis(); 2651 app.lastActivityTime = now; 2652 2653 // First a quick reject: if the app is already at the position we will 2654 // put it, then there is nothing to do. 2655 if (hasActivity) { 2656 final int N = mLruProcesses.size(); 2657 if (N > 0 && mLruProcesses.get(N-1) == app) { 2658 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2659 return; 2660 } 2661 } else { 2662 if (mLruProcessServiceStart > 0 2663 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2664 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2665 return; 2666 } 2667 } 2668 2669 int lrui = mLruProcesses.lastIndexOf(app); 2670 2671 if (app.persistent && lrui >= 0) { 2672 // We don't care about the position of persistent processes, as long as 2673 // they are in the list. 2674 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2675 return; 2676 } 2677 2678 /* In progress: compute new position first, so we can avoid doing work 2679 if the process is not actually going to move. Not yet working. 2680 int addIndex; 2681 int nextIndex; 2682 boolean inActivity = false, inService = false; 2683 if (hasActivity) { 2684 // Process has activities, put it at the very tipsy-top. 2685 addIndex = mLruProcesses.size(); 2686 nextIndex = mLruProcessServiceStart; 2687 inActivity = true; 2688 } else if (hasService) { 2689 // Process has services, put it at the top of the service list. 2690 addIndex = mLruProcessActivityStart; 2691 nextIndex = mLruProcessServiceStart; 2692 inActivity = true; 2693 inService = true; 2694 } else { 2695 // Process not otherwise of interest, it goes to the top of the non-service area. 2696 addIndex = mLruProcessServiceStart; 2697 if (client != null) { 2698 int clientIndex = mLruProcesses.lastIndexOf(client); 2699 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2700 + app); 2701 if (clientIndex >= 0 && addIndex > clientIndex) { 2702 addIndex = clientIndex; 2703 } 2704 } 2705 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2706 } 2707 2708 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2709 + mLruProcessActivityStart + "): " + app); 2710 */ 2711 2712 if (lrui >= 0) { 2713 if (lrui < mLruProcessActivityStart) { 2714 mLruProcessActivityStart--; 2715 } 2716 if (lrui < mLruProcessServiceStart) { 2717 mLruProcessServiceStart--; 2718 } 2719 /* 2720 if (addIndex > lrui) { 2721 addIndex--; 2722 } 2723 if (nextIndex > lrui) { 2724 nextIndex--; 2725 } 2726 */ 2727 mLruProcesses.remove(lrui); 2728 } 2729 2730 /* 2731 mLruProcesses.add(addIndex, app); 2732 if (inActivity) { 2733 mLruProcessActivityStart++; 2734 } 2735 if (inService) { 2736 mLruProcessActivityStart++; 2737 } 2738 */ 2739 2740 int nextIndex; 2741 if (hasActivity) { 2742 final int N = mLruProcesses.size(); 2743 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2744 // Process doesn't have activities, but has clients with 2745 // activities... move it up, but one below the top (the top 2746 // should always have a real activity). 2747 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2748 mLruProcesses.add(N-1, app); 2749 // To keep it from spamming the LRU list (by making a bunch of clients), 2750 // we will push down any other entries owned by the app. 2751 final int uid = app.info.uid; 2752 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2753 ProcessRecord subProc = mLruProcesses.get(i); 2754 if (subProc.info.uid == uid) { 2755 // We want to push this one down the list. If the process after 2756 // it is for the same uid, however, don't do so, because we don't 2757 // want them internally to be re-ordered. 2758 if (mLruProcesses.get(i-1).info.uid != uid) { 2759 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2760 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2761 ProcessRecord tmp = mLruProcesses.get(i); 2762 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2763 mLruProcesses.set(i-1, tmp); 2764 i--; 2765 } 2766 } else { 2767 // A gap, we can stop here. 2768 break; 2769 } 2770 } 2771 } else { 2772 // Process has activities, put it at the very tipsy-top. 2773 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2774 mLruProcesses.add(app); 2775 } 2776 nextIndex = mLruProcessServiceStart; 2777 } else if (hasService) { 2778 // Process has services, put it at the top of the service list. 2779 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2780 mLruProcesses.add(mLruProcessActivityStart, app); 2781 nextIndex = mLruProcessServiceStart; 2782 mLruProcessActivityStart++; 2783 } else { 2784 // Process not otherwise of interest, it goes to the top of the non-service area. 2785 int index = mLruProcessServiceStart; 2786 if (client != null) { 2787 // If there is a client, don't allow the process to be moved up higher 2788 // in the list than that client. 2789 int clientIndex = mLruProcesses.lastIndexOf(client); 2790 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2791 + " when updating " + app); 2792 if (clientIndex <= lrui) { 2793 // Don't allow the client index restriction to push it down farther in the 2794 // list than it already is. 2795 clientIndex = lrui; 2796 } 2797 if (clientIndex >= 0 && index > clientIndex) { 2798 index = clientIndex; 2799 } 2800 } 2801 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2802 mLruProcesses.add(index, app); 2803 nextIndex = index-1; 2804 mLruProcessActivityStart++; 2805 mLruProcessServiceStart++; 2806 } 2807 2808 // If the app is currently using a content provider or service, 2809 // bump those processes as well. 2810 for (int j=app.connections.size()-1; j>=0; j--) { 2811 ConnectionRecord cr = app.connections.valueAt(j); 2812 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2813 && cr.binding.service.app != null 2814 && cr.binding.service.app.lruSeq != mLruSeq 2815 && !cr.binding.service.app.persistent) { 2816 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2817 "service connection", cr, app); 2818 } 2819 } 2820 for (int j=app.conProviders.size()-1; j>=0; j--) { 2821 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2822 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2823 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2824 "provider reference", cpr, app); 2825 } 2826 } 2827 } 2828 2829 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2830 if (uid == Process.SYSTEM_UID) { 2831 // The system gets to run in any process. If there are multiple 2832 // processes with the same uid, just pick the first (this 2833 // should never happen). 2834 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2835 if (procs == null) return null; 2836 final int N = procs.size(); 2837 for (int i = 0; i < N; i++) { 2838 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2839 } 2840 } 2841 ProcessRecord proc = mProcessNames.get(processName, uid); 2842 if (false && proc != null && !keepIfLarge 2843 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2844 && proc.lastCachedPss >= 4000) { 2845 // Turn this condition on to cause killing to happen regularly, for testing. 2846 if (proc.baseProcessTracker != null) { 2847 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2848 } 2849 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2850 } else if (proc != null && !keepIfLarge 2851 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2852 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2853 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2854 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2855 if (proc.baseProcessTracker != null) { 2856 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2857 } 2858 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2859 } 2860 } 2861 return proc; 2862 } 2863 2864 void ensurePackageDexOpt(String packageName) { 2865 IPackageManager pm = AppGlobals.getPackageManager(); 2866 try { 2867 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2868 mDidDexOpt = true; 2869 } 2870 } catch (RemoteException e) { 2871 } 2872 } 2873 2874 boolean isNextTransitionForward() { 2875 int transit = mWindowManager.getPendingAppTransition(); 2876 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2877 || transit == AppTransition.TRANSIT_TASK_OPEN 2878 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2879 } 2880 2881 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2882 String processName, String abiOverride, int uid, Runnable crashHandler) { 2883 synchronized(this) { 2884 ApplicationInfo info = new ApplicationInfo(); 2885 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2886 // For isolated processes, the former contains the parent's uid and the latter the 2887 // actual uid of the isolated process. 2888 // In the special case introduced by this method (which is, starting an isolated 2889 // process directly from the SystemServer without an actual parent app process) the 2890 // closest thing to a parent's uid is SYSTEM_UID. 2891 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2892 // the |isolated| logic in the ProcessRecord constructor. 2893 info.uid = Process.SYSTEM_UID; 2894 info.processName = processName; 2895 info.className = entryPoint; 2896 info.packageName = "android"; 2897 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2898 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2899 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2900 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2901 crashHandler); 2902 return proc != null ? proc.pid : 0; 2903 } 2904 } 2905 2906 final ProcessRecord startProcessLocked(String processName, 2907 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2908 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2909 boolean isolated, boolean keepIfLarge) { 2910 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2911 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2912 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2913 null /* crashHandler */); 2914 } 2915 2916 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2917 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2918 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2919 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2920 long startTime = SystemClock.elapsedRealtime(); 2921 ProcessRecord app; 2922 if (!isolated) { 2923 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2924 checkTime(startTime, "startProcess: after getProcessRecord"); 2925 } else { 2926 // If this is an isolated process, it can't re-use an existing process. 2927 app = null; 2928 } 2929 // We don't have to do anything more if: 2930 // (1) There is an existing application record; and 2931 // (2) The caller doesn't think it is dead, OR there is no thread 2932 // object attached to it so we know it couldn't have crashed; and 2933 // (3) There is a pid assigned to it, so it is either starting or 2934 // already running. 2935 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2936 + " app=" + app + " knownToBeDead=" + knownToBeDead 2937 + " thread=" + (app != null ? app.thread : null) 2938 + " pid=" + (app != null ? app.pid : -1)); 2939 if (app != null && app.pid > 0) { 2940 if (!knownToBeDead || app.thread == null) { 2941 // We already have the app running, or are waiting for it to 2942 // come up (we have a pid but not yet its thread), so keep it. 2943 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2944 // If this is a new package in the process, add the package to the list 2945 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2946 checkTime(startTime, "startProcess: done, added package to proc"); 2947 return app; 2948 } 2949 2950 // An application record is attached to a previous process, 2951 // clean it up now. 2952 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2953 checkTime(startTime, "startProcess: bad proc running, killing"); 2954 Process.killProcessGroup(app.info.uid, app.pid); 2955 handleAppDiedLocked(app, true, true); 2956 checkTime(startTime, "startProcess: done killing old proc"); 2957 } 2958 2959 String hostingNameStr = hostingName != null 2960 ? hostingName.flattenToShortString() : null; 2961 2962 if (!isolated) { 2963 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2964 // If we are in the background, then check to see if this process 2965 // is bad. If so, we will just silently fail. 2966 if (mBadProcesses.get(info.processName, info.uid) != null) { 2967 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2968 + "/" + info.processName); 2969 return null; 2970 } 2971 } else { 2972 // When the user is explicitly starting a process, then clear its 2973 // crash count so that we won't make it bad until they see at 2974 // least one crash dialog again, and make the process good again 2975 // if it had been bad. 2976 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2977 + "/" + info.processName); 2978 mProcessCrashTimes.remove(info.processName, info.uid); 2979 if (mBadProcesses.get(info.processName, info.uid) != null) { 2980 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2981 UserHandle.getUserId(info.uid), info.uid, 2982 info.processName); 2983 mBadProcesses.remove(info.processName, info.uid); 2984 if (app != null) { 2985 app.bad = false; 2986 } 2987 } 2988 } 2989 } 2990 2991 if (app == null) { 2992 checkTime(startTime, "startProcess: creating new process record"); 2993 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2994 app.crashHandler = crashHandler; 2995 if (app == null) { 2996 Slog.w(TAG, "Failed making new process record for " 2997 + processName + "/" + info.uid + " isolated=" + isolated); 2998 return null; 2999 } 3000 mProcessNames.put(processName, app.uid, app); 3001 if (isolated) { 3002 mIsolatedProcesses.put(app.uid, app); 3003 } 3004 checkTime(startTime, "startProcess: done creating new process record"); 3005 } else { 3006 // If this is a new package in the process, add the package to the list 3007 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3008 checkTime(startTime, "startProcess: added package to existing proc"); 3009 } 3010 3011 // If the system is not ready yet, then hold off on starting this 3012 // process until it is. 3013 if (!mProcessesReady 3014 && !isAllowedWhileBooting(info) 3015 && !allowWhileBooting) { 3016 if (!mProcessesOnHold.contains(app)) { 3017 mProcessesOnHold.add(app); 3018 } 3019 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3020 checkTime(startTime, "startProcess: returning with proc on hold"); 3021 return app; 3022 } 3023 3024 checkTime(startTime, "startProcess: stepping in to startProcess"); 3025 startProcessLocked( 3026 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3027 checkTime(startTime, "startProcess: done starting proc!"); 3028 return (app.pid != 0) ? app : null; 3029 } 3030 3031 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3032 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3033 } 3034 3035 private final void startProcessLocked(ProcessRecord app, 3036 String hostingType, String hostingNameStr) { 3037 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3038 null /* entryPoint */, null /* entryPointArgs */); 3039 } 3040 3041 private final void startProcessLocked(ProcessRecord app, String hostingType, 3042 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3043 long startTime = SystemClock.elapsedRealtime(); 3044 if (app.pid > 0 && app.pid != MY_PID) { 3045 checkTime(startTime, "startProcess: removing from pids map"); 3046 synchronized (mPidsSelfLocked) { 3047 mPidsSelfLocked.remove(app.pid); 3048 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3049 } 3050 checkTime(startTime, "startProcess: done removing from pids map"); 3051 app.setPid(0); 3052 } 3053 3054 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3055 "startProcessLocked removing on hold: " + app); 3056 mProcessesOnHold.remove(app); 3057 3058 checkTime(startTime, "startProcess: starting to update cpu stats"); 3059 updateCpuStats(); 3060 checkTime(startTime, "startProcess: done updating cpu stats"); 3061 3062 try { 3063 int uid = app.uid; 3064 3065 int[] gids = null; 3066 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3067 if (!app.isolated) { 3068 int[] permGids = null; 3069 try { 3070 checkTime(startTime, "startProcess: getting gids from package manager"); 3071 final PackageManager pm = mContext.getPackageManager(); 3072 permGids = pm.getPackageGids(app.info.packageName); 3073 3074 if (Environment.isExternalStorageEmulated()) { 3075 checkTime(startTime, "startProcess: checking external storage perm"); 3076 if (pm.checkPermission( 3077 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3078 app.info.packageName) == PERMISSION_GRANTED) { 3079 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3080 } else { 3081 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3082 } 3083 } 3084 } catch (PackageManager.NameNotFoundException e) { 3085 Slog.w(TAG, "Unable to retrieve gids", e); 3086 } 3087 3088 /* 3089 * Add shared application and profile GIDs so applications can share some 3090 * resources like shared libraries and access user-wide resources 3091 */ 3092 if (permGids == null) { 3093 gids = new int[2]; 3094 } else { 3095 gids = new int[permGids.length + 2]; 3096 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3097 } 3098 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3099 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3100 } 3101 checkTime(startTime, "startProcess: building args"); 3102 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3103 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3104 && mTopComponent != null 3105 && app.processName.equals(mTopComponent.getPackageName())) { 3106 uid = 0; 3107 } 3108 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3109 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3110 uid = 0; 3111 } 3112 } 3113 int debugFlags = 0; 3114 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3115 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3116 // Also turn on CheckJNI for debuggable apps. It's quite 3117 // awkward to turn on otherwise. 3118 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3119 } 3120 // Run the app in safe mode if its manifest requests so or the 3121 // system is booted in safe mode. 3122 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3123 mSafeMode == true) { 3124 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3125 } 3126 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3127 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3128 } 3129 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3130 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3131 } 3132 if ("1".equals(SystemProperties.get("debug.assert"))) { 3133 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3134 } 3135 3136 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3137 if (requiredAbi == null) { 3138 requiredAbi = Build.SUPPORTED_ABIS[0]; 3139 } 3140 3141 String instructionSet = null; 3142 if (app.info.primaryCpuAbi != null) { 3143 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3144 } 3145 3146 // Start the process. It will either succeed and return a result containing 3147 // the PID of the new process, or else throw a RuntimeException. 3148 boolean isActivityProcess = (entryPoint == null); 3149 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3150 checkTime(startTime, "startProcess: asking zygote to start proc"); 3151 Process.ProcessStartResult startResult = Process.start(entryPoint, 3152 app.processName, uid, uid, gids, debugFlags, mountExternal, 3153 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3154 entryPointArgs); 3155 checkTime(startTime, "startProcess: returned from zygote!"); 3156 3157 if (app.isolated) { 3158 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3159 } 3160 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3161 checkTime(startTime, "startProcess: done updating battery stats"); 3162 3163 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3164 UserHandle.getUserId(uid), startResult.pid, uid, 3165 app.processName, hostingType, 3166 hostingNameStr != null ? hostingNameStr : ""); 3167 3168 if (app.persistent) { 3169 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3170 } 3171 3172 checkTime(startTime, "startProcess: building log message"); 3173 StringBuilder buf = mStringBuilder; 3174 buf.setLength(0); 3175 buf.append("Start proc "); 3176 buf.append(app.processName); 3177 if (!isActivityProcess) { 3178 buf.append(" ["); 3179 buf.append(entryPoint); 3180 buf.append("]"); 3181 } 3182 buf.append(" for "); 3183 buf.append(hostingType); 3184 if (hostingNameStr != null) { 3185 buf.append(" "); 3186 buf.append(hostingNameStr); 3187 } 3188 buf.append(": pid="); 3189 buf.append(startResult.pid); 3190 buf.append(" uid="); 3191 buf.append(uid); 3192 buf.append(" gids={"); 3193 if (gids != null) { 3194 for (int gi=0; gi<gids.length; gi++) { 3195 if (gi != 0) buf.append(", "); 3196 buf.append(gids[gi]); 3197 3198 } 3199 } 3200 buf.append("}"); 3201 if (requiredAbi != null) { 3202 buf.append(" abi="); 3203 buf.append(requiredAbi); 3204 } 3205 Slog.i(TAG, buf.toString()); 3206 app.setPid(startResult.pid); 3207 app.usingWrapper = startResult.usingWrapper; 3208 app.removed = false; 3209 app.killedByAm = false; 3210 checkTime(startTime, "startProcess: starting to update pids map"); 3211 synchronized (mPidsSelfLocked) { 3212 this.mPidsSelfLocked.put(startResult.pid, app); 3213 if (isActivityProcess) { 3214 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3215 msg.obj = app; 3216 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3217 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3218 } 3219 } 3220 checkTime(startTime, "startProcess: done updating pids map"); 3221 } catch (RuntimeException e) { 3222 // XXX do better error recovery. 3223 app.setPid(0); 3224 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3225 if (app.isolated) { 3226 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3227 } 3228 Slog.e(TAG, "Failure starting process " + app.processName, e); 3229 } 3230 } 3231 3232 void updateUsageStats(ActivityRecord component, boolean resumed) { 3233 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3234 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3235 if (resumed) { 3236 if (mUsageStatsService != null) { 3237 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3238 UsageEvents.Event.MOVE_TO_FOREGROUND); 3239 } 3240 synchronized (stats) { 3241 stats.noteActivityResumedLocked(component.app.uid); 3242 } 3243 } else { 3244 if (mUsageStatsService != null) { 3245 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3246 UsageEvents.Event.MOVE_TO_BACKGROUND); 3247 } 3248 synchronized (stats) { 3249 stats.noteActivityPausedLocked(component.app.uid); 3250 } 3251 } 3252 } 3253 3254 Intent getHomeIntent() { 3255 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3256 intent.setComponent(mTopComponent); 3257 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3258 intent.addCategory(Intent.CATEGORY_HOME); 3259 } 3260 return intent; 3261 } 3262 3263 boolean startHomeActivityLocked(int userId) { 3264 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3265 && mTopAction == null) { 3266 // We are running in factory test mode, but unable to find 3267 // the factory test app, so just sit around displaying the 3268 // error message and don't try to start anything. 3269 return false; 3270 } 3271 Intent intent = getHomeIntent(); 3272 ActivityInfo aInfo = 3273 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3274 if (aInfo != null) { 3275 intent.setComponent(new ComponentName( 3276 aInfo.applicationInfo.packageName, aInfo.name)); 3277 // Don't do this if the home app is currently being 3278 // instrumented. 3279 aInfo = new ActivityInfo(aInfo); 3280 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3281 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3282 aInfo.applicationInfo.uid, true); 3283 if (app == null || app.instrumentationClass == null) { 3284 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3285 mStackSupervisor.startHomeActivity(intent, aInfo); 3286 } 3287 } 3288 3289 return true; 3290 } 3291 3292 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3293 ActivityInfo ai = null; 3294 ComponentName comp = intent.getComponent(); 3295 try { 3296 if (comp != null) { 3297 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3298 } else { 3299 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3300 intent, 3301 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3302 flags, userId); 3303 3304 if (info != null) { 3305 ai = info.activityInfo; 3306 } 3307 } 3308 } catch (RemoteException e) { 3309 // ignore 3310 } 3311 3312 return ai; 3313 } 3314 3315 /** 3316 * Starts the "new version setup screen" if appropriate. 3317 */ 3318 void startSetupActivityLocked() { 3319 // Only do this once per boot. 3320 if (mCheckedForSetup) { 3321 return; 3322 } 3323 3324 // We will show this screen if the current one is a different 3325 // version than the last one shown, and we are not running in 3326 // low-level factory test mode. 3327 final ContentResolver resolver = mContext.getContentResolver(); 3328 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3329 Settings.Global.getInt(resolver, 3330 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3331 mCheckedForSetup = true; 3332 3333 // See if we should be showing the platform update setup UI. 3334 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3335 List<ResolveInfo> ris = mContext.getPackageManager() 3336 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3337 3338 // We don't allow third party apps to replace this. 3339 ResolveInfo ri = null; 3340 for (int i=0; ris != null && i<ris.size(); i++) { 3341 if ((ris.get(i).activityInfo.applicationInfo.flags 3342 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3343 ri = ris.get(i); 3344 break; 3345 } 3346 } 3347 3348 if (ri != null) { 3349 String vers = ri.activityInfo.metaData != null 3350 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3351 : null; 3352 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3353 vers = ri.activityInfo.applicationInfo.metaData.getString( 3354 Intent.METADATA_SETUP_VERSION); 3355 } 3356 String lastVers = Settings.Secure.getString( 3357 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3358 if (vers != null && !vers.equals(lastVers)) { 3359 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3360 intent.setComponent(new ComponentName( 3361 ri.activityInfo.packageName, ri.activityInfo.name)); 3362 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3363 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3364 null); 3365 } 3366 } 3367 } 3368 } 3369 3370 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3371 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3372 } 3373 3374 void enforceNotIsolatedCaller(String caller) { 3375 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3376 throw new SecurityException("Isolated process not allowed to call " + caller); 3377 } 3378 } 3379 3380 void enforceShellRestriction(String restriction, int userHandle) { 3381 if (Binder.getCallingUid() == Process.SHELL_UID) { 3382 if (userHandle < 0 3383 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3384 throw new SecurityException("Shell does not have permission to access user " 3385 + userHandle); 3386 } 3387 } 3388 } 3389 3390 @Override 3391 public int getFrontActivityScreenCompatMode() { 3392 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3393 synchronized (this) { 3394 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3395 } 3396 } 3397 3398 @Override 3399 public void setFrontActivityScreenCompatMode(int mode) { 3400 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3401 "setFrontActivityScreenCompatMode"); 3402 synchronized (this) { 3403 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3404 } 3405 } 3406 3407 @Override 3408 public int getPackageScreenCompatMode(String packageName) { 3409 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3410 synchronized (this) { 3411 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3412 } 3413 } 3414 3415 @Override 3416 public void setPackageScreenCompatMode(String packageName, int mode) { 3417 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3418 "setPackageScreenCompatMode"); 3419 synchronized (this) { 3420 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3421 } 3422 } 3423 3424 @Override 3425 public boolean getPackageAskScreenCompat(String packageName) { 3426 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3427 synchronized (this) { 3428 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3429 } 3430 } 3431 3432 @Override 3433 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3434 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3435 "setPackageAskScreenCompat"); 3436 synchronized (this) { 3437 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3438 } 3439 } 3440 3441 private void dispatchProcessesChanged() { 3442 int N; 3443 synchronized (this) { 3444 N = mPendingProcessChanges.size(); 3445 if (mActiveProcessChanges.length < N) { 3446 mActiveProcessChanges = new ProcessChangeItem[N]; 3447 } 3448 mPendingProcessChanges.toArray(mActiveProcessChanges); 3449 mAvailProcessChanges.addAll(mPendingProcessChanges); 3450 mPendingProcessChanges.clear(); 3451 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3452 } 3453 3454 int i = mProcessObservers.beginBroadcast(); 3455 while (i > 0) { 3456 i--; 3457 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3458 if (observer != null) { 3459 try { 3460 for (int j=0; j<N; j++) { 3461 ProcessChangeItem item = mActiveProcessChanges[j]; 3462 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3463 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3464 + item.pid + " uid=" + item.uid + ": " 3465 + item.foregroundActivities); 3466 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3467 item.foregroundActivities); 3468 } 3469 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3470 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3471 + item.pid + " uid=" + item.uid + ": " + item.processState); 3472 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3473 } 3474 } 3475 } catch (RemoteException e) { 3476 } 3477 } 3478 } 3479 mProcessObservers.finishBroadcast(); 3480 } 3481 3482 private void dispatchProcessDied(int pid, int uid) { 3483 int i = mProcessObservers.beginBroadcast(); 3484 while (i > 0) { 3485 i--; 3486 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3487 if (observer != null) { 3488 try { 3489 observer.onProcessDied(pid, uid); 3490 } catch (RemoteException e) { 3491 } 3492 } 3493 } 3494 mProcessObservers.finishBroadcast(); 3495 } 3496 3497 @Override 3498 public final int startActivity(IApplicationThread caller, String callingPackage, 3499 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3500 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3501 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3502 resultWho, requestCode, startFlags, profilerInfo, options, 3503 UserHandle.getCallingUserId()); 3504 } 3505 3506 @Override 3507 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3508 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3509 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3510 enforceNotIsolatedCaller("startActivity"); 3511 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3512 false, ALLOW_FULL_ONLY, "startActivity", null); 3513 // TODO: Switch to user app stacks here. 3514 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3515 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3516 profilerInfo, null, null, options, userId, null, null); 3517 } 3518 3519 @Override 3520 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3521 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3522 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3523 3524 // This is very dangerous -- it allows you to perform a start activity (including 3525 // permission grants) as any app that may launch one of your own activities. So 3526 // we will only allow this to be done from activities that are part of the core framework, 3527 // and then only when they are running as the system. 3528 final ActivityRecord sourceRecord; 3529 final int targetUid; 3530 final String targetPackage; 3531 synchronized (this) { 3532 if (resultTo == null) { 3533 throw new SecurityException("Must be called from an activity"); 3534 } 3535 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3536 if (sourceRecord == null) { 3537 throw new SecurityException("Called with bad activity token: " + resultTo); 3538 } 3539 if (!sourceRecord.info.packageName.equals("android")) { 3540 throw new SecurityException( 3541 "Must be called from an activity that is declared in the android package"); 3542 } 3543 if (sourceRecord.app == null) { 3544 throw new SecurityException("Called without a process attached to activity"); 3545 } 3546 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3547 // This is still okay, as long as this activity is running under the 3548 // uid of the original calling activity. 3549 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3550 throw new SecurityException( 3551 "Calling activity in uid " + sourceRecord.app.uid 3552 + " must be system uid or original calling uid " 3553 + sourceRecord.launchedFromUid); 3554 } 3555 } 3556 targetUid = sourceRecord.launchedFromUid; 3557 targetPackage = sourceRecord.launchedFromPackage; 3558 } 3559 3560 // TODO: Switch to user app stacks here. 3561 try { 3562 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3563 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3564 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3565 return ret; 3566 } catch (SecurityException e) { 3567 // XXX need to figure out how to propagate to original app. 3568 // A SecurityException here is generally actually a fault of the original 3569 // calling activity (such as a fairly granting permissions), so propagate it 3570 // back to them. 3571 /* 3572 StringBuilder msg = new StringBuilder(); 3573 msg.append("While launching"); 3574 msg.append(intent.toString()); 3575 msg.append(": "); 3576 msg.append(e.getMessage()); 3577 */ 3578 throw e; 3579 } 3580 } 3581 3582 @Override 3583 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3584 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3585 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3586 enforceNotIsolatedCaller("startActivityAndWait"); 3587 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3588 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3589 WaitResult res = new WaitResult(); 3590 // TODO: Switch to user app stacks here. 3591 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3592 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3593 options, userId, null, null); 3594 return res; 3595 } 3596 3597 @Override 3598 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3599 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3600 int startFlags, Configuration config, Bundle options, int userId) { 3601 enforceNotIsolatedCaller("startActivityWithConfig"); 3602 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3603 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3604 // TODO: Switch to user app stacks here. 3605 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3606 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3607 null, null, config, options, userId, null, null); 3608 return ret; 3609 } 3610 3611 @Override 3612 public int startActivityIntentSender(IApplicationThread caller, 3613 IntentSender intent, Intent fillInIntent, String resolvedType, 3614 IBinder resultTo, String resultWho, int requestCode, 3615 int flagsMask, int flagsValues, Bundle options) { 3616 enforceNotIsolatedCaller("startActivityIntentSender"); 3617 // Refuse possible leaked file descriptors 3618 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3619 throw new IllegalArgumentException("File descriptors passed in Intent"); 3620 } 3621 3622 IIntentSender sender = intent.getTarget(); 3623 if (!(sender instanceof PendingIntentRecord)) { 3624 throw new IllegalArgumentException("Bad PendingIntent object"); 3625 } 3626 3627 PendingIntentRecord pir = (PendingIntentRecord)sender; 3628 3629 synchronized (this) { 3630 // If this is coming from the currently resumed activity, it is 3631 // effectively saying that app switches are allowed at this point. 3632 final ActivityStack stack = getFocusedStack(); 3633 if (stack.mResumedActivity != null && 3634 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3635 mAppSwitchesAllowedTime = 0; 3636 } 3637 } 3638 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3639 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3640 return ret; 3641 } 3642 3643 @Override 3644 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3645 Intent intent, String resolvedType, IVoiceInteractionSession session, 3646 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3647 Bundle options, int userId) { 3648 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3649 != PackageManager.PERMISSION_GRANTED) { 3650 String msg = "Permission Denial: startVoiceActivity() from pid=" 3651 + Binder.getCallingPid() 3652 + ", uid=" + Binder.getCallingUid() 3653 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3654 Slog.w(TAG, msg); 3655 throw new SecurityException(msg); 3656 } 3657 if (session == null || interactor == null) { 3658 throw new NullPointerException("null session or interactor"); 3659 } 3660 userId = handleIncomingUser(callingPid, callingUid, userId, 3661 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3662 // TODO: Switch to user app stacks here. 3663 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3664 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3665 null, options, userId, null, null); 3666 } 3667 3668 @Override 3669 public boolean startNextMatchingActivity(IBinder callingActivity, 3670 Intent intent, Bundle options) { 3671 // Refuse possible leaked file descriptors 3672 if (intent != null && intent.hasFileDescriptors() == true) { 3673 throw new IllegalArgumentException("File descriptors passed in Intent"); 3674 } 3675 3676 synchronized (this) { 3677 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3678 if (r == null) { 3679 ActivityOptions.abort(options); 3680 return false; 3681 } 3682 if (r.app == null || r.app.thread == null) { 3683 // The caller is not running... d'oh! 3684 ActivityOptions.abort(options); 3685 return false; 3686 } 3687 intent = new Intent(intent); 3688 // The caller is not allowed to change the data. 3689 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3690 // And we are resetting to find the next component... 3691 intent.setComponent(null); 3692 3693 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3694 3695 ActivityInfo aInfo = null; 3696 try { 3697 List<ResolveInfo> resolves = 3698 AppGlobals.getPackageManager().queryIntentActivities( 3699 intent, r.resolvedType, 3700 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3701 UserHandle.getCallingUserId()); 3702 3703 // Look for the original activity in the list... 3704 final int N = resolves != null ? resolves.size() : 0; 3705 for (int i=0; i<N; i++) { 3706 ResolveInfo rInfo = resolves.get(i); 3707 if (rInfo.activityInfo.packageName.equals(r.packageName) 3708 && rInfo.activityInfo.name.equals(r.info.name)) { 3709 // We found the current one... the next matching is 3710 // after it. 3711 i++; 3712 if (i<N) { 3713 aInfo = resolves.get(i).activityInfo; 3714 } 3715 if (debug) { 3716 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3717 + "/" + r.info.name); 3718 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3719 + "/" + aInfo.name); 3720 } 3721 break; 3722 } 3723 } 3724 } catch (RemoteException e) { 3725 } 3726 3727 if (aInfo == null) { 3728 // Nobody who is next! 3729 ActivityOptions.abort(options); 3730 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3731 return false; 3732 } 3733 3734 intent.setComponent(new ComponentName( 3735 aInfo.applicationInfo.packageName, aInfo.name)); 3736 intent.setFlags(intent.getFlags()&~( 3737 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3738 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3739 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3740 Intent.FLAG_ACTIVITY_NEW_TASK)); 3741 3742 // Okay now we need to start the new activity, replacing the 3743 // currently running activity. This is a little tricky because 3744 // we want to start the new one as if the current one is finished, 3745 // but not finish the current one first so that there is no flicker. 3746 // And thus... 3747 final boolean wasFinishing = r.finishing; 3748 r.finishing = true; 3749 3750 // Propagate reply information over to the new activity. 3751 final ActivityRecord resultTo = r.resultTo; 3752 final String resultWho = r.resultWho; 3753 final int requestCode = r.requestCode; 3754 r.resultTo = null; 3755 if (resultTo != null) { 3756 resultTo.removeResultsLocked(r, resultWho, requestCode); 3757 } 3758 3759 final long origId = Binder.clearCallingIdentity(); 3760 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3761 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3762 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3763 -1, r.launchedFromUid, 0, options, false, null, null, null); 3764 Binder.restoreCallingIdentity(origId); 3765 3766 r.finishing = wasFinishing; 3767 if (res != ActivityManager.START_SUCCESS) { 3768 return false; 3769 } 3770 return true; 3771 } 3772 } 3773 3774 @Override 3775 public final int startActivityFromRecents(int taskId, Bundle options) { 3776 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3777 String msg = "Permission Denial: startActivityFromRecents called without " + 3778 START_TASKS_FROM_RECENTS; 3779 Slog.w(TAG, msg); 3780 throw new SecurityException(msg); 3781 } 3782 return startActivityFromRecentsInner(taskId, options); 3783 } 3784 3785 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3786 final TaskRecord task; 3787 final int callingUid; 3788 final String callingPackage; 3789 final Intent intent; 3790 final int userId; 3791 synchronized (this) { 3792 task = recentTaskForIdLocked(taskId); 3793 if (task == null) { 3794 throw new IllegalArgumentException("Task " + taskId + " not found."); 3795 } 3796 callingUid = task.mCallingUid; 3797 callingPackage = task.mCallingPackage; 3798 intent = task.intent; 3799 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3800 userId = task.userId; 3801 } 3802 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3803 options, userId, null, task); 3804 } 3805 3806 final int startActivityInPackage(int uid, String callingPackage, 3807 Intent intent, String resolvedType, IBinder resultTo, 3808 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3809 IActivityContainer container, TaskRecord inTask) { 3810 3811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3812 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3813 3814 // TODO: Switch to user app stacks here. 3815 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3816 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3817 null, null, null, options, userId, container, inTask); 3818 return ret; 3819 } 3820 3821 @Override 3822 public final int startActivities(IApplicationThread caller, String callingPackage, 3823 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3824 int userId) { 3825 enforceNotIsolatedCaller("startActivities"); 3826 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3827 false, ALLOW_FULL_ONLY, "startActivity", null); 3828 // TODO: Switch to user app stacks here. 3829 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3830 resolvedTypes, resultTo, options, userId); 3831 return ret; 3832 } 3833 3834 final int startActivitiesInPackage(int uid, String callingPackage, 3835 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3836 Bundle options, int userId) { 3837 3838 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3839 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3840 // TODO: Switch to user app stacks here. 3841 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3842 resultTo, options, userId); 3843 return ret; 3844 } 3845 3846 //explicitly remove thd old information in mRecentTasks when removing existing user. 3847 private void removeRecentTasksForUserLocked(int userId) { 3848 if(userId <= 0) { 3849 Slog.i(TAG, "Can't remove recent task on user " + userId); 3850 return; 3851 } 3852 3853 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3854 TaskRecord tr = mRecentTasks.get(i); 3855 if (tr.userId == userId) { 3856 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3857 + " when finishing user" + userId); 3858 mRecentTasks.remove(i); 3859 tr.removedFromRecents(mTaskPersister); 3860 } 3861 } 3862 3863 // Remove tasks from persistent storage. 3864 mTaskPersister.wakeup(null, true); 3865 } 3866 3867 // Sort by taskId 3868 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3869 @Override 3870 public int compare(TaskRecord lhs, TaskRecord rhs) { 3871 return rhs.taskId - lhs.taskId; 3872 } 3873 }; 3874 3875 // Extract the affiliates of the chain containing mRecentTasks[start]. 3876 private int processNextAffiliateChain(int start) { 3877 final TaskRecord startTask = mRecentTasks.get(start); 3878 final int affiliateId = startTask.mAffiliatedTaskId; 3879 3880 // Quick identification of isolated tasks. I.e. those not launched behind. 3881 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3882 startTask.mNextAffiliate == null) { 3883 // There is still a slim chance that there are other tasks that point to this task 3884 // and that the chain is so messed up that this task no longer points to them but 3885 // the gain of this optimization outweighs the risk. 3886 startTask.inRecents = true; 3887 return start + 1; 3888 } 3889 3890 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3891 mTmpRecents.clear(); 3892 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3893 final TaskRecord task = mRecentTasks.get(i); 3894 if (task.mAffiliatedTaskId == affiliateId) { 3895 mRecentTasks.remove(i); 3896 mTmpRecents.add(task); 3897 } 3898 } 3899 3900 // Sort them all by taskId. That is the order they were create in and that order will 3901 // always be correct. 3902 Collections.sort(mTmpRecents, mTaskRecordComparator); 3903 3904 // Go through and fix up the linked list. 3905 // The first one is the end of the chain and has no next. 3906 final TaskRecord first = mTmpRecents.get(0); 3907 first.inRecents = true; 3908 if (first.mNextAffiliate != null) { 3909 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3910 first.setNextAffiliate(null); 3911 mTaskPersister.wakeup(first, false); 3912 } 3913 // Everything in the middle is doubly linked from next to prev. 3914 final int tmpSize = mTmpRecents.size(); 3915 for (int i = 0; i < tmpSize - 1; ++i) { 3916 final TaskRecord next = mTmpRecents.get(i); 3917 final TaskRecord prev = mTmpRecents.get(i + 1); 3918 if (next.mPrevAffiliate != prev) { 3919 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3920 " setting prev=" + prev); 3921 next.setPrevAffiliate(prev); 3922 mTaskPersister.wakeup(next, false); 3923 } 3924 if (prev.mNextAffiliate != next) { 3925 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3926 " setting next=" + next); 3927 prev.setNextAffiliate(next); 3928 mTaskPersister.wakeup(prev, false); 3929 } 3930 prev.inRecents = true; 3931 } 3932 // The last one is the beginning of the list and has no prev. 3933 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3934 if (last.mPrevAffiliate != null) { 3935 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3936 last.setPrevAffiliate(null); 3937 mTaskPersister.wakeup(last, false); 3938 } 3939 3940 // Insert the group back into mRecentTasks at start. 3941 mRecentTasks.addAll(start, mTmpRecents); 3942 3943 // Let the caller know where we left off. 3944 return start + tmpSize; 3945 } 3946 3947 /** 3948 * Update the recent tasks lists: make sure tasks should still be here (their 3949 * applications / activities still exist), update their availability, fixup ordering 3950 * of affiliations. 3951 */ 3952 void cleanupRecentTasksLocked(int userId) { 3953 if (mRecentTasks == null) { 3954 // Happens when called from the packagemanager broadcast before boot. 3955 return; 3956 } 3957 3958 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3959 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3960 final IPackageManager pm = AppGlobals.getPackageManager(); 3961 final ActivityInfo dummyAct = new ActivityInfo(); 3962 final ApplicationInfo dummyApp = new ApplicationInfo(); 3963 3964 int N = mRecentTasks.size(); 3965 3966 int[] users = userId == UserHandle.USER_ALL 3967 ? getUsersLocked() : new int[] { userId }; 3968 for (int user : users) { 3969 for (int i = 0; i < N; i++) { 3970 TaskRecord task = mRecentTasks.get(i); 3971 if (task.userId != user) { 3972 // Only look at tasks for the user ID of interest. 3973 continue; 3974 } 3975 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3976 // This situation is broken, and we should just get rid of it now. 3977 mRecentTasks.remove(i); 3978 task.removedFromRecents(mTaskPersister); 3979 i--; 3980 N--; 3981 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3982 continue; 3983 } 3984 // Check whether this activity is currently available. 3985 if (task.realActivity != null) { 3986 ActivityInfo ai = availActCache.get(task.realActivity); 3987 if (ai == null) { 3988 try { 3989 ai = pm.getActivityInfo(task.realActivity, 3990 PackageManager.GET_UNINSTALLED_PACKAGES 3991 | PackageManager.GET_DISABLED_COMPONENTS, user); 3992 } catch (RemoteException e) { 3993 // Will never happen. 3994 continue; 3995 } 3996 if (ai == null) { 3997 ai = dummyAct; 3998 } 3999 availActCache.put(task.realActivity, ai); 4000 } 4001 if (ai == dummyAct) { 4002 // This could be either because the activity no longer exists, or the 4003 // app is temporarily gone. For the former we want to remove the recents 4004 // entry; for the latter we want to mark it as unavailable. 4005 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4006 if (app == null) { 4007 try { 4008 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4009 PackageManager.GET_UNINSTALLED_PACKAGES 4010 | PackageManager.GET_DISABLED_COMPONENTS, user); 4011 } catch (RemoteException e) { 4012 // Will never happen. 4013 continue; 4014 } 4015 if (app == null) { 4016 app = dummyApp; 4017 } 4018 availAppCache.put(task.realActivity.getPackageName(), app); 4019 } 4020 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4021 // Doesn't exist any more! Good-bye. 4022 mRecentTasks.remove(i); 4023 task.removedFromRecents(mTaskPersister); 4024 i--; 4025 N--; 4026 Slog.w(TAG, "Removing no longer valid recent: " + task); 4027 continue; 4028 } else { 4029 // Otherwise just not available for now. 4030 if (task.isAvailable) { 4031 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4032 + task); 4033 } 4034 task.isAvailable = false; 4035 } 4036 } else { 4037 if (!ai.enabled || !ai.applicationInfo.enabled 4038 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4039 if (task.isAvailable) { 4040 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4041 + task + " (enabled=" + ai.enabled + "/" 4042 + ai.applicationInfo.enabled + " flags=" 4043 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4044 } 4045 task.isAvailable = false; 4046 } else { 4047 if (!task.isAvailable) { 4048 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4049 + task); 4050 } 4051 task.isAvailable = true; 4052 } 4053 } 4054 } 4055 } 4056 } 4057 4058 // Verify the affiliate chain for each task. 4059 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4060 } 4061 4062 mTmpRecents.clear(); 4063 // mRecentTasks is now in sorted, affiliated order. 4064 } 4065 4066 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4067 int N = mRecentTasks.size(); 4068 TaskRecord top = task; 4069 int topIndex = taskIndex; 4070 while (top.mNextAffiliate != null && topIndex > 0) { 4071 top = top.mNextAffiliate; 4072 topIndex--; 4073 } 4074 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4075 + topIndex + " from intial " + taskIndex); 4076 // Find the end of the chain, doing a sanity check along the way. 4077 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4078 int endIndex = topIndex; 4079 TaskRecord prev = top; 4080 while (endIndex < N) { 4081 TaskRecord cur = mRecentTasks.get(endIndex); 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4083 + endIndex + " " + cur); 4084 if (cur == top) { 4085 // Verify start of the chain. 4086 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4087 Slog.wtf(TAG, "Bad chain @" + endIndex 4088 + ": first task has next affiliate: " + prev); 4089 sane = false; 4090 break; 4091 } 4092 } else { 4093 // Verify middle of the chain's next points back to the one before. 4094 if (cur.mNextAffiliate != prev 4095 || cur.mNextAffiliateTaskId != prev.taskId) { 4096 Slog.wtf(TAG, "Bad chain @" + endIndex 4097 + ": middle task " + cur + " @" + endIndex 4098 + " has bad next affiliate " 4099 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4100 + ", expected " + prev); 4101 sane = false; 4102 break; 4103 } 4104 } 4105 if (cur.mPrevAffiliateTaskId == -1) { 4106 // Chain ends here. 4107 if (cur.mPrevAffiliate != null) { 4108 Slog.wtf(TAG, "Bad chain @" + endIndex 4109 + ": last task " + cur + " has previous affiliate " 4110 + cur.mPrevAffiliate); 4111 sane = false; 4112 } 4113 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4114 break; 4115 } else { 4116 // Verify middle of the chain's prev points to a valid item. 4117 if (cur.mPrevAffiliate == null) { 4118 Slog.wtf(TAG, "Bad chain @" + endIndex 4119 + ": task " + cur + " has previous affiliate " 4120 + cur.mPrevAffiliate + " but should be id " 4121 + cur.mPrevAffiliate); 4122 sane = false; 4123 break; 4124 } 4125 } 4126 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4127 Slog.wtf(TAG, "Bad chain @" + endIndex 4128 + ": task " + cur + " has affiliated id " 4129 + cur.mAffiliatedTaskId + " but should be " 4130 + task.mAffiliatedTaskId); 4131 sane = false; 4132 break; 4133 } 4134 prev = cur; 4135 endIndex++; 4136 if (endIndex >= N) { 4137 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4138 + ": last task " + prev); 4139 sane = false; 4140 break; 4141 } 4142 } 4143 if (sane) { 4144 if (endIndex < taskIndex) { 4145 Slog.wtf(TAG, "Bad chain @" + endIndex 4146 + ": did not extend to task " + task + " @" + taskIndex); 4147 sane = false; 4148 } 4149 } 4150 if (sane) { 4151 // All looks good, we can just move all of the affiliated tasks 4152 // to the top. 4153 for (int i=topIndex; i<=endIndex; i++) { 4154 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4155 + " from " + i + " to " + (i-topIndex)); 4156 TaskRecord cur = mRecentTasks.remove(i); 4157 mRecentTasks.add(i-topIndex, cur); 4158 } 4159 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4160 + " to " + endIndex); 4161 return true; 4162 } 4163 4164 // Whoops, couldn't do it. 4165 return false; 4166 } 4167 4168 final void addRecentTaskLocked(TaskRecord task) { 4169 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4170 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4171 4172 int N = mRecentTasks.size(); 4173 // Quick case: check if the top-most recent task is the same. 4174 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4175 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4176 return; 4177 } 4178 // Another quick case: check if this is part of a set of affiliated 4179 // tasks that are at the top. 4180 if (isAffiliated && N > 0 && task.inRecents 4181 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4182 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4183 + " at top when adding " + task); 4184 return; 4185 } 4186 // Another quick case: never add voice sessions. 4187 if (task.voiceSession != null) { 4188 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4189 return; 4190 } 4191 4192 boolean needAffiliationFix = false; 4193 4194 // Slightly less quick case: the task is already in recents, so all we need 4195 // to do is move it. 4196 if (task.inRecents) { 4197 int taskIndex = mRecentTasks.indexOf(task); 4198 if (taskIndex >= 0) { 4199 if (!isAffiliated) { 4200 // Simple case: this is not an affiliated task, so we just move it to the front. 4201 mRecentTasks.remove(taskIndex); 4202 mRecentTasks.add(0, task); 4203 notifyTaskPersisterLocked(task, false); 4204 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4205 + " from " + taskIndex); 4206 return; 4207 } else { 4208 // More complicated: need to keep all affiliated tasks together. 4209 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4210 // All went well. 4211 return; 4212 } 4213 4214 // Uh oh... something bad in the affiliation chain, try to rebuild 4215 // everything and then go through our general path of adding a new task. 4216 needAffiliationFix = true; 4217 } 4218 } else { 4219 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4220 needAffiliationFix = true; 4221 } 4222 } 4223 4224 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4225 trimRecentsForTask(task, true); 4226 4227 N = mRecentTasks.size(); 4228 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4229 final TaskRecord tr = mRecentTasks.remove(N - 1); 4230 tr.removedFromRecents(mTaskPersister); 4231 N--; 4232 } 4233 task.inRecents = true; 4234 if (!isAffiliated || needAffiliationFix) { 4235 // If this is a simple non-affiliated task, or we had some failure trying to 4236 // handle it as part of an affilated task, then just place it at the top. 4237 mRecentTasks.add(0, task); 4238 } else if (isAffiliated) { 4239 // If this is a new affiliated task, then move all of the affiliated tasks 4240 // to the front and insert this new one. 4241 TaskRecord other = task.mNextAffiliate; 4242 if (other == null) { 4243 other = task.mPrevAffiliate; 4244 } 4245 if (other != null) { 4246 int otherIndex = mRecentTasks.indexOf(other); 4247 if (otherIndex >= 0) { 4248 // Insert new task at appropriate location. 4249 int taskIndex; 4250 if (other == task.mNextAffiliate) { 4251 // We found the index of our next affiliation, which is who is 4252 // before us in the list, so add after that point. 4253 taskIndex = otherIndex+1; 4254 } else { 4255 // We found the index of our previous affiliation, which is who is 4256 // after us in the list, so add at their position. 4257 taskIndex = otherIndex; 4258 } 4259 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4260 + taskIndex + ": " + task); 4261 mRecentTasks.add(taskIndex, task); 4262 4263 // Now move everything to the front. 4264 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4265 // All went well. 4266 return; 4267 } 4268 4269 // Uh oh... something bad in the affiliation chain, try to rebuild 4270 // everything and then go through our general path of adding a new task. 4271 needAffiliationFix = true; 4272 } else { 4273 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4274 + other); 4275 needAffiliationFix = true; 4276 } 4277 } else { 4278 if (DEBUG_RECENTS) Slog.d(TAG, 4279 "addRecent: adding affiliated task without next/prev:" + task); 4280 needAffiliationFix = true; 4281 } 4282 } 4283 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4284 4285 if (needAffiliationFix) { 4286 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4287 cleanupRecentTasksLocked(task.userId); 4288 } 4289 } 4290 4291 /** 4292 * If needed, remove oldest existing entries in recents that are for the same kind 4293 * of task as the given one. 4294 */ 4295 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4296 int N = mRecentTasks.size(); 4297 final Intent intent = task.intent; 4298 final boolean document = intent != null && intent.isDocument(); 4299 4300 int maxRecents = task.maxRecents - 1; 4301 for (int i=0; i<N; i++) { 4302 final TaskRecord tr = mRecentTasks.get(i); 4303 if (task != tr) { 4304 if (task.userId != tr.userId) { 4305 continue; 4306 } 4307 if (i > MAX_RECENT_BITMAPS) { 4308 tr.freeLastThumbnail(); 4309 } 4310 final Intent trIntent = tr.intent; 4311 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4312 (intent == null || !intent.filterEquals(trIntent))) { 4313 continue; 4314 } 4315 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4316 if (document && trIsDocument) { 4317 // These are the same document activity (not necessarily the same doc). 4318 if (maxRecents > 0) { 4319 --maxRecents; 4320 continue; 4321 } 4322 // Hit the maximum number of documents for this task. Fall through 4323 // and remove this document from recents. 4324 } else if (document || trIsDocument) { 4325 // Only one of these is a document. Not the droid we're looking for. 4326 continue; 4327 } 4328 } 4329 4330 if (!doTrim) { 4331 // If the caller is not actually asking for a trim, just tell them we reached 4332 // a point where the trim would happen. 4333 return i; 4334 } 4335 4336 // Either task and tr are the same or, their affinities match or their intents match 4337 // and neither of them is a document, or they are documents using the same activity 4338 // and their maxRecents has been reached. 4339 tr.disposeThumbnail(); 4340 mRecentTasks.remove(i); 4341 if (task != tr) { 4342 tr.removedFromRecents(mTaskPersister); 4343 } 4344 i--; 4345 N--; 4346 if (task.intent == null) { 4347 // If the new recent task we are adding is not fully 4348 // specified, then replace it with the existing recent task. 4349 task = tr; 4350 } 4351 notifyTaskPersisterLocked(tr, false); 4352 } 4353 4354 return -1; 4355 } 4356 4357 @Override 4358 public void reportActivityFullyDrawn(IBinder token) { 4359 synchronized (this) { 4360 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4361 if (r == null) { 4362 return; 4363 } 4364 r.reportFullyDrawnLocked(); 4365 } 4366 } 4367 4368 @Override 4369 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4370 synchronized (this) { 4371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4372 if (r == null) { 4373 return; 4374 } 4375 final long origId = Binder.clearCallingIdentity(); 4376 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4377 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4378 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4379 if (config != null) { 4380 r.frozenBeforeDestroy = true; 4381 if (!updateConfigurationLocked(config, r, false, false)) { 4382 mStackSupervisor.resumeTopActivitiesLocked(); 4383 } 4384 } 4385 Binder.restoreCallingIdentity(origId); 4386 } 4387 } 4388 4389 @Override 4390 public int getRequestedOrientation(IBinder token) { 4391 synchronized (this) { 4392 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4393 if (r == null) { 4394 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4395 } 4396 return mWindowManager.getAppOrientation(r.appToken); 4397 } 4398 } 4399 4400 /** 4401 * This is the internal entry point for handling Activity.finish(). 4402 * 4403 * @param token The Binder token referencing the Activity we want to finish. 4404 * @param resultCode Result code, if any, from this Activity. 4405 * @param resultData Result data (Intent), if any, from this Activity. 4406 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4407 * the root Activity in the task. 4408 * 4409 * @return Returns true if the activity successfully finished, or false if it is still running. 4410 */ 4411 @Override 4412 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4413 boolean finishTask) { 4414 // Refuse possible leaked file descriptors 4415 if (resultData != null && resultData.hasFileDescriptors() == true) { 4416 throw new IllegalArgumentException("File descriptors passed in Intent"); 4417 } 4418 4419 synchronized(this) { 4420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4421 if (r == null) { 4422 return true; 4423 } 4424 // Keep track of the root activity of the task before we finish it 4425 TaskRecord tr = r.task; 4426 ActivityRecord rootR = tr.getRootActivity(); 4427 // Do not allow task to finish in Lock Task mode. 4428 if (tr == mStackSupervisor.mLockTaskModeTask) { 4429 if (rootR == r) { 4430 mStackSupervisor.showLockTaskToast(); 4431 return false; 4432 } 4433 } 4434 if (mController != null) { 4435 // Find the first activity that is not finishing. 4436 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4437 if (next != null) { 4438 // ask watcher if this is allowed 4439 boolean resumeOK = true; 4440 try { 4441 resumeOK = mController.activityResuming(next.packageName); 4442 } catch (RemoteException e) { 4443 mController = null; 4444 Watchdog.getInstance().setActivityController(null); 4445 } 4446 4447 if (!resumeOK) { 4448 return false; 4449 } 4450 } 4451 } 4452 final long origId = Binder.clearCallingIdentity(); 4453 try { 4454 boolean res; 4455 if (finishTask && r == rootR) { 4456 // If requested, remove the task that is associated to this activity only if it 4457 // was the root activity in the task. The result code and data is ignored because 4458 // we don't support returning them across task boundaries. 4459 res = removeTaskByIdLocked(tr.taskId, 0); 4460 } else { 4461 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4462 resultData, "app-request", true); 4463 } 4464 return res; 4465 } finally { 4466 Binder.restoreCallingIdentity(origId); 4467 } 4468 } 4469 } 4470 4471 @Override 4472 public final void finishHeavyWeightApp() { 4473 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4474 != PackageManager.PERMISSION_GRANTED) { 4475 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4476 + Binder.getCallingPid() 4477 + ", uid=" + Binder.getCallingUid() 4478 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4479 Slog.w(TAG, msg); 4480 throw new SecurityException(msg); 4481 } 4482 4483 synchronized(this) { 4484 if (mHeavyWeightProcess == null) { 4485 return; 4486 } 4487 4488 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4489 mHeavyWeightProcess.activities); 4490 for (int i=0; i<activities.size(); i++) { 4491 ActivityRecord r = activities.get(i); 4492 if (!r.finishing) { 4493 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4494 null, "finish-heavy", true); 4495 } 4496 } 4497 4498 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4499 mHeavyWeightProcess.userId, 0)); 4500 mHeavyWeightProcess = null; 4501 } 4502 } 4503 4504 @Override 4505 public void crashApplication(int uid, int initialPid, String packageName, 4506 String message) { 4507 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4508 != PackageManager.PERMISSION_GRANTED) { 4509 String msg = "Permission Denial: crashApplication() from pid=" 4510 + Binder.getCallingPid() 4511 + ", uid=" + Binder.getCallingUid() 4512 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4513 Slog.w(TAG, msg); 4514 throw new SecurityException(msg); 4515 } 4516 4517 synchronized(this) { 4518 ProcessRecord proc = null; 4519 4520 // Figure out which process to kill. We don't trust that initialPid 4521 // still has any relation to current pids, so must scan through the 4522 // list. 4523 synchronized (mPidsSelfLocked) { 4524 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4525 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4526 if (p.uid != uid) { 4527 continue; 4528 } 4529 if (p.pid == initialPid) { 4530 proc = p; 4531 break; 4532 } 4533 if (p.pkgList.containsKey(packageName)) { 4534 proc = p; 4535 } 4536 } 4537 } 4538 4539 if (proc == null) { 4540 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4541 + " initialPid=" + initialPid 4542 + " packageName=" + packageName); 4543 return; 4544 } 4545 4546 if (proc.thread != null) { 4547 if (proc.pid == Process.myPid()) { 4548 Log.w(TAG, "crashApplication: trying to crash self!"); 4549 return; 4550 } 4551 long ident = Binder.clearCallingIdentity(); 4552 try { 4553 proc.thread.scheduleCrash(message); 4554 } catch (RemoteException e) { 4555 } 4556 Binder.restoreCallingIdentity(ident); 4557 } 4558 } 4559 } 4560 4561 @Override 4562 public final void finishSubActivity(IBinder token, String resultWho, 4563 int requestCode) { 4564 synchronized(this) { 4565 final long origId = Binder.clearCallingIdentity(); 4566 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4567 if (r != null) { 4568 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4569 } 4570 Binder.restoreCallingIdentity(origId); 4571 } 4572 } 4573 4574 @Override 4575 public boolean finishActivityAffinity(IBinder token) { 4576 synchronized(this) { 4577 final long origId = Binder.clearCallingIdentity(); 4578 try { 4579 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4580 4581 ActivityRecord rootR = r.task.getRootActivity(); 4582 // Do not allow task to finish in Lock Task mode. 4583 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4584 if (rootR == r) { 4585 mStackSupervisor.showLockTaskToast(); 4586 return false; 4587 } 4588 } 4589 boolean res = false; 4590 if (r != null) { 4591 res = r.task.stack.finishActivityAffinityLocked(r); 4592 } 4593 return res; 4594 } finally { 4595 Binder.restoreCallingIdentity(origId); 4596 } 4597 } 4598 } 4599 4600 @Override 4601 public void finishVoiceTask(IVoiceInteractionSession session) { 4602 synchronized(this) { 4603 final long origId = Binder.clearCallingIdentity(); 4604 try { 4605 mStackSupervisor.finishVoiceTask(session); 4606 } finally { 4607 Binder.restoreCallingIdentity(origId); 4608 } 4609 } 4610 4611 } 4612 4613 @Override 4614 public boolean releaseActivityInstance(IBinder token) { 4615 synchronized(this) { 4616 final long origId = Binder.clearCallingIdentity(); 4617 try { 4618 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4619 if (r.task == null || r.task.stack == null) { 4620 return false; 4621 } 4622 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4623 } finally { 4624 Binder.restoreCallingIdentity(origId); 4625 } 4626 } 4627 } 4628 4629 @Override 4630 public void releaseSomeActivities(IApplicationThread appInt) { 4631 synchronized(this) { 4632 final long origId = Binder.clearCallingIdentity(); 4633 try { 4634 ProcessRecord app = getRecordForAppLocked(appInt); 4635 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4636 } finally { 4637 Binder.restoreCallingIdentity(origId); 4638 } 4639 } 4640 } 4641 4642 @Override 4643 public boolean willActivityBeVisible(IBinder token) { 4644 synchronized(this) { 4645 ActivityStack stack = ActivityRecord.getStackLocked(token); 4646 if (stack != null) { 4647 return stack.willActivityBeVisibleLocked(token); 4648 } 4649 return false; 4650 } 4651 } 4652 4653 @Override 4654 public void overridePendingTransition(IBinder token, String packageName, 4655 int enterAnim, int exitAnim) { 4656 synchronized(this) { 4657 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4658 if (self == null) { 4659 return; 4660 } 4661 4662 final long origId = Binder.clearCallingIdentity(); 4663 4664 if (self.state == ActivityState.RESUMED 4665 || self.state == ActivityState.PAUSING) { 4666 mWindowManager.overridePendingAppTransition(packageName, 4667 enterAnim, exitAnim, null); 4668 } 4669 4670 Binder.restoreCallingIdentity(origId); 4671 } 4672 } 4673 4674 /** 4675 * Main function for removing an existing process from the activity manager 4676 * as a result of that process going away. Clears out all connections 4677 * to the process. 4678 */ 4679 private final void handleAppDiedLocked(ProcessRecord app, 4680 boolean restarting, boolean allowRestart) { 4681 int pid = app.pid; 4682 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4683 if (!restarting) { 4684 removeLruProcessLocked(app); 4685 if (pid > 0) { 4686 ProcessList.remove(pid); 4687 } 4688 } 4689 4690 if (mProfileProc == app) { 4691 clearProfilerLocked(); 4692 } 4693 4694 // Remove this application's activities from active lists. 4695 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4696 4697 app.activities.clear(); 4698 4699 if (app.instrumentationClass != null) { 4700 Slog.w(TAG, "Crash of app " + app.processName 4701 + " running instrumentation " + app.instrumentationClass); 4702 Bundle info = new Bundle(); 4703 info.putString("shortMsg", "Process crashed."); 4704 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4705 } 4706 4707 if (!restarting) { 4708 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4709 // If there was nothing to resume, and we are not already 4710 // restarting this process, but there is a visible activity that 4711 // is hosted by the process... then make sure all visible 4712 // activities are running, taking care of restarting this 4713 // process. 4714 if (hasVisibleActivities) { 4715 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4716 } 4717 } 4718 } 4719 } 4720 4721 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4722 IBinder threadBinder = thread.asBinder(); 4723 // Find the application record. 4724 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4725 ProcessRecord rec = mLruProcesses.get(i); 4726 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4727 return i; 4728 } 4729 } 4730 return -1; 4731 } 4732 4733 final ProcessRecord getRecordForAppLocked( 4734 IApplicationThread thread) { 4735 if (thread == null) { 4736 return null; 4737 } 4738 4739 int appIndex = getLRURecordIndexForAppLocked(thread); 4740 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4741 } 4742 4743 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4744 // If there are no longer any background processes running, 4745 // and the app that died was not running instrumentation, 4746 // then tell everyone we are now low on memory. 4747 boolean haveBg = false; 4748 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4749 ProcessRecord rec = mLruProcesses.get(i); 4750 if (rec.thread != null 4751 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4752 haveBg = true; 4753 break; 4754 } 4755 } 4756 4757 if (!haveBg) { 4758 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4759 if (doReport) { 4760 long now = SystemClock.uptimeMillis(); 4761 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4762 doReport = false; 4763 } else { 4764 mLastMemUsageReportTime = now; 4765 } 4766 } 4767 final ArrayList<ProcessMemInfo> memInfos 4768 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4769 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4770 long now = SystemClock.uptimeMillis(); 4771 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4772 ProcessRecord rec = mLruProcesses.get(i); 4773 if (rec == dyingProc || rec.thread == null) { 4774 continue; 4775 } 4776 if (doReport) { 4777 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4778 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4779 } 4780 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4781 // The low memory report is overriding any current 4782 // state for a GC request. Make sure to do 4783 // heavy/important/visible/foreground processes first. 4784 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4785 rec.lastRequestedGc = 0; 4786 } else { 4787 rec.lastRequestedGc = rec.lastLowMemory; 4788 } 4789 rec.reportLowMemory = true; 4790 rec.lastLowMemory = now; 4791 mProcessesToGc.remove(rec); 4792 addProcessToGcListLocked(rec); 4793 } 4794 } 4795 if (doReport) { 4796 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4797 mHandler.sendMessage(msg); 4798 } 4799 scheduleAppGcsLocked(); 4800 } 4801 } 4802 4803 final void appDiedLocked(ProcessRecord app) { 4804 appDiedLocked(app, app.pid, app.thread); 4805 } 4806 4807 final void appDiedLocked(ProcessRecord app, int pid, 4808 IApplicationThread thread) { 4809 4810 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4811 synchronized (stats) { 4812 stats.noteProcessDiedLocked(app.info.uid, pid); 4813 } 4814 4815 Process.killProcessGroup(app.info.uid, pid); 4816 4817 // Clean up already done if the process has been re-started. 4818 if (app.pid == pid && app.thread != null && 4819 app.thread.asBinder() == thread.asBinder()) { 4820 boolean doLowMem = app.instrumentationClass == null; 4821 boolean doOomAdj = doLowMem; 4822 if (!app.killedByAm) { 4823 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4824 + ") has died."); 4825 mAllowLowerMemLevel = true; 4826 } else { 4827 // Note that we always want to do oom adj to update our state with the 4828 // new number of procs. 4829 mAllowLowerMemLevel = false; 4830 doLowMem = false; 4831 } 4832 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4833 if (DEBUG_CLEANUP) Slog.v( 4834 TAG, "Dying app: " + app + ", pid: " + pid 4835 + ", thread: " + thread.asBinder()); 4836 handleAppDiedLocked(app, false, true); 4837 4838 if (doOomAdj) { 4839 updateOomAdjLocked(); 4840 } 4841 if (doLowMem) { 4842 doLowMemReportIfNeededLocked(app); 4843 } 4844 } else if (app.pid != pid) { 4845 // A new process has already been started. 4846 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4847 + ") has died and restarted (pid " + app.pid + ")."); 4848 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4849 } else if (DEBUG_PROCESSES) { 4850 Slog.d(TAG, "Received spurious death notification for thread " 4851 + thread.asBinder()); 4852 } 4853 } 4854 4855 /** 4856 * If a stack trace dump file is configured, dump process stack traces. 4857 * @param clearTraces causes the dump file to be erased prior to the new 4858 * traces being written, if true; when false, the new traces will be 4859 * appended to any existing file content. 4860 * @param firstPids of dalvik VM processes to dump stack traces for first 4861 * @param lastPids of dalvik VM processes to dump stack traces for last 4862 * @param nativeProcs optional list of native process names to dump stack crawls 4863 * @return file containing stack traces, or null if no dump file is configured 4864 */ 4865 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4866 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4867 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4868 if (tracesPath == null || tracesPath.length() == 0) { 4869 return null; 4870 } 4871 4872 File tracesFile = new File(tracesPath); 4873 try { 4874 File tracesDir = tracesFile.getParentFile(); 4875 if (!tracesDir.exists()) { 4876 tracesDir.mkdirs(); 4877 if (!SELinux.restorecon(tracesDir)) { 4878 return null; 4879 } 4880 } 4881 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4882 4883 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4884 tracesFile.createNewFile(); 4885 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4886 } catch (IOException e) { 4887 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4888 return null; 4889 } 4890 4891 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4892 return tracesFile; 4893 } 4894 4895 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4896 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4897 // Use a FileObserver to detect when traces finish writing. 4898 // The order of traces is considered important to maintain for legibility. 4899 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4900 @Override 4901 public synchronized void onEvent(int event, String path) { notify(); } 4902 }; 4903 4904 try { 4905 observer.startWatching(); 4906 4907 // First collect all of the stacks of the most important pids. 4908 if (firstPids != null) { 4909 try { 4910 int num = firstPids.size(); 4911 for (int i = 0; i < num; i++) { 4912 synchronized (observer) { 4913 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4914 observer.wait(200); // Wait for write-close, give up after 200msec 4915 } 4916 } 4917 } catch (InterruptedException e) { 4918 Log.wtf(TAG, e); 4919 } 4920 } 4921 4922 // Next collect the stacks of the native pids 4923 if (nativeProcs != null) { 4924 int[] pids = Process.getPidsForCommands(nativeProcs); 4925 if (pids != null) { 4926 for (int pid : pids) { 4927 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4928 } 4929 } 4930 } 4931 4932 // Lastly, measure CPU usage. 4933 if (processCpuTracker != null) { 4934 processCpuTracker.init(); 4935 System.gc(); 4936 processCpuTracker.update(); 4937 try { 4938 synchronized (processCpuTracker) { 4939 processCpuTracker.wait(500); // measure over 1/2 second. 4940 } 4941 } catch (InterruptedException e) { 4942 } 4943 processCpuTracker.update(); 4944 4945 // We'll take the stack crawls of just the top apps using CPU. 4946 final int N = processCpuTracker.countWorkingStats(); 4947 int numProcs = 0; 4948 for (int i=0; i<N && numProcs<5; i++) { 4949 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4950 if (lastPids.indexOfKey(stats.pid) >= 0) { 4951 numProcs++; 4952 try { 4953 synchronized (observer) { 4954 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4955 observer.wait(200); // Wait for write-close, give up after 200msec 4956 } 4957 } catch (InterruptedException e) { 4958 Log.wtf(TAG, e); 4959 } 4960 4961 } 4962 } 4963 } 4964 } finally { 4965 observer.stopWatching(); 4966 } 4967 } 4968 4969 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4970 if (true || IS_USER_BUILD) { 4971 return; 4972 } 4973 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4974 if (tracesPath == null || tracesPath.length() == 0) { 4975 return; 4976 } 4977 4978 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4979 StrictMode.allowThreadDiskWrites(); 4980 try { 4981 final File tracesFile = new File(tracesPath); 4982 final File tracesDir = tracesFile.getParentFile(); 4983 final File tracesTmp = new File(tracesDir, "__tmp__"); 4984 try { 4985 if (!tracesDir.exists()) { 4986 tracesDir.mkdirs(); 4987 if (!SELinux.restorecon(tracesDir.getPath())) { 4988 return; 4989 } 4990 } 4991 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4992 4993 if (tracesFile.exists()) { 4994 tracesTmp.delete(); 4995 tracesFile.renameTo(tracesTmp); 4996 } 4997 StringBuilder sb = new StringBuilder(); 4998 Time tobj = new Time(); 4999 tobj.set(System.currentTimeMillis()); 5000 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5001 sb.append(": "); 5002 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5003 sb.append(" since "); 5004 sb.append(msg); 5005 FileOutputStream fos = new FileOutputStream(tracesFile); 5006 fos.write(sb.toString().getBytes()); 5007 if (app == null) { 5008 fos.write("\n*** No application process!".getBytes()); 5009 } 5010 fos.close(); 5011 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5012 } catch (IOException e) { 5013 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5014 return; 5015 } 5016 5017 if (app != null) { 5018 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5019 firstPids.add(app.pid); 5020 dumpStackTraces(tracesPath, firstPids, null, null, null); 5021 } 5022 5023 File lastTracesFile = null; 5024 File curTracesFile = null; 5025 for (int i=9; i>=0; i--) { 5026 String name = String.format(Locale.US, "slow%02d.txt", i); 5027 curTracesFile = new File(tracesDir, name); 5028 if (curTracesFile.exists()) { 5029 if (lastTracesFile != null) { 5030 curTracesFile.renameTo(lastTracesFile); 5031 } else { 5032 curTracesFile.delete(); 5033 } 5034 } 5035 lastTracesFile = curTracesFile; 5036 } 5037 tracesFile.renameTo(curTracesFile); 5038 if (tracesTmp.exists()) { 5039 tracesTmp.renameTo(tracesFile); 5040 } 5041 } finally { 5042 StrictMode.setThreadPolicy(oldPolicy); 5043 } 5044 } 5045 5046 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5047 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5048 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5049 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5050 5051 if (mController != null) { 5052 try { 5053 // 0 == continue, -1 = kill process immediately 5054 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5055 if (res < 0 && app.pid != MY_PID) { 5056 app.kill("anr", true); 5057 } 5058 } catch (RemoteException e) { 5059 mController = null; 5060 Watchdog.getInstance().setActivityController(null); 5061 } 5062 } 5063 5064 long anrTime = SystemClock.uptimeMillis(); 5065 if (MONITOR_CPU_USAGE) { 5066 updateCpuStatsNow(); 5067 } 5068 5069 synchronized (this) { 5070 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5071 if (mShuttingDown) { 5072 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5073 return; 5074 } else if (app.notResponding) { 5075 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5076 return; 5077 } else if (app.crashing) { 5078 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5079 return; 5080 } 5081 5082 // In case we come through here for the same app before completing 5083 // this one, mark as anring now so we will bail out. 5084 app.notResponding = true; 5085 5086 // Log the ANR to the event log. 5087 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5088 app.processName, app.info.flags, annotation); 5089 5090 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5091 firstPids.add(app.pid); 5092 5093 int parentPid = app.pid; 5094 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5095 if (parentPid != app.pid) firstPids.add(parentPid); 5096 5097 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5098 5099 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5100 ProcessRecord r = mLruProcesses.get(i); 5101 if (r != null && r.thread != null) { 5102 int pid = r.pid; 5103 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5104 if (r.persistent) { 5105 firstPids.add(pid); 5106 } else { 5107 lastPids.put(pid, Boolean.TRUE); 5108 } 5109 } 5110 } 5111 } 5112 } 5113 5114 // Log the ANR to the main log. 5115 StringBuilder info = new StringBuilder(); 5116 info.setLength(0); 5117 info.append("ANR in ").append(app.processName); 5118 if (activity != null && activity.shortComponentName != null) { 5119 info.append(" (").append(activity.shortComponentName).append(")"); 5120 } 5121 info.append("\n"); 5122 info.append("PID: ").append(app.pid).append("\n"); 5123 if (annotation != null) { 5124 info.append("Reason: ").append(annotation).append("\n"); 5125 } 5126 if (parent != null && parent != activity) { 5127 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5128 } 5129 5130 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5131 5132 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5133 NATIVE_STACKS_OF_INTEREST); 5134 5135 String cpuInfo = null; 5136 if (MONITOR_CPU_USAGE) { 5137 updateCpuStatsNow(); 5138 synchronized (mProcessCpuTracker) { 5139 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5140 } 5141 info.append(processCpuTracker.printCurrentLoad()); 5142 info.append(cpuInfo); 5143 } 5144 5145 info.append(processCpuTracker.printCurrentState(anrTime)); 5146 5147 Slog.e(TAG, info.toString()); 5148 if (tracesFile == null) { 5149 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5150 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5151 } 5152 5153 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5154 cpuInfo, tracesFile, null); 5155 5156 if (mController != null) { 5157 try { 5158 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5159 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5160 if (res != 0) { 5161 if (res < 0 && app.pid != MY_PID) { 5162 app.kill("anr", true); 5163 } else { 5164 synchronized (this) { 5165 mServices.scheduleServiceTimeoutLocked(app); 5166 } 5167 } 5168 return; 5169 } 5170 } catch (RemoteException e) { 5171 mController = null; 5172 Watchdog.getInstance().setActivityController(null); 5173 } 5174 } 5175 5176 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5177 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5178 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5179 5180 synchronized (this) { 5181 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5182 app.kill("bg anr", true); 5183 return; 5184 } 5185 5186 // Set the app's notResponding state, and look up the errorReportReceiver 5187 makeAppNotRespondingLocked(app, 5188 activity != null ? activity.shortComponentName : null, 5189 annotation != null ? "ANR " + annotation : "ANR", 5190 info.toString()); 5191 5192 // Bring up the infamous App Not Responding dialog 5193 Message msg = Message.obtain(); 5194 HashMap<String, Object> map = new HashMap<String, Object>(); 5195 msg.what = SHOW_NOT_RESPONDING_MSG; 5196 msg.obj = map; 5197 msg.arg1 = aboveSystem ? 1 : 0; 5198 map.put("app", app); 5199 if (activity != null) { 5200 map.put("activity", activity); 5201 } 5202 5203 mHandler.sendMessage(msg); 5204 } 5205 } 5206 5207 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5208 if (!mLaunchWarningShown) { 5209 mLaunchWarningShown = true; 5210 mHandler.post(new Runnable() { 5211 @Override 5212 public void run() { 5213 synchronized (ActivityManagerService.this) { 5214 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5215 d.show(); 5216 mHandler.postDelayed(new Runnable() { 5217 @Override 5218 public void run() { 5219 synchronized (ActivityManagerService.this) { 5220 d.dismiss(); 5221 mLaunchWarningShown = false; 5222 } 5223 } 5224 }, 4000); 5225 } 5226 } 5227 }); 5228 } 5229 } 5230 5231 @Override 5232 public boolean clearApplicationUserData(final String packageName, 5233 final IPackageDataObserver observer, int userId) { 5234 enforceNotIsolatedCaller("clearApplicationUserData"); 5235 int uid = Binder.getCallingUid(); 5236 int pid = Binder.getCallingPid(); 5237 userId = handleIncomingUser(pid, uid, 5238 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5239 long callingId = Binder.clearCallingIdentity(); 5240 try { 5241 IPackageManager pm = AppGlobals.getPackageManager(); 5242 int pkgUid = -1; 5243 synchronized(this) { 5244 try { 5245 pkgUid = pm.getPackageUid(packageName, userId); 5246 } catch (RemoteException e) { 5247 } 5248 if (pkgUid == -1) { 5249 Slog.w(TAG, "Invalid packageName: " + packageName); 5250 if (observer != null) { 5251 try { 5252 observer.onRemoveCompleted(packageName, false); 5253 } catch (RemoteException e) { 5254 Slog.i(TAG, "Observer no longer exists."); 5255 } 5256 } 5257 return false; 5258 } 5259 if (uid == pkgUid || checkComponentPermission( 5260 android.Manifest.permission.CLEAR_APP_USER_DATA, 5261 pid, uid, -1, true) 5262 == PackageManager.PERMISSION_GRANTED) { 5263 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5264 } else { 5265 throw new SecurityException("PID " + pid + " does not have permission " 5266 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5267 + " of package " + packageName); 5268 } 5269 5270 // Remove all tasks match the cleared application package and user 5271 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5272 final TaskRecord tr = mRecentTasks.get(i); 5273 final String taskPackageName = 5274 tr.getBaseIntent().getComponent().getPackageName(); 5275 if (tr.userId != userId) continue; 5276 if (!taskPackageName.equals(packageName)) continue; 5277 removeTaskByIdLocked(tr.taskId, 0); 5278 } 5279 } 5280 5281 try { 5282 // Clear application user data 5283 pm.clearApplicationUserData(packageName, observer, userId); 5284 5285 synchronized(this) { 5286 // Remove all permissions granted from/to this package 5287 removeUriPermissionsForPackageLocked(packageName, userId, true); 5288 } 5289 5290 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5291 Uri.fromParts("package", packageName, null)); 5292 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5293 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5294 null, null, 0, null, null, null, false, false, userId); 5295 } catch (RemoteException e) { 5296 } 5297 } finally { 5298 Binder.restoreCallingIdentity(callingId); 5299 } 5300 return true; 5301 } 5302 5303 @Override 5304 public void killBackgroundProcesses(final String packageName, int userId) { 5305 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5306 != PackageManager.PERMISSION_GRANTED && 5307 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5308 != PackageManager.PERMISSION_GRANTED) { 5309 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5310 + Binder.getCallingPid() 5311 + ", uid=" + Binder.getCallingUid() 5312 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5313 Slog.w(TAG, msg); 5314 throw new SecurityException(msg); 5315 } 5316 5317 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5318 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5319 long callingId = Binder.clearCallingIdentity(); 5320 try { 5321 IPackageManager pm = AppGlobals.getPackageManager(); 5322 synchronized(this) { 5323 int appId = -1; 5324 try { 5325 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5326 } catch (RemoteException e) { 5327 } 5328 if (appId == -1) { 5329 Slog.w(TAG, "Invalid packageName: " + packageName); 5330 return; 5331 } 5332 killPackageProcessesLocked(packageName, appId, userId, 5333 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5334 } 5335 } finally { 5336 Binder.restoreCallingIdentity(callingId); 5337 } 5338 } 5339 5340 @Override 5341 public void killAllBackgroundProcesses() { 5342 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5343 != PackageManager.PERMISSION_GRANTED) { 5344 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5345 + Binder.getCallingPid() 5346 + ", uid=" + Binder.getCallingUid() 5347 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5348 Slog.w(TAG, msg); 5349 throw new SecurityException(msg); 5350 } 5351 5352 long callingId = Binder.clearCallingIdentity(); 5353 try { 5354 synchronized(this) { 5355 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5356 final int NP = mProcessNames.getMap().size(); 5357 for (int ip=0; ip<NP; ip++) { 5358 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5359 final int NA = apps.size(); 5360 for (int ia=0; ia<NA; ia++) { 5361 ProcessRecord app = apps.valueAt(ia); 5362 if (app.persistent) { 5363 // we don't kill persistent processes 5364 continue; 5365 } 5366 if (app.removed) { 5367 procs.add(app); 5368 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5369 app.removed = true; 5370 procs.add(app); 5371 } 5372 } 5373 } 5374 5375 int N = procs.size(); 5376 for (int i=0; i<N; i++) { 5377 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5378 } 5379 mAllowLowerMemLevel = true; 5380 updateOomAdjLocked(); 5381 doLowMemReportIfNeededLocked(null); 5382 } 5383 } finally { 5384 Binder.restoreCallingIdentity(callingId); 5385 } 5386 } 5387 5388 @Override 5389 public void forceStopPackage(final String packageName, int userId) { 5390 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5391 != PackageManager.PERMISSION_GRANTED) { 5392 String msg = "Permission Denial: forceStopPackage() from pid=" 5393 + Binder.getCallingPid() 5394 + ", uid=" + Binder.getCallingUid() 5395 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5396 Slog.w(TAG, msg); 5397 throw new SecurityException(msg); 5398 } 5399 final int callingPid = Binder.getCallingPid(); 5400 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5401 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5402 long callingId = Binder.clearCallingIdentity(); 5403 try { 5404 IPackageManager pm = AppGlobals.getPackageManager(); 5405 synchronized(this) { 5406 int[] users = userId == UserHandle.USER_ALL 5407 ? getUsersLocked() : new int[] { userId }; 5408 for (int user : users) { 5409 int pkgUid = -1; 5410 try { 5411 pkgUid = pm.getPackageUid(packageName, user); 5412 } catch (RemoteException e) { 5413 } 5414 if (pkgUid == -1) { 5415 Slog.w(TAG, "Invalid packageName: " + packageName); 5416 continue; 5417 } 5418 try { 5419 pm.setPackageStoppedState(packageName, true, user); 5420 } catch (RemoteException e) { 5421 } catch (IllegalArgumentException e) { 5422 Slog.w(TAG, "Failed trying to unstop package " 5423 + packageName + ": " + e); 5424 } 5425 if (isUserRunningLocked(user, false)) { 5426 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5427 } 5428 } 5429 } 5430 } finally { 5431 Binder.restoreCallingIdentity(callingId); 5432 } 5433 } 5434 5435 @Override 5436 public void addPackageDependency(String packageName) { 5437 synchronized (this) { 5438 int callingPid = Binder.getCallingPid(); 5439 if (callingPid == Process.myPid()) { 5440 // Yeah, um, no. 5441 Slog.w(TAG, "Can't addPackageDependency on system process"); 5442 return; 5443 } 5444 ProcessRecord proc; 5445 synchronized (mPidsSelfLocked) { 5446 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5447 } 5448 if (proc != null) { 5449 if (proc.pkgDeps == null) { 5450 proc.pkgDeps = new ArraySet<String>(1); 5451 } 5452 proc.pkgDeps.add(packageName); 5453 } 5454 } 5455 } 5456 5457 /* 5458 * The pkg name and app id have to be specified. 5459 */ 5460 @Override 5461 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5462 if (pkg == null) { 5463 return; 5464 } 5465 // Make sure the uid is valid. 5466 if (appid < 0) { 5467 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5468 return; 5469 } 5470 int callerUid = Binder.getCallingUid(); 5471 // Only the system server can kill an application 5472 if (callerUid == Process.SYSTEM_UID) { 5473 // Post an aysnc message to kill the application 5474 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5475 msg.arg1 = appid; 5476 msg.arg2 = 0; 5477 Bundle bundle = new Bundle(); 5478 bundle.putString("pkg", pkg); 5479 bundle.putString("reason", reason); 5480 msg.obj = bundle; 5481 mHandler.sendMessage(msg); 5482 } else { 5483 throw new SecurityException(callerUid + " cannot kill pkg: " + 5484 pkg); 5485 } 5486 } 5487 5488 @Override 5489 public void closeSystemDialogs(String reason) { 5490 enforceNotIsolatedCaller("closeSystemDialogs"); 5491 5492 final int pid = Binder.getCallingPid(); 5493 final int uid = Binder.getCallingUid(); 5494 final long origId = Binder.clearCallingIdentity(); 5495 try { 5496 synchronized (this) { 5497 // Only allow this from foreground processes, so that background 5498 // applications can't abuse it to prevent system UI from being shown. 5499 if (uid >= Process.FIRST_APPLICATION_UID) { 5500 ProcessRecord proc; 5501 synchronized (mPidsSelfLocked) { 5502 proc = mPidsSelfLocked.get(pid); 5503 } 5504 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5505 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5506 + " from background process " + proc); 5507 return; 5508 } 5509 } 5510 closeSystemDialogsLocked(reason); 5511 } 5512 } finally { 5513 Binder.restoreCallingIdentity(origId); 5514 } 5515 } 5516 5517 void closeSystemDialogsLocked(String reason) { 5518 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5520 | Intent.FLAG_RECEIVER_FOREGROUND); 5521 if (reason != null) { 5522 intent.putExtra("reason", reason); 5523 } 5524 mWindowManager.closeSystemDialogs(reason); 5525 5526 mStackSupervisor.closeSystemDialogsLocked(); 5527 5528 broadcastIntentLocked(null, null, intent, null, 5529 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5530 Process.SYSTEM_UID, UserHandle.USER_ALL); 5531 } 5532 5533 @Override 5534 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5535 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5536 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5537 for (int i=pids.length-1; i>=0; i--) { 5538 ProcessRecord proc; 5539 int oomAdj; 5540 synchronized (this) { 5541 synchronized (mPidsSelfLocked) { 5542 proc = mPidsSelfLocked.get(pids[i]); 5543 oomAdj = proc != null ? proc.setAdj : 0; 5544 } 5545 } 5546 infos[i] = new Debug.MemoryInfo(); 5547 Debug.getMemoryInfo(pids[i], infos[i]); 5548 if (proc != null) { 5549 synchronized (this) { 5550 if (proc.thread != null && proc.setAdj == oomAdj) { 5551 // Record this for posterity if the process has been stable. 5552 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5553 infos[i].getTotalUss(), false, proc.pkgList); 5554 } 5555 } 5556 } 5557 } 5558 return infos; 5559 } 5560 5561 @Override 5562 public long[] getProcessPss(int[] pids) { 5563 enforceNotIsolatedCaller("getProcessPss"); 5564 long[] pss = new long[pids.length]; 5565 for (int i=pids.length-1; i>=0; i--) { 5566 ProcessRecord proc; 5567 int oomAdj; 5568 synchronized (this) { 5569 synchronized (mPidsSelfLocked) { 5570 proc = mPidsSelfLocked.get(pids[i]); 5571 oomAdj = proc != null ? proc.setAdj : 0; 5572 } 5573 } 5574 long[] tmpUss = new long[1]; 5575 pss[i] = Debug.getPss(pids[i], tmpUss); 5576 if (proc != null) { 5577 synchronized (this) { 5578 if (proc.thread != null && proc.setAdj == oomAdj) { 5579 // Record this for posterity if the process has been stable. 5580 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5581 } 5582 } 5583 } 5584 } 5585 return pss; 5586 } 5587 5588 @Override 5589 public void killApplicationProcess(String processName, int uid) { 5590 if (processName == null) { 5591 return; 5592 } 5593 5594 int callerUid = Binder.getCallingUid(); 5595 // Only the system server can kill an application 5596 if (callerUid == Process.SYSTEM_UID) { 5597 synchronized (this) { 5598 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5599 if (app != null && app.thread != null) { 5600 try { 5601 app.thread.scheduleSuicide(); 5602 } catch (RemoteException e) { 5603 // If the other end already died, then our work here is done. 5604 } 5605 } else { 5606 Slog.w(TAG, "Process/uid not found attempting kill of " 5607 + processName + " / " + uid); 5608 } 5609 } 5610 } else { 5611 throw new SecurityException(callerUid + " cannot kill app process: " + 5612 processName); 5613 } 5614 } 5615 5616 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5617 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5618 false, true, false, false, UserHandle.getUserId(uid), reason); 5619 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5620 Uri.fromParts("package", packageName, null)); 5621 if (!mProcessesReady) { 5622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5623 | Intent.FLAG_RECEIVER_FOREGROUND); 5624 } 5625 intent.putExtra(Intent.EXTRA_UID, uid); 5626 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5627 broadcastIntentLocked(null, null, intent, 5628 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5629 false, false, 5630 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5631 } 5632 5633 private void forceStopUserLocked(int userId, String reason) { 5634 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5635 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5636 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5637 | Intent.FLAG_RECEIVER_FOREGROUND); 5638 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5639 broadcastIntentLocked(null, null, intent, 5640 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5641 false, false, 5642 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5643 } 5644 5645 private final boolean killPackageProcessesLocked(String packageName, int appId, 5646 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5647 boolean doit, boolean evenPersistent, String reason) { 5648 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5649 5650 // Remove all processes this package may have touched: all with the 5651 // same UID (except for the system or root user), and all whose name 5652 // matches the package name. 5653 final int NP = mProcessNames.getMap().size(); 5654 for (int ip=0; ip<NP; ip++) { 5655 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5656 final int NA = apps.size(); 5657 for (int ia=0; ia<NA; ia++) { 5658 ProcessRecord app = apps.valueAt(ia); 5659 if (app.persistent && !evenPersistent) { 5660 // we don't kill persistent processes 5661 continue; 5662 } 5663 if (app.removed) { 5664 if (doit) { 5665 procs.add(app); 5666 } 5667 continue; 5668 } 5669 5670 // Skip process if it doesn't meet our oom adj requirement. 5671 if (app.setAdj < minOomAdj) { 5672 continue; 5673 } 5674 5675 // If no package is specified, we call all processes under the 5676 // give user id. 5677 if (packageName == null) { 5678 if (app.userId != userId) { 5679 continue; 5680 } 5681 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5682 continue; 5683 } 5684 // Package has been specified, we want to hit all processes 5685 // that match it. We need to qualify this by the processes 5686 // that are running under the specified app and user ID. 5687 } else { 5688 final boolean isDep = app.pkgDeps != null 5689 && app.pkgDeps.contains(packageName); 5690 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5691 continue; 5692 } 5693 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5694 continue; 5695 } 5696 if (!app.pkgList.containsKey(packageName) && !isDep) { 5697 continue; 5698 } 5699 } 5700 5701 // Process has passed all conditions, kill it! 5702 if (!doit) { 5703 return true; 5704 } 5705 app.removed = true; 5706 procs.add(app); 5707 } 5708 } 5709 5710 int N = procs.size(); 5711 for (int i=0; i<N; i++) { 5712 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5713 } 5714 updateOomAdjLocked(); 5715 return N > 0; 5716 } 5717 5718 private final boolean forceStopPackageLocked(String name, int appId, 5719 boolean callerWillRestart, boolean purgeCache, boolean doit, 5720 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5721 int i; 5722 int N; 5723 5724 if (userId == UserHandle.USER_ALL && name == null) { 5725 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5726 } 5727 5728 if (appId < 0 && name != null) { 5729 try { 5730 appId = UserHandle.getAppId( 5731 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5732 } catch (RemoteException e) { 5733 } 5734 } 5735 5736 if (doit) { 5737 if (name != null) { 5738 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5739 + " user=" + userId + ": " + reason); 5740 } else { 5741 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5742 } 5743 5744 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5745 for (int ip=pmap.size()-1; ip>=0; ip--) { 5746 SparseArray<Long> ba = pmap.valueAt(ip); 5747 for (i=ba.size()-1; i>=0; i--) { 5748 boolean remove = false; 5749 final int entUid = ba.keyAt(i); 5750 if (name != null) { 5751 if (userId == UserHandle.USER_ALL) { 5752 if (UserHandle.getAppId(entUid) == appId) { 5753 remove = true; 5754 } 5755 } else { 5756 if (entUid == UserHandle.getUid(userId, appId)) { 5757 remove = true; 5758 } 5759 } 5760 } else if (UserHandle.getUserId(entUid) == userId) { 5761 remove = true; 5762 } 5763 if (remove) { 5764 ba.removeAt(i); 5765 } 5766 } 5767 if (ba.size() == 0) { 5768 pmap.removeAt(ip); 5769 } 5770 } 5771 } 5772 5773 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5774 -100, callerWillRestart, true, doit, evenPersistent, 5775 name == null ? ("stop user " + userId) : ("stop " + name)); 5776 5777 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5778 if (!doit) { 5779 return true; 5780 } 5781 didSomething = true; 5782 } 5783 5784 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5785 if (!doit) { 5786 return true; 5787 } 5788 didSomething = true; 5789 } 5790 5791 if (name == null) { 5792 // Remove all sticky broadcasts from this user. 5793 mStickyBroadcasts.remove(userId); 5794 } 5795 5796 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5797 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5798 userId, providers)) { 5799 if (!doit) { 5800 return true; 5801 } 5802 didSomething = true; 5803 } 5804 N = providers.size(); 5805 for (i=0; i<N; i++) { 5806 removeDyingProviderLocked(null, providers.get(i), true); 5807 } 5808 5809 // Remove transient permissions granted from/to this package/user 5810 removeUriPermissionsForPackageLocked(name, userId, false); 5811 5812 if (name == null || uninstalling) { 5813 // Remove pending intents. For now we only do this when force 5814 // stopping users, because we have some problems when doing this 5815 // for packages -- app widgets are not currently cleaned up for 5816 // such packages, so they can be left with bad pending intents. 5817 if (mIntentSenderRecords.size() > 0) { 5818 Iterator<WeakReference<PendingIntentRecord>> it 5819 = mIntentSenderRecords.values().iterator(); 5820 while (it.hasNext()) { 5821 WeakReference<PendingIntentRecord> wpir = it.next(); 5822 if (wpir == null) { 5823 it.remove(); 5824 continue; 5825 } 5826 PendingIntentRecord pir = wpir.get(); 5827 if (pir == null) { 5828 it.remove(); 5829 continue; 5830 } 5831 if (name == null) { 5832 // Stopping user, remove all objects for the user. 5833 if (pir.key.userId != userId) { 5834 // Not the same user, skip it. 5835 continue; 5836 } 5837 } else { 5838 if (UserHandle.getAppId(pir.uid) != appId) { 5839 // Different app id, skip it. 5840 continue; 5841 } 5842 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5843 // Different user, skip it. 5844 continue; 5845 } 5846 if (!pir.key.packageName.equals(name)) { 5847 // Different package, skip it. 5848 continue; 5849 } 5850 } 5851 if (!doit) { 5852 return true; 5853 } 5854 didSomething = true; 5855 it.remove(); 5856 pir.canceled = true; 5857 if (pir.key.activity != null) { 5858 pir.key.activity.pendingResults.remove(pir.ref); 5859 } 5860 } 5861 } 5862 } 5863 5864 if (doit) { 5865 if (purgeCache && name != null) { 5866 AttributeCache ac = AttributeCache.instance(); 5867 if (ac != null) { 5868 ac.removePackage(name); 5869 } 5870 } 5871 if (mBooted) { 5872 mStackSupervisor.resumeTopActivitiesLocked(); 5873 mStackSupervisor.scheduleIdleLocked(); 5874 } 5875 } 5876 5877 return didSomething; 5878 } 5879 5880 private final boolean removeProcessLocked(ProcessRecord app, 5881 boolean callerWillRestart, boolean allowRestart, String reason) { 5882 final String name = app.processName; 5883 final int uid = app.uid; 5884 if (DEBUG_PROCESSES) Slog.d( 5885 TAG, "Force removing proc " + app.toShortString() + " (" + name 5886 + "/" + uid + ")"); 5887 5888 mProcessNames.remove(name, uid); 5889 mIsolatedProcesses.remove(app.uid); 5890 if (mHeavyWeightProcess == app) { 5891 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5892 mHeavyWeightProcess.userId, 0)); 5893 mHeavyWeightProcess = null; 5894 } 5895 boolean needRestart = false; 5896 if (app.pid > 0 && app.pid != MY_PID) { 5897 int pid = app.pid; 5898 synchronized (mPidsSelfLocked) { 5899 mPidsSelfLocked.remove(pid); 5900 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5901 } 5902 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5903 if (app.isolated) { 5904 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5905 } 5906 app.kill(reason, true); 5907 handleAppDiedLocked(app, true, allowRestart); 5908 removeLruProcessLocked(app); 5909 5910 if (app.persistent && !app.isolated) { 5911 if (!callerWillRestart) { 5912 addAppLocked(app.info, false, null /* ABI override */); 5913 } else { 5914 needRestart = true; 5915 } 5916 } 5917 } else { 5918 mRemovedProcesses.add(app); 5919 } 5920 5921 return needRestart; 5922 } 5923 5924 private final void processStartTimedOutLocked(ProcessRecord app) { 5925 final int pid = app.pid; 5926 boolean gone = false; 5927 synchronized (mPidsSelfLocked) { 5928 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5929 if (knownApp != null && knownApp.thread == null) { 5930 mPidsSelfLocked.remove(pid); 5931 gone = true; 5932 } 5933 } 5934 5935 if (gone) { 5936 Slog.w(TAG, "Process " + app + " failed to attach"); 5937 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5938 pid, app.uid, app.processName); 5939 mProcessNames.remove(app.processName, app.uid); 5940 mIsolatedProcesses.remove(app.uid); 5941 if (mHeavyWeightProcess == app) { 5942 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5943 mHeavyWeightProcess.userId, 0)); 5944 mHeavyWeightProcess = null; 5945 } 5946 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5947 if (app.isolated) { 5948 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5949 } 5950 // Take care of any launching providers waiting for this process. 5951 checkAppInLaunchingProvidersLocked(app, true); 5952 // Take care of any services that are waiting for the process. 5953 mServices.processStartTimedOutLocked(app); 5954 app.kill("start timeout", true); 5955 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5956 Slog.w(TAG, "Unattached app died before backup, skipping"); 5957 try { 5958 IBackupManager bm = IBackupManager.Stub.asInterface( 5959 ServiceManager.getService(Context.BACKUP_SERVICE)); 5960 bm.agentDisconnected(app.info.packageName); 5961 } catch (RemoteException e) { 5962 // Can't happen; the backup manager is local 5963 } 5964 } 5965 if (isPendingBroadcastProcessLocked(pid)) { 5966 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5967 skipPendingBroadcastLocked(pid); 5968 } 5969 } else { 5970 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5971 } 5972 } 5973 5974 private final boolean attachApplicationLocked(IApplicationThread thread, 5975 int pid) { 5976 5977 // Find the application record that is being attached... either via 5978 // the pid if we are running in multiple processes, or just pull the 5979 // next app record if we are emulating process with anonymous threads. 5980 ProcessRecord app; 5981 if (pid != MY_PID && pid >= 0) { 5982 synchronized (mPidsSelfLocked) { 5983 app = mPidsSelfLocked.get(pid); 5984 } 5985 } else { 5986 app = null; 5987 } 5988 5989 if (app == null) { 5990 Slog.w(TAG, "No pending application record for pid " + pid 5991 + " (IApplicationThread " + thread + "); dropping process"); 5992 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5993 if (pid > 0 && pid != MY_PID) { 5994 Process.killProcessQuiet(pid); 5995 //TODO: Process.killProcessGroup(app.info.uid, pid); 5996 } else { 5997 try { 5998 thread.scheduleExit(); 5999 } catch (Exception e) { 6000 // Ignore exceptions. 6001 } 6002 } 6003 return false; 6004 } 6005 6006 // If this application record is still attached to a previous 6007 // process, clean it up now. 6008 if (app.thread != null) { 6009 handleAppDiedLocked(app, true, true); 6010 } 6011 6012 // Tell the process all about itself. 6013 6014 if (localLOGV) Slog.v( 6015 TAG, "Binding process pid " + pid + " to record " + app); 6016 6017 final String processName = app.processName; 6018 try { 6019 AppDeathRecipient adr = new AppDeathRecipient( 6020 app, pid, thread); 6021 thread.asBinder().linkToDeath(adr, 0); 6022 app.deathRecipient = adr; 6023 } catch (RemoteException e) { 6024 app.resetPackageList(mProcessStats); 6025 startProcessLocked(app, "link fail", processName); 6026 return false; 6027 } 6028 6029 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6030 6031 app.makeActive(thread, mProcessStats); 6032 app.curAdj = app.setAdj = -100; 6033 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6034 app.forcingToForeground = null; 6035 updateProcessForegroundLocked(app, false, false); 6036 app.hasShownUi = false; 6037 app.debugging = false; 6038 app.cached = false; 6039 6040 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6041 6042 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6043 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6044 6045 if (!normalMode) { 6046 Slog.i(TAG, "Launching preboot mode app: " + app); 6047 } 6048 6049 if (localLOGV) Slog.v( 6050 TAG, "New app record " + app 6051 + " thread=" + thread.asBinder() + " pid=" + pid); 6052 try { 6053 int testMode = IApplicationThread.DEBUG_OFF; 6054 if (mDebugApp != null && mDebugApp.equals(processName)) { 6055 testMode = mWaitForDebugger 6056 ? IApplicationThread.DEBUG_WAIT 6057 : IApplicationThread.DEBUG_ON; 6058 app.debugging = true; 6059 if (mDebugTransient) { 6060 mDebugApp = mOrigDebugApp; 6061 mWaitForDebugger = mOrigWaitForDebugger; 6062 } 6063 } 6064 String profileFile = app.instrumentationProfileFile; 6065 ParcelFileDescriptor profileFd = null; 6066 int samplingInterval = 0; 6067 boolean profileAutoStop = false; 6068 if (mProfileApp != null && mProfileApp.equals(processName)) { 6069 mProfileProc = app; 6070 profileFile = mProfileFile; 6071 profileFd = mProfileFd; 6072 samplingInterval = mSamplingInterval; 6073 profileAutoStop = mAutoStopProfiler; 6074 } 6075 boolean enableOpenGlTrace = false; 6076 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6077 enableOpenGlTrace = true; 6078 mOpenGlTraceApp = null; 6079 } 6080 6081 // If the app is being launched for restore or full backup, set it up specially 6082 boolean isRestrictedBackupMode = false; 6083 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6084 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6085 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6086 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6087 } 6088 6089 ensurePackageDexOpt(app.instrumentationInfo != null 6090 ? app.instrumentationInfo.packageName 6091 : app.info.packageName); 6092 if (app.instrumentationClass != null) { 6093 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6094 } 6095 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6096 + processName + " with config " + mConfiguration); 6097 ApplicationInfo appInfo = app.instrumentationInfo != null 6098 ? app.instrumentationInfo : app.info; 6099 app.compat = compatibilityInfoForPackageLocked(appInfo); 6100 if (profileFd != null) { 6101 profileFd = profileFd.dup(); 6102 } 6103 ProfilerInfo profilerInfo = profileFile == null ? null 6104 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6105 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6106 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6107 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6108 isRestrictedBackupMode || !normalMode, app.persistent, 6109 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6110 mCoreSettingsObserver.getCoreSettingsLocked()); 6111 updateLruProcessLocked(app, false, null); 6112 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6113 } catch (Exception e) { 6114 // todo: Yikes! What should we do? For now we will try to 6115 // start another process, but that could easily get us in 6116 // an infinite loop of restarting processes... 6117 Slog.w(TAG, "Exception thrown during bind!", e); 6118 6119 app.resetPackageList(mProcessStats); 6120 app.unlinkDeathRecipient(); 6121 startProcessLocked(app, "bind fail", processName); 6122 return false; 6123 } 6124 6125 // Remove this record from the list of starting applications. 6126 mPersistentStartingProcesses.remove(app); 6127 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6128 "Attach application locked removing on hold: " + app); 6129 mProcessesOnHold.remove(app); 6130 6131 boolean badApp = false; 6132 boolean didSomething = false; 6133 6134 // See if the top visible activity is waiting to run in this process... 6135 if (normalMode) { 6136 try { 6137 if (mStackSupervisor.attachApplicationLocked(app)) { 6138 didSomething = true; 6139 } 6140 } catch (Exception e) { 6141 badApp = true; 6142 } 6143 } 6144 6145 // Find any services that should be running in this process... 6146 if (!badApp) { 6147 try { 6148 didSomething |= mServices.attachApplicationLocked(app, processName); 6149 } catch (Exception e) { 6150 badApp = true; 6151 } 6152 } 6153 6154 // Check if a next-broadcast receiver is in this process... 6155 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6156 try { 6157 didSomething |= sendPendingBroadcastsLocked(app); 6158 } catch (Exception e) { 6159 // If the app died trying to launch the receiver we declare it 'bad' 6160 badApp = true; 6161 } 6162 } 6163 6164 // Check whether the next backup agent is in this process... 6165 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6166 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6167 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6168 try { 6169 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6170 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6171 mBackupTarget.backupMode); 6172 } catch (Exception e) { 6173 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6174 e.printStackTrace(); 6175 } 6176 } 6177 6178 if (badApp) { 6179 // todo: Also need to kill application to deal with all 6180 // kinds of exceptions. 6181 handleAppDiedLocked(app, false, true); 6182 return false; 6183 } 6184 6185 if (!didSomething) { 6186 updateOomAdjLocked(); 6187 } 6188 6189 return true; 6190 } 6191 6192 @Override 6193 public final void attachApplication(IApplicationThread thread) { 6194 synchronized (this) { 6195 int callingPid = Binder.getCallingPid(); 6196 final long origId = Binder.clearCallingIdentity(); 6197 attachApplicationLocked(thread, callingPid); 6198 Binder.restoreCallingIdentity(origId); 6199 } 6200 } 6201 6202 @Override 6203 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6204 final long origId = Binder.clearCallingIdentity(); 6205 synchronized (this) { 6206 ActivityStack stack = ActivityRecord.getStackLocked(token); 6207 if (stack != null) { 6208 ActivityRecord r = 6209 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6210 if (stopProfiling) { 6211 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6212 try { 6213 mProfileFd.close(); 6214 } catch (IOException e) { 6215 } 6216 clearProfilerLocked(); 6217 } 6218 } 6219 } 6220 } 6221 Binder.restoreCallingIdentity(origId); 6222 } 6223 6224 void postEnableScreenAfterBootLocked() { 6225 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6226 } 6227 6228 void enableScreenAfterBoot() { 6229 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6230 SystemClock.uptimeMillis()); 6231 mWindowManager.enableScreenAfterBoot(); 6232 6233 synchronized (this) { 6234 updateEventDispatchingLocked(); 6235 } 6236 } 6237 6238 @Override 6239 public void showBootMessage(final CharSequence msg, final boolean always) { 6240 enforceNotIsolatedCaller("showBootMessage"); 6241 mWindowManager.showBootMessage(msg, always); 6242 } 6243 6244 @Override 6245 public void keyguardWaitingForActivityDrawn() { 6246 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6247 final long token = Binder.clearCallingIdentity(); 6248 try { 6249 synchronized (this) { 6250 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6251 mWindowManager.keyguardWaitingForActivityDrawn(); 6252 mKeyguardWaitingForDraw = true; 6253 } 6254 } finally { 6255 Binder.restoreCallingIdentity(token); 6256 } 6257 } 6258 6259 final void finishBooting() { 6260 synchronized (this) { 6261 if (!mBootAnimationComplete) { 6262 mCallFinishBooting = true; 6263 return; 6264 } 6265 mCallFinishBooting = false; 6266 } 6267 6268 // Register receivers to handle package update events 6269 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6270 6271 // Let system services know. 6272 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6273 6274 synchronized (this) { 6275 // Ensure that any processes we had put on hold are now started 6276 // up. 6277 final int NP = mProcessesOnHold.size(); 6278 if (NP > 0) { 6279 ArrayList<ProcessRecord> procs = 6280 new ArrayList<ProcessRecord>(mProcessesOnHold); 6281 for (int ip=0; ip<NP; ip++) { 6282 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6283 + procs.get(ip)); 6284 startProcessLocked(procs.get(ip), "on-hold", null); 6285 } 6286 } 6287 6288 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6289 // Start looking for apps that are abusing wake locks. 6290 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6291 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6292 // Tell anyone interested that we are done booting! 6293 SystemProperties.set("sys.boot_completed", "1"); 6294 SystemProperties.set("dev.bootcomplete", "1"); 6295 for (int i=0; i<mStartedUsers.size(); i++) { 6296 UserStartedState uss = mStartedUsers.valueAt(i); 6297 if (uss.mState == UserStartedState.STATE_BOOTING) { 6298 uss.mState = UserStartedState.STATE_RUNNING; 6299 final int userId = mStartedUsers.keyAt(i); 6300 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6301 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6302 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6303 broadcastIntentLocked(null, null, intent, null, 6304 new IIntentReceiver.Stub() { 6305 @Override 6306 public void performReceive(Intent intent, int resultCode, 6307 String data, Bundle extras, boolean ordered, 6308 boolean sticky, int sendingUser) { 6309 synchronized (ActivityManagerService.this) { 6310 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6311 true, false); 6312 } 6313 } 6314 }, 6315 0, null, null, 6316 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6317 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6318 userId); 6319 } 6320 } 6321 scheduleStartProfilesLocked(); 6322 } 6323 } 6324 } 6325 6326 @Override 6327 public void bootAnimationComplete() { 6328 final boolean callFinishBooting; 6329 synchronized (this) { 6330 callFinishBooting = mCallFinishBooting; 6331 mBootAnimationComplete = true; 6332 } 6333 if (callFinishBooting) { 6334 finishBooting(); 6335 } 6336 } 6337 6338 final void ensureBootCompleted() { 6339 boolean booting; 6340 boolean enableScreen; 6341 synchronized (this) { 6342 booting = mBooting; 6343 mBooting = false; 6344 enableScreen = !mBooted; 6345 mBooted = true; 6346 } 6347 6348 if (booting) { 6349 finishBooting(); 6350 } 6351 6352 if (enableScreen) { 6353 enableScreenAfterBoot(); 6354 } 6355 } 6356 6357 @Override 6358 public final void activityResumed(IBinder token) { 6359 final long origId = Binder.clearCallingIdentity(); 6360 synchronized(this) { 6361 ActivityStack stack = ActivityRecord.getStackLocked(token); 6362 if (stack != null) { 6363 ActivityRecord.activityResumedLocked(token); 6364 } 6365 } 6366 Binder.restoreCallingIdentity(origId); 6367 } 6368 6369 @Override 6370 public final void activityPaused(IBinder token) { 6371 final long origId = Binder.clearCallingIdentity(); 6372 synchronized(this) { 6373 ActivityStack stack = ActivityRecord.getStackLocked(token); 6374 if (stack != null) { 6375 stack.activityPausedLocked(token, false); 6376 } 6377 } 6378 Binder.restoreCallingIdentity(origId); 6379 } 6380 6381 @Override 6382 public final void activityStopped(IBinder token, Bundle icicle, 6383 PersistableBundle persistentState, CharSequence description) { 6384 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6385 6386 // Refuse possible leaked file descriptors 6387 if (icicle != null && icicle.hasFileDescriptors()) { 6388 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6389 } 6390 6391 final long origId = Binder.clearCallingIdentity(); 6392 6393 synchronized (this) { 6394 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6395 if (r != null) { 6396 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6397 } 6398 } 6399 6400 trimApplications(); 6401 6402 Binder.restoreCallingIdentity(origId); 6403 } 6404 6405 @Override 6406 public final void activityDestroyed(IBinder token) { 6407 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6408 synchronized (this) { 6409 ActivityStack stack = ActivityRecord.getStackLocked(token); 6410 if (stack != null) { 6411 stack.activityDestroyedLocked(token); 6412 } 6413 } 6414 } 6415 6416 @Override 6417 public final void backgroundResourcesReleased(IBinder token) { 6418 final long origId = Binder.clearCallingIdentity(); 6419 try { 6420 synchronized (this) { 6421 ActivityStack stack = ActivityRecord.getStackLocked(token); 6422 if (stack != null) { 6423 stack.backgroundResourcesReleased(token); 6424 } 6425 } 6426 } finally { 6427 Binder.restoreCallingIdentity(origId); 6428 } 6429 } 6430 6431 @Override 6432 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6433 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6434 } 6435 6436 @Override 6437 public final void notifyEnterAnimationComplete(IBinder token) { 6438 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6439 } 6440 6441 @Override 6442 public String getCallingPackage(IBinder token) { 6443 synchronized (this) { 6444 ActivityRecord r = getCallingRecordLocked(token); 6445 return r != null ? r.info.packageName : null; 6446 } 6447 } 6448 6449 @Override 6450 public ComponentName getCallingActivity(IBinder token) { 6451 synchronized (this) { 6452 ActivityRecord r = getCallingRecordLocked(token); 6453 return r != null ? r.intent.getComponent() : null; 6454 } 6455 } 6456 6457 private ActivityRecord getCallingRecordLocked(IBinder token) { 6458 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6459 if (r == null) { 6460 return null; 6461 } 6462 return r.resultTo; 6463 } 6464 6465 @Override 6466 public ComponentName getActivityClassForToken(IBinder token) { 6467 synchronized(this) { 6468 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6469 if (r == null) { 6470 return null; 6471 } 6472 return r.intent.getComponent(); 6473 } 6474 } 6475 6476 @Override 6477 public String getPackageForToken(IBinder token) { 6478 synchronized(this) { 6479 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6480 if (r == null) { 6481 return null; 6482 } 6483 return r.packageName; 6484 } 6485 } 6486 6487 @Override 6488 public IIntentSender getIntentSender(int type, 6489 String packageName, IBinder token, String resultWho, 6490 int requestCode, Intent[] intents, String[] resolvedTypes, 6491 int flags, Bundle options, int userId) { 6492 enforceNotIsolatedCaller("getIntentSender"); 6493 // Refuse possible leaked file descriptors 6494 if (intents != null) { 6495 if (intents.length < 1) { 6496 throw new IllegalArgumentException("Intents array length must be >= 1"); 6497 } 6498 for (int i=0; i<intents.length; i++) { 6499 Intent intent = intents[i]; 6500 if (intent != null) { 6501 if (intent.hasFileDescriptors()) { 6502 throw new IllegalArgumentException("File descriptors passed in Intent"); 6503 } 6504 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6505 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6506 throw new IllegalArgumentException( 6507 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6508 } 6509 intents[i] = new Intent(intent); 6510 } 6511 } 6512 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6513 throw new IllegalArgumentException( 6514 "Intent array length does not match resolvedTypes length"); 6515 } 6516 } 6517 if (options != null) { 6518 if (options.hasFileDescriptors()) { 6519 throw new IllegalArgumentException("File descriptors passed in options"); 6520 } 6521 } 6522 6523 synchronized(this) { 6524 int callingUid = Binder.getCallingUid(); 6525 int origUserId = userId; 6526 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6527 type == ActivityManager.INTENT_SENDER_BROADCAST, 6528 ALLOW_NON_FULL, "getIntentSender", null); 6529 if (origUserId == UserHandle.USER_CURRENT) { 6530 // We don't want to evaluate this until the pending intent is 6531 // actually executed. However, we do want to always do the 6532 // security checking for it above. 6533 userId = UserHandle.USER_CURRENT; 6534 } 6535 try { 6536 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6537 int uid = AppGlobals.getPackageManager() 6538 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6539 if (!UserHandle.isSameApp(callingUid, uid)) { 6540 String msg = "Permission Denial: getIntentSender() from pid=" 6541 + Binder.getCallingPid() 6542 + ", uid=" + Binder.getCallingUid() 6543 + ", (need uid=" + uid + ")" 6544 + " is not allowed to send as package " + packageName; 6545 Slog.w(TAG, msg); 6546 throw new SecurityException(msg); 6547 } 6548 } 6549 6550 return getIntentSenderLocked(type, packageName, callingUid, userId, 6551 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6552 6553 } catch (RemoteException e) { 6554 throw new SecurityException(e); 6555 } 6556 } 6557 } 6558 6559 IIntentSender getIntentSenderLocked(int type, String packageName, 6560 int callingUid, int userId, IBinder token, String resultWho, 6561 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6562 Bundle options) { 6563 if (DEBUG_MU) 6564 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6565 ActivityRecord activity = null; 6566 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6567 activity = ActivityRecord.isInStackLocked(token); 6568 if (activity == null) { 6569 return null; 6570 } 6571 if (activity.finishing) { 6572 return null; 6573 } 6574 } 6575 6576 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6577 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6578 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6579 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6580 |PendingIntent.FLAG_UPDATE_CURRENT); 6581 6582 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6583 type, packageName, activity, resultWho, 6584 requestCode, intents, resolvedTypes, flags, options, userId); 6585 WeakReference<PendingIntentRecord> ref; 6586 ref = mIntentSenderRecords.get(key); 6587 PendingIntentRecord rec = ref != null ? ref.get() : null; 6588 if (rec != null) { 6589 if (!cancelCurrent) { 6590 if (updateCurrent) { 6591 if (rec.key.requestIntent != null) { 6592 rec.key.requestIntent.replaceExtras(intents != null ? 6593 intents[intents.length - 1] : null); 6594 } 6595 if (intents != null) { 6596 intents[intents.length-1] = rec.key.requestIntent; 6597 rec.key.allIntents = intents; 6598 rec.key.allResolvedTypes = resolvedTypes; 6599 } else { 6600 rec.key.allIntents = null; 6601 rec.key.allResolvedTypes = null; 6602 } 6603 } 6604 return rec; 6605 } 6606 rec.canceled = true; 6607 mIntentSenderRecords.remove(key); 6608 } 6609 if (noCreate) { 6610 return rec; 6611 } 6612 rec = new PendingIntentRecord(this, key, callingUid); 6613 mIntentSenderRecords.put(key, rec.ref); 6614 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6615 if (activity.pendingResults == null) { 6616 activity.pendingResults 6617 = new HashSet<WeakReference<PendingIntentRecord>>(); 6618 } 6619 activity.pendingResults.add(rec.ref); 6620 } 6621 return rec; 6622 } 6623 6624 @Override 6625 public void cancelIntentSender(IIntentSender sender) { 6626 if (!(sender instanceof PendingIntentRecord)) { 6627 return; 6628 } 6629 synchronized(this) { 6630 PendingIntentRecord rec = (PendingIntentRecord)sender; 6631 try { 6632 int uid = AppGlobals.getPackageManager() 6633 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6634 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6635 String msg = "Permission Denial: cancelIntentSender() from pid=" 6636 + Binder.getCallingPid() 6637 + ", uid=" + Binder.getCallingUid() 6638 + " is not allowed to cancel packges " 6639 + rec.key.packageName; 6640 Slog.w(TAG, msg); 6641 throw new SecurityException(msg); 6642 } 6643 } catch (RemoteException e) { 6644 throw new SecurityException(e); 6645 } 6646 cancelIntentSenderLocked(rec, true); 6647 } 6648 } 6649 6650 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6651 rec.canceled = true; 6652 mIntentSenderRecords.remove(rec.key); 6653 if (cleanActivity && rec.key.activity != null) { 6654 rec.key.activity.pendingResults.remove(rec.ref); 6655 } 6656 } 6657 6658 @Override 6659 public String getPackageForIntentSender(IIntentSender pendingResult) { 6660 if (!(pendingResult instanceof PendingIntentRecord)) { 6661 return null; 6662 } 6663 try { 6664 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6665 return res.key.packageName; 6666 } catch (ClassCastException e) { 6667 } 6668 return null; 6669 } 6670 6671 @Override 6672 public int getUidForIntentSender(IIntentSender sender) { 6673 if (sender instanceof PendingIntentRecord) { 6674 try { 6675 PendingIntentRecord res = (PendingIntentRecord)sender; 6676 return res.uid; 6677 } catch (ClassCastException e) { 6678 } 6679 } 6680 return -1; 6681 } 6682 6683 @Override 6684 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6685 if (!(pendingResult instanceof PendingIntentRecord)) { 6686 return false; 6687 } 6688 try { 6689 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6690 if (res.key.allIntents == null) { 6691 return false; 6692 } 6693 for (int i=0; i<res.key.allIntents.length; i++) { 6694 Intent intent = res.key.allIntents[i]; 6695 if (intent.getPackage() != null && intent.getComponent() != null) { 6696 return false; 6697 } 6698 } 6699 return true; 6700 } catch (ClassCastException e) { 6701 } 6702 return false; 6703 } 6704 6705 @Override 6706 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6707 if (!(pendingResult instanceof PendingIntentRecord)) { 6708 return false; 6709 } 6710 try { 6711 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6712 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6713 return true; 6714 } 6715 return false; 6716 } catch (ClassCastException e) { 6717 } 6718 return false; 6719 } 6720 6721 @Override 6722 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6723 if (!(pendingResult instanceof PendingIntentRecord)) { 6724 return null; 6725 } 6726 try { 6727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6728 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6729 } catch (ClassCastException e) { 6730 } 6731 return null; 6732 } 6733 6734 @Override 6735 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6736 if (!(pendingResult instanceof PendingIntentRecord)) { 6737 return null; 6738 } 6739 try { 6740 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6741 Intent intent = res.key.requestIntent; 6742 if (intent != null) { 6743 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6744 || res.lastTagPrefix.equals(prefix))) { 6745 return res.lastTag; 6746 } 6747 res.lastTagPrefix = prefix; 6748 StringBuilder sb = new StringBuilder(128); 6749 if (prefix != null) { 6750 sb.append(prefix); 6751 } 6752 if (intent.getAction() != null) { 6753 sb.append(intent.getAction()); 6754 } else if (intent.getComponent() != null) { 6755 intent.getComponent().appendShortString(sb); 6756 } else { 6757 sb.append("?"); 6758 } 6759 return res.lastTag = sb.toString(); 6760 } 6761 } catch (ClassCastException e) { 6762 } 6763 return null; 6764 } 6765 6766 @Override 6767 public void setProcessLimit(int max) { 6768 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6769 "setProcessLimit()"); 6770 synchronized (this) { 6771 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6772 mProcessLimitOverride = max; 6773 } 6774 trimApplications(); 6775 } 6776 6777 @Override 6778 public int getProcessLimit() { 6779 synchronized (this) { 6780 return mProcessLimitOverride; 6781 } 6782 } 6783 6784 void foregroundTokenDied(ForegroundToken token) { 6785 synchronized (ActivityManagerService.this) { 6786 synchronized (mPidsSelfLocked) { 6787 ForegroundToken cur 6788 = mForegroundProcesses.get(token.pid); 6789 if (cur != token) { 6790 return; 6791 } 6792 mForegroundProcesses.remove(token.pid); 6793 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6794 if (pr == null) { 6795 return; 6796 } 6797 pr.forcingToForeground = null; 6798 updateProcessForegroundLocked(pr, false, false); 6799 } 6800 updateOomAdjLocked(); 6801 } 6802 } 6803 6804 @Override 6805 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6806 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6807 "setProcessForeground()"); 6808 synchronized(this) { 6809 boolean changed = false; 6810 6811 synchronized (mPidsSelfLocked) { 6812 ProcessRecord pr = mPidsSelfLocked.get(pid); 6813 if (pr == null && isForeground) { 6814 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6815 return; 6816 } 6817 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6818 if (oldToken != null) { 6819 oldToken.token.unlinkToDeath(oldToken, 0); 6820 mForegroundProcesses.remove(pid); 6821 if (pr != null) { 6822 pr.forcingToForeground = null; 6823 } 6824 changed = true; 6825 } 6826 if (isForeground && token != null) { 6827 ForegroundToken newToken = new ForegroundToken() { 6828 @Override 6829 public void binderDied() { 6830 foregroundTokenDied(this); 6831 } 6832 }; 6833 newToken.pid = pid; 6834 newToken.token = token; 6835 try { 6836 token.linkToDeath(newToken, 0); 6837 mForegroundProcesses.put(pid, newToken); 6838 pr.forcingToForeground = token; 6839 changed = true; 6840 } catch (RemoteException e) { 6841 // If the process died while doing this, we will later 6842 // do the cleanup with the process death link. 6843 } 6844 } 6845 } 6846 6847 if (changed) { 6848 updateOomAdjLocked(); 6849 } 6850 } 6851 } 6852 6853 // ========================================================= 6854 // PERMISSIONS 6855 // ========================================================= 6856 6857 static class PermissionController extends IPermissionController.Stub { 6858 ActivityManagerService mActivityManagerService; 6859 PermissionController(ActivityManagerService activityManagerService) { 6860 mActivityManagerService = activityManagerService; 6861 } 6862 6863 @Override 6864 public boolean checkPermission(String permission, int pid, int uid) { 6865 return mActivityManagerService.checkPermission(permission, pid, 6866 uid) == PackageManager.PERMISSION_GRANTED; 6867 } 6868 } 6869 6870 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6871 @Override 6872 public int checkComponentPermission(String permission, int pid, int uid, 6873 int owningUid, boolean exported) { 6874 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6875 owningUid, exported); 6876 } 6877 6878 @Override 6879 public Object getAMSLock() { 6880 return ActivityManagerService.this; 6881 } 6882 } 6883 6884 /** 6885 * This can be called with or without the global lock held. 6886 */ 6887 int checkComponentPermission(String permission, int pid, int uid, 6888 int owningUid, boolean exported) { 6889 // We might be performing an operation on behalf of an indirect binder 6890 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6891 // client identity accordingly before proceeding. 6892 Identity tlsIdentity = sCallerIdentity.get(); 6893 if (tlsIdentity != null) { 6894 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6895 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6896 uid = tlsIdentity.uid; 6897 pid = tlsIdentity.pid; 6898 } 6899 6900 if (pid == MY_PID) { 6901 return PackageManager.PERMISSION_GRANTED; 6902 } 6903 6904 return ActivityManager.checkComponentPermission(permission, uid, 6905 owningUid, exported); 6906 } 6907 6908 /** 6909 * As the only public entry point for permissions checking, this method 6910 * can enforce the semantic that requesting a check on a null global 6911 * permission is automatically denied. (Internally a null permission 6912 * string is used when calling {@link #checkComponentPermission} in cases 6913 * when only uid-based security is needed.) 6914 * 6915 * This can be called with or without the global lock held. 6916 */ 6917 @Override 6918 public int checkPermission(String permission, int pid, int uid) { 6919 if (permission == null) { 6920 return PackageManager.PERMISSION_DENIED; 6921 } 6922 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6923 } 6924 6925 /** 6926 * Binder IPC calls go through the public entry point. 6927 * This can be called with or without the global lock held. 6928 */ 6929 int checkCallingPermission(String permission) { 6930 return checkPermission(permission, 6931 Binder.getCallingPid(), 6932 UserHandle.getAppId(Binder.getCallingUid())); 6933 } 6934 6935 /** 6936 * This can be called with or without the global lock held. 6937 */ 6938 void enforceCallingPermission(String permission, String func) { 6939 if (checkCallingPermission(permission) 6940 == PackageManager.PERMISSION_GRANTED) { 6941 return; 6942 } 6943 6944 String msg = "Permission Denial: " + func + " from pid=" 6945 + Binder.getCallingPid() 6946 + ", uid=" + Binder.getCallingUid() 6947 + " requires " + permission; 6948 Slog.w(TAG, msg); 6949 throw new SecurityException(msg); 6950 } 6951 6952 /** 6953 * Determine if UID is holding permissions required to access {@link Uri} in 6954 * the given {@link ProviderInfo}. Final permission checking is always done 6955 * in {@link ContentProvider}. 6956 */ 6957 private final boolean checkHoldingPermissionsLocked( 6958 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6959 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6960 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6961 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6962 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6963 != PERMISSION_GRANTED) { 6964 return false; 6965 } 6966 } 6967 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6968 } 6969 6970 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6971 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6972 if (pi.applicationInfo.uid == uid) { 6973 return true; 6974 } else if (!pi.exported) { 6975 return false; 6976 } 6977 6978 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6979 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6980 try { 6981 // check if target holds top-level <provider> permissions 6982 if (!readMet && pi.readPermission != null && considerUidPermissions 6983 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6984 readMet = true; 6985 } 6986 if (!writeMet && pi.writePermission != null && considerUidPermissions 6987 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6988 writeMet = true; 6989 } 6990 6991 // track if unprotected read/write is allowed; any denied 6992 // <path-permission> below removes this ability 6993 boolean allowDefaultRead = pi.readPermission == null; 6994 boolean allowDefaultWrite = pi.writePermission == null; 6995 6996 // check if target holds any <path-permission> that match uri 6997 final PathPermission[] pps = pi.pathPermissions; 6998 if (pps != null) { 6999 final String path = grantUri.uri.getPath(); 7000 int i = pps.length; 7001 while (i > 0 && (!readMet || !writeMet)) { 7002 i--; 7003 PathPermission pp = pps[i]; 7004 if (pp.match(path)) { 7005 if (!readMet) { 7006 final String pprperm = pp.getReadPermission(); 7007 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7008 + pprperm + " for " + pp.getPath() 7009 + ": match=" + pp.match(path) 7010 + " check=" + pm.checkUidPermission(pprperm, uid)); 7011 if (pprperm != null) { 7012 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7013 == PERMISSION_GRANTED) { 7014 readMet = true; 7015 } else { 7016 allowDefaultRead = false; 7017 } 7018 } 7019 } 7020 if (!writeMet) { 7021 final String ppwperm = pp.getWritePermission(); 7022 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7023 + ppwperm + " for " + pp.getPath() 7024 + ": match=" + pp.match(path) 7025 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7026 if (ppwperm != null) { 7027 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7028 == PERMISSION_GRANTED) { 7029 writeMet = true; 7030 } else { 7031 allowDefaultWrite = false; 7032 } 7033 } 7034 } 7035 } 7036 } 7037 } 7038 7039 // grant unprotected <provider> read/write, if not blocked by 7040 // <path-permission> above 7041 if (allowDefaultRead) readMet = true; 7042 if (allowDefaultWrite) writeMet = true; 7043 7044 } catch (RemoteException e) { 7045 return false; 7046 } 7047 7048 return readMet && writeMet; 7049 } 7050 7051 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7052 ProviderInfo pi = null; 7053 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7054 if (cpr != null) { 7055 pi = cpr.info; 7056 } else { 7057 try { 7058 pi = AppGlobals.getPackageManager().resolveContentProvider( 7059 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7060 } catch (RemoteException ex) { 7061 } 7062 } 7063 return pi; 7064 } 7065 7066 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7067 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7068 if (targetUris != null) { 7069 return targetUris.get(grantUri); 7070 } 7071 return null; 7072 } 7073 7074 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7075 String targetPkg, int targetUid, GrantUri grantUri) { 7076 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7077 if (targetUris == null) { 7078 targetUris = Maps.newArrayMap(); 7079 mGrantedUriPermissions.put(targetUid, targetUris); 7080 } 7081 7082 UriPermission perm = targetUris.get(grantUri); 7083 if (perm == null) { 7084 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7085 targetUris.put(grantUri, perm); 7086 } 7087 7088 return perm; 7089 } 7090 7091 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7092 final int modeFlags) { 7093 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7094 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7095 : UriPermission.STRENGTH_OWNED; 7096 7097 // Root gets to do everything. 7098 if (uid == 0) { 7099 return true; 7100 } 7101 7102 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7103 if (perms == null) return false; 7104 7105 // First look for exact match 7106 final UriPermission exactPerm = perms.get(grantUri); 7107 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7108 return true; 7109 } 7110 7111 // No exact match, look for prefixes 7112 final int N = perms.size(); 7113 for (int i = 0; i < N; i++) { 7114 final UriPermission perm = perms.valueAt(i); 7115 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7116 && perm.getStrength(modeFlags) >= minStrength) { 7117 return true; 7118 } 7119 } 7120 7121 return false; 7122 } 7123 7124 /** 7125 * @param uri This uri must NOT contain an embedded userId. 7126 * @param userId The userId in which the uri is to be resolved. 7127 */ 7128 @Override 7129 public int checkUriPermission(Uri uri, int pid, int uid, 7130 final int modeFlags, int userId) { 7131 enforceNotIsolatedCaller("checkUriPermission"); 7132 7133 // Another redirected-binder-call permissions check as in 7134 // {@link checkComponentPermission}. 7135 Identity tlsIdentity = sCallerIdentity.get(); 7136 if (tlsIdentity != null) { 7137 uid = tlsIdentity.uid; 7138 pid = tlsIdentity.pid; 7139 } 7140 7141 // Our own process gets to do everything. 7142 if (pid == MY_PID) { 7143 return PackageManager.PERMISSION_GRANTED; 7144 } 7145 synchronized (this) { 7146 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7147 ? PackageManager.PERMISSION_GRANTED 7148 : PackageManager.PERMISSION_DENIED; 7149 } 7150 } 7151 7152 /** 7153 * Check if the targetPkg can be granted permission to access uri by 7154 * the callingUid using the given modeFlags. Throws a security exception 7155 * if callingUid is not allowed to do this. Returns the uid of the target 7156 * if the URI permission grant should be performed; returns -1 if it is not 7157 * needed (for example targetPkg already has permission to access the URI). 7158 * If you already know the uid of the target, you can supply it in 7159 * lastTargetUid else set that to -1. 7160 */ 7161 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7162 final int modeFlags, int lastTargetUid) { 7163 if (!Intent.isAccessUriMode(modeFlags)) { 7164 return -1; 7165 } 7166 7167 if (targetPkg != null) { 7168 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7169 "Checking grant " + targetPkg + " permission to " + grantUri); 7170 } 7171 7172 final IPackageManager pm = AppGlobals.getPackageManager(); 7173 7174 // If this is not a content: uri, we can't do anything with it. 7175 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7176 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7177 "Can't grant URI permission for non-content URI: " + grantUri); 7178 return -1; 7179 } 7180 7181 final String authority = grantUri.uri.getAuthority(); 7182 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7183 if (pi == null) { 7184 Slog.w(TAG, "No content provider found for permission check: " + 7185 grantUri.uri.toSafeString()); 7186 return -1; 7187 } 7188 7189 int targetUid = lastTargetUid; 7190 if (targetUid < 0 && targetPkg != null) { 7191 try { 7192 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7193 if (targetUid < 0) { 7194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7195 "Can't grant URI permission no uid for: " + targetPkg); 7196 return -1; 7197 } 7198 } catch (RemoteException ex) { 7199 return -1; 7200 } 7201 } 7202 7203 if (targetUid >= 0) { 7204 // First... does the target actually need this permission? 7205 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7206 // No need to grant the target this permission. 7207 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7208 "Target " + targetPkg + " already has full permission to " + grantUri); 7209 return -1; 7210 } 7211 } else { 7212 // First... there is no target package, so can anyone access it? 7213 boolean allowed = pi.exported; 7214 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7215 if (pi.readPermission != null) { 7216 allowed = false; 7217 } 7218 } 7219 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7220 if (pi.writePermission != null) { 7221 allowed = false; 7222 } 7223 } 7224 if (allowed) { 7225 return -1; 7226 } 7227 } 7228 7229 /* There is a special cross user grant if: 7230 * - The target is on another user. 7231 * - Apps on the current user can access the uri without any uid permissions. 7232 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7233 * grant uri permissions. 7234 */ 7235 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7236 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7237 modeFlags, false /*without considering the uid permissions*/); 7238 7239 // Second... is the provider allowing granting of URI permissions? 7240 if (!specialCrossUserGrant) { 7241 if (!pi.grantUriPermissions) { 7242 throw new SecurityException("Provider " + pi.packageName 7243 + "/" + pi.name 7244 + " does not allow granting of Uri permissions (uri " 7245 + grantUri + ")"); 7246 } 7247 if (pi.uriPermissionPatterns != null) { 7248 final int N = pi.uriPermissionPatterns.length; 7249 boolean allowed = false; 7250 for (int i=0; i<N; i++) { 7251 if (pi.uriPermissionPatterns[i] != null 7252 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7253 allowed = true; 7254 break; 7255 } 7256 } 7257 if (!allowed) { 7258 throw new SecurityException("Provider " + pi.packageName 7259 + "/" + pi.name 7260 + " does not allow granting of permission to path of Uri " 7261 + grantUri); 7262 } 7263 } 7264 } 7265 7266 // Third... does the caller itself have permission to access 7267 // this uri? 7268 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7269 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7270 // Require they hold a strong enough Uri permission 7271 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7272 throw new SecurityException("Uid " + callingUid 7273 + " does not have permission to uri " + grantUri); 7274 } 7275 } 7276 } 7277 return targetUid; 7278 } 7279 7280 /** 7281 * @param uri This uri must NOT contain an embedded userId. 7282 * @param userId The userId in which the uri is to be resolved. 7283 */ 7284 @Override 7285 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7286 final int modeFlags, int userId) { 7287 enforceNotIsolatedCaller("checkGrantUriPermission"); 7288 synchronized(this) { 7289 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7290 new GrantUri(userId, uri, false), modeFlags, -1); 7291 } 7292 } 7293 7294 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7295 final int modeFlags, UriPermissionOwner owner) { 7296 if (!Intent.isAccessUriMode(modeFlags)) { 7297 return; 7298 } 7299 7300 // So here we are: the caller has the assumed permission 7301 // to the uri, and the target doesn't. Let's now give this to 7302 // the target. 7303 7304 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7305 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7306 7307 final String authority = grantUri.uri.getAuthority(); 7308 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7309 if (pi == null) { 7310 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7311 return; 7312 } 7313 7314 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7315 grantUri.prefix = true; 7316 } 7317 final UriPermission perm = findOrCreateUriPermissionLocked( 7318 pi.packageName, targetPkg, targetUid, grantUri); 7319 perm.grantModes(modeFlags, owner); 7320 } 7321 7322 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7323 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7324 if (targetPkg == null) { 7325 throw new NullPointerException("targetPkg"); 7326 } 7327 int targetUid; 7328 final IPackageManager pm = AppGlobals.getPackageManager(); 7329 try { 7330 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7331 } catch (RemoteException ex) { 7332 return; 7333 } 7334 7335 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7336 targetUid); 7337 if (targetUid < 0) { 7338 return; 7339 } 7340 7341 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7342 owner); 7343 } 7344 7345 static class NeededUriGrants extends ArrayList<GrantUri> { 7346 final String targetPkg; 7347 final int targetUid; 7348 final int flags; 7349 7350 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7351 this.targetPkg = targetPkg; 7352 this.targetUid = targetUid; 7353 this.flags = flags; 7354 } 7355 } 7356 7357 /** 7358 * Like checkGrantUriPermissionLocked, but takes an Intent. 7359 */ 7360 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7361 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7362 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7363 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7364 + " clip=" + (intent != null ? intent.getClipData() : null) 7365 + " from " + intent + "; flags=0x" 7366 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7367 7368 if (targetPkg == null) { 7369 throw new NullPointerException("targetPkg"); 7370 } 7371 7372 if (intent == null) { 7373 return null; 7374 } 7375 Uri data = intent.getData(); 7376 ClipData clip = intent.getClipData(); 7377 if (data == null && clip == null) { 7378 return null; 7379 } 7380 // Default userId for uris in the intent (if they don't specify it themselves) 7381 int contentUserHint = intent.getContentUserHint(); 7382 if (contentUserHint == UserHandle.USER_CURRENT) { 7383 contentUserHint = UserHandle.getUserId(callingUid); 7384 } 7385 final IPackageManager pm = AppGlobals.getPackageManager(); 7386 int targetUid; 7387 if (needed != null) { 7388 targetUid = needed.targetUid; 7389 } else { 7390 try { 7391 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7392 } catch (RemoteException ex) { 7393 return null; 7394 } 7395 if (targetUid < 0) { 7396 if (DEBUG_URI_PERMISSION) { 7397 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7398 + " on user " + targetUserId); 7399 } 7400 return null; 7401 } 7402 } 7403 if (data != null) { 7404 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7405 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7406 targetUid); 7407 if (targetUid > 0) { 7408 if (needed == null) { 7409 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7410 } 7411 needed.add(grantUri); 7412 } 7413 } 7414 if (clip != null) { 7415 for (int i=0; i<clip.getItemCount(); i++) { 7416 Uri uri = clip.getItemAt(i).getUri(); 7417 if (uri != null) { 7418 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7419 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7420 targetUid); 7421 if (targetUid > 0) { 7422 if (needed == null) { 7423 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7424 } 7425 needed.add(grantUri); 7426 } 7427 } else { 7428 Intent clipIntent = clip.getItemAt(i).getIntent(); 7429 if (clipIntent != null) { 7430 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7431 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7432 if (newNeeded != null) { 7433 needed = newNeeded; 7434 } 7435 } 7436 } 7437 } 7438 } 7439 7440 return needed; 7441 } 7442 7443 /** 7444 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7445 */ 7446 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7447 UriPermissionOwner owner) { 7448 if (needed != null) { 7449 for (int i=0; i<needed.size(); i++) { 7450 GrantUri grantUri = needed.get(i); 7451 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7452 grantUri, needed.flags, owner); 7453 } 7454 } 7455 } 7456 7457 void grantUriPermissionFromIntentLocked(int callingUid, 7458 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7459 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7460 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7461 if (needed == null) { 7462 return; 7463 } 7464 7465 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7466 } 7467 7468 /** 7469 * @param uri This uri must NOT contain an embedded userId. 7470 * @param userId The userId in which the uri is to be resolved. 7471 */ 7472 @Override 7473 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7474 final int modeFlags, int userId) { 7475 enforceNotIsolatedCaller("grantUriPermission"); 7476 GrantUri grantUri = new GrantUri(userId, uri, false); 7477 synchronized(this) { 7478 final ProcessRecord r = getRecordForAppLocked(caller); 7479 if (r == null) { 7480 throw new SecurityException("Unable to find app for caller " 7481 + caller 7482 + " when granting permission to uri " + grantUri); 7483 } 7484 if (targetPkg == null) { 7485 throw new IllegalArgumentException("null target"); 7486 } 7487 if (grantUri == null) { 7488 throw new IllegalArgumentException("null uri"); 7489 } 7490 7491 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7492 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7493 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7494 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7495 7496 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7497 UserHandle.getUserId(r.uid)); 7498 } 7499 } 7500 7501 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7502 if (perm.modeFlags == 0) { 7503 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7504 perm.targetUid); 7505 if (perms != null) { 7506 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7507 "Removing " + perm.targetUid + " permission to " + perm.uri); 7508 7509 perms.remove(perm.uri); 7510 if (perms.isEmpty()) { 7511 mGrantedUriPermissions.remove(perm.targetUid); 7512 } 7513 } 7514 } 7515 } 7516 7517 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7518 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7519 7520 final IPackageManager pm = AppGlobals.getPackageManager(); 7521 final String authority = grantUri.uri.getAuthority(); 7522 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7523 if (pi == null) { 7524 Slog.w(TAG, "No content provider found for permission revoke: " 7525 + grantUri.toSafeString()); 7526 return; 7527 } 7528 7529 // Does the caller have this permission on the URI? 7530 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7531 // Have they don't have direct access to the URI, then revoke any URI 7532 // permissions that have been granted to them. 7533 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7534 if (perms != null) { 7535 boolean persistChanged = false; 7536 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7537 final UriPermission perm = it.next(); 7538 if (perm.uri.sourceUserId == grantUri.sourceUserId 7539 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7540 if (DEBUG_URI_PERMISSION) 7541 Slog.v(TAG, 7542 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7543 persistChanged |= perm.revokeModes( 7544 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7545 if (perm.modeFlags == 0) { 7546 it.remove(); 7547 } 7548 } 7549 } 7550 if (perms.isEmpty()) { 7551 mGrantedUriPermissions.remove(callingUid); 7552 } 7553 if (persistChanged) { 7554 schedulePersistUriGrants(); 7555 } 7556 } 7557 return; 7558 } 7559 7560 boolean persistChanged = false; 7561 7562 // Go through all of the permissions and remove any that match. 7563 int N = mGrantedUriPermissions.size(); 7564 for (int i = 0; i < N; i++) { 7565 final int targetUid = mGrantedUriPermissions.keyAt(i); 7566 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7567 7568 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7569 final UriPermission perm = it.next(); 7570 if (perm.uri.sourceUserId == grantUri.sourceUserId 7571 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7572 if (DEBUG_URI_PERMISSION) 7573 Slog.v(TAG, 7574 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7575 persistChanged |= perm.revokeModes( 7576 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7577 if (perm.modeFlags == 0) { 7578 it.remove(); 7579 } 7580 } 7581 } 7582 7583 if (perms.isEmpty()) { 7584 mGrantedUriPermissions.remove(targetUid); 7585 N--; 7586 i--; 7587 } 7588 } 7589 7590 if (persistChanged) { 7591 schedulePersistUriGrants(); 7592 } 7593 } 7594 7595 /** 7596 * @param uri This uri must NOT contain an embedded userId. 7597 * @param userId The userId in which the uri is to be resolved. 7598 */ 7599 @Override 7600 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7601 int userId) { 7602 enforceNotIsolatedCaller("revokeUriPermission"); 7603 synchronized(this) { 7604 final ProcessRecord r = getRecordForAppLocked(caller); 7605 if (r == null) { 7606 throw new SecurityException("Unable to find app for caller " 7607 + caller 7608 + " when revoking permission to uri " + uri); 7609 } 7610 if (uri == null) { 7611 Slog.w(TAG, "revokeUriPermission: null uri"); 7612 return; 7613 } 7614 7615 if (!Intent.isAccessUriMode(modeFlags)) { 7616 return; 7617 } 7618 7619 final IPackageManager pm = AppGlobals.getPackageManager(); 7620 final String authority = uri.getAuthority(); 7621 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7622 if (pi == null) { 7623 Slog.w(TAG, "No content provider found for permission revoke: " 7624 + uri.toSafeString()); 7625 return; 7626 } 7627 7628 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7629 } 7630 } 7631 7632 /** 7633 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7634 * given package. 7635 * 7636 * @param packageName Package name to match, or {@code null} to apply to all 7637 * packages. 7638 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7639 * to all users. 7640 * @param persistable If persistable grants should be removed. 7641 */ 7642 private void removeUriPermissionsForPackageLocked( 7643 String packageName, int userHandle, boolean persistable) { 7644 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7645 throw new IllegalArgumentException("Must narrow by either package or user"); 7646 } 7647 7648 boolean persistChanged = false; 7649 7650 int N = mGrantedUriPermissions.size(); 7651 for (int i = 0; i < N; i++) { 7652 final int targetUid = mGrantedUriPermissions.keyAt(i); 7653 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7654 7655 // Only inspect grants matching user 7656 if (userHandle == UserHandle.USER_ALL 7657 || userHandle == UserHandle.getUserId(targetUid)) { 7658 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7659 final UriPermission perm = it.next(); 7660 7661 // Only inspect grants matching package 7662 if (packageName == null || perm.sourcePkg.equals(packageName) 7663 || perm.targetPkg.equals(packageName)) { 7664 persistChanged |= perm.revokeModes( 7665 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7666 7667 // Only remove when no modes remain; any persisted grants 7668 // will keep this alive. 7669 if (perm.modeFlags == 0) { 7670 it.remove(); 7671 } 7672 } 7673 } 7674 7675 if (perms.isEmpty()) { 7676 mGrantedUriPermissions.remove(targetUid); 7677 N--; 7678 i--; 7679 } 7680 } 7681 } 7682 7683 if (persistChanged) { 7684 schedulePersistUriGrants(); 7685 } 7686 } 7687 7688 @Override 7689 public IBinder newUriPermissionOwner(String name) { 7690 enforceNotIsolatedCaller("newUriPermissionOwner"); 7691 synchronized(this) { 7692 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7693 return owner.getExternalTokenLocked(); 7694 } 7695 } 7696 7697 /** 7698 * @param uri This uri must NOT contain an embedded userId. 7699 * @param sourceUserId The userId in which the uri is to be resolved. 7700 * @param targetUserId The userId of the app that receives the grant. 7701 */ 7702 @Override 7703 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7704 final int modeFlags, int sourceUserId, int targetUserId) { 7705 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7706 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7707 synchronized(this) { 7708 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7709 if (owner == null) { 7710 throw new IllegalArgumentException("Unknown owner: " + token); 7711 } 7712 if (fromUid != Binder.getCallingUid()) { 7713 if (Binder.getCallingUid() != Process.myUid()) { 7714 // Only system code can grant URI permissions on behalf 7715 // of other users. 7716 throw new SecurityException("nice try"); 7717 } 7718 } 7719 if (targetPkg == null) { 7720 throw new IllegalArgumentException("null target"); 7721 } 7722 if (uri == null) { 7723 throw new IllegalArgumentException("null uri"); 7724 } 7725 7726 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7727 modeFlags, owner, targetUserId); 7728 } 7729 } 7730 7731 /** 7732 * @param uri This uri must NOT contain an embedded userId. 7733 * @param userId The userId in which the uri is to be resolved. 7734 */ 7735 @Override 7736 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7737 synchronized(this) { 7738 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7739 if (owner == null) { 7740 throw new IllegalArgumentException("Unknown owner: " + token); 7741 } 7742 7743 if (uri == null) { 7744 owner.removeUriPermissionsLocked(mode); 7745 } else { 7746 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7747 } 7748 } 7749 } 7750 7751 private void schedulePersistUriGrants() { 7752 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7753 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7754 10 * DateUtils.SECOND_IN_MILLIS); 7755 } 7756 } 7757 7758 private void writeGrantedUriPermissions() { 7759 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7760 7761 // Snapshot permissions so we can persist without lock 7762 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7763 synchronized (this) { 7764 final int size = mGrantedUriPermissions.size(); 7765 for (int i = 0; i < size; i++) { 7766 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7767 for (UriPermission perm : perms.values()) { 7768 if (perm.persistedModeFlags != 0) { 7769 persist.add(perm.snapshot()); 7770 } 7771 } 7772 } 7773 } 7774 7775 FileOutputStream fos = null; 7776 try { 7777 fos = mGrantFile.startWrite(); 7778 7779 XmlSerializer out = new FastXmlSerializer(); 7780 out.setOutput(fos, "utf-8"); 7781 out.startDocument(null, true); 7782 out.startTag(null, TAG_URI_GRANTS); 7783 for (UriPermission.Snapshot perm : persist) { 7784 out.startTag(null, TAG_URI_GRANT); 7785 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7786 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7787 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7788 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7789 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7790 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7791 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7792 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7793 out.endTag(null, TAG_URI_GRANT); 7794 } 7795 out.endTag(null, TAG_URI_GRANTS); 7796 out.endDocument(); 7797 7798 mGrantFile.finishWrite(fos); 7799 } catch (IOException e) { 7800 if (fos != null) { 7801 mGrantFile.failWrite(fos); 7802 } 7803 } 7804 } 7805 7806 private void readGrantedUriPermissionsLocked() { 7807 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7808 7809 final long now = System.currentTimeMillis(); 7810 7811 FileInputStream fis = null; 7812 try { 7813 fis = mGrantFile.openRead(); 7814 final XmlPullParser in = Xml.newPullParser(); 7815 in.setInput(fis, null); 7816 7817 int type; 7818 while ((type = in.next()) != END_DOCUMENT) { 7819 final String tag = in.getName(); 7820 if (type == START_TAG) { 7821 if (TAG_URI_GRANT.equals(tag)) { 7822 final int sourceUserId; 7823 final int targetUserId; 7824 final int userHandle = readIntAttribute(in, 7825 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7826 if (userHandle != UserHandle.USER_NULL) { 7827 // For backwards compatibility. 7828 sourceUserId = userHandle; 7829 targetUserId = userHandle; 7830 } else { 7831 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7832 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7833 } 7834 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7835 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7836 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7837 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7838 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7839 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7840 7841 // Sanity check that provider still belongs to source package 7842 final ProviderInfo pi = getProviderInfoLocked( 7843 uri.getAuthority(), sourceUserId); 7844 if (pi != null && sourcePkg.equals(pi.packageName)) { 7845 int targetUid = -1; 7846 try { 7847 targetUid = AppGlobals.getPackageManager() 7848 .getPackageUid(targetPkg, targetUserId); 7849 } catch (RemoteException e) { 7850 } 7851 if (targetUid != -1) { 7852 final UriPermission perm = findOrCreateUriPermissionLocked( 7853 sourcePkg, targetPkg, targetUid, 7854 new GrantUri(sourceUserId, uri, prefix)); 7855 perm.initPersistedModes(modeFlags, createdTime); 7856 } 7857 } else { 7858 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7859 + " but instead found " + pi); 7860 } 7861 } 7862 } 7863 } 7864 } catch (FileNotFoundException e) { 7865 // Missing grants is okay 7866 } catch (IOException e) { 7867 Log.wtf(TAG, "Failed reading Uri grants", e); 7868 } catch (XmlPullParserException e) { 7869 Log.wtf(TAG, "Failed reading Uri grants", e); 7870 } finally { 7871 IoUtils.closeQuietly(fis); 7872 } 7873 } 7874 7875 /** 7876 * @param uri This uri must NOT contain an embedded userId. 7877 * @param userId The userId in which the uri is to be resolved. 7878 */ 7879 @Override 7880 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7881 enforceNotIsolatedCaller("takePersistableUriPermission"); 7882 7883 Preconditions.checkFlagsArgument(modeFlags, 7884 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7885 7886 synchronized (this) { 7887 final int callingUid = Binder.getCallingUid(); 7888 boolean persistChanged = false; 7889 GrantUri grantUri = new GrantUri(userId, uri, false); 7890 7891 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7892 new GrantUri(userId, uri, false)); 7893 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7894 new GrantUri(userId, uri, true)); 7895 7896 final boolean exactValid = (exactPerm != null) 7897 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7898 final boolean prefixValid = (prefixPerm != null) 7899 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7900 7901 if (!(exactValid || prefixValid)) { 7902 throw new SecurityException("No persistable permission grants found for UID " 7903 + callingUid + " and Uri " + grantUri.toSafeString()); 7904 } 7905 7906 if (exactValid) { 7907 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7908 } 7909 if (prefixValid) { 7910 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7911 } 7912 7913 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7914 7915 if (persistChanged) { 7916 schedulePersistUriGrants(); 7917 } 7918 } 7919 } 7920 7921 /** 7922 * @param uri This uri must NOT contain an embedded userId. 7923 * @param userId The userId in which the uri is to be resolved. 7924 */ 7925 @Override 7926 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7927 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7928 7929 Preconditions.checkFlagsArgument(modeFlags, 7930 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7931 7932 synchronized (this) { 7933 final int callingUid = Binder.getCallingUid(); 7934 boolean persistChanged = false; 7935 7936 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7937 new GrantUri(userId, uri, false)); 7938 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7939 new GrantUri(userId, uri, true)); 7940 if (exactPerm == null && prefixPerm == null) { 7941 throw new SecurityException("No permission grants found for UID " + callingUid 7942 + " and Uri " + uri.toSafeString()); 7943 } 7944 7945 if (exactPerm != null) { 7946 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7947 removeUriPermissionIfNeededLocked(exactPerm); 7948 } 7949 if (prefixPerm != null) { 7950 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7951 removeUriPermissionIfNeededLocked(prefixPerm); 7952 } 7953 7954 if (persistChanged) { 7955 schedulePersistUriGrants(); 7956 } 7957 } 7958 } 7959 7960 /** 7961 * Prune any older {@link UriPermission} for the given UID until outstanding 7962 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7963 * 7964 * @return if any mutations occured that require persisting. 7965 */ 7966 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7967 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7968 if (perms == null) return false; 7969 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7970 7971 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7972 for (UriPermission perm : perms.values()) { 7973 if (perm.persistedModeFlags != 0) { 7974 persisted.add(perm); 7975 } 7976 } 7977 7978 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7979 if (trimCount <= 0) return false; 7980 7981 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7982 for (int i = 0; i < trimCount; i++) { 7983 final UriPermission perm = persisted.get(i); 7984 7985 if (DEBUG_URI_PERMISSION) { 7986 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7987 } 7988 7989 perm.releasePersistableModes(~0); 7990 removeUriPermissionIfNeededLocked(perm); 7991 } 7992 7993 return true; 7994 } 7995 7996 @Override 7997 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7998 String packageName, boolean incoming) { 7999 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8000 Preconditions.checkNotNull(packageName, "packageName"); 8001 8002 final int callingUid = Binder.getCallingUid(); 8003 final IPackageManager pm = AppGlobals.getPackageManager(); 8004 try { 8005 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8006 if (packageUid != callingUid) { 8007 throw new SecurityException( 8008 "Package " + packageName + " does not belong to calling UID " + callingUid); 8009 } 8010 } catch (RemoteException e) { 8011 throw new SecurityException("Failed to verify package name ownership"); 8012 } 8013 8014 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8015 synchronized (this) { 8016 if (incoming) { 8017 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8018 callingUid); 8019 if (perms == null) { 8020 Slog.w(TAG, "No permission grants found for " + packageName); 8021 } else { 8022 for (UriPermission perm : perms.values()) { 8023 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8024 result.add(perm.buildPersistedPublicApiObject()); 8025 } 8026 } 8027 } 8028 } else { 8029 final int size = mGrantedUriPermissions.size(); 8030 for (int i = 0; i < size; i++) { 8031 final ArrayMap<GrantUri, UriPermission> perms = 8032 mGrantedUriPermissions.valueAt(i); 8033 for (UriPermission perm : perms.values()) { 8034 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8035 result.add(perm.buildPersistedPublicApiObject()); 8036 } 8037 } 8038 } 8039 } 8040 } 8041 return new ParceledListSlice<android.content.UriPermission>(result); 8042 } 8043 8044 @Override 8045 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8046 synchronized (this) { 8047 ProcessRecord app = 8048 who != null ? getRecordForAppLocked(who) : null; 8049 if (app == null) return; 8050 8051 Message msg = Message.obtain(); 8052 msg.what = WAIT_FOR_DEBUGGER_MSG; 8053 msg.obj = app; 8054 msg.arg1 = waiting ? 1 : 0; 8055 mHandler.sendMessage(msg); 8056 } 8057 } 8058 8059 @Override 8060 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8061 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8062 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8063 outInfo.availMem = Process.getFreeMemory(); 8064 outInfo.totalMem = Process.getTotalMemory(); 8065 outInfo.threshold = homeAppMem; 8066 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8067 outInfo.hiddenAppThreshold = cachedAppMem; 8068 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8069 ProcessList.SERVICE_ADJ); 8070 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8071 ProcessList.VISIBLE_APP_ADJ); 8072 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8073 ProcessList.FOREGROUND_APP_ADJ); 8074 } 8075 8076 // ========================================================= 8077 // TASK MANAGEMENT 8078 // ========================================================= 8079 8080 @Override 8081 public List<IAppTask> getAppTasks(String callingPackage) { 8082 int callingUid = Binder.getCallingUid(); 8083 long ident = Binder.clearCallingIdentity(); 8084 8085 synchronized(this) { 8086 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8087 try { 8088 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8089 8090 final int N = mRecentTasks.size(); 8091 for (int i = 0; i < N; i++) { 8092 TaskRecord tr = mRecentTasks.get(i); 8093 // Skip tasks that do not match the caller. We don't need to verify 8094 // callingPackage, because we are also limiting to callingUid and know 8095 // that will limit to the correct security sandbox. 8096 if (tr.effectiveUid != callingUid) { 8097 continue; 8098 } 8099 Intent intent = tr.getBaseIntent(); 8100 if (intent == null || 8101 !callingPackage.equals(intent.getComponent().getPackageName())) { 8102 continue; 8103 } 8104 ActivityManager.RecentTaskInfo taskInfo = 8105 createRecentTaskInfoFromTaskRecord(tr); 8106 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8107 list.add(taskImpl); 8108 } 8109 } finally { 8110 Binder.restoreCallingIdentity(ident); 8111 } 8112 return list; 8113 } 8114 } 8115 8116 @Override 8117 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8118 final int callingUid = Binder.getCallingUid(); 8119 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8120 8121 synchronized(this) { 8122 if (localLOGV) Slog.v( 8123 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8124 8125 final boolean allowed = checkCallingPermission( 8126 android.Manifest.permission.GET_TASKS) 8127 == PackageManager.PERMISSION_GRANTED; 8128 if (!allowed) { 8129 Slog.w(TAG, "getTasks: caller " + callingUid 8130 + " does not hold GET_TASKS; limiting output"); 8131 } 8132 8133 // TODO: Improve with MRU list from all ActivityStacks. 8134 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8135 } 8136 8137 return list; 8138 } 8139 8140 TaskRecord getMostRecentTask() { 8141 return mRecentTasks.get(0); 8142 } 8143 8144 /** 8145 * Creates a new RecentTaskInfo from a TaskRecord. 8146 */ 8147 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8148 // Update the task description to reflect any changes in the task stack 8149 tr.updateTaskDescription(); 8150 8151 // Compose the recent task info 8152 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8153 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8154 rti.persistentId = tr.taskId; 8155 rti.baseIntent = new Intent(tr.getBaseIntent()); 8156 rti.origActivity = tr.origActivity; 8157 rti.description = tr.lastDescription; 8158 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8159 rti.userId = tr.userId; 8160 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8161 rti.firstActiveTime = tr.firstActiveTime; 8162 rti.lastActiveTime = tr.lastActiveTime; 8163 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8164 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8165 return rti; 8166 } 8167 8168 @Override 8169 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8170 final int callingUid = Binder.getCallingUid(); 8171 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8172 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8173 8174 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8175 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8176 synchronized (this) { 8177 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8178 == PackageManager.PERMISSION_GRANTED; 8179 if (!allowed) { 8180 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8181 + " does not hold GET_TASKS; limiting output"); 8182 } 8183 final boolean detailed = checkCallingPermission( 8184 android.Manifest.permission.GET_DETAILED_TASKS) 8185 == PackageManager.PERMISSION_GRANTED; 8186 8187 final int N = mRecentTasks.size(); 8188 ArrayList<ActivityManager.RecentTaskInfo> res 8189 = new ArrayList<ActivityManager.RecentTaskInfo>( 8190 maxNum < N ? maxNum : N); 8191 8192 final Set<Integer> includedUsers; 8193 if (includeProfiles) { 8194 includedUsers = getProfileIdsLocked(userId); 8195 } else { 8196 includedUsers = new HashSet<Integer>(); 8197 } 8198 includedUsers.add(Integer.valueOf(userId)); 8199 8200 for (int i=0; i<N && maxNum > 0; i++) { 8201 TaskRecord tr = mRecentTasks.get(i); 8202 // Only add calling user or related users recent tasks 8203 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8204 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8205 continue; 8206 } 8207 8208 // Return the entry if desired by the caller. We always return 8209 // the first entry, because callers always expect this to be the 8210 // foreground app. We may filter others if the caller has 8211 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8212 // we should exclude the entry. 8213 8214 if (i == 0 8215 || withExcluded 8216 || (tr.intent == null) 8217 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8218 == 0)) { 8219 if (!allowed) { 8220 // If the caller doesn't have the GET_TASKS permission, then only 8221 // allow them to see a small subset of tasks -- their own and home. 8222 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8223 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8224 continue; 8225 } 8226 } 8227 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8228 if (tr.stack != null && tr.stack.isHomeStack()) { 8229 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8230 continue; 8231 } 8232 } 8233 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8234 // Don't include auto remove tasks that are finished or finishing. 8235 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8236 + tr); 8237 continue; 8238 } 8239 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8240 && !tr.isAvailable) { 8241 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8242 continue; 8243 } 8244 8245 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8246 if (!detailed) { 8247 rti.baseIntent.replaceExtras((Bundle)null); 8248 } 8249 8250 res.add(rti); 8251 maxNum--; 8252 } 8253 } 8254 return res; 8255 } 8256 } 8257 8258 private TaskRecord recentTaskForIdLocked(int id) { 8259 final int N = mRecentTasks.size(); 8260 for (int i=0; i<N; i++) { 8261 TaskRecord tr = mRecentTasks.get(i); 8262 if (tr.taskId == id) { 8263 return tr; 8264 } 8265 } 8266 return null; 8267 } 8268 8269 @Override 8270 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8271 synchronized (this) { 8272 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8273 "getTaskThumbnail()"); 8274 TaskRecord tr = recentTaskForIdLocked(id); 8275 if (tr != null) { 8276 return tr.getTaskThumbnailLocked(); 8277 } 8278 } 8279 return null; 8280 } 8281 8282 @Override 8283 public int addAppTask(IBinder activityToken, Intent intent, 8284 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8285 final int callingUid = Binder.getCallingUid(); 8286 final long callingIdent = Binder.clearCallingIdentity(); 8287 8288 try { 8289 synchronized (this) { 8290 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8291 if (r == null) { 8292 throw new IllegalArgumentException("Activity does not exist; token=" 8293 + activityToken); 8294 } 8295 ComponentName comp = intent.getComponent(); 8296 if (comp == null) { 8297 throw new IllegalArgumentException("Intent " + intent 8298 + " must specify explicit component"); 8299 } 8300 if (thumbnail.getWidth() != mThumbnailWidth 8301 || thumbnail.getHeight() != mThumbnailHeight) { 8302 throw new IllegalArgumentException("Bad thumbnail size: got " 8303 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8304 + mThumbnailWidth + "x" + mThumbnailHeight); 8305 } 8306 if (intent.getSelector() != null) { 8307 intent.setSelector(null); 8308 } 8309 if (intent.getSourceBounds() != null) { 8310 intent.setSourceBounds(null); 8311 } 8312 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8313 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8314 // The caller has added this as an auto-remove task... that makes no 8315 // sense, so turn off auto-remove. 8316 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8317 } 8318 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8319 // Must be a new task. 8320 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8321 } 8322 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8323 mLastAddedTaskActivity = null; 8324 } 8325 ActivityInfo ainfo = mLastAddedTaskActivity; 8326 if (ainfo == null) { 8327 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8328 comp, 0, UserHandle.getUserId(callingUid)); 8329 if (ainfo.applicationInfo.uid != callingUid) { 8330 throw new SecurityException( 8331 "Can't add task for another application: target uid=" 8332 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8333 } 8334 } 8335 8336 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8337 intent, description); 8338 8339 int trimIdx = trimRecentsForTask(task, false); 8340 if (trimIdx >= 0) { 8341 // If this would have caused a trim, then we'll abort because that 8342 // means it would be added at the end of the list but then just removed. 8343 return -1; 8344 } 8345 8346 final int N = mRecentTasks.size(); 8347 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8348 final TaskRecord tr = mRecentTasks.remove(N - 1); 8349 tr.removedFromRecents(mTaskPersister); 8350 } 8351 8352 task.inRecents = true; 8353 mRecentTasks.add(task); 8354 r.task.stack.addTask(task, false, false); 8355 8356 task.setLastThumbnail(thumbnail); 8357 task.freeLastThumbnail(); 8358 8359 return task.taskId; 8360 } 8361 } finally { 8362 Binder.restoreCallingIdentity(callingIdent); 8363 } 8364 } 8365 8366 @Override 8367 public Point getAppTaskThumbnailSize() { 8368 synchronized (this) { 8369 return new Point(mThumbnailWidth, mThumbnailHeight); 8370 } 8371 } 8372 8373 @Override 8374 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8375 synchronized (this) { 8376 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8377 if (r != null) { 8378 r.setTaskDescription(td); 8379 r.task.updateTaskDescription(); 8380 } 8381 } 8382 } 8383 8384 @Override 8385 public Bitmap getTaskDescriptionIcon(String filename) { 8386 return mTaskPersister.getTaskDescriptionIcon(filename); 8387 } 8388 8389 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8390 mRecentTasks.remove(tr); 8391 tr.removedFromRecents(mTaskPersister); 8392 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8393 Intent baseIntent = new Intent( 8394 tr.intent != null ? tr.intent : tr.affinityIntent); 8395 ComponentName component = baseIntent.getComponent(); 8396 if (component == null) { 8397 Slog.w(TAG, "Now component for base intent of task: " + tr); 8398 return; 8399 } 8400 8401 // Find any running services associated with this app. 8402 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8403 8404 if (killProcesses) { 8405 // Find any running processes associated with this app. 8406 final String pkg = component.getPackageName(); 8407 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8408 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8409 for (int i=0; i<pmap.size(); i++) { 8410 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8411 for (int j=0; j<uids.size(); j++) { 8412 ProcessRecord proc = uids.valueAt(j); 8413 if (proc.userId != tr.userId) { 8414 continue; 8415 } 8416 if (!proc.pkgList.containsKey(pkg)) { 8417 continue; 8418 } 8419 procs.add(proc); 8420 } 8421 } 8422 8423 // Kill the running processes. 8424 for (int i=0; i<procs.size(); i++) { 8425 ProcessRecord pr = procs.get(i); 8426 if (pr == mHomeProcess) { 8427 // Don't kill the home process along with tasks from the same package. 8428 continue; 8429 } 8430 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8431 pr.kill("remove task", true); 8432 } else { 8433 pr.waitingToKill = "remove task"; 8434 } 8435 } 8436 } 8437 } 8438 8439 /** 8440 * Removes the task with the specified task id. 8441 * 8442 * @param taskId Identifier of the task to be removed. 8443 * @param flags Additional operational flags. May be 0 or 8444 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8445 * @return Returns true if the given task was found and removed. 8446 */ 8447 private boolean removeTaskByIdLocked(int taskId, int flags) { 8448 TaskRecord tr = recentTaskForIdLocked(taskId); 8449 if (tr != null) { 8450 tr.removeTaskActivitiesLocked(); 8451 cleanUpRemovedTaskLocked(tr, flags); 8452 if (tr.isPersistable) { 8453 notifyTaskPersisterLocked(null, true); 8454 } 8455 return true; 8456 } 8457 return false; 8458 } 8459 8460 @Override 8461 public boolean removeTask(int taskId, int flags) { 8462 synchronized (this) { 8463 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8464 "removeTask()"); 8465 long ident = Binder.clearCallingIdentity(); 8466 try { 8467 return removeTaskByIdLocked(taskId, flags); 8468 } finally { 8469 Binder.restoreCallingIdentity(ident); 8470 } 8471 } 8472 } 8473 8474 /** 8475 * TODO: Add mController hook 8476 */ 8477 @Override 8478 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8479 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8480 "moveTaskToFront()"); 8481 8482 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8483 synchronized(this) { 8484 moveTaskToFrontLocked(taskId, flags, options); 8485 } 8486 } 8487 8488 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8489 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8490 Binder.getCallingUid(), -1, -1, "Task to front")) { 8491 ActivityOptions.abort(options); 8492 return; 8493 } 8494 final long origId = Binder.clearCallingIdentity(); 8495 try { 8496 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8497 if (task == null) { 8498 return; 8499 } 8500 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8501 mStackSupervisor.showLockTaskToast(); 8502 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8503 return; 8504 } 8505 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8506 if (prev != null && prev.isRecentsActivity()) { 8507 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8508 } 8509 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8510 } finally { 8511 Binder.restoreCallingIdentity(origId); 8512 } 8513 ActivityOptions.abort(options); 8514 } 8515 8516 @Override 8517 public void moveTaskToBack(int taskId) { 8518 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8519 "moveTaskToBack()"); 8520 8521 synchronized(this) { 8522 TaskRecord tr = recentTaskForIdLocked(taskId); 8523 if (tr != null) { 8524 if (tr == mStackSupervisor.mLockTaskModeTask) { 8525 mStackSupervisor.showLockTaskToast(); 8526 return; 8527 } 8528 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8529 ActivityStack stack = tr.stack; 8530 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8531 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8532 Binder.getCallingUid(), -1, -1, "Task to back")) { 8533 return; 8534 } 8535 } 8536 final long origId = Binder.clearCallingIdentity(); 8537 try { 8538 stack.moveTaskToBackLocked(taskId, null); 8539 } finally { 8540 Binder.restoreCallingIdentity(origId); 8541 } 8542 } 8543 } 8544 } 8545 8546 /** 8547 * Moves an activity, and all of the other activities within the same task, to the bottom 8548 * of the history stack. The activity's order within the task is unchanged. 8549 * 8550 * @param token A reference to the activity we wish to move 8551 * @param nonRoot If false then this only works if the activity is the root 8552 * of a task; if true it will work for any activity in a task. 8553 * @return Returns true if the move completed, false if not. 8554 */ 8555 @Override 8556 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8557 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8558 synchronized(this) { 8559 final long origId = Binder.clearCallingIdentity(); 8560 try { 8561 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8562 if (taskId >= 0) { 8563 if ((mStackSupervisor.mLockTaskModeTask != null) 8564 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8565 mStackSupervisor.showLockTaskToast(); 8566 return false; 8567 } 8568 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8569 } 8570 } finally { 8571 Binder.restoreCallingIdentity(origId); 8572 } 8573 } 8574 return false; 8575 } 8576 8577 @Override 8578 public void moveTaskBackwards(int task) { 8579 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8580 "moveTaskBackwards()"); 8581 8582 synchronized(this) { 8583 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8584 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8585 return; 8586 } 8587 final long origId = Binder.clearCallingIdentity(); 8588 moveTaskBackwardsLocked(task); 8589 Binder.restoreCallingIdentity(origId); 8590 } 8591 } 8592 8593 private final void moveTaskBackwardsLocked(int task) { 8594 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8595 } 8596 8597 @Override 8598 public IBinder getHomeActivityToken() throws RemoteException { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "getHomeActivityToken()"); 8601 synchronized (this) { 8602 return mStackSupervisor.getHomeActivityToken(); 8603 } 8604 } 8605 8606 @Override 8607 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8608 IActivityContainerCallback callback) throws RemoteException { 8609 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8610 "createActivityContainer()"); 8611 synchronized (this) { 8612 if (parentActivityToken == null) { 8613 throw new IllegalArgumentException("parent token must not be null"); 8614 } 8615 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8616 if (r == null) { 8617 return null; 8618 } 8619 if (callback == null) { 8620 throw new IllegalArgumentException("callback must not be null"); 8621 } 8622 return mStackSupervisor.createActivityContainer(r, callback); 8623 } 8624 } 8625 8626 @Override 8627 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8628 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8629 "deleteActivityContainer()"); 8630 synchronized (this) { 8631 mStackSupervisor.deleteActivityContainer(container); 8632 } 8633 } 8634 8635 @Override 8636 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8637 throws RemoteException { 8638 synchronized (this) { 8639 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8640 if (stack != null) { 8641 return stack.mActivityContainer; 8642 } 8643 return null; 8644 } 8645 } 8646 8647 @Override 8648 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8649 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8650 "moveTaskToStack()"); 8651 if (stackId == HOME_STACK_ID) { 8652 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8653 new RuntimeException("here").fillInStackTrace()); 8654 } 8655 synchronized (this) { 8656 long ident = Binder.clearCallingIdentity(); 8657 try { 8658 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8659 + stackId + " toTop=" + toTop); 8660 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8661 } finally { 8662 Binder.restoreCallingIdentity(ident); 8663 } 8664 } 8665 } 8666 8667 @Override 8668 public void resizeStack(int stackBoxId, Rect bounds) { 8669 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8670 "resizeStackBox()"); 8671 long ident = Binder.clearCallingIdentity(); 8672 try { 8673 mWindowManager.resizeStack(stackBoxId, bounds); 8674 } finally { 8675 Binder.restoreCallingIdentity(ident); 8676 } 8677 } 8678 8679 @Override 8680 public List<StackInfo> getAllStackInfos() { 8681 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8682 "getAllStackInfos()"); 8683 long ident = Binder.clearCallingIdentity(); 8684 try { 8685 synchronized (this) { 8686 return mStackSupervisor.getAllStackInfosLocked(); 8687 } 8688 } finally { 8689 Binder.restoreCallingIdentity(ident); 8690 } 8691 } 8692 8693 @Override 8694 public StackInfo getStackInfo(int stackId) { 8695 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8696 "getStackInfo()"); 8697 long ident = Binder.clearCallingIdentity(); 8698 try { 8699 synchronized (this) { 8700 return mStackSupervisor.getStackInfoLocked(stackId); 8701 } 8702 } finally { 8703 Binder.restoreCallingIdentity(ident); 8704 } 8705 } 8706 8707 @Override 8708 public boolean isInHomeStack(int taskId) { 8709 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8710 "getStackInfo()"); 8711 long ident = Binder.clearCallingIdentity(); 8712 try { 8713 synchronized (this) { 8714 TaskRecord tr = recentTaskForIdLocked(taskId); 8715 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8716 } 8717 } finally { 8718 Binder.restoreCallingIdentity(ident); 8719 } 8720 } 8721 8722 @Override 8723 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8724 synchronized(this) { 8725 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8726 } 8727 } 8728 8729 private boolean isLockTaskAuthorized(String pkg) { 8730 final DevicePolicyManager dpm = (DevicePolicyManager) 8731 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8732 try { 8733 int uid = mContext.getPackageManager().getPackageUid(pkg, 8734 Binder.getCallingUserHandle().getIdentifier()); 8735 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8736 } catch (NameNotFoundException e) { 8737 return false; 8738 } 8739 } 8740 8741 void startLockTaskMode(TaskRecord task) { 8742 final String pkg; 8743 synchronized (this) { 8744 pkg = task.intent.getComponent().getPackageName(); 8745 } 8746 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8747 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8748 final TaskRecord taskRecord = task; 8749 mHandler.post(new Runnable() { 8750 @Override 8751 public void run() { 8752 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8753 } 8754 }); 8755 return; 8756 } 8757 long ident = Binder.clearCallingIdentity(); 8758 try { 8759 synchronized (this) { 8760 // Since we lost lock on task, make sure it is still there. 8761 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8762 if (task != null) { 8763 if (!isSystemInitiated 8764 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8765 throw new IllegalArgumentException("Invalid task, not in foreground"); 8766 } 8767 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8768 } 8769 } 8770 } finally { 8771 Binder.restoreCallingIdentity(ident); 8772 } 8773 } 8774 8775 @Override 8776 public void startLockTaskMode(int taskId) { 8777 final TaskRecord task; 8778 long ident = Binder.clearCallingIdentity(); 8779 try { 8780 synchronized (this) { 8781 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8782 } 8783 } finally { 8784 Binder.restoreCallingIdentity(ident); 8785 } 8786 if (task != null) { 8787 startLockTaskMode(task); 8788 } 8789 } 8790 8791 @Override 8792 public void startLockTaskMode(IBinder token) { 8793 final TaskRecord task; 8794 long ident = Binder.clearCallingIdentity(); 8795 try { 8796 synchronized (this) { 8797 final ActivityRecord r = ActivityRecord.forToken(token); 8798 if (r == null) { 8799 return; 8800 } 8801 task = r.task; 8802 } 8803 } finally { 8804 Binder.restoreCallingIdentity(ident); 8805 } 8806 if (task != null) { 8807 startLockTaskMode(task); 8808 } 8809 } 8810 8811 @Override 8812 public void startLockTaskModeOnCurrent() throws RemoteException { 8813 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8814 "startLockTaskModeOnCurrent"); 8815 ActivityRecord r = null; 8816 synchronized (this) { 8817 r = mStackSupervisor.topRunningActivityLocked(); 8818 } 8819 startLockTaskMode(r.task); 8820 } 8821 8822 @Override 8823 public void stopLockTaskMode() { 8824 // Verify that the user matches the package of the intent for the TaskRecord 8825 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8826 // and stopLockTaskMode. 8827 final int callingUid = Binder.getCallingUid(); 8828 if (callingUid != Process.SYSTEM_UID) { 8829 try { 8830 String pkg = 8831 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8832 int uid = mContext.getPackageManager().getPackageUid(pkg, 8833 Binder.getCallingUserHandle().getIdentifier()); 8834 if (uid != callingUid) { 8835 throw new SecurityException("Invalid uid, expected " + uid); 8836 } 8837 } catch (NameNotFoundException e) { 8838 Log.d(TAG, "stopLockTaskMode " + e); 8839 return; 8840 } 8841 } 8842 long ident = Binder.clearCallingIdentity(); 8843 try { 8844 Log.d(TAG, "stopLockTaskMode"); 8845 // Stop lock task 8846 synchronized (this) { 8847 mStackSupervisor.setLockTaskModeLocked(null, false); 8848 } 8849 } finally { 8850 Binder.restoreCallingIdentity(ident); 8851 } 8852 } 8853 8854 @Override 8855 public void stopLockTaskModeOnCurrent() throws RemoteException { 8856 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8857 "stopLockTaskModeOnCurrent"); 8858 long ident = Binder.clearCallingIdentity(); 8859 try { 8860 stopLockTaskMode(); 8861 } finally { 8862 Binder.restoreCallingIdentity(ident); 8863 } 8864 } 8865 8866 @Override 8867 public boolean isInLockTaskMode() { 8868 synchronized (this) { 8869 return mStackSupervisor.isInLockTaskMode(); 8870 } 8871 } 8872 8873 // ========================================================= 8874 // CONTENT PROVIDERS 8875 // ========================================================= 8876 8877 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8878 List<ProviderInfo> providers = null; 8879 try { 8880 providers = AppGlobals.getPackageManager(). 8881 queryContentProviders(app.processName, app.uid, 8882 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8883 } catch (RemoteException ex) { 8884 } 8885 if (DEBUG_MU) 8886 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8887 int userId = app.userId; 8888 if (providers != null) { 8889 int N = providers.size(); 8890 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8891 for (int i=0; i<N; i++) { 8892 ProviderInfo cpi = 8893 (ProviderInfo)providers.get(i); 8894 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8895 cpi.name, cpi.flags); 8896 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8897 // This is a singleton provider, but a user besides the 8898 // default user is asking to initialize a process it runs 8899 // in... well, no, it doesn't actually run in this process, 8900 // it runs in the process of the default user. Get rid of it. 8901 providers.remove(i); 8902 N--; 8903 i--; 8904 continue; 8905 } 8906 8907 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8908 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8909 if (cpr == null) { 8910 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8911 mProviderMap.putProviderByClass(comp, cpr); 8912 } 8913 if (DEBUG_MU) 8914 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8915 app.pubProviders.put(cpi.name, cpr); 8916 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8917 // Don't add this if it is a platform component that is marked 8918 // to run in multiple processes, because this is actually 8919 // part of the framework so doesn't make sense to track as a 8920 // separate apk in the process. 8921 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8922 mProcessStats); 8923 } 8924 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8925 } 8926 } 8927 return providers; 8928 } 8929 8930 /** 8931 * Check if {@link ProcessRecord} has a possible chance at accessing the 8932 * given {@link ProviderInfo}. Final permission checking is always done 8933 * in {@link ContentProvider}. 8934 */ 8935 private final String checkContentProviderPermissionLocked( 8936 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8937 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8938 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8939 boolean checkedGrants = false; 8940 if (checkUser) { 8941 // Looking for cross-user grants before enforcing the typical cross-users permissions 8942 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8943 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8944 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8945 return null; 8946 } 8947 checkedGrants = true; 8948 } 8949 userId = handleIncomingUser(callingPid, callingUid, userId, 8950 false, ALLOW_NON_FULL, 8951 "checkContentProviderPermissionLocked " + cpi.authority, null); 8952 if (userId != tmpTargetUserId) { 8953 // When we actually went to determine the final targer user ID, this ended 8954 // up different than our initial check for the authority. This is because 8955 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8956 // SELF. So we need to re-check the grants again. 8957 checkedGrants = false; 8958 } 8959 } 8960 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8961 cpi.applicationInfo.uid, cpi.exported) 8962 == PackageManager.PERMISSION_GRANTED) { 8963 return null; 8964 } 8965 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8966 cpi.applicationInfo.uid, cpi.exported) 8967 == PackageManager.PERMISSION_GRANTED) { 8968 return null; 8969 } 8970 8971 PathPermission[] pps = cpi.pathPermissions; 8972 if (pps != null) { 8973 int i = pps.length; 8974 while (i > 0) { 8975 i--; 8976 PathPermission pp = pps[i]; 8977 String pprperm = pp.getReadPermission(); 8978 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8979 cpi.applicationInfo.uid, cpi.exported) 8980 == PackageManager.PERMISSION_GRANTED) { 8981 return null; 8982 } 8983 String ppwperm = pp.getWritePermission(); 8984 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8985 cpi.applicationInfo.uid, cpi.exported) 8986 == PackageManager.PERMISSION_GRANTED) { 8987 return null; 8988 } 8989 } 8990 } 8991 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8992 return null; 8993 } 8994 8995 String msg; 8996 if (!cpi.exported) { 8997 msg = "Permission Denial: opening provider " + cpi.name 8998 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8999 + ", uid=" + callingUid + ") that is not exported from uid " 9000 + cpi.applicationInfo.uid; 9001 } else { 9002 msg = "Permission Denial: opening provider " + cpi.name 9003 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9004 + ", uid=" + callingUid + ") requires " 9005 + cpi.readPermission + " or " + cpi.writePermission; 9006 } 9007 Slog.w(TAG, msg); 9008 return msg; 9009 } 9010 9011 /** 9012 * Returns if the ContentProvider has granted a uri to callingUid 9013 */ 9014 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9015 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9016 if (perms != null) { 9017 for (int i=perms.size()-1; i>=0; i--) { 9018 GrantUri grantUri = perms.keyAt(i); 9019 if (grantUri.sourceUserId == userId || !checkUser) { 9020 if (matchesProvider(grantUri.uri, cpi)) { 9021 return true; 9022 } 9023 } 9024 } 9025 } 9026 return false; 9027 } 9028 9029 /** 9030 * Returns true if the uri authority is one of the authorities specified in the provider. 9031 */ 9032 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9033 String uriAuth = uri.getAuthority(); 9034 String cpiAuth = cpi.authority; 9035 if (cpiAuth.indexOf(';') == -1) { 9036 return cpiAuth.equals(uriAuth); 9037 } 9038 String[] cpiAuths = cpiAuth.split(";"); 9039 int length = cpiAuths.length; 9040 for (int i = 0; i < length; i++) { 9041 if (cpiAuths[i].equals(uriAuth)) return true; 9042 } 9043 return false; 9044 } 9045 9046 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9047 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9048 if (r != null) { 9049 for (int i=0; i<r.conProviders.size(); i++) { 9050 ContentProviderConnection conn = r.conProviders.get(i); 9051 if (conn.provider == cpr) { 9052 if (DEBUG_PROVIDER) Slog.v(TAG, 9053 "Adding provider requested by " 9054 + r.processName + " from process " 9055 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9056 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9057 if (stable) { 9058 conn.stableCount++; 9059 conn.numStableIncs++; 9060 } else { 9061 conn.unstableCount++; 9062 conn.numUnstableIncs++; 9063 } 9064 return conn; 9065 } 9066 } 9067 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9068 if (stable) { 9069 conn.stableCount = 1; 9070 conn.numStableIncs = 1; 9071 } else { 9072 conn.unstableCount = 1; 9073 conn.numUnstableIncs = 1; 9074 } 9075 cpr.connections.add(conn); 9076 r.conProviders.add(conn); 9077 return conn; 9078 } 9079 cpr.addExternalProcessHandleLocked(externalProcessToken); 9080 return null; 9081 } 9082 9083 boolean decProviderCountLocked(ContentProviderConnection conn, 9084 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9085 if (conn != null) { 9086 cpr = conn.provider; 9087 if (DEBUG_PROVIDER) Slog.v(TAG, 9088 "Removing provider requested by " 9089 + conn.client.processName + " from process " 9090 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9091 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9092 if (stable) { 9093 conn.stableCount--; 9094 } else { 9095 conn.unstableCount--; 9096 } 9097 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9098 cpr.connections.remove(conn); 9099 conn.client.conProviders.remove(conn); 9100 return true; 9101 } 9102 return false; 9103 } 9104 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9105 return false; 9106 } 9107 9108 private void checkTime(long startTime, String where) { 9109 long now = SystemClock.elapsedRealtime(); 9110 if ((now-startTime) > 1000) { 9111 // If we are taking more than a second, log about it. 9112 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9113 } 9114 } 9115 9116 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9117 String name, IBinder token, boolean stable, int userId) { 9118 ContentProviderRecord cpr; 9119 ContentProviderConnection conn = null; 9120 ProviderInfo cpi = null; 9121 9122 synchronized(this) { 9123 long startTime = SystemClock.elapsedRealtime(); 9124 9125 ProcessRecord r = null; 9126 if (caller != null) { 9127 r = getRecordForAppLocked(caller); 9128 if (r == null) { 9129 throw new SecurityException( 9130 "Unable to find app for caller " + caller 9131 + " (pid=" + Binder.getCallingPid() 9132 + ") when getting content provider " + name); 9133 } 9134 } 9135 9136 boolean checkCrossUser = true; 9137 9138 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9139 9140 // First check if this content provider has been published... 9141 cpr = mProviderMap.getProviderByName(name, userId); 9142 // If that didn't work, check if it exists for user 0 and then 9143 // verify that it's a singleton provider before using it. 9144 if (cpr == null && userId != UserHandle.USER_OWNER) { 9145 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9146 if (cpr != null) { 9147 cpi = cpr.info; 9148 if (isSingleton(cpi.processName, cpi.applicationInfo, 9149 cpi.name, cpi.flags) 9150 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9151 userId = UserHandle.USER_OWNER; 9152 checkCrossUser = false; 9153 } else { 9154 cpr = null; 9155 cpi = null; 9156 } 9157 } 9158 } 9159 9160 boolean providerRunning = cpr != null; 9161 if (providerRunning) { 9162 cpi = cpr.info; 9163 String msg; 9164 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9165 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9166 != null) { 9167 throw new SecurityException(msg); 9168 } 9169 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9170 9171 if (r != null && cpr.canRunHere(r)) { 9172 // This provider has been published or is in the process 9173 // of being published... but it is also allowed to run 9174 // in the caller's process, so don't make a connection 9175 // and just let the caller instantiate its own instance. 9176 ContentProviderHolder holder = cpr.newHolder(null); 9177 // don't give caller the provider object, it needs 9178 // to make its own. 9179 holder.provider = null; 9180 return holder; 9181 } 9182 9183 final long origId = Binder.clearCallingIdentity(); 9184 9185 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9186 9187 // In this case the provider instance already exists, so we can 9188 // return it right away. 9189 conn = incProviderCountLocked(r, cpr, token, stable); 9190 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9191 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9192 // If this is a perceptible app accessing the provider, 9193 // make sure to count it as being accessed and thus 9194 // back up on the LRU list. This is good because 9195 // content providers are often expensive to start. 9196 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9197 updateLruProcessLocked(cpr.proc, false, null); 9198 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9199 } 9200 } 9201 9202 if (cpr.proc != null) { 9203 if (false) { 9204 if (cpr.name.flattenToShortString().equals( 9205 "com.android.providers.calendar/.CalendarProvider2")) { 9206 Slog.v(TAG, "****************** KILLING " 9207 + cpr.name.flattenToShortString()); 9208 Process.killProcess(cpr.proc.pid); 9209 } 9210 } 9211 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9212 boolean success = updateOomAdjLocked(cpr.proc); 9213 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9214 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9215 // NOTE: there is still a race here where a signal could be 9216 // pending on the process even though we managed to update its 9217 // adj level. Not sure what to do about this, but at least 9218 // the race is now smaller. 9219 if (!success) { 9220 // Uh oh... it looks like the provider's process 9221 // has been killed on us. We need to wait for a new 9222 // process to be started, and make sure its death 9223 // doesn't kill our process. 9224 Slog.i(TAG, 9225 "Existing provider " + cpr.name.flattenToShortString() 9226 + " is crashing; detaching " + r); 9227 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9228 checkTime(startTime, "getContentProviderImpl: before appDied"); 9229 appDiedLocked(cpr.proc); 9230 checkTime(startTime, "getContentProviderImpl: after appDied"); 9231 if (!lastRef) { 9232 // This wasn't the last ref our process had on 9233 // the provider... we have now been killed, bail. 9234 return null; 9235 } 9236 providerRunning = false; 9237 conn = null; 9238 } 9239 } 9240 9241 Binder.restoreCallingIdentity(origId); 9242 } 9243 9244 boolean singleton; 9245 if (!providerRunning) { 9246 try { 9247 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9248 cpi = AppGlobals.getPackageManager(). 9249 resolveContentProvider(name, 9250 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9251 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9252 } catch (RemoteException ex) { 9253 } 9254 if (cpi == null) { 9255 return null; 9256 } 9257 // If the provider is a singleton AND 9258 // (it's a call within the same user || the provider is a 9259 // privileged app) 9260 // Then allow connecting to the singleton provider 9261 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9262 cpi.name, cpi.flags) 9263 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9264 if (singleton) { 9265 userId = UserHandle.USER_OWNER; 9266 } 9267 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9268 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9269 9270 String msg; 9271 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9272 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9273 != null) { 9274 throw new SecurityException(msg); 9275 } 9276 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9277 9278 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9279 && !cpi.processName.equals("system")) { 9280 // If this content provider does not run in the system 9281 // process, and the system is not yet ready to run other 9282 // processes, then fail fast instead of hanging. 9283 throw new IllegalArgumentException( 9284 "Attempt to launch content provider before system ready"); 9285 } 9286 9287 // Make sure that the user who owns this provider is started. If not, 9288 // we don't want to allow it to run. 9289 if (mStartedUsers.get(userId) == null) { 9290 Slog.w(TAG, "Unable to launch app " 9291 + cpi.applicationInfo.packageName + "/" 9292 + cpi.applicationInfo.uid + " for provider " 9293 + name + ": user " + userId + " is stopped"); 9294 return null; 9295 } 9296 9297 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9298 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9299 cpr = mProviderMap.getProviderByClass(comp, userId); 9300 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9301 final boolean firstClass = cpr == null; 9302 if (firstClass) { 9303 try { 9304 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9305 ApplicationInfo ai = 9306 AppGlobals.getPackageManager(). 9307 getApplicationInfo( 9308 cpi.applicationInfo.packageName, 9309 STOCK_PM_FLAGS, userId); 9310 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9311 if (ai == null) { 9312 Slog.w(TAG, "No package info for content provider " 9313 + cpi.name); 9314 return null; 9315 } 9316 ai = getAppInfoForUser(ai, userId); 9317 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9318 } catch (RemoteException ex) { 9319 // pm is in same process, this will never happen. 9320 } 9321 } 9322 9323 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9324 9325 if (r != null && cpr.canRunHere(r)) { 9326 // If this is a multiprocess provider, then just return its 9327 // info and allow the caller to instantiate it. Only do 9328 // this if the provider is the same user as the caller's 9329 // process, or can run as root (so can be in any process). 9330 return cpr.newHolder(null); 9331 } 9332 9333 if (DEBUG_PROVIDER) { 9334 RuntimeException e = new RuntimeException("here"); 9335 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9336 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9337 } 9338 9339 // This is single process, and our app is now connecting to it. 9340 // See if we are already in the process of launching this 9341 // provider. 9342 final int N = mLaunchingProviders.size(); 9343 int i; 9344 for (i=0; i<N; i++) { 9345 if (mLaunchingProviders.get(i) == cpr) { 9346 break; 9347 } 9348 } 9349 9350 // If the provider is not already being launched, then get it 9351 // started. 9352 if (i >= N) { 9353 final long origId = Binder.clearCallingIdentity(); 9354 9355 try { 9356 // Content provider is now in use, its package can't be stopped. 9357 try { 9358 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9359 AppGlobals.getPackageManager().setPackageStoppedState( 9360 cpr.appInfo.packageName, false, userId); 9361 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9362 } catch (RemoteException e) { 9363 } catch (IllegalArgumentException e) { 9364 Slog.w(TAG, "Failed trying to unstop package " 9365 + cpr.appInfo.packageName + ": " + e); 9366 } 9367 9368 // Use existing process if already started 9369 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9370 ProcessRecord proc = getProcessRecordLocked( 9371 cpi.processName, cpr.appInfo.uid, false); 9372 if (proc != null && proc.thread != null) { 9373 if (DEBUG_PROVIDER) { 9374 Slog.d(TAG, "Installing in existing process " + proc); 9375 } 9376 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9377 proc.pubProviders.put(cpi.name, cpr); 9378 try { 9379 proc.thread.scheduleInstallProvider(cpi); 9380 } catch (RemoteException e) { 9381 } 9382 } else { 9383 checkTime(startTime, "getContentProviderImpl: before start process"); 9384 proc = startProcessLocked(cpi.processName, 9385 cpr.appInfo, false, 0, "content provider", 9386 new ComponentName(cpi.applicationInfo.packageName, 9387 cpi.name), false, false, false); 9388 checkTime(startTime, "getContentProviderImpl: after start process"); 9389 if (proc == null) { 9390 Slog.w(TAG, "Unable to launch app " 9391 + cpi.applicationInfo.packageName + "/" 9392 + cpi.applicationInfo.uid + " for provider " 9393 + name + ": process is bad"); 9394 return null; 9395 } 9396 } 9397 cpr.launchingApp = proc; 9398 mLaunchingProviders.add(cpr); 9399 } finally { 9400 Binder.restoreCallingIdentity(origId); 9401 } 9402 } 9403 9404 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9405 9406 // Make sure the provider is published (the same provider class 9407 // may be published under multiple names). 9408 if (firstClass) { 9409 mProviderMap.putProviderByClass(comp, cpr); 9410 } 9411 9412 mProviderMap.putProviderByName(name, cpr); 9413 conn = incProviderCountLocked(r, cpr, token, stable); 9414 if (conn != null) { 9415 conn.waiting = true; 9416 } 9417 } 9418 checkTime(startTime, "getContentProviderImpl: done!"); 9419 } 9420 9421 // Wait for the provider to be published... 9422 synchronized (cpr) { 9423 while (cpr.provider == null) { 9424 if (cpr.launchingApp == null) { 9425 Slog.w(TAG, "Unable to launch app " 9426 + cpi.applicationInfo.packageName + "/" 9427 + cpi.applicationInfo.uid + " for provider " 9428 + name + ": launching app became null"); 9429 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9430 UserHandle.getUserId(cpi.applicationInfo.uid), 9431 cpi.applicationInfo.packageName, 9432 cpi.applicationInfo.uid, name); 9433 return null; 9434 } 9435 try { 9436 if (DEBUG_MU) { 9437 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9438 + cpr.launchingApp); 9439 } 9440 if (conn != null) { 9441 conn.waiting = true; 9442 } 9443 cpr.wait(); 9444 } catch (InterruptedException ex) { 9445 } finally { 9446 if (conn != null) { 9447 conn.waiting = false; 9448 } 9449 } 9450 } 9451 } 9452 return cpr != null ? cpr.newHolder(conn) : null; 9453 } 9454 9455 @Override 9456 public final ContentProviderHolder getContentProvider( 9457 IApplicationThread caller, String name, int userId, boolean stable) { 9458 enforceNotIsolatedCaller("getContentProvider"); 9459 if (caller == null) { 9460 String msg = "null IApplicationThread when getting content provider " 9461 + name; 9462 Slog.w(TAG, msg); 9463 throw new SecurityException(msg); 9464 } 9465 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9466 // with cross-user grant. 9467 return getContentProviderImpl(caller, name, null, stable, userId); 9468 } 9469 9470 public ContentProviderHolder getContentProviderExternal( 9471 String name, int userId, IBinder token) { 9472 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9473 "Do not have permission in call getContentProviderExternal()"); 9474 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9475 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9476 return getContentProviderExternalUnchecked(name, token, userId); 9477 } 9478 9479 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9480 IBinder token, int userId) { 9481 return getContentProviderImpl(null, name, token, true, userId); 9482 } 9483 9484 /** 9485 * Drop a content provider from a ProcessRecord's bookkeeping 9486 */ 9487 public void removeContentProvider(IBinder connection, boolean stable) { 9488 enforceNotIsolatedCaller("removeContentProvider"); 9489 long ident = Binder.clearCallingIdentity(); 9490 try { 9491 synchronized (this) { 9492 ContentProviderConnection conn; 9493 try { 9494 conn = (ContentProviderConnection)connection; 9495 } catch (ClassCastException e) { 9496 String msg ="removeContentProvider: " + connection 9497 + " not a ContentProviderConnection"; 9498 Slog.w(TAG, msg); 9499 throw new IllegalArgumentException(msg); 9500 } 9501 if (conn == null) { 9502 throw new NullPointerException("connection is null"); 9503 } 9504 if (decProviderCountLocked(conn, null, null, stable)) { 9505 updateOomAdjLocked(); 9506 } 9507 } 9508 } finally { 9509 Binder.restoreCallingIdentity(ident); 9510 } 9511 } 9512 9513 public void removeContentProviderExternal(String name, IBinder token) { 9514 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9515 "Do not have permission in call removeContentProviderExternal()"); 9516 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9517 } 9518 9519 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9520 synchronized (this) { 9521 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9522 if(cpr == null) { 9523 //remove from mProvidersByClass 9524 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9525 return; 9526 } 9527 9528 //update content provider record entry info 9529 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9530 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9531 if (localCpr.hasExternalProcessHandles()) { 9532 if (localCpr.removeExternalProcessHandleLocked(token)) { 9533 updateOomAdjLocked(); 9534 } else { 9535 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9536 + " with no external reference for token: " 9537 + token + "."); 9538 } 9539 } else { 9540 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9541 + " with no external references."); 9542 } 9543 } 9544 } 9545 9546 public final void publishContentProviders(IApplicationThread caller, 9547 List<ContentProviderHolder> providers) { 9548 if (providers == null) { 9549 return; 9550 } 9551 9552 enforceNotIsolatedCaller("publishContentProviders"); 9553 synchronized (this) { 9554 final ProcessRecord r = getRecordForAppLocked(caller); 9555 if (DEBUG_MU) 9556 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9557 if (r == null) { 9558 throw new SecurityException( 9559 "Unable to find app for caller " + caller 9560 + " (pid=" + Binder.getCallingPid() 9561 + ") when publishing content providers"); 9562 } 9563 9564 final long origId = Binder.clearCallingIdentity(); 9565 9566 final int N = providers.size(); 9567 for (int i=0; i<N; i++) { 9568 ContentProviderHolder src = providers.get(i); 9569 if (src == null || src.info == null || src.provider == null) { 9570 continue; 9571 } 9572 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9573 if (DEBUG_MU) 9574 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9575 if (dst != null) { 9576 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9577 mProviderMap.putProviderByClass(comp, dst); 9578 String names[] = dst.info.authority.split(";"); 9579 for (int j = 0; j < names.length; j++) { 9580 mProviderMap.putProviderByName(names[j], dst); 9581 } 9582 9583 int NL = mLaunchingProviders.size(); 9584 int j; 9585 for (j=0; j<NL; j++) { 9586 if (mLaunchingProviders.get(j) == dst) { 9587 mLaunchingProviders.remove(j); 9588 j--; 9589 NL--; 9590 } 9591 } 9592 synchronized (dst) { 9593 dst.provider = src.provider; 9594 dst.proc = r; 9595 dst.notifyAll(); 9596 } 9597 updateOomAdjLocked(r); 9598 } 9599 } 9600 9601 Binder.restoreCallingIdentity(origId); 9602 } 9603 } 9604 9605 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9606 ContentProviderConnection conn; 9607 try { 9608 conn = (ContentProviderConnection)connection; 9609 } catch (ClassCastException e) { 9610 String msg ="refContentProvider: " + connection 9611 + " not a ContentProviderConnection"; 9612 Slog.w(TAG, msg); 9613 throw new IllegalArgumentException(msg); 9614 } 9615 if (conn == null) { 9616 throw new NullPointerException("connection is null"); 9617 } 9618 9619 synchronized (this) { 9620 if (stable > 0) { 9621 conn.numStableIncs += stable; 9622 } 9623 stable = conn.stableCount + stable; 9624 if (stable < 0) { 9625 throw new IllegalStateException("stableCount < 0: " + stable); 9626 } 9627 9628 if (unstable > 0) { 9629 conn.numUnstableIncs += unstable; 9630 } 9631 unstable = conn.unstableCount + unstable; 9632 if (unstable < 0) { 9633 throw new IllegalStateException("unstableCount < 0: " + unstable); 9634 } 9635 9636 if ((stable+unstable) <= 0) { 9637 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9638 + stable + " unstable=" + unstable); 9639 } 9640 conn.stableCount = stable; 9641 conn.unstableCount = unstable; 9642 return !conn.dead; 9643 } 9644 } 9645 9646 public void unstableProviderDied(IBinder connection) { 9647 ContentProviderConnection conn; 9648 try { 9649 conn = (ContentProviderConnection)connection; 9650 } catch (ClassCastException e) { 9651 String msg ="refContentProvider: " + connection 9652 + " not a ContentProviderConnection"; 9653 Slog.w(TAG, msg); 9654 throw new IllegalArgumentException(msg); 9655 } 9656 if (conn == null) { 9657 throw new NullPointerException("connection is null"); 9658 } 9659 9660 // Safely retrieve the content provider associated with the connection. 9661 IContentProvider provider; 9662 synchronized (this) { 9663 provider = conn.provider.provider; 9664 } 9665 9666 if (provider == null) { 9667 // Um, yeah, we're way ahead of you. 9668 return; 9669 } 9670 9671 // Make sure the caller is being honest with us. 9672 if (provider.asBinder().pingBinder()) { 9673 // Er, no, still looks good to us. 9674 synchronized (this) { 9675 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9676 + " says " + conn + " died, but we don't agree"); 9677 return; 9678 } 9679 } 9680 9681 // Well look at that! It's dead! 9682 synchronized (this) { 9683 if (conn.provider.provider != provider) { 9684 // But something changed... good enough. 9685 return; 9686 } 9687 9688 ProcessRecord proc = conn.provider.proc; 9689 if (proc == null || proc.thread == null) { 9690 // Seems like the process is already cleaned up. 9691 return; 9692 } 9693 9694 // As far as we're concerned, this is just like receiving a 9695 // death notification... just a bit prematurely. 9696 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9697 + ") early provider death"); 9698 final long ident = Binder.clearCallingIdentity(); 9699 try { 9700 appDiedLocked(proc); 9701 } finally { 9702 Binder.restoreCallingIdentity(ident); 9703 } 9704 } 9705 } 9706 9707 @Override 9708 public void appNotRespondingViaProvider(IBinder connection) { 9709 enforceCallingPermission( 9710 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9711 9712 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9713 if (conn == null) { 9714 Slog.w(TAG, "ContentProviderConnection is null"); 9715 return; 9716 } 9717 9718 final ProcessRecord host = conn.provider.proc; 9719 if (host == null) { 9720 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9721 return; 9722 } 9723 9724 final long token = Binder.clearCallingIdentity(); 9725 try { 9726 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9727 } finally { 9728 Binder.restoreCallingIdentity(token); 9729 } 9730 } 9731 9732 public final void installSystemProviders() { 9733 List<ProviderInfo> providers; 9734 synchronized (this) { 9735 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9736 providers = generateApplicationProvidersLocked(app); 9737 if (providers != null) { 9738 for (int i=providers.size()-1; i>=0; i--) { 9739 ProviderInfo pi = (ProviderInfo)providers.get(i); 9740 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9741 Slog.w(TAG, "Not installing system proc provider " + pi.name 9742 + ": not system .apk"); 9743 providers.remove(i); 9744 } 9745 } 9746 } 9747 } 9748 if (providers != null) { 9749 mSystemThread.installSystemProviders(providers); 9750 } 9751 9752 mCoreSettingsObserver = new CoreSettingsObserver(this); 9753 9754 //mUsageStatsService.monitorPackages(); 9755 } 9756 9757 /** 9758 * Allows apps to retrieve the MIME type of a URI. 9759 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9760 * users, then it does not need permission to access the ContentProvider. 9761 * Either, it needs cross-user uri grants. 9762 * 9763 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9764 * 9765 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9766 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9767 */ 9768 public String getProviderMimeType(Uri uri, int userId) { 9769 enforceNotIsolatedCaller("getProviderMimeType"); 9770 final String name = uri.getAuthority(); 9771 int callingUid = Binder.getCallingUid(); 9772 int callingPid = Binder.getCallingPid(); 9773 long ident = 0; 9774 boolean clearedIdentity = false; 9775 userId = unsafeConvertIncomingUser(userId); 9776 if (canClearIdentity(callingPid, callingUid, userId)) { 9777 clearedIdentity = true; 9778 ident = Binder.clearCallingIdentity(); 9779 } 9780 ContentProviderHolder holder = null; 9781 try { 9782 holder = getContentProviderExternalUnchecked(name, null, userId); 9783 if (holder != null) { 9784 return holder.provider.getType(uri); 9785 } 9786 } catch (RemoteException e) { 9787 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9788 return null; 9789 } finally { 9790 // We need to clear the identity to call removeContentProviderExternalUnchecked 9791 if (!clearedIdentity) { 9792 ident = Binder.clearCallingIdentity(); 9793 } 9794 try { 9795 if (holder != null) { 9796 removeContentProviderExternalUnchecked(name, null, userId); 9797 } 9798 } finally { 9799 Binder.restoreCallingIdentity(ident); 9800 } 9801 } 9802 9803 return null; 9804 } 9805 9806 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9807 if (UserHandle.getUserId(callingUid) == userId) { 9808 return true; 9809 } 9810 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9811 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9812 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9813 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9814 return true; 9815 } 9816 return false; 9817 } 9818 9819 // ========================================================= 9820 // GLOBAL MANAGEMENT 9821 // ========================================================= 9822 9823 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9824 boolean isolated, int isolatedUid) { 9825 String proc = customProcess != null ? customProcess : info.processName; 9826 BatteryStatsImpl.Uid.Proc ps = null; 9827 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9828 int uid = info.uid; 9829 if (isolated) { 9830 if (isolatedUid == 0) { 9831 int userId = UserHandle.getUserId(uid); 9832 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9833 while (true) { 9834 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9835 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9836 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9837 } 9838 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9839 mNextIsolatedProcessUid++; 9840 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9841 // No process for this uid, use it. 9842 break; 9843 } 9844 stepsLeft--; 9845 if (stepsLeft <= 0) { 9846 return null; 9847 } 9848 } 9849 } else { 9850 // Special case for startIsolatedProcess (internal only), where 9851 // the uid of the isolated process is specified by the caller. 9852 uid = isolatedUid; 9853 } 9854 } 9855 return new ProcessRecord(stats, info, proc, uid); 9856 } 9857 9858 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9859 String abiOverride) { 9860 ProcessRecord app; 9861 if (!isolated) { 9862 app = getProcessRecordLocked(info.processName, info.uid, true); 9863 } else { 9864 app = null; 9865 } 9866 9867 if (app == null) { 9868 app = newProcessRecordLocked(info, null, isolated, 0); 9869 mProcessNames.put(info.processName, app.uid, app); 9870 if (isolated) { 9871 mIsolatedProcesses.put(app.uid, app); 9872 } 9873 updateLruProcessLocked(app, false, null); 9874 updateOomAdjLocked(); 9875 } 9876 9877 // This package really, really can not be stopped. 9878 try { 9879 AppGlobals.getPackageManager().setPackageStoppedState( 9880 info.packageName, false, UserHandle.getUserId(app.uid)); 9881 } catch (RemoteException e) { 9882 } catch (IllegalArgumentException e) { 9883 Slog.w(TAG, "Failed trying to unstop package " 9884 + info.packageName + ": " + e); 9885 } 9886 9887 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9888 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9889 app.persistent = true; 9890 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9891 } 9892 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9893 mPersistentStartingProcesses.add(app); 9894 startProcessLocked(app, "added application", app.processName, abiOverride, 9895 null /* entryPoint */, null /* entryPointArgs */); 9896 } 9897 9898 return app; 9899 } 9900 9901 public void unhandledBack() { 9902 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9903 "unhandledBack()"); 9904 9905 synchronized(this) { 9906 final long origId = Binder.clearCallingIdentity(); 9907 try { 9908 getFocusedStack().unhandledBackLocked(); 9909 } finally { 9910 Binder.restoreCallingIdentity(origId); 9911 } 9912 } 9913 } 9914 9915 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9916 enforceNotIsolatedCaller("openContentUri"); 9917 final int userId = UserHandle.getCallingUserId(); 9918 String name = uri.getAuthority(); 9919 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9920 ParcelFileDescriptor pfd = null; 9921 if (cph != null) { 9922 // We record the binder invoker's uid in thread-local storage before 9923 // going to the content provider to open the file. Later, in the code 9924 // that handles all permissions checks, we look for this uid and use 9925 // that rather than the Activity Manager's own uid. The effect is that 9926 // we do the check against the caller's permissions even though it looks 9927 // to the content provider like the Activity Manager itself is making 9928 // the request. 9929 sCallerIdentity.set(new Identity( 9930 Binder.getCallingPid(), Binder.getCallingUid())); 9931 try { 9932 pfd = cph.provider.openFile(null, uri, "r", null); 9933 } catch (FileNotFoundException e) { 9934 // do nothing; pfd will be returned null 9935 } finally { 9936 // Ensure that whatever happens, we clean up the identity state 9937 sCallerIdentity.remove(); 9938 } 9939 9940 // We've got the fd now, so we're done with the provider. 9941 removeContentProviderExternalUnchecked(name, null, userId); 9942 } else { 9943 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9944 } 9945 return pfd; 9946 } 9947 9948 // Actually is sleeping or shutting down or whatever else in the future 9949 // is an inactive state. 9950 public boolean isSleepingOrShuttingDown() { 9951 return isSleeping() || mShuttingDown; 9952 } 9953 9954 public boolean isSleeping() { 9955 return mSleeping && !mKeyguardWaitingForDraw; 9956 } 9957 9958 void goingToSleep() { 9959 synchronized(this) { 9960 mWentToSleep = true; 9961 updateEventDispatchingLocked(); 9962 goToSleepIfNeededLocked(); 9963 } 9964 } 9965 9966 void finishRunningVoiceLocked() { 9967 if (mRunningVoice) { 9968 mRunningVoice = false; 9969 goToSleepIfNeededLocked(); 9970 } 9971 } 9972 9973 void goToSleepIfNeededLocked() { 9974 if (mWentToSleep && !mRunningVoice) { 9975 if (!mSleeping) { 9976 mSleeping = true; 9977 mKeyguardWaitingForDraw = false; 9978 mStackSupervisor.goingToSleepLocked(); 9979 9980 // Initialize the wake times of all processes. 9981 checkExcessivePowerUsageLocked(false); 9982 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9983 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9984 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9985 } 9986 } 9987 } 9988 9989 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9990 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9991 // Never persist the home stack. 9992 return; 9993 } 9994 mTaskPersister.wakeup(task, flush); 9995 } 9996 9997 @Override 9998 public boolean shutdown(int timeout) { 9999 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10000 != PackageManager.PERMISSION_GRANTED) { 10001 throw new SecurityException("Requires permission " 10002 + android.Manifest.permission.SHUTDOWN); 10003 } 10004 10005 boolean timedout = false; 10006 10007 synchronized(this) { 10008 mShuttingDown = true; 10009 updateEventDispatchingLocked(); 10010 timedout = mStackSupervisor.shutdownLocked(timeout); 10011 } 10012 10013 mAppOpsService.shutdown(); 10014 if (mUsageStatsService != null) { 10015 mUsageStatsService.prepareShutdown(); 10016 } 10017 mBatteryStatsService.shutdown(); 10018 synchronized (this) { 10019 mProcessStats.shutdownLocked(); 10020 } 10021 notifyTaskPersisterLocked(null, true); 10022 10023 return timedout; 10024 } 10025 10026 public final void activitySlept(IBinder token) { 10027 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10028 10029 final long origId = Binder.clearCallingIdentity(); 10030 10031 synchronized (this) { 10032 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10033 if (r != null) { 10034 mStackSupervisor.activitySleptLocked(r); 10035 } 10036 } 10037 10038 Binder.restoreCallingIdentity(origId); 10039 } 10040 10041 void logLockScreen(String msg) { 10042 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10043 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10044 mWentToSleep + " mSleeping=" + mSleeping); 10045 } 10046 10047 private void comeOutOfSleepIfNeededLocked() { 10048 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10049 if (mSleeping) { 10050 mSleeping = false; 10051 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10052 } 10053 } 10054 } 10055 10056 void wakingUp() { 10057 synchronized(this) { 10058 mWentToSleep = false; 10059 updateEventDispatchingLocked(); 10060 comeOutOfSleepIfNeededLocked(); 10061 } 10062 } 10063 10064 void startRunningVoiceLocked() { 10065 if (!mRunningVoice) { 10066 mRunningVoice = true; 10067 comeOutOfSleepIfNeededLocked(); 10068 } 10069 } 10070 10071 private void updateEventDispatchingLocked() { 10072 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10073 } 10074 10075 public void setLockScreenShown(boolean shown) { 10076 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10077 != PackageManager.PERMISSION_GRANTED) { 10078 throw new SecurityException("Requires permission " 10079 + android.Manifest.permission.DEVICE_POWER); 10080 } 10081 10082 synchronized(this) { 10083 long ident = Binder.clearCallingIdentity(); 10084 try { 10085 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10086 mLockScreenShown = shown; 10087 mKeyguardWaitingForDraw = false; 10088 comeOutOfSleepIfNeededLocked(); 10089 } finally { 10090 Binder.restoreCallingIdentity(ident); 10091 } 10092 } 10093 } 10094 10095 @Override 10096 public void stopAppSwitches() { 10097 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10098 != PackageManager.PERMISSION_GRANTED) { 10099 throw new SecurityException("Requires permission " 10100 + android.Manifest.permission.STOP_APP_SWITCHES); 10101 } 10102 10103 synchronized(this) { 10104 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10105 + APP_SWITCH_DELAY_TIME; 10106 mDidAppSwitch = false; 10107 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10108 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10109 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10110 } 10111 } 10112 10113 public void resumeAppSwitches() { 10114 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10115 != PackageManager.PERMISSION_GRANTED) { 10116 throw new SecurityException("Requires permission " 10117 + android.Manifest.permission.STOP_APP_SWITCHES); 10118 } 10119 10120 synchronized(this) { 10121 // Note that we don't execute any pending app switches... we will 10122 // let those wait until either the timeout, or the next start 10123 // activity request. 10124 mAppSwitchesAllowedTime = 0; 10125 } 10126 } 10127 10128 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10129 int callingPid, int callingUid, String name) { 10130 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10131 return true; 10132 } 10133 10134 int perm = checkComponentPermission( 10135 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10136 sourceUid, -1, true); 10137 if (perm == PackageManager.PERMISSION_GRANTED) { 10138 return true; 10139 } 10140 10141 // If the actual IPC caller is different from the logical source, then 10142 // also see if they are allowed to control app switches. 10143 if (callingUid != -1 && callingUid != sourceUid) { 10144 perm = checkComponentPermission( 10145 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10146 callingUid, -1, true); 10147 if (perm == PackageManager.PERMISSION_GRANTED) { 10148 return true; 10149 } 10150 } 10151 10152 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10153 return false; 10154 } 10155 10156 public void setDebugApp(String packageName, boolean waitForDebugger, 10157 boolean persistent) { 10158 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10159 "setDebugApp()"); 10160 10161 long ident = Binder.clearCallingIdentity(); 10162 try { 10163 // Note that this is not really thread safe if there are multiple 10164 // callers into it at the same time, but that's not a situation we 10165 // care about. 10166 if (persistent) { 10167 final ContentResolver resolver = mContext.getContentResolver(); 10168 Settings.Global.putString( 10169 resolver, Settings.Global.DEBUG_APP, 10170 packageName); 10171 Settings.Global.putInt( 10172 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10173 waitForDebugger ? 1 : 0); 10174 } 10175 10176 synchronized (this) { 10177 if (!persistent) { 10178 mOrigDebugApp = mDebugApp; 10179 mOrigWaitForDebugger = mWaitForDebugger; 10180 } 10181 mDebugApp = packageName; 10182 mWaitForDebugger = waitForDebugger; 10183 mDebugTransient = !persistent; 10184 if (packageName != null) { 10185 forceStopPackageLocked(packageName, -1, false, false, true, true, 10186 false, UserHandle.USER_ALL, "set debug app"); 10187 } 10188 } 10189 } finally { 10190 Binder.restoreCallingIdentity(ident); 10191 } 10192 } 10193 10194 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10195 synchronized (this) { 10196 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10197 if (!isDebuggable) { 10198 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10199 throw new SecurityException("Process not debuggable: " + app.packageName); 10200 } 10201 } 10202 10203 mOpenGlTraceApp = processName; 10204 } 10205 } 10206 10207 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10208 synchronized (this) { 10209 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10210 if (!isDebuggable) { 10211 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10212 throw new SecurityException("Process not debuggable: " + app.packageName); 10213 } 10214 } 10215 mProfileApp = processName; 10216 mProfileFile = profilerInfo.profileFile; 10217 if (mProfileFd != null) { 10218 try { 10219 mProfileFd.close(); 10220 } catch (IOException e) { 10221 } 10222 mProfileFd = null; 10223 } 10224 mProfileFd = profilerInfo.profileFd; 10225 mSamplingInterval = profilerInfo.samplingInterval; 10226 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10227 mProfileType = 0; 10228 } 10229 } 10230 10231 @Override 10232 public void setAlwaysFinish(boolean enabled) { 10233 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10234 "setAlwaysFinish()"); 10235 10236 Settings.Global.putInt( 10237 mContext.getContentResolver(), 10238 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10239 10240 synchronized (this) { 10241 mAlwaysFinishActivities = enabled; 10242 } 10243 } 10244 10245 @Override 10246 public void setActivityController(IActivityController controller) { 10247 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10248 "setActivityController()"); 10249 synchronized (this) { 10250 mController = controller; 10251 Watchdog.getInstance().setActivityController(controller); 10252 } 10253 } 10254 10255 @Override 10256 public void setUserIsMonkey(boolean userIsMonkey) { 10257 synchronized (this) { 10258 synchronized (mPidsSelfLocked) { 10259 final int callingPid = Binder.getCallingPid(); 10260 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10261 if (precessRecord == null) { 10262 throw new SecurityException("Unknown process: " + callingPid); 10263 } 10264 if (precessRecord.instrumentationUiAutomationConnection == null) { 10265 throw new SecurityException("Only an instrumentation process " 10266 + "with a UiAutomation can call setUserIsMonkey"); 10267 } 10268 } 10269 mUserIsMonkey = userIsMonkey; 10270 } 10271 } 10272 10273 @Override 10274 public boolean isUserAMonkey() { 10275 synchronized (this) { 10276 // If there is a controller also implies the user is a monkey. 10277 return (mUserIsMonkey || mController != null); 10278 } 10279 } 10280 10281 public void requestBugReport() { 10282 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10283 SystemProperties.set("ctl.start", "bugreport"); 10284 } 10285 10286 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10287 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10288 } 10289 10290 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10291 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10292 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10293 } 10294 return KEY_DISPATCHING_TIMEOUT; 10295 } 10296 10297 @Override 10298 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10299 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10300 != PackageManager.PERMISSION_GRANTED) { 10301 throw new SecurityException("Requires permission " 10302 + android.Manifest.permission.FILTER_EVENTS); 10303 } 10304 ProcessRecord proc; 10305 long timeout; 10306 synchronized (this) { 10307 synchronized (mPidsSelfLocked) { 10308 proc = mPidsSelfLocked.get(pid); 10309 } 10310 timeout = getInputDispatchingTimeoutLocked(proc); 10311 } 10312 10313 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10314 return -1; 10315 } 10316 10317 return timeout; 10318 } 10319 10320 /** 10321 * Handle input dispatching timeouts. 10322 * Returns whether input dispatching should be aborted or not. 10323 */ 10324 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10325 final ActivityRecord activity, final ActivityRecord parent, 10326 final boolean aboveSystem, String reason) { 10327 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10328 != PackageManager.PERMISSION_GRANTED) { 10329 throw new SecurityException("Requires permission " 10330 + android.Manifest.permission.FILTER_EVENTS); 10331 } 10332 10333 final String annotation; 10334 if (reason == null) { 10335 annotation = "Input dispatching timed out"; 10336 } else { 10337 annotation = "Input dispatching timed out (" + reason + ")"; 10338 } 10339 10340 if (proc != null) { 10341 synchronized (this) { 10342 if (proc.debugging) { 10343 return false; 10344 } 10345 10346 if (mDidDexOpt) { 10347 // Give more time since we were dexopting. 10348 mDidDexOpt = false; 10349 return false; 10350 } 10351 10352 if (proc.instrumentationClass != null) { 10353 Bundle info = new Bundle(); 10354 info.putString("shortMsg", "keyDispatchingTimedOut"); 10355 info.putString("longMsg", annotation); 10356 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10357 return true; 10358 } 10359 } 10360 mHandler.post(new Runnable() { 10361 @Override 10362 public void run() { 10363 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10364 } 10365 }); 10366 } 10367 10368 return true; 10369 } 10370 10371 public Bundle getAssistContextExtras(int requestType) { 10372 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10373 "getAssistContextExtras()"); 10374 PendingAssistExtras pae; 10375 Bundle extras = new Bundle(); 10376 synchronized (this) { 10377 ActivityRecord activity = getFocusedStack().mResumedActivity; 10378 if (activity == null) { 10379 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10380 return null; 10381 } 10382 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10383 if (activity.app == null || activity.app.thread == null) { 10384 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10385 return extras; 10386 } 10387 if (activity.app.pid == Binder.getCallingPid()) { 10388 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10389 return extras; 10390 } 10391 pae = new PendingAssistExtras(activity); 10392 try { 10393 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10394 requestType); 10395 mPendingAssistExtras.add(pae); 10396 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10397 } catch (RemoteException e) { 10398 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10399 return extras; 10400 } 10401 } 10402 synchronized (pae) { 10403 while (!pae.haveResult) { 10404 try { 10405 pae.wait(); 10406 } catch (InterruptedException e) { 10407 } 10408 } 10409 if (pae.result != null) { 10410 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10411 } 10412 } 10413 synchronized (this) { 10414 mPendingAssistExtras.remove(pae); 10415 mHandler.removeCallbacks(pae); 10416 } 10417 return extras; 10418 } 10419 10420 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10421 PendingAssistExtras pae = (PendingAssistExtras)token; 10422 synchronized (pae) { 10423 pae.result = extras; 10424 pae.haveResult = true; 10425 pae.notifyAll(); 10426 } 10427 } 10428 10429 public void registerProcessObserver(IProcessObserver observer) { 10430 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10431 "registerProcessObserver()"); 10432 synchronized (this) { 10433 mProcessObservers.register(observer); 10434 } 10435 } 10436 10437 @Override 10438 public void unregisterProcessObserver(IProcessObserver observer) { 10439 synchronized (this) { 10440 mProcessObservers.unregister(observer); 10441 } 10442 } 10443 10444 @Override 10445 public boolean convertFromTranslucent(IBinder token) { 10446 final long origId = Binder.clearCallingIdentity(); 10447 try { 10448 synchronized (this) { 10449 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10450 if (r == null) { 10451 return false; 10452 } 10453 final boolean translucentChanged = r.changeWindowTranslucency(true); 10454 if (translucentChanged) { 10455 r.task.stack.releaseBackgroundResources(); 10456 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10457 } 10458 mWindowManager.setAppFullscreen(token, true); 10459 return translucentChanged; 10460 } 10461 } finally { 10462 Binder.restoreCallingIdentity(origId); 10463 } 10464 } 10465 10466 @Override 10467 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10468 final long origId = Binder.clearCallingIdentity(); 10469 try { 10470 synchronized (this) { 10471 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10472 if (r == null) { 10473 return false; 10474 } 10475 int index = r.task.mActivities.lastIndexOf(r); 10476 if (index > 0) { 10477 ActivityRecord under = r.task.mActivities.get(index - 1); 10478 under.returningOptions = options; 10479 } 10480 final boolean translucentChanged = r.changeWindowTranslucency(false); 10481 if (translucentChanged) { 10482 r.task.stack.convertToTranslucent(r); 10483 } 10484 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10485 mWindowManager.setAppFullscreen(token, false); 10486 return translucentChanged; 10487 } 10488 } finally { 10489 Binder.restoreCallingIdentity(origId); 10490 } 10491 } 10492 10493 @Override 10494 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10495 final long origId = Binder.clearCallingIdentity(); 10496 try { 10497 synchronized (this) { 10498 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10499 if (r != null) { 10500 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10501 } 10502 } 10503 return false; 10504 } finally { 10505 Binder.restoreCallingIdentity(origId); 10506 } 10507 } 10508 10509 @Override 10510 public boolean isBackgroundVisibleBehind(IBinder token) { 10511 final long origId = Binder.clearCallingIdentity(); 10512 try { 10513 synchronized (this) { 10514 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10515 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10516 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10517 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10518 return visible; 10519 } 10520 } finally { 10521 Binder.restoreCallingIdentity(origId); 10522 } 10523 } 10524 10525 @Override 10526 public ActivityOptions getActivityOptions(IBinder token) { 10527 final long origId = Binder.clearCallingIdentity(); 10528 try { 10529 synchronized (this) { 10530 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10531 if (r != null) { 10532 final ActivityOptions activityOptions = r.pendingOptions; 10533 r.pendingOptions = null; 10534 return activityOptions; 10535 } 10536 return null; 10537 } 10538 } finally { 10539 Binder.restoreCallingIdentity(origId); 10540 } 10541 } 10542 10543 @Override 10544 public void setImmersive(IBinder token, boolean immersive) { 10545 synchronized(this) { 10546 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10547 if (r == null) { 10548 throw new IllegalArgumentException(); 10549 } 10550 r.immersive = immersive; 10551 10552 // update associated state if we're frontmost 10553 if (r == mFocusedActivity) { 10554 if (DEBUG_IMMERSIVE) { 10555 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10556 } 10557 applyUpdateLockStateLocked(r); 10558 } 10559 } 10560 } 10561 10562 @Override 10563 public boolean isImmersive(IBinder token) { 10564 synchronized (this) { 10565 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10566 if (r == null) { 10567 throw new IllegalArgumentException(); 10568 } 10569 return r.immersive; 10570 } 10571 } 10572 10573 public boolean isTopActivityImmersive() { 10574 enforceNotIsolatedCaller("startActivity"); 10575 synchronized (this) { 10576 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10577 return (r != null) ? r.immersive : false; 10578 } 10579 } 10580 10581 @Override 10582 public boolean isTopOfTask(IBinder token) { 10583 synchronized (this) { 10584 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10585 if (r == null) { 10586 throw new IllegalArgumentException(); 10587 } 10588 return r.task.getTopActivity() == r; 10589 } 10590 } 10591 10592 public final void enterSafeMode() { 10593 synchronized(this) { 10594 // It only makes sense to do this before the system is ready 10595 // and started launching other packages. 10596 if (!mSystemReady) { 10597 try { 10598 AppGlobals.getPackageManager().enterSafeMode(); 10599 } catch (RemoteException e) { 10600 } 10601 } 10602 10603 mSafeMode = true; 10604 } 10605 } 10606 10607 public final void showSafeModeOverlay() { 10608 View v = LayoutInflater.from(mContext).inflate( 10609 com.android.internal.R.layout.safe_mode, null); 10610 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10611 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10612 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10613 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10614 lp.gravity = Gravity.BOTTOM | Gravity.START; 10615 lp.format = v.getBackground().getOpacity(); 10616 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10617 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10618 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10619 ((WindowManager)mContext.getSystemService( 10620 Context.WINDOW_SERVICE)).addView(v, lp); 10621 } 10622 10623 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10624 if (!(sender instanceof PendingIntentRecord)) { 10625 return; 10626 } 10627 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10628 synchronized (stats) { 10629 if (mBatteryStatsService.isOnBattery()) { 10630 mBatteryStatsService.enforceCallingPermission(); 10631 PendingIntentRecord rec = (PendingIntentRecord)sender; 10632 int MY_UID = Binder.getCallingUid(); 10633 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10634 BatteryStatsImpl.Uid.Pkg pkg = 10635 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10636 sourcePkg != null ? sourcePkg : rec.key.packageName); 10637 pkg.incWakeupsLocked(); 10638 } 10639 } 10640 } 10641 10642 public boolean killPids(int[] pids, String pReason, boolean secure) { 10643 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10644 throw new SecurityException("killPids only available to the system"); 10645 } 10646 String reason = (pReason == null) ? "Unknown" : pReason; 10647 // XXX Note: don't acquire main activity lock here, because the window 10648 // manager calls in with its locks held. 10649 10650 boolean killed = false; 10651 synchronized (mPidsSelfLocked) { 10652 int[] types = new int[pids.length]; 10653 int worstType = 0; 10654 for (int i=0; i<pids.length; i++) { 10655 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10656 if (proc != null) { 10657 int type = proc.setAdj; 10658 types[i] = type; 10659 if (type > worstType) { 10660 worstType = type; 10661 } 10662 } 10663 } 10664 10665 // If the worst oom_adj is somewhere in the cached proc LRU range, 10666 // then constrain it so we will kill all cached procs. 10667 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10668 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10669 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10670 } 10671 10672 // If this is not a secure call, don't let it kill processes that 10673 // are important. 10674 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10675 worstType = ProcessList.SERVICE_ADJ; 10676 } 10677 10678 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10679 for (int i=0; i<pids.length; i++) { 10680 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10681 if (proc == null) { 10682 continue; 10683 } 10684 int adj = proc.setAdj; 10685 if (adj >= worstType && !proc.killedByAm) { 10686 proc.kill(reason, true); 10687 killed = true; 10688 } 10689 } 10690 } 10691 return killed; 10692 } 10693 10694 @Override 10695 public void killUid(int uid, String reason) { 10696 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10697 throw new SecurityException("killUid only available to the system"); 10698 } 10699 synchronized (this) { 10700 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10701 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10702 reason != null ? reason : "kill uid"); 10703 } 10704 } 10705 10706 @Override 10707 public boolean killProcessesBelowForeground(String reason) { 10708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10709 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10710 } 10711 10712 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10713 } 10714 10715 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10716 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10717 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10718 } 10719 10720 boolean killed = false; 10721 synchronized (mPidsSelfLocked) { 10722 final int size = mPidsSelfLocked.size(); 10723 for (int i = 0; i < size; i++) { 10724 final int pid = mPidsSelfLocked.keyAt(i); 10725 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10726 if (proc == null) continue; 10727 10728 final int adj = proc.setAdj; 10729 if (adj > belowAdj && !proc.killedByAm) { 10730 proc.kill(reason, true); 10731 killed = true; 10732 } 10733 } 10734 } 10735 return killed; 10736 } 10737 10738 @Override 10739 public void hang(final IBinder who, boolean allowRestart) { 10740 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10741 != PackageManager.PERMISSION_GRANTED) { 10742 throw new SecurityException("Requires permission " 10743 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10744 } 10745 10746 final IBinder.DeathRecipient death = new DeathRecipient() { 10747 @Override 10748 public void binderDied() { 10749 synchronized (this) { 10750 notifyAll(); 10751 } 10752 } 10753 }; 10754 10755 try { 10756 who.linkToDeath(death, 0); 10757 } catch (RemoteException e) { 10758 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10759 return; 10760 } 10761 10762 synchronized (this) { 10763 Watchdog.getInstance().setAllowRestart(allowRestart); 10764 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10765 synchronized (death) { 10766 while (who.isBinderAlive()) { 10767 try { 10768 death.wait(); 10769 } catch (InterruptedException e) { 10770 } 10771 } 10772 } 10773 Watchdog.getInstance().setAllowRestart(true); 10774 } 10775 } 10776 10777 @Override 10778 public void restart() { 10779 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10780 != PackageManager.PERMISSION_GRANTED) { 10781 throw new SecurityException("Requires permission " 10782 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10783 } 10784 10785 Log.i(TAG, "Sending shutdown broadcast..."); 10786 10787 BroadcastReceiver br = new BroadcastReceiver() { 10788 @Override public void onReceive(Context context, Intent intent) { 10789 // Now the broadcast is done, finish up the low-level shutdown. 10790 Log.i(TAG, "Shutting down activity manager..."); 10791 shutdown(10000); 10792 Log.i(TAG, "Shutdown complete, restarting!"); 10793 Process.killProcess(Process.myPid()); 10794 System.exit(10); 10795 } 10796 }; 10797 10798 // First send the high-level shut down broadcast. 10799 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10800 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10801 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10802 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10803 mContext.sendOrderedBroadcastAsUser(intent, 10804 UserHandle.ALL, null, br, mHandler, 0, null, null); 10805 */ 10806 br.onReceive(mContext, intent); 10807 } 10808 10809 private long getLowRamTimeSinceIdle(long now) { 10810 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10811 } 10812 10813 @Override 10814 public void performIdleMaintenance() { 10815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10816 != PackageManager.PERMISSION_GRANTED) { 10817 throw new SecurityException("Requires permission " 10818 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10819 } 10820 10821 synchronized (this) { 10822 final long now = SystemClock.uptimeMillis(); 10823 final long timeSinceLastIdle = now - mLastIdleTime; 10824 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10825 mLastIdleTime = now; 10826 mLowRamTimeSinceLastIdle = 0; 10827 if (mLowRamStartTime != 0) { 10828 mLowRamStartTime = now; 10829 } 10830 10831 StringBuilder sb = new StringBuilder(128); 10832 sb.append("Idle maintenance over "); 10833 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10834 sb.append(" low RAM for "); 10835 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10836 Slog.i(TAG, sb.toString()); 10837 10838 // If at least 1/3 of our time since the last idle period has been spent 10839 // with RAM low, then we want to kill processes. 10840 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10841 10842 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10843 ProcessRecord proc = mLruProcesses.get(i); 10844 if (proc.notCachedSinceIdle) { 10845 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10846 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10847 if (doKilling && proc.initialIdlePss != 0 10848 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10849 proc.kill("idle maint (pss " + proc.lastPss 10850 + " from " + proc.initialIdlePss + ")", true); 10851 } 10852 } 10853 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10854 proc.notCachedSinceIdle = true; 10855 proc.initialIdlePss = 0; 10856 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10857 isSleeping(), now); 10858 } 10859 } 10860 10861 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10862 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10863 } 10864 } 10865 10866 private void retrieveSettings() { 10867 final ContentResolver resolver = mContext.getContentResolver(); 10868 String debugApp = Settings.Global.getString( 10869 resolver, Settings.Global.DEBUG_APP); 10870 boolean waitForDebugger = Settings.Global.getInt( 10871 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10872 boolean alwaysFinishActivities = Settings.Global.getInt( 10873 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10874 boolean forceRtl = Settings.Global.getInt( 10875 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10876 // Transfer any global setting for forcing RTL layout, into a System Property 10877 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10878 10879 Configuration configuration = new Configuration(); 10880 Settings.System.getConfiguration(resolver, configuration); 10881 if (forceRtl) { 10882 // This will take care of setting the correct layout direction flags 10883 configuration.setLayoutDirection(configuration.locale); 10884 } 10885 10886 synchronized (this) { 10887 mDebugApp = mOrigDebugApp = debugApp; 10888 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10889 mAlwaysFinishActivities = alwaysFinishActivities; 10890 // This happens before any activities are started, so we can 10891 // change mConfiguration in-place. 10892 updateConfigurationLocked(configuration, null, false, true); 10893 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10894 } 10895 } 10896 10897 /** Loads resources after the current configuration has been set. */ 10898 private void loadResourcesOnSystemReady() { 10899 final Resources res = mContext.getResources(); 10900 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10901 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10902 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10903 } 10904 10905 public boolean testIsSystemReady() { 10906 // no need to synchronize(this) just to read & return the value 10907 return mSystemReady; 10908 } 10909 10910 private static File getCalledPreBootReceiversFile() { 10911 File dataDir = Environment.getDataDirectory(); 10912 File systemDir = new File(dataDir, "system"); 10913 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10914 return fname; 10915 } 10916 10917 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10918 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10919 File file = getCalledPreBootReceiversFile(); 10920 FileInputStream fis = null; 10921 try { 10922 fis = new FileInputStream(file); 10923 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10924 int fvers = dis.readInt(); 10925 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10926 String vers = dis.readUTF(); 10927 String codename = dis.readUTF(); 10928 String build = dis.readUTF(); 10929 if (android.os.Build.VERSION.RELEASE.equals(vers) 10930 && android.os.Build.VERSION.CODENAME.equals(codename) 10931 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10932 int num = dis.readInt(); 10933 while (num > 0) { 10934 num--; 10935 String pkg = dis.readUTF(); 10936 String cls = dis.readUTF(); 10937 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10938 } 10939 } 10940 } 10941 } catch (FileNotFoundException e) { 10942 } catch (IOException e) { 10943 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10944 } finally { 10945 if (fis != null) { 10946 try { 10947 fis.close(); 10948 } catch (IOException e) { 10949 } 10950 } 10951 } 10952 return lastDoneReceivers; 10953 } 10954 10955 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10956 File file = getCalledPreBootReceiversFile(); 10957 FileOutputStream fos = null; 10958 DataOutputStream dos = null; 10959 try { 10960 fos = new FileOutputStream(file); 10961 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10962 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10963 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10964 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10965 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10966 dos.writeInt(list.size()); 10967 for (int i=0; i<list.size(); i++) { 10968 dos.writeUTF(list.get(i).getPackageName()); 10969 dos.writeUTF(list.get(i).getClassName()); 10970 } 10971 } catch (IOException e) { 10972 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10973 file.delete(); 10974 } finally { 10975 FileUtils.sync(fos); 10976 if (dos != null) { 10977 try { 10978 dos.close(); 10979 } catch (IOException e) { 10980 // TODO Auto-generated catch block 10981 e.printStackTrace(); 10982 } 10983 } 10984 } 10985 } 10986 10987 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10988 ArrayList<ComponentName> doneReceivers, int userId) { 10989 boolean waitingUpdate = false; 10990 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10991 List<ResolveInfo> ris = null; 10992 try { 10993 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10994 intent, null, 0, userId); 10995 } catch (RemoteException e) { 10996 } 10997 if (ris != null) { 10998 for (int i=ris.size()-1; i>=0; i--) { 10999 if ((ris.get(i).activityInfo.applicationInfo.flags 11000 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11001 ris.remove(i); 11002 } 11003 } 11004 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11005 11006 // For User 0, load the version number. When delivering to a new user, deliver 11007 // to all receivers. 11008 if (userId == UserHandle.USER_OWNER) { 11009 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11010 for (int i=0; i<ris.size(); i++) { 11011 ActivityInfo ai = ris.get(i).activityInfo; 11012 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11013 if (lastDoneReceivers.contains(comp)) { 11014 // We already did the pre boot receiver for this app with the current 11015 // platform version, so don't do it again... 11016 ris.remove(i); 11017 i--; 11018 // ...however, do keep it as one that has been done, so we don't 11019 // forget about it when rewriting the file of last done receivers. 11020 doneReceivers.add(comp); 11021 } 11022 } 11023 } 11024 11025 // If primary user, send broadcast to all available users, else just to userId 11026 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11027 : new int[] { userId }; 11028 for (int i = 0; i < ris.size(); i++) { 11029 ActivityInfo ai = ris.get(i).activityInfo; 11030 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11031 doneReceivers.add(comp); 11032 intent.setComponent(comp); 11033 for (int j=0; j<users.length; j++) { 11034 IIntentReceiver finisher = null; 11035 // On last receiver and user, set up a completion callback 11036 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11037 finisher = new IIntentReceiver.Stub() { 11038 public void performReceive(Intent intent, int resultCode, 11039 String data, Bundle extras, boolean ordered, 11040 boolean sticky, int sendingUser) { 11041 // The raw IIntentReceiver interface is called 11042 // with the AM lock held, so redispatch to 11043 // execute our code without the lock. 11044 mHandler.post(onFinishCallback); 11045 } 11046 }; 11047 } 11048 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11049 + " for user " + users[j]); 11050 broadcastIntentLocked(null, null, intent, null, finisher, 11051 0, null, null, null, AppOpsManager.OP_NONE, 11052 true, false, MY_PID, Process.SYSTEM_UID, 11053 users[j]); 11054 if (finisher != null) { 11055 waitingUpdate = true; 11056 } 11057 } 11058 } 11059 } 11060 11061 return waitingUpdate; 11062 } 11063 11064 public void systemReady(final Runnable goingCallback) { 11065 synchronized(this) { 11066 if (mSystemReady) { 11067 // If we're done calling all the receivers, run the next "boot phase" passed in 11068 // by the SystemServer 11069 if (goingCallback != null) { 11070 goingCallback.run(); 11071 } 11072 return; 11073 } 11074 11075 // Make sure we have the current profile info, since it is needed for 11076 // security checks. 11077 updateCurrentProfileIdsLocked(); 11078 11079 if (mRecentTasks == null) { 11080 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11081 if (!mRecentTasks.isEmpty()) { 11082 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11083 } 11084 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11085 mTaskPersister.startPersisting(); 11086 } 11087 11088 // Check to see if there are any update receivers to run. 11089 if (!mDidUpdate) { 11090 if (mWaitingUpdate) { 11091 return; 11092 } 11093 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11094 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11095 public void run() { 11096 synchronized (ActivityManagerService.this) { 11097 mDidUpdate = true; 11098 } 11099 writeLastDonePreBootReceivers(doneReceivers); 11100 showBootMessage(mContext.getText( 11101 R.string.android_upgrading_complete), 11102 false); 11103 systemReady(goingCallback); 11104 } 11105 }, doneReceivers, UserHandle.USER_OWNER); 11106 11107 if (mWaitingUpdate) { 11108 return; 11109 } 11110 mDidUpdate = true; 11111 } 11112 11113 mAppOpsService.systemReady(); 11114 mSystemReady = true; 11115 } 11116 11117 ArrayList<ProcessRecord> procsToKill = null; 11118 synchronized(mPidsSelfLocked) { 11119 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11120 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11121 if (!isAllowedWhileBooting(proc.info)){ 11122 if (procsToKill == null) { 11123 procsToKill = new ArrayList<ProcessRecord>(); 11124 } 11125 procsToKill.add(proc); 11126 } 11127 } 11128 } 11129 11130 synchronized(this) { 11131 if (procsToKill != null) { 11132 for (int i=procsToKill.size()-1; i>=0; i--) { 11133 ProcessRecord proc = procsToKill.get(i); 11134 Slog.i(TAG, "Removing system update proc: " + proc); 11135 removeProcessLocked(proc, true, false, "system update done"); 11136 } 11137 } 11138 11139 // Now that we have cleaned up any update processes, we 11140 // are ready to start launching real processes and know that 11141 // we won't trample on them any more. 11142 mProcessesReady = true; 11143 } 11144 11145 Slog.i(TAG, "System now ready"); 11146 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11147 SystemClock.uptimeMillis()); 11148 11149 synchronized(this) { 11150 // Make sure we have no pre-ready processes sitting around. 11151 11152 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11153 ResolveInfo ri = mContext.getPackageManager() 11154 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11155 STOCK_PM_FLAGS); 11156 CharSequence errorMsg = null; 11157 if (ri != null) { 11158 ActivityInfo ai = ri.activityInfo; 11159 ApplicationInfo app = ai.applicationInfo; 11160 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11161 mTopAction = Intent.ACTION_FACTORY_TEST; 11162 mTopData = null; 11163 mTopComponent = new ComponentName(app.packageName, 11164 ai.name); 11165 } else { 11166 errorMsg = mContext.getResources().getText( 11167 com.android.internal.R.string.factorytest_not_system); 11168 } 11169 } else { 11170 errorMsg = mContext.getResources().getText( 11171 com.android.internal.R.string.factorytest_no_action); 11172 } 11173 if (errorMsg != null) { 11174 mTopAction = null; 11175 mTopData = null; 11176 mTopComponent = null; 11177 Message msg = Message.obtain(); 11178 msg.what = SHOW_FACTORY_ERROR_MSG; 11179 msg.getData().putCharSequence("msg", errorMsg); 11180 mHandler.sendMessage(msg); 11181 } 11182 } 11183 } 11184 11185 retrieveSettings(); 11186 loadResourcesOnSystemReady(); 11187 11188 synchronized (this) { 11189 readGrantedUriPermissionsLocked(); 11190 } 11191 11192 if (goingCallback != null) goingCallback.run(); 11193 11194 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11195 Integer.toString(mCurrentUserId), mCurrentUserId); 11196 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11197 Integer.toString(mCurrentUserId), mCurrentUserId); 11198 mSystemServiceManager.startUser(mCurrentUserId); 11199 11200 synchronized (this) { 11201 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11202 try { 11203 List apps = AppGlobals.getPackageManager(). 11204 getPersistentApplications(STOCK_PM_FLAGS); 11205 if (apps != null) { 11206 int N = apps.size(); 11207 int i; 11208 for (i=0; i<N; i++) { 11209 ApplicationInfo info 11210 = (ApplicationInfo)apps.get(i); 11211 if (info != null && 11212 !info.packageName.equals("android")) { 11213 addAppLocked(info, false, null /* ABI override */); 11214 } 11215 } 11216 } 11217 } catch (RemoteException ex) { 11218 // pm is in same process, this will never happen. 11219 } 11220 } 11221 11222 // Start up initial activity. 11223 mBooting = true; 11224 11225 try { 11226 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11227 Message msg = Message.obtain(); 11228 msg.what = SHOW_UID_ERROR_MSG; 11229 mHandler.sendMessage(msg); 11230 } 11231 } catch (RemoteException e) { 11232 } 11233 11234 long ident = Binder.clearCallingIdentity(); 11235 try { 11236 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11237 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11238 | Intent.FLAG_RECEIVER_FOREGROUND); 11239 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11240 broadcastIntentLocked(null, null, intent, 11241 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11242 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11243 intent = new Intent(Intent.ACTION_USER_STARTING); 11244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11245 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11246 broadcastIntentLocked(null, null, intent, 11247 null, new IIntentReceiver.Stub() { 11248 @Override 11249 public void performReceive(Intent intent, int resultCode, String data, 11250 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11251 throws RemoteException { 11252 } 11253 }, 0, null, null, 11254 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11255 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11256 } catch (Throwable t) { 11257 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11258 } finally { 11259 Binder.restoreCallingIdentity(ident); 11260 } 11261 mStackSupervisor.resumeTopActivitiesLocked(); 11262 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11263 } 11264 } 11265 11266 private boolean makeAppCrashingLocked(ProcessRecord app, 11267 String shortMsg, String longMsg, String stackTrace) { 11268 app.crashing = true; 11269 app.crashingReport = generateProcessError(app, 11270 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11271 startAppProblemLocked(app); 11272 app.stopFreezingAllLocked(); 11273 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11274 } 11275 11276 private void makeAppNotRespondingLocked(ProcessRecord app, 11277 String activity, String shortMsg, String longMsg) { 11278 app.notResponding = true; 11279 app.notRespondingReport = generateProcessError(app, 11280 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11281 activity, shortMsg, longMsg, null); 11282 startAppProblemLocked(app); 11283 app.stopFreezingAllLocked(); 11284 } 11285 11286 /** 11287 * Generate a process error record, suitable for attachment to a ProcessRecord. 11288 * 11289 * @param app The ProcessRecord in which the error occurred. 11290 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11291 * ActivityManager.AppErrorStateInfo 11292 * @param activity The activity associated with the crash, if known. 11293 * @param shortMsg Short message describing the crash. 11294 * @param longMsg Long message describing the crash. 11295 * @param stackTrace Full crash stack trace, may be null. 11296 * 11297 * @return Returns a fully-formed AppErrorStateInfo record. 11298 */ 11299 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11300 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11301 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11302 11303 report.condition = condition; 11304 report.processName = app.processName; 11305 report.pid = app.pid; 11306 report.uid = app.info.uid; 11307 report.tag = activity; 11308 report.shortMsg = shortMsg; 11309 report.longMsg = longMsg; 11310 report.stackTrace = stackTrace; 11311 11312 return report; 11313 } 11314 11315 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11316 synchronized (this) { 11317 app.crashing = false; 11318 app.crashingReport = null; 11319 app.notResponding = false; 11320 app.notRespondingReport = null; 11321 if (app.anrDialog == fromDialog) { 11322 app.anrDialog = null; 11323 } 11324 if (app.waitDialog == fromDialog) { 11325 app.waitDialog = null; 11326 } 11327 if (app.pid > 0 && app.pid != MY_PID) { 11328 handleAppCrashLocked(app, null, null, null); 11329 app.kill("user request after error", true); 11330 } 11331 } 11332 } 11333 11334 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11335 String stackTrace) { 11336 long now = SystemClock.uptimeMillis(); 11337 11338 Long crashTime; 11339 if (!app.isolated) { 11340 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11341 } else { 11342 crashTime = null; 11343 } 11344 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11345 // This process loses! 11346 Slog.w(TAG, "Process " + app.info.processName 11347 + " has crashed too many times: killing!"); 11348 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11349 app.userId, app.info.processName, app.uid); 11350 mStackSupervisor.handleAppCrashLocked(app); 11351 if (!app.persistent) { 11352 // We don't want to start this process again until the user 11353 // explicitly does so... but for persistent process, we really 11354 // need to keep it running. If a persistent process is actually 11355 // repeatedly crashing, then badness for everyone. 11356 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11357 app.info.processName); 11358 if (!app.isolated) { 11359 // XXX We don't have a way to mark isolated processes 11360 // as bad, since they don't have a peristent identity. 11361 mBadProcesses.put(app.info.processName, app.uid, 11362 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11363 mProcessCrashTimes.remove(app.info.processName, app.uid); 11364 } 11365 app.bad = true; 11366 app.removed = true; 11367 // Don't let services in this process be restarted and potentially 11368 // annoy the user repeatedly. Unless it is persistent, since those 11369 // processes run critical code. 11370 removeProcessLocked(app, false, false, "crash"); 11371 mStackSupervisor.resumeTopActivitiesLocked(); 11372 return false; 11373 } 11374 mStackSupervisor.resumeTopActivitiesLocked(); 11375 } else { 11376 mStackSupervisor.finishTopRunningActivityLocked(app); 11377 } 11378 11379 // Bump up the crash count of any services currently running in the proc. 11380 for (int i=app.services.size()-1; i>=0; i--) { 11381 // Any services running in the application need to be placed 11382 // back in the pending list. 11383 ServiceRecord sr = app.services.valueAt(i); 11384 sr.crashCount++; 11385 } 11386 11387 // If the crashing process is what we consider to be the "home process" and it has been 11388 // replaced by a third-party app, clear the package preferred activities from packages 11389 // with a home activity running in the process to prevent a repeatedly crashing app 11390 // from blocking the user to manually clear the list. 11391 final ArrayList<ActivityRecord> activities = app.activities; 11392 if (app == mHomeProcess && activities.size() > 0 11393 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11394 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11395 final ActivityRecord r = activities.get(activityNdx); 11396 if (r.isHomeActivity()) { 11397 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11398 try { 11399 ActivityThread.getPackageManager() 11400 .clearPackagePreferredActivities(r.packageName); 11401 } catch (RemoteException c) { 11402 // pm is in same process, this will never happen. 11403 } 11404 } 11405 } 11406 } 11407 11408 if (!app.isolated) { 11409 // XXX Can't keep track of crash times for isolated processes, 11410 // because they don't have a perisistent identity. 11411 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11412 } 11413 11414 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11415 return true; 11416 } 11417 11418 void startAppProblemLocked(ProcessRecord app) { 11419 // If this app is not running under the current user, then we 11420 // can't give it a report button because that would require 11421 // launching the report UI under a different user. 11422 app.errorReportReceiver = null; 11423 11424 for (int userId : mCurrentProfileIds) { 11425 if (app.userId == userId) { 11426 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11427 mContext, app.info.packageName, app.info.flags); 11428 } 11429 } 11430 skipCurrentReceiverLocked(app); 11431 } 11432 11433 void skipCurrentReceiverLocked(ProcessRecord app) { 11434 for (BroadcastQueue queue : mBroadcastQueues) { 11435 queue.skipCurrentReceiverLocked(app); 11436 } 11437 } 11438 11439 /** 11440 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11441 * The application process will exit immediately after this call returns. 11442 * @param app object of the crashing app, null for the system server 11443 * @param crashInfo describing the exception 11444 */ 11445 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11446 ProcessRecord r = findAppProcess(app, "Crash"); 11447 final String processName = app == null ? "system_server" 11448 : (r == null ? "unknown" : r.processName); 11449 11450 handleApplicationCrashInner("crash", r, processName, crashInfo); 11451 } 11452 11453 /* Native crash reporting uses this inner version because it needs to be somewhat 11454 * decoupled from the AM-managed cleanup lifecycle 11455 */ 11456 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11457 ApplicationErrorReport.CrashInfo crashInfo) { 11458 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11459 UserHandle.getUserId(Binder.getCallingUid()), processName, 11460 r == null ? -1 : r.info.flags, 11461 crashInfo.exceptionClassName, 11462 crashInfo.exceptionMessage, 11463 crashInfo.throwFileName, 11464 crashInfo.throwLineNumber); 11465 11466 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11467 11468 crashApplication(r, crashInfo); 11469 } 11470 11471 public void handleApplicationStrictModeViolation( 11472 IBinder app, 11473 int violationMask, 11474 StrictMode.ViolationInfo info) { 11475 ProcessRecord r = findAppProcess(app, "StrictMode"); 11476 if (r == null) { 11477 return; 11478 } 11479 11480 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11481 Integer stackFingerprint = info.hashCode(); 11482 boolean logIt = true; 11483 synchronized (mAlreadyLoggedViolatedStacks) { 11484 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11485 logIt = false; 11486 // TODO: sub-sample into EventLog for these, with 11487 // the info.durationMillis? Then we'd get 11488 // the relative pain numbers, without logging all 11489 // the stack traces repeatedly. We'd want to do 11490 // likewise in the client code, which also does 11491 // dup suppression, before the Binder call. 11492 } else { 11493 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11494 mAlreadyLoggedViolatedStacks.clear(); 11495 } 11496 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11497 } 11498 } 11499 if (logIt) { 11500 logStrictModeViolationToDropBox(r, info); 11501 } 11502 } 11503 11504 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11505 AppErrorResult result = new AppErrorResult(); 11506 synchronized (this) { 11507 final long origId = Binder.clearCallingIdentity(); 11508 11509 Message msg = Message.obtain(); 11510 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11511 HashMap<String, Object> data = new HashMap<String, Object>(); 11512 data.put("result", result); 11513 data.put("app", r); 11514 data.put("violationMask", violationMask); 11515 data.put("info", info); 11516 msg.obj = data; 11517 mHandler.sendMessage(msg); 11518 11519 Binder.restoreCallingIdentity(origId); 11520 } 11521 int res = result.get(); 11522 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11523 } 11524 } 11525 11526 // Depending on the policy in effect, there could be a bunch of 11527 // these in quick succession so we try to batch these together to 11528 // minimize disk writes, number of dropbox entries, and maximize 11529 // compression, by having more fewer, larger records. 11530 private void logStrictModeViolationToDropBox( 11531 ProcessRecord process, 11532 StrictMode.ViolationInfo info) { 11533 if (info == null) { 11534 return; 11535 } 11536 final boolean isSystemApp = process == null || 11537 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11538 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11539 final String processName = process == null ? "unknown" : process.processName; 11540 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11541 final DropBoxManager dbox = (DropBoxManager) 11542 mContext.getSystemService(Context.DROPBOX_SERVICE); 11543 11544 // Exit early if the dropbox isn't configured to accept this report type. 11545 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11546 11547 boolean bufferWasEmpty; 11548 boolean needsFlush; 11549 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11550 synchronized (sb) { 11551 bufferWasEmpty = sb.length() == 0; 11552 appendDropBoxProcessHeaders(process, processName, sb); 11553 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11554 sb.append("System-App: ").append(isSystemApp).append("\n"); 11555 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11556 if (info.violationNumThisLoop != 0) { 11557 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11558 } 11559 if (info.numAnimationsRunning != 0) { 11560 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11561 } 11562 if (info.broadcastIntentAction != null) { 11563 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11564 } 11565 if (info.durationMillis != -1) { 11566 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11567 } 11568 if (info.numInstances != -1) { 11569 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11570 } 11571 if (info.tags != null) { 11572 for (String tag : info.tags) { 11573 sb.append("Span-Tag: ").append(tag).append("\n"); 11574 } 11575 } 11576 sb.append("\n"); 11577 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11578 sb.append(info.crashInfo.stackTrace); 11579 } 11580 sb.append("\n"); 11581 11582 // Only buffer up to ~64k. Various logging bits truncate 11583 // things at 128k. 11584 needsFlush = (sb.length() > 64 * 1024); 11585 } 11586 11587 // Flush immediately if the buffer's grown too large, or this 11588 // is a non-system app. Non-system apps are isolated with a 11589 // different tag & policy and not batched. 11590 // 11591 // Batching is useful during internal testing with 11592 // StrictMode settings turned up high. Without batching, 11593 // thousands of separate files could be created on boot. 11594 if (!isSystemApp || needsFlush) { 11595 new Thread("Error dump: " + dropboxTag) { 11596 @Override 11597 public void run() { 11598 String report; 11599 synchronized (sb) { 11600 report = sb.toString(); 11601 sb.delete(0, sb.length()); 11602 sb.trimToSize(); 11603 } 11604 if (report.length() != 0) { 11605 dbox.addText(dropboxTag, report); 11606 } 11607 } 11608 }.start(); 11609 return; 11610 } 11611 11612 // System app batching: 11613 if (!bufferWasEmpty) { 11614 // An existing dropbox-writing thread is outstanding, so 11615 // we don't need to start it up. The existing thread will 11616 // catch the buffer appends we just did. 11617 return; 11618 } 11619 11620 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11621 // (After this point, we shouldn't access AMS internal data structures.) 11622 new Thread("Error dump: " + dropboxTag) { 11623 @Override 11624 public void run() { 11625 // 5 second sleep to let stacks arrive and be batched together 11626 try { 11627 Thread.sleep(5000); // 5 seconds 11628 } catch (InterruptedException e) {} 11629 11630 String errorReport; 11631 synchronized (mStrictModeBuffer) { 11632 errorReport = mStrictModeBuffer.toString(); 11633 if (errorReport.length() == 0) { 11634 return; 11635 } 11636 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11637 mStrictModeBuffer.trimToSize(); 11638 } 11639 dbox.addText(dropboxTag, errorReport); 11640 } 11641 }.start(); 11642 } 11643 11644 /** 11645 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11646 * @param app object of the crashing app, null for the system server 11647 * @param tag reported by the caller 11648 * @param system whether this wtf is coming from the system 11649 * @param crashInfo describing the context of the error 11650 * @return true if the process should exit immediately (WTF is fatal) 11651 */ 11652 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11653 final ApplicationErrorReport.CrashInfo crashInfo) { 11654 final ProcessRecord r = findAppProcess(app, "WTF"); 11655 final String processName = app == null ? "system_server" 11656 : (r == null ? "unknown" : r.processName); 11657 11658 EventLog.writeEvent(EventLogTags.AM_WTF, 11659 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11660 processName, 11661 r == null ? -1 : r.info.flags, 11662 tag, crashInfo.exceptionMessage); 11663 11664 if (system) { 11665 // If this is coming from the system, we could very well have low-level 11666 // system locks held, so we want to do this all asynchronously. And we 11667 // never want this to become fatal, so there is that too. 11668 mHandler.post(new Runnable() { 11669 @Override public void run() { 11670 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11671 crashInfo); 11672 } 11673 }); 11674 return false; 11675 } 11676 11677 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11678 11679 if (r != null && r.pid != Process.myPid() && 11680 Settings.Global.getInt(mContext.getContentResolver(), 11681 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11682 crashApplication(r, crashInfo); 11683 return true; 11684 } else { 11685 return false; 11686 } 11687 } 11688 11689 /** 11690 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11691 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11692 */ 11693 private ProcessRecord findAppProcess(IBinder app, String reason) { 11694 if (app == null) { 11695 return null; 11696 } 11697 11698 synchronized (this) { 11699 final int NP = mProcessNames.getMap().size(); 11700 for (int ip=0; ip<NP; ip++) { 11701 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11702 final int NA = apps.size(); 11703 for (int ia=0; ia<NA; ia++) { 11704 ProcessRecord p = apps.valueAt(ia); 11705 if (p.thread != null && p.thread.asBinder() == app) { 11706 return p; 11707 } 11708 } 11709 } 11710 11711 Slog.w(TAG, "Can't find mystery application for " + reason 11712 + " from pid=" + Binder.getCallingPid() 11713 + " uid=" + Binder.getCallingUid() + ": " + app); 11714 return null; 11715 } 11716 } 11717 11718 /** 11719 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11720 * to append various headers to the dropbox log text. 11721 */ 11722 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11723 StringBuilder sb) { 11724 // Watchdog thread ends up invoking this function (with 11725 // a null ProcessRecord) to add the stack file to dropbox. 11726 // Do not acquire a lock on this (am) in such cases, as it 11727 // could cause a potential deadlock, if and when watchdog 11728 // is invoked due to unavailability of lock on am and it 11729 // would prevent watchdog from killing system_server. 11730 if (process == null) { 11731 sb.append("Process: ").append(processName).append("\n"); 11732 return; 11733 } 11734 // Note: ProcessRecord 'process' is guarded by the service 11735 // instance. (notably process.pkgList, which could otherwise change 11736 // concurrently during execution of this method) 11737 synchronized (this) { 11738 sb.append("Process: ").append(processName).append("\n"); 11739 int flags = process.info.flags; 11740 IPackageManager pm = AppGlobals.getPackageManager(); 11741 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11742 for (int ip=0; ip<process.pkgList.size(); ip++) { 11743 String pkg = process.pkgList.keyAt(ip); 11744 sb.append("Package: ").append(pkg); 11745 try { 11746 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11747 if (pi != null) { 11748 sb.append(" v").append(pi.versionCode); 11749 if (pi.versionName != null) { 11750 sb.append(" (").append(pi.versionName).append(")"); 11751 } 11752 } 11753 } catch (RemoteException e) { 11754 Slog.e(TAG, "Error getting package info: " + pkg, e); 11755 } 11756 sb.append("\n"); 11757 } 11758 } 11759 } 11760 11761 private static String processClass(ProcessRecord process) { 11762 if (process == null || process.pid == MY_PID) { 11763 return "system_server"; 11764 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11765 return "system_app"; 11766 } else { 11767 return "data_app"; 11768 } 11769 } 11770 11771 /** 11772 * Write a description of an error (crash, WTF, ANR) to the drop box. 11773 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11774 * @param process which caused the error, null means the system server 11775 * @param activity which triggered the error, null if unknown 11776 * @param parent activity related to the error, null if unknown 11777 * @param subject line related to the error, null if absent 11778 * @param report in long form describing the error, null if absent 11779 * @param logFile to include in the report, null if none 11780 * @param crashInfo giving an application stack trace, null if absent 11781 */ 11782 public void addErrorToDropBox(String eventType, 11783 ProcessRecord process, String processName, ActivityRecord activity, 11784 ActivityRecord parent, String subject, 11785 final String report, final File logFile, 11786 final ApplicationErrorReport.CrashInfo crashInfo) { 11787 // NOTE -- this must never acquire the ActivityManagerService lock, 11788 // otherwise the watchdog may be prevented from resetting the system. 11789 11790 final String dropboxTag = processClass(process) + "_" + eventType; 11791 final DropBoxManager dbox = (DropBoxManager) 11792 mContext.getSystemService(Context.DROPBOX_SERVICE); 11793 11794 // Exit early if the dropbox isn't configured to accept this report type. 11795 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11796 11797 final StringBuilder sb = new StringBuilder(1024); 11798 appendDropBoxProcessHeaders(process, processName, sb); 11799 if (activity != null) { 11800 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11801 } 11802 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11803 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11804 } 11805 if (parent != null && parent != activity) { 11806 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11807 } 11808 if (subject != null) { 11809 sb.append("Subject: ").append(subject).append("\n"); 11810 } 11811 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11812 if (Debug.isDebuggerConnected()) { 11813 sb.append("Debugger: Connected\n"); 11814 } 11815 sb.append("\n"); 11816 11817 // Do the rest in a worker thread to avoid blocking the caller on I/O 11818 // (After this point, we shouldn't access AMS internal data structures.) 11819 Thread worker = new Thread("Error dump: " + dropboxTag) { 11820 @Override 11821 public void run() { 11822 if (report != null) { 11823 sb.append(report); 11824 } 11825 if (logFile != null) { 11826 try { 11827 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11828 "\n\n[[TRUNCATED]]")); 11829 } catch (IOException e) { 11830 Slog.e(TAG, "Error reading " + logFile, e); 11831 } 11832 } 11833 if (crashInfo != null && crashInfo.stackTrace != null) { 11834 sb.append(crashInfo.stackTrace); 11835 } 11836 11837 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11838 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11839 if (lines > 0) { 11840 sb.append("\n"); 11841 11842 // Merge several logcat streams, and take the last N lines 11843 InputStreamReader input = null; 11844 try { 11845 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11846 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11847 "-b", "crash", 11848 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11849 11850 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11851 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11852 input = new InputStreamReader(logcat.getInputStream()); 11853 11854 int num; 11855 char[] buf = new char[8192]; 11856 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11857 } catch (IOException e) { 11858 Slog.e(TAG, "Error running logcat", e); 11859 } finally { 11860 if (input != null) try { input.close(); } catch (IOException e) {} 11861 } 11862 } 11863 11864 dbox.addText(dropboxTag, sb.toString()); 11865 } 11866 }; 11867 11868 if (process == null) { 11869 // If process is null, we are being called from some internal code 11870 // and may be about to die -- run this synchronously. 11871 worker.run(); 11872 } else { 11873 worker.start(); 11874 } 11875 } 11876 11877 /** 11878 * Bring up the "unexpected error" dialog box for a crashing app. 11879 * Deal with edge cases (intercepts from instrumented applications, 11880 * ActivityController, error intent receivers, that sort of thing). 11881 * @param r the application crashing 11882 * @param crashInfo describing the failure 11883 */ 11884 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11885 long timeMillis = System.currentTimeMillis(); 11886 String shortMsg = crashInfo.exceptionClassName; 11887 String longMsg = crashInfo.exceptionMessage; 11888 String stackTrace = crashInfo.stackTrace; 11889 if (shortMsg != null && longMsg != null) { 11890 longMsg = shortMsg + ": " + longMsg; 11891 } else if (shortMsg != null) { 11892 longMsg = shortMsg; 11893 } 11894 11895 AppErrorResult result = new AppErrorResult(); 11896 synchronized (this) { 11897 if (mController != null) { 11898 try { 11899 String name = r != null ? r.processName : null; 11900 int pid = r != null ? r.pid : Binder.getCallingPid(); 11901 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11902 if (!mController.appCrashed(name, pid, 11903 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11904 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11905 && "Native crash".equals(crashInfo.exceptionClassName)) { 11906 Slog.w(TAG, "Skip killing native crashed app " + name 11907 + "(" + pid + ") during testing"); 11908 } else { 11909 Slog.w(TAG, "Force-killing crashed app " + name 11910 + " at watcher's request"); 11911 if (r != null) { 11912 r.kill("crash", true); 11913 } else { 11914 // Huh. 11915 Process.killProcess(pid); 11916 Process.killProcessGroup(uid, pid); 11917 } 11918 } 11919 return; 11920 } 11921 } catch (RemoteException e) { 11922 mController = null; 11923 Watchdog.getInstance().setActivityController(null); 11924 } 11925 } 11926 11927 final long origId = Binder.clearCallingIdentity(); 11928 11929 // If this process is running instrumentation, finish it. 11930 if (r != null && r.instrumentationClass != null) { 11931 Slog.w(TAG, "Error in app " + r.processName 11932 + " running instrumentation " + r.instrumentationClass + ":"); 11933 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11934 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11935 Bundle info = new Bundle(); 11936 info.putString("shortMsg", shortMsg); 11937 info.putString("longMsg", longMsg); 11938 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11939 Binder.restoreCallingIdentity(origId); 11940 return; 11941 } 11942 11943 // If we can't identify the process or it's already exceeded its crash quota, 11944 // quit right away without showing a crash dialog. 11945 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11946 Binder.restoreCallingIdentity(origId); 11947 return; 11948 } 11949 11950 Message msg = Message.obtain(); 11951 msg.what = SHOW_ERROR_MSG; 11952 HashMap data = new HashMap(); 11953 data.put("result", result); 11954 data.put("app", r); 11955 msg.obj = data; 11956 mHandler.sendMessage(msg); 11957 11958 Binder.restoreCallingIdentity(origId); 11959 } 11960 11961 int res = result.get(); 11962 11963 Intent appErrorIntent = null; 11964 synchronized (this) { 11965 if (r != null && !r.isolated) { 11966 // XXX Can't keep track of crash time for isolated processes, 11967 // since they don't have a persistent identity. 11968 mProcessCrashTimes.put(r.info.processName, r.uid, 11969 SystemClock.uptimeMillis()); 11970 } 11971 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11972 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11973 } 11974 } 11975 11976 if (appErrorIntent != null) { 11977 try { 11978 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11979 } catch (ActivityNotFoundException e) { 11980 Slog.w(TAG, "bug report receiver dissappeared", e); 11981 } 11982 } 11983 } 11984 11985 Intent createAppErrorIntentLocked(ProcessRecord r, 11986 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11987 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11988 if (report == null) { 11989 return null; 11990 } 11991 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11992 result.setComponent(r.errorReportReceiver); 11993 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11994 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11995 return result; 11996 } 11997 11998 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11999 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12000 if (r.errorReportReceiver == null) { 12001 return null; 12002 } 12003 12004 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12005 return null; 12006 } 12007 12008 ApplicationErrorReport report = new ApplicationErrorReport(); 12009 report.packageName = r.info.packageName; 12010 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12011 report.processName = r.processName; 12012 report.time = timeMillis; 12013 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12014 12015 if (r.crashing || r.forceCrashReport) { 12016 report.type = ApplicationErrorReport.TYPE_CRASH; 12017 report.crashInfo = crashInfo; 12018 } else if (r.notResponding) { 12019 report.type = ApplicationErrorReport.TYPE_ANR; 12020 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12021 12022 report.anrInfo.activity = r.notRespondingReport.tag; 12023 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12024 report.anrInfo.info = r.notRespondingReport.longMsg; 12025 } 12026 12027 return report; 12028 } 12029 12030 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12031 enforceNotIsolatedCaller("getProcessesInErrorState"); 12032 // assume our apps are happy - lazy create the list 12033 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12034 12035 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12036 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12037 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12038 12039 synchronized (this) { 12040 12041 // iterate across all processes 12042 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12043 ProcessRecord app = mLruProcesses.get(i); 12044 if (!allUsers && app.userId != userId) { 12045 continue; 12046 } 12047 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12048 // This one's in trouble, so we'll generate a report for it 12049 // crashes are higher priority (in case there's a crash *and* an anr) 12050 ActivityManager.ProcessErrorStateInfo report = null; 12051 if (app.crashing) { 12052 report = app.crashingReport; 12053 } else if (app.notResponding) { 12054 report = app.notRespondingReport; 12055 } 12056 12057 if (report != null) { 12058 if (errList == null) { 12059 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12060 } 12061 errList.add(report); 12062 } else { 12063 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12064 " crashing = " + app.crashing + 12065 " notResponding = " + app.notResponding); 12066 } 12067 } 12068 } 12069 } 12070 12071 return errList; 12072 } 12073 12074 static int procStateToImportance(int procState, int memAdj, 12075 ActivityManager.RunningAppProcessInfo currApp) { 12076 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12077 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12078 currApp.lru = memAdj; 12079 } else { 12080 currApp.lru = 0; 12081 } 12082 return imp; 12083 } 12084 12085 private void fillInProcMemInfo(ProcessRecord app, 12086 ActivityManager.RunningAppProcessInfo outInfo) { 12087 outInfo.pid = app.pid; 12088 outInfo.uid = app.info.uid; 12089 if (mHeavyWeightProcess == app) { 12090 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12091 } 12092 if (app.persistent) { 12093 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12094 } 12095 if (app.activities.size() > 0) { 12096 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12097 } 12098 outInfo.lastTrimLevel = app.trimMemoryLevel; 12099 int adj = app.curAdj; 12100 int procState = app.curProcState; 12101 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12102 outInfo.importanceReasonCode = app.adjTypeCode; 12103 outInfo.processState = app.curProcState; 12104 } 12105 12106 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12107 enforceNotIsolatedCaller("getRunningAppProcesses"); 12108 // Lazy instantiation of list 12109 List<ActivityManager.RunningAppProcessInfo> runList = null; 12110 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12111 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12112 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12113 synchronized (this) { 12114 // Iterate across all processes 12115 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12116 ProcessRecord app = mLruProcesses.get(i); 12117 if (!allUsers && app.userId != userId) { 12118 continue; 12119 } 12120 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12121 // Generate process state info for running application 12122 ActivityManager.RunningAppProcessInfo currApp = 12123 new ActivityManager.RunningAppProcessInfo(app.processName, 12124 app.pid, app.getPackageList()); 12125 fillInProcMemInfo(app, currApp); 12126 if (app.adjSource instanceof ProcessRecord) { 12127 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12128 currApp.importanceReasonImportance = 12129 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12130 app.adjSourceProcState); 12131 } else if (app.adjSource instanceof ActivityRecord) { 12132 ActivityRecord r = (ActivityRecord)app.adjSource; 12133 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12134 } 12135 if (app.adjTarget instanceof ComponentName) { 12136 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12137 } 12138 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12139 // + " lru=" + currApp.lru); 12140 if (runList == null) { 12141 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12142 } 12143 runList.add(currApp); 12144 } 12145 } 12146 } 12147 return runList; 12148 } 12149 12150 public List<ApplicationInfo> getRunningExternalApplications() { 12151 enforceNotIsolatedCaller("getRunningExternalApplications"); 12152 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12153 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12154 if (runningApps != null && runningApps.size() > 0) { 12155 Set<String> extList = new HashSet<String>(); 12156 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12157 if (app.pkgList != null) { 12158 for (String pkg : app.pkgList) { 12159 extList.add(pkg); 12160 } 12161 } 12162 } 12163 IPackageManager pm = AppGlobals.getPackageManager(); 12164 for (String pkg : extList) { 12165 try { 12166 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12167 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12168 retList.add(info); 12169 } 12170 } catch (RemoteException e) { 12171 } 12172 } 12173 } 12174 return retList; 12175 } 12176 12177 @Override 12178 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12179 enforceNotIsolatedCaller("getMyMemoryState"); 12180 synchronized (this) { 12181 ProcessRecord proc; 12182 synchronized (mPidsSelfLocked) { 12183 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12184 } 12185 fillInProcMemInfo(proc, outInfo); 12186 } 12187 } 12188 12189 @Override 12190 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12191 if (checkCallingPermission(android.Manifest.permission.DUMP) 12192 != PackageManager.PERMISSION_GRANTED) { 12193 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12194 + Binder.getCallingPid() 12195 + ", uid=" + Binder.getCallingUid() 12196 + " without permission " 12197 + android.Manifest.permission.DUMP); 12198 return; 12199 } 12200 12201 boolean dumpAll = false; 12202 boolean dumpClient = false; 12203 String dumpPackage = null; 12204 12205 int opti = 0; 12206 while (opti < args.length) { 12207 String opt = args[opti]; 12208 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12209 break; 12210 } 12211 opti++; 12212 if ("-a".equals(opt)) { 12213 dumpAll = true; 12214 } else if ("-c".equals(opt)) { 12215 dumpClient = true; 12216 } else if ("-h".equals(opt)) { 12217 pw.println("Activity manager dump options:"); 12218 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12219 pw.println(" cmd may be one of:"); 12220 pw.println(" a[ctivities]: activity stack state"); 12221 pw.println(" r[recents]: recent activities state"); 12222 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12223 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12224 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12225 pw.println(" o[om]: out of memory management"); 12226 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12227 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12228 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12229 pw.println(" service [COMP_SPEC]: service client-side state"); 12230 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12231 pw.println(" all: dump all activities"); 12232 pw.println(" top: dump the top activity"); 12233 pw.println(" write: write all pending state to storage"); 12234 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12235 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12236 pw.println(" a partial substring in a component name, a"); 12237 pw.println(" hex object identifier."); 12238 pw.println(" -a: include all available server state."); 12239 pw.println(" -c: include client state."); 12240 return; 12241 } else { 12242 pw.println("Unknown argument: " + opt + "; use -h for help"); 12243 } 12244 } 12245 12246 long origId = Binder.clearCallingIdentity(); 12247 boolean more = false; 12248 // Is the caller requesting to dump a particular piece of data? 12249 if (opti < args.length) { 12250 String cmd = args[opti]; 12251 opti++; 12252 if ("activities".equals(cmd) || "a".equals(cmd)) { 12253 synchronized (this) { 12254 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12255 } 12256 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12257 synchronized (this) { 12258 dumpRecentsLocked(fd, pw, args, opti, true, null); 12259 } 12260 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12261 String[] newArgs; 12262 String name; 12263 if (opti >= args.length) { 12264 name = null; 12265 newArgs = EMPTY_STRING_ARRAY; 12266 } else { 12267 name = args[opti]; 12268 opti++; 12269 newArgs = new String[args.length - opti]; 12270 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12271 args.length - opti); 12272 } 12273 synchronized (this) { 12274 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12275 } 12276 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12277 String[] newArgs; 12278 String name; 12279 if (opti >= args.length) { 12280 name = null; 12281 newArgs = EMPTY_STRING_ARRAY; 12282 } else { 12283 name = args[opti]; 12284 opti++; 12285 newArgs = new String[args.length - opti]; 12286 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12287 args.length - opti); 12288 } 12289 synchronized (this) { 12290 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12291 } 12292 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12293 String[] newArgs; 12294 String name; 12295 if (opti >= args.length) { 12296 name = null; 12297 newArgs = EMPTY_STRING_ARRAY; 12298 } else { 12299 name = args[opti]; 12300 opti++; 12301 newArgs = new String[args.length - opti]; 12302 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12303 args.length - opti); 12304 } 12305 synchronized (this) { 12306 dumpProcessesLocked(fd, pw, args, opti, true, name); 12307 } 12308 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12309 synchronized (this) { 12310 dumpOomLocked(fd, pw, args, opti, true); 12311 } 12312 } else if ("provider".equals(cmd)) { 12313 String[] newArgs; 12314 String name; 12315 if (opti >= args.length) { 12316 name = null; 12317 newArgs = EMPTY_STRING_ARRAY; 12318 } else { 12319 name = args[opti]; 12320 opti++; 12321 newArgs = new String[args.length - opti]; 12322 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12323 } 12324 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12325 pw.println("No providers match: " + name); 12326 pw.println("Use -h for help."); 12327 } 12328 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12329 synchronized (this) { 12330 dumpProvidersLocked(fd, pw, args, opti, true, null); 12331 } 12332 } else if ("service".equals(cmd)) { 12333 String[] newArgs; 12334 String name; 12335 if (opti >= args.length) { 12336 name = null; 12337 newArgs = EMPTY_STRING_ARRAY; 12338 } else { 12339 name = args[opti]; 12340 opti++; 12341 newArgs = new String[args.length - opti]; 12342 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12343 args.length - opti); 12344 } 12345 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12346 pw.println("No services match: " + name); 12347 pw.println("Use -h for help."); 12348 } 12349 } else if ("package".equals(cmd)) { 12350 String[] newArgs; 12351 if (opti >= args.length) { 12352 pw.println("package: no package name specified"); 12353 pw.println("Use -h for help."); 12354 } else { 12355 dumpPackage = args[opti]; 12356 opti++; 12357 newArgs = new String[args.length - opti]; 12358 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12359 args.length - opti); 12360 args = newArgs; 12361 opti = 0; 12362 more = true; 12363 } 12364 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12365 synchronized (this) { 12366 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12367 } 12368 } else if ("write".equals(cmd)) { 12369 mTaskPersister.flush(); 12370 pw.println("All tasks persisted."); 12371 return; 12372 } else { 12373 // Dumping a single activity? 12374 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12375 pw.println("Bad activity command, or no activities match: " + cmd); 12376 pw.println("Use -h for help."); 12377 } 12378 } 12379 if (!more) { 12380 Binder.restoreCallingIdentity(origId); 12381 return; 12382 } 12383 } 12384 12385 // No piece of data specified, dump everything. 12386 synchronized (this) { 12387 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12388 pw.println(); 12389 if (dumpAll) { 12390 pw.println("-------------------------------------------------------------------------------"); 12391 } 12392 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12393 pw.println(); 12394 if (dumpAll) { 12395 pw.println("-------------------------------------------------------------------------------"); 12396 } 12397 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12398 pw.println(); 12399 if (dumpAll) { 12400 pw.println("-------------------------------------------------------------------------------"); 12401 } 12402 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12403 pw.println(); 12404 if (dumpAll) { 12405 pw.println("-------------------------------------------------------------------------------"); 12406 } 12407 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12408 pw.println(); 12409 if (dumpAll) { 12410 pw.println("-------------------------------------------------------------------------------"); 12411 } 12412 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12413 pw.println(); 12414 if (dumpAll) { 12415 pw.println("-------------------------------------------------------------------------------"); 12416 } 12417 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12418 } 12419 Binder.restoreCallingIdentity(origId); 12420 } 12421 12422 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12423 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12424 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12425 12426 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12427 dumpPackage); 12428 boolean needSep = printedAnything; 12429 12430 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12431 dumpPackage, needSep, " mFocusedActivity: "); 12432 if (printed) { 12433 printedAnything = true; 12434 needSep = false; 12435 } 12436 12437 if (dumpPackage == null) { 12438 if (needSep) { 12439 pw.println(); 12440 } 12441 needSep = true; 12442 printedAnything = true; 12443 mStackSupervisor.dump(pw, " "); 12444 } 12445 12446 if (!printedAnything) { 12447 pw.println(" (nothing)"); 12448 } 12449 } 12450 12451 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12452 int opti, boolean dumpAll, String dumpPackage) { 12453 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12454 12455 boolean printedAnything = false; 12456 12457 if (mRecentTasks.size() > 0) { 12458 boolean printedHeader = false; 12459 12460 final int N = mRecentTasks.size(); 12461 for (int i=0; i<N; i++) { 12462 TaskRecord tr = mRecentTasks.get(i); 12463 if (dumpPackage != null) { 12464 if (tr.realActivity == null || 12465 !dumpPackage.equals(tr.realActivity)) { 12466 continue; 12467 } 12468 } 12469 if (!printedHeader) { 12470 pw.println(" Recent tasks:"); 12471 printedHeader = true; 12472 printedAnything = true; 12473 } 12474 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12475 pw.println(tr); 12476 if (dumpAll) { 12477 mRecentTasks.get(i).dump(pw, " "); 12478 } 12479 } 12480 } 12481 12482 if (!printedAnything) { 12483 pw.println(" (nothing)"); 12484 } 12485 } 12486 12487 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12488 int opti, boolean dumpAll, String dumpPackage) { 12489 boolean needSep = false; 12490 boolean printedAnything = false; 12491 int numPers = 0; 12492 12493 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12494 12495 if (dumpAll) { 12496 final int NP = mProcessNames.getMap().size(); 12497 for (int ip=0; ip<NP; ip++) { 12498 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12499 final int NA = procs.size(); 12500 for (int ia=0; ia<NA; ia++) { 12501 ProcessRecord r = procs.valueAt(ia); 12502 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12503 continue; 12504 } 12505 if (!needSep) { 12506 pw.println(" All known processes:"); 12507 needSep = true; 12508 printedAnything = true; 12509 } 12510 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12511 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12512 pw.print(" "); pw.println(r); 12513 r.dump(pw, " "); 12514 if (r.persistent) { 12515 numPers++; 12516 } 12517 } 12518 } 12519 } 12520 12521 if (mIsolatedProcesses.size() > 0) { 12522 boolean printed = false; 12523 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12524 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12525 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12526 continue; 12527 } 12528 if (!printed) { 12529 if (needSep) { 12530 pw.println(); 12531 } 12532 pw.println(" Isolated process list (sorted by uid):"); 12533 printedAnything = true; 12534 printed = true; 12535 needSep = true; 12536 } 12537 pw.println(String.format("%sIsolated #%2d: %s", 12538 " ", i, r.toString())); 12539 } 12540 } 12541 12542 if (mLruProcesses.size() > 0) { 12543 if (needSep) { 12544 pw.println(); 12545 } 12546 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12547 pw.print(" total, non-act at "); 12548 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12549 pw.print(", non-svc at "); 12550 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12551 pw.println("):"); 12552 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12553 needSep = true; 12554 printedAnything = true; 12555 } 12556 12557 if (dumpAll || dumpPackage != null) { 12558 synchronized (mPidsSelfLocked) { 12559 boolean printed = false; 12560 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12561 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12562 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12563 continue; 12564 } 12565 if (!printed) { 12566 if (needSep) pw.println(); 12567 needSep = true; 12568 pw.println(" PID mappings:"); 12569 printed = true; 12570 printedAnything = true; 12571 } 12572 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12573 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12574 } 12575 } 12576 } 12577 12578 if (mForegroundProcesses.size() > 0) { 12579 synchronized (mPidsSelfLocked) { 12580 boolean printed = false; 12581 for (int i=0; i<mForegroundProcesses.size(); i++) { 12582 ProcessRecord r = mPidsSelfLocked.get( 12583 mForegroundProcesses.valueAt(i).pid); 12584 if (dumpPackage != null && (r == null 12585 || !r.pkgList.containsKey(dumpPackage))) { 12586 continue; 12587 } 12588 if (!printed) { 12589 if (needSep) pw.println(); 12590 needSep = true; 12591 pw.println(" Foreground Processes:"); 12592 printed = true; 12593 printedAnything = true; 12594 } 12595 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12596 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12597 } 12598 } 12599 } 12600 12601 if (mPersistentStartingProcesses.size() > 0) { 12602 if (needSep) pw.println(); 12603 needSep = true; 12604 printedAnything = true; 12605 pw.println(" Persisent processes that are starting:"); 12606 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12607 "Starting Norm", "Restarting PERS", dumpPackage); 12608 } 12609 12610 if (mRemovedProcesses.size() > 0) { 12611 if (needSep) pw.println(); 12612 needSep = true; 12613 printedAnything = true; 12614 pw.println(" Processes that are being removed:"); 12615 dumpProcessList(pw, this, mRemovedProcesses, " ", 12616 "Removed Norm", "Removed PERS", dumpPackage); 12617 } 12618 12619 if (mProcessesOnHold.size() > 0) { 12620 if (needSep) pw.println(); 12621 needSep = true; 12622 printedAnything = true; 12623 pw.println(" Processes that are on old until the system is ready:"); 12624 dumpProcessList(pw, this, mProcessesOnHold, " ", 12625 "OnHold Norm", "OnHold PERS", dumpPackage); 12626 } 12627 12628 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12629 12630 if (mProcessCrashTimes.getMap().size() > 0) { 12631 boolean printed = false; 12632 long now = SystemClock.uptimeMillis(); 12633 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12634 final int NP = pmap.size(); 12635 for (int ip=0; ip<NP; ip++) { 12636 String pname = pmap.keyAt(ip); 12637 SparseArray<Long> uids = pmap.valueAt(ip); 12638 final int N = uids.size(); 12639 for (int i=0; i<N; i++) { 12640 int puid = uids.keyAt(i); 12641 ProcessRecord r = mProcessNames.get(pname, puid); 12642 if (dumpPackage != null && (r == null 12643 || !r.pkgList.containsKey(dumpPackage))) { 12644 continue; 12645 } 12646 if (!printed) { 12647 if (needSep) pw.println(); 12648 needSep = true; 12649 pw.println(" Time since processes crashed:"); 12650 printed = true; 12651 printedAnything = true; 12652 } 12653 pw.print(" Process "); pw.print(pname); 12654 pw.print(" uid "); pw.print(puid); 12655 pw.print(": last crashed "); 12656 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12657 pw.println(" ago"); 12658 } 12659 } 12660 } 12661 12662 if (mBadProcesses.getMap().size() > 0) { 12663 boolean printed = false; 12664 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12665 final int NP = pmap.size(); 12666 for (int ip=0; ip<NP; ip++) { 12667 String pname = pmap.keyAt(ip); 12668 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12669 final int N = uids.size(); 12670 for (int i=0; i<N; i++) { 12671 int puid = uids.keyAt(i); 12672 ProcessRecord r = mProcessNames.get(pname, puid); 12673 if (dumpPackage != null && (r == null 12674 || !r.pkgList.containsKey(dumpPackage))) { 12675 continue; 12676 } 12677 if (!printed) { 12678 if (needSep) pw.println(); 12679 needSep = true; 12680 pw.println(" Bad processes:"); 12681 printedAnything = true; 12682 } 12683 BadProcessInfo info = uids.valueAt(i); 12684 pw.print(" Bad process "); pw.print(pname); 12685 pw.print(" uid "); pw.print(puid); 12686 pw.print(": crashed at time "); pw.println(info.time); 12687 if (info.shortMsg != null) { 12688 pw.print(" Short msg: "); pw.println(info.shortMsg); 12689 } 12690 if (info.longMsg != null) { 12691 pw.print(" Long msg: "); pw.println(info.longMsg); 12692 } 12693 if (info.stack != null) { 12694 pw.println(" Stack:"); 12695 int lastPos = 0; 12696 for (int pos=0; pos<info.stack.length(); pos++) { 12697 if (info.stack.charAt(pos) == '\n') { 12698 pw.print(" "); 12699 pw.write(info.stack, lastPos, pos-lastPos); 12700 pw.println(); 12701 lastPos = pos+1; 12702 } 12703 } 12704 if (lastPos < info.stack.length()) { 12705 pw.print(" "); 12706 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12707 pw.println(); 12708 } 12709 } 12710 } 12711 } 12712 } 12713 12714 if (dumpPackage == null) { 12715 pw.println(); 12716 needSep = false; 12717 pw.println(" mStartedUsers:"); 12718 for (int i=0; i<mStartedUsers.size(); i++) { 12719 UserStartedState uss = mStartedUsers.valueAt(i); 12720 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12721 pw.print(": "); uss.dump("", pw); 12722 } 12723 pw.print(" mStartedUserArray: ["); 12724 for (int i=0; i<mStartedUserArray.length; i++) { 12725 if (i > 0) pw.print(", "); 12726 pw.print(mStartedUserArray[i]); 12727 } 12728 pw.println("]"); 12729 pw.print(" mUserLru: ["); 12730 for (int i=0; i<mUserLru.size(); i++) { 12731 if (i > 0) pw.print(", "); 12732 pw.print(mUserLru.get(i)); 12733 } 12734 pw.println("]"); 12735 if (dumpAll) { 12736 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12737 } 12738 synchronized (mUserProfileGroupIdsSelfLocked) { 12739 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12740 pw.println(" mUserProfileGroupIds:"); 12741 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12742 pw.print(" User #"); 12743 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12744 pw.print(" -> profile #"); 12745 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12746 } 12747 } 12748 } 12749 } 12750 if (mHomeProcess != null && (dumpPackage == null 12751 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12752 if (needSep) { 12753 pw.println(); 12754 needSep = false; 12755 } 12756 pw.println(" mHomeProcess: " + mHomeProcess); 12757 } 12758 if (mPreviousProcess != null && (dumpPackage == null 12759 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12760 if (needSep) { 12761 pw.println(); 12762 needSep = false; 12763 } 12764 pw.println(" mPreviousProcess: " + mPreviousProcess); 12765 } 12766 if (dumpAll) { 12767 StringBuilder sb = new StringBuilder(128); 12768 sb.append(" mPreviousProcessVisibleTime: "); 12769 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12770 pw.println(sb); 12771 } 12772 if (mHeavyWeightProcess != null && (dumpPackage == null 12773 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12774 if (needSep) { 12775 pw.println(); 12776 needSep = false; 12777 } 12778 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12779 } 12780 if (dumpPackage == null) { 12781 pw.println(" mConfiguration: " + mConfiguration); 12782 } 12783 if (dumpAll) { 12784 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12785 if (mCompatModePackages.getPackages().size() > 0) { 12786 boolean printed = false; 12787 for (Map.Entry<String, Integer> entry 12788 : mCompatModePackages.getPackages().entrySet()) { 12789 String pkg = entry.getKey(); 12790 int mode = entry.getValue(); 12791 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12792 continue; 12793 } 12794 if (!printed) { 12795 pw.println(" mScreenCompatPackages:"); 12796 printed = true; 12797 } 12798 pw.print(" "); pw.print(pkg); pw.print(": "); 12799 pw.print(mode); pw.println(); 12800 } 12801 } 12802 } 12803 if (dumpPackage == null) { 12804 if (mSleeping || mWentToSleep || mLockScreenShown) { 12805 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12806 + " mLockScreenShown " + mLockScreenShown); 12807 } 12808 if (mShuttingDown || mRunningVoice) { 12809 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12810 } 12811 } 12812 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12813 || mOrigWaitForDebugger) { 12814 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12815 || dumpPackage.equals(mOrigDebugApp)) { 12816 if (needSep) { 12817 pw.println(); 12818 needSep = false; 12819 } 12820 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12821 + " mDebugTransient=" + mDebugTransient 12822 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12823 } 12824 } 12825 if (mOpenGlTraceApp != null) { 12826 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12827 if (needSep) { 12828 pw.println(); 12829 needSep = false; 12830 } 12831 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12832 } 12833 } 12834 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12835 || mProfileFd != null) { 12836 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12837 if (needSep) { 12838 pw.println(); 12839 needSep = false; 12840 } 12841 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12842 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12843 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12844 + mAutoStopProfiler); 12845 pw.println(" mProfileType=" + mProfileType); 12846 } 12847 } 12848 if (dumpPackage == null) { 12849 if (mAlwaysFinishActivities || mController != null) { 12850 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12851 + " mController=" + mController); 12852 } 12853 if (dumpAll) { 12854 pw.println(" Total persistent processes: " + numPers); 12855 pw.println(" mProcessesReady=" + mProcessesReady 12856 + " mSystemReady=" + mSystemReady); 12857 pw.println(" mBooting=" + mBooting 12858 + " mBooted=" + mBooted 12859 + " mFactoryTest=" + mFactoryTest); 12860 pw.print(" mLastPowerCheckRealtime="); 12861 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12862 pw.println(""); 12863 pw.print(" mLastPowerCheckUptime="); 12864 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12865 pw.println(""); 12866 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12867 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12868 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12869 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12870 + " (" + mLruProcesses.size() + " total)" 12871 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12872 + " mNumServiceProcs=" + mNumServiceProcs 12873 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12874 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12875 + " mLastMemoryLevel" + mLastMemoryLevel 12876 + " mLastNumProcesses" + mLastNumProcesses); 12877 long now = SystemClock.uptimeMillis(); 12878 pw.print(" mLastIdleTime="); 12879 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12880 pw.print(" mLowRamSinceLastIdle="); 12881 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12882 pw.println(); 12883 } 12884 } 12885 12886 if (!printedAnything) { 12887 pw.println(" (nothing)"); 12888 } 12889 } 12890 12891 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12892 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12893 if (mProcessesToGc.size() > 0) { 12894 boolean printed = false; 12895 long now = SystemClock.uptimeMillis(); 12896 for (int i=0; i<mProcessesToGc.size(); i++) { 12897 ProcessRecord proc = mProcessesToGc.get(i); 12898 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12899 continue; 12900 } 12901 if (!printed) { 12902 if (needSep) pw.println(); 12903 needSep = true; 12904 pw.println(" Processes that are waiting to GC:"); 12905 printed = true; 12906 } 12907 pw.print(" Process "); pw.println(proc); 12908 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12909 pw.print(", last gced="); 12910 pw.print(now-proc.lastRequestedGc); 12911 pw.print(" ms ago, last lowMem="); 12912 pw.print(now-proc.lastLowMemory); 12913 pw.println(" ms ago"); 12914 12915 } 12916 } 12917 return needSep; 12918 } 12919 12920 void printOomLevel(PrintWriter pw, String name, int adj) { 12921 pw.print(" "); 12922 if (adj >= 0) { 12923 pw.print(' '); 12924 if (adj < 10) pw.print(' '); 12925 } else { 12926 if (adj > -10) pw.print(' '); 12927 } 12928 pw.print(adj); 12929 pw.print(": "); 12930 pw.print(name); 12931 pw.print(" ("); 12932 pw.print(mProcessList.getMemLevel(adj)/1024); 12933 pw.println(" kB)"); 12934 } 12935 12936 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12937 int opti, boolean dumpAll) { 12938 boolean needSep = false; 12939 12940 if (mLruProcesses.size() > 0) { 12941 if (needSep) pw.println(); 12942 needSep = true; 12943 pw.println(" OOM levels:"); 12944 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12945 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12946 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12947 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12948 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12949 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12950 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12951 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12952 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12953 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12954 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12955 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12956 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12957 12958 if (needSep) pw.println(); 12959 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12960 pw.print(" total, non-act at "); 12961 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12962 pw.print(", non-svc at "); 12963 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12964 pw.println("):"); 12965 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12966 needSep = true; 12967 } 12968 12969 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12970 12971 pw.println(); 12972 pw.println(" mHomeProcess: " + mHomeProcess); 12973 pw.println(" mPreviousProcess: " + mPreviousProcess); 12974 if (mHeavyWeightProcess != null) { 12975 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12976 } 12977 12978 return true; 12979 } 12980 12981 /** 12982 * There are three ways to call this: 12983 * - no provider specified: dump all the providers 12984 * - a flattened component name that matched an existing provider was specified as the 12985 * first arg: dump that one provider 12986 * - the first arg isn't the flattened component name of an existing provider: 12987 * dump all providers whose component contains the first arg as a substring 12988 */ 12989 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12990 int opti, boolean dumpAll) { 12991 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12992 } 12993 12994 static class ItemMatcher { 12995 ArrayList<ComponentName> components; 12996 ArrayList<String> strings; 12997 ArrayList<Integer> objects; 12998 boolean all; 12999 13000 ItemMatcher() { 13001 all = true; 13002 } 13003 13004 void build(String name) { 13005 ComponentName componentName = ComponentName.unflattenFromString(name); 13006 if (componentName != null) { 13007 if (components == null) { 13008 components = new ArrayList<ComponentName>(); 13009 } 13010 components.add(componentName); 13011 all = false; 13012 } else { 13013 int objectId = 0; 13014 // Not a '/' separated full component name; maybe an object ID? 13015 try { 13016 objectId = Integer.parseInt(name, 16); 13017 if (objects == null) { 13018 objects = new ArrayList<Integer>(); 13019 } 13020 objects.add(objectId); 13021 all = false; 13022 } catch (RuntimeException e) { 13023 // Not an integer; just do string match. 13024 if (strings == null) { 13025 strings = new ArrayList<String>(); 13026 } 13027 strings.add(name); 13028 all = false; 13029 } 13030 } 13031 } 13032 13033 int build(String[] args, int opti) { 13034 for (; opti<args.length; opti++) { 13035 String name = args[opti]; 13036 if ("--".equals(name)) { 13037 return opti+1; 13038 } 13039 build(name); 13040 } 13041 return opti; 13042 } 13043 13044 boolean match(Object object, ComponentName comp) { 13045 if (all) { 13046 return true; 13047 } 13048 if (components != null) { 13049 for (int i=0; i<components.size(); i++) { 13050 if (components.get(i).equals(comp)) { 13051 return true; 13052 } 13053 } 13054 } 13055 if (objects != null) { 13056 for (int i=0; i<objects.size(); i++) { 13057 if (System.identityHashCode(object) == objects.get(i)) { 13058 return true; 13059 } 13060 } 13061 } 13062 if (strings != null) { 13063 String flat = comp.flattenToString(); 13064 for (int i=0; i<strings.size(); i++) { 13065 if (flat.contains(strings.get(i))) { 13066 return true; 13067 } 13068 } 13069 } 13070 return false; 13071 } 13072 } 13073 13074 /** 13075 * There are three things that cmd can be: 13076 * - a flattened component name that matches an existing activity 13077 * - the cmd arg isn't the flattened component name of an existing activity: 13078 * dump all activity whose component contains the cmd as a substring 13079 * - A hex number of the ActivityRecord object instance. 13080 */ 13081 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13082 int opti, boolean dumpAll) { 13083 ArrayList<ActivityRecord> activities; 13084 13085 synchronized (this) { 13086 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13087 } 13088 13089 if (activities.size() <= 0) { 13090 return false; 13091 } 13092 13093 String[] newArgs = new String[args.length - opti]; 13094 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13095 13096 TaskRecord lastTask = null; 13097 boolean needSep = false; 13098 for (int i=activities.size()-1; i>=0; i--) { 13099 ActivityRecord r = activities.get(i); 13100 if (needSep) { 13101 pw.println(); 13102 } 13103 needSep = true; 13104 synchronized (this) { 13105 if (lastTask != r.task) { 13106 lastTask = r.task; 13107 pw.print("TASK "); pw.print(lastTask.affinity); 13108 pw.print(" id="); pw.println(lastTask.taskId); 13109 if (dumpAll) { 13110 lastTask.dump(pw, " "); 13111 } 13112 } 13113 } 13114 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13115 } 13116 return true; 13117 } 13118 13119 /** 13120 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13121 * there is a thread associated with the activity. 13122 */ 13123 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13124 final ActivityRecord r, String[] args, boolean dumpAll) { 13125 String innerPrefix = prefix + " "; 13126 synchronized (this) { 13127 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13128 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13129 pw.print(" pid="); 13130 if (r.app != null) pw.println(r.app.pid); 13131 else pw.println("(not running)"); 13132 if (dumpAll) { 13133 r.dump(pw, innerPrefix); 13134 } 13135 } 13136 if (r.app != null && r.app.thread != null) { 13137 // flush anything that is already in the PrintWriter since the thread is going 13138 // to write to the file descriptor directly 13139 pw.flush(); 13140 try { 13141 TransferPipe tp = new TransferPipe(); 13142 try { 13143 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13144 r.appToken, innerPrefix, args); 13145 tp.go(fd); 13146 } finally { 13147 tp.kill(); 13148 } 13149 } catch (IOException e) { 13150 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13151 } catch (RemoteException e) { 13152 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13153 } 13154 } 13155 } 13156 13157 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13158 int opti, boolean dumpAll, String dumpPackage) { 13159 boolean needSep = false; 13160 boolean onlyHistory = false; 13161 boolean printedAnything = false; 13162 13163 if ("history".equals(dumpPackage)) { 13164 if (opti < args.length && "-s".equals(args[opti])) { 13165 dumpAll = false; 13166 } 13167 onlyHistory = true; 13168 dumpPackage = null; 13169 } 13170 13171 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13172 if (!onlyHistory && dumpAll) { 13173 if (mRegisteredReceivers.size() > 0) { 13174 boolean printed = false; 13175 Iterator it = mRegisteredReceivers.values().iterator(); 13176 while (it.hasNext()) { 13177 ReceiverList r = (ReceiverList)it.next(); 13178 if (dumpPackage != null && (r.app == null || 13179 !dumpPackage.equals(r.app.info.packageName))) { 13180 continue; 13181 } 13182 if (!printed) { 13183 pw.println(" Registered Receivers:"); 13184 needSep = true; 13185 printed = true; 13186 printedAnything = true; 13187 } 13188 pw.print(" * "); pw.println(r); 13189 r.dump(pw, " "); 13190 } 13191 } 13192 13193 if (mReceiverResolver.dump(pw, needSep ? 13194 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13195 " ", dumpPackage, false)) { 13196 needSep = true; 13197 printedAnything = true; 13198 } 13199 } 13200 13201 for (BroadcastQueue q : mBroadcastQueues) { 13202 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13203 printedAnything |= needSep; 13204 } 13205 13206 needSep = true; 13207 13208 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13209 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13210 if (needSep) { 13211 pw.println(); 13212 } 13213 needSep = true; 13214 printedAnything = true; 13215 pw.print(" Sticky broadcasts for user "); 13216 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13217 StringBuilder sb = new StringBuilder(128); 13218 for (Map.Entry<String, ArrayList<Intent>> ent 13219 : mStickyBroadcasts.valueAt(user).entrySet()) { 13220 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13221 if (dumpAll) { 13222 pw.println(":"); 13223 ArrayList<Intent> intents = ent.getValue(); 13224 final int N = intents.size(); 13225 for (int i=0; i<N; i++) { 13226 sb.setLength(0); 13227 sb.append(" Intent: "); 13228 intents.get(i).toShortString(sb, false, true, false, false); 13229 pw.println(sb.toString()); 13230 Bundle bundle = intents.get(i).getExtras(); 13231 if (bundle != null) { 13232 pw.print(" "); 13233 pw.println(bundle.toString()); 13234 } 13235 } 13236 } else { 13237 pw.println(""); 13238 } 13239 } 13240 } 13241 } 13242 13243 if (!onlyHistory && dumpAll) { 13244 pw.println(); 13245 for (BroadcastQueue queue : mBroadcastQueues) { 13246 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13247 + queue.mBroadcastsScheduled); 13248 } 13249 pw.println(" mHandler:"); 13250 mHandler.dump(new PrintWriterPrinter(pw), " "); 13251 needSep = true; 13252 printedAnything = true; 13253 } 13254 13255 if (!printedAnything) { 13256 pw.println(" (nothing)"); 13257 } 13258 } 13259 13260 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13261 int opti, boolean dumpAll, String dumpPackage) { 13262 boolean needSep; 13263 boolean printedAnything = false; 13264 13265 ItemMatcher matcher = new ItemMatcher(); 13266 matcher.build(args, opti); 13267 13268 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13269 13270 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13271 printedAnything |= needSep; 13272 13273 if (mLaunchingProviders.size() > 0) { 13274 boolean printed = false; 13275 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13276 ContentProviderRecord r = mLaunchingProviders.get(i); 13277 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13278 continue; 13279 } 13280 if (!printed) { 13281 if (needSep) pw.println(); 13282 needSep = true; 13283 pw.println(" Launching content providers:"); 13284 printed = true; 13285 printedAnything = true; 13286 } 13287 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13288 pw.println(r); 13289 } 13290 } 13291 13292 if (mGrantedUriPermissions.size() > 0) { 13293 boolean printed = false; 13294 int dumpUid = -2; 13295 if (dumpPackage != null) { 13296 try { 13297 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13298 } catch (NameNotFoundException e) { 13299 dumpUid = -1; 13300 } 13301 } 13302 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13303 int uid = mGrantedUriPermissions.keyAt(i); 13304 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13305 continue; 13306 } 13307 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13308 if (!printed) { 13309 if (needSep) pw.println(); 13310 needSep = true; 13311 pw.println(" Granted Uri Permissions:"); 13312 printed = true; 13313 printedAnything = true; 13314 } 13315 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13316 for (UriPermission perm : perms.values()) { 13317 pw.print(" "); pw.println(perm); 13318 if (dumpAll) { 13319 perm.dump(pw, " "); 13320 } 13321 } 13322 } 13323 } 13324 13325 if (!printedAnything) { 13326 pw.println(" (nothing)"); 13327 } 13328 } 13329 13330 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13331 int opti, boolean dumpAll, String dumpPackage) { 13332 boolean printed = false; 13333 13334 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13335 13336 if (mIntentSenderRecords.size() > 0) { 13337 Iterator<WeakReference<PendingIntentRecord>> it 13338 = mIntentSenderRecords.values().iterator(); 13339 while (it.hasNext()) { 13340 WeakReference<PendingIntentRecord> ref = it.next(); 13341 PendingIntentRecord rec = ref != null ? ref.get(): null; 13342 if (dumpPackage != null && (rec == null 13343 || !dumpPackage.equals(rec.key.packageName))) { 13344 continue; 13345 } 13346 printed = true; 13347 if (rec != null) { 13348 pw.print(" * "); pw.println(rec); 13349 if (dumpAll) { 13350 rec.dump(pw, " "); 13351 } 13352 } else { 13353 pw.print(" * "); pw.println(ref); 13354 } 13355 } 13356 } 13357 13358 if (!printed) { 13359 pw.println(" (nothing)"); 13360 } 13361 } 13362 13363 private static final int dumpProcessList(PrintWriter pw, 13364 ActivityManagerService service, List list, 13365 String prefix, String normalLabel, String persistentLabel, 13366 String dumpPackage) { 13367 int numPers = 0; 13368 final int N = list.size()-1; 13369 for (int i=N; i>=0; i--) { 13370 ProcessRecord r = (ProcessRecord)list.get(i); 13371 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13372 continue; 13373 } 13374 pw.println(String.format("%s%s #%2d: %s", 13375 prefix, (r.persistent ? persistentLabel : normalLabel), 13376 i, r.toString())); 13377 if (r.persistent) { 13378 numPers++; 13379 } 13380 } 13381 return numPers; 13382 } 13383 13384 private static final boolean dumpProcessOomList(PrintWriter pw, 13385 ActivityManagerService service, List<ProcessRecord> origList, 13386 String prefix, String normalLabel, String persistentLabel, 13387 boolean inclDetails, String dumpPackage) { 13388 13389 ArrayList<Pair<ProcessRecord, Integer>> list 13390 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13391 for (int i=0; i<origList.size(); i++) { 13392 ProcessRecord r = origList.get(i); 13393 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13394 continue; 13395 } 13396 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13397 } 13398 13399 if (list.size() <= 0) { 13400 return false; 13401 } 13402 13403 Comparator<Pair<ProcessRecord, Integer>> comparator 13404 = new Comparator<Pair<ProcessRecord, Integer>>() { 13405 @Override 13406 public int compare(Pair<ProcessRecord, Integer> object1, 13407 Pair<ProcessRecord, Integer> object2) { 13408 if (object1.first.setAdj != object2.first.setAdj) { 13409 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13410 } 13411 if (object1.second.intValue() != object2.second.intValue()) { 13412 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13413 } 13414 return 0; 13415 } 13416 }; 13417 13418 Collections.sort(list, comparator); 13419 13420 final long curRealtime = SystemClock.elapsedRealtime(); 13421 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13422 final long curUptime = SystemClock.uptimeMillis(); 13423 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13424 13425 for (int i=list.size()-1; i>=0; i--) { 13426 ProcessRecord r = list.get(i).first; 13427 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13428 char schedGroup; 13429 switch (r.setSchedGroup) { 13430 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13431 schedGroup = 'B'; 13432 break; 13433 case Process.THREAD_GROUP_DEFAULT: 13434 schedGroup = 'F'; 13435 break; 13436 default: 13437 schedGroup = '?'; 13438 break; 13439 } 13440 char foreground; 13441 if (r.foregroundActivities) { 13442 foreground = 'A'; 13443 } else if (r.foregroundServices) { 13444 foreground = 'S'; 13445 } else { 13446 foreground = ' '; 13447 } 13448 String procState = ProcessList.makeProcStateString(r.curProcState); 13449 pw.print(prefix); 13450 pw.print(r.persistent ? persistentLabel : normalLabel); 13451 pw.print(" #"); 13452 int num = (origList.size()-1)-list.get(i).second; 13453 if (num < 10) pw.print(' '); 13454 pw.print(num); 13455 pw.print(": "); 13456 pw.print(oomAdj); 13457 pw.print(' '); 13458 pw.print(schedGroup); 13459 pw.print('/'); 13460 pw.print(foreground); 13461 pw.print('/'); 13462 pw.print(procState); 13463 pw.print(" trm:"); 13464 if (r.trimMemoryLevel < 10) pw.print(' '); 13465 pw.print(r.trimMemoryLevel); 13466 pw.print(' '); 13467 pw.print(r.toShortString()); 13468 pw.print(" ("); 13469 pw.print(r.adjType); 13470 pw.println(')'); 13471 if (r.adjSource != null || r.adjTarget != null) { 13472 pw.print(prefix); 13473 pw.print(" "); 13474 if (r.adjTarget instanceof ComponentName) { 13475 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13476 } else if (r.adjTarget != null) { 13477 pw.print(r.adjTarget.toString()); 13478 } else { 13479 pw.print("{null}"); 13480 } 13481 pw.print("<="); 13482 if (r.adjSource instanceof ProcessRecord) { 13483 pw.print("Proc{"); 13484 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13485 pw.println("}"); 13486 } else if (r.adjSource != null) { 13487 pw.println(r.adjSource.toString()); 13488 } else { 13489 pw.println("{null}"); 13490 } 13491 } 13492 if (inclDetails) { 13493 pw.print(prefix); 13494 pw.print(" "); 13495 pw.print("oom: max="); pw.print(r.maxAdj); 13496 pw.print(" curRaw="); pw.print(r.curRawAdj); 13497 pw.print(" setRaw="); pw.print(r.setRawAdj); 13498 pw.print(" cur="); pw.print(r.curAdj); 13499 pw.print(" set="); pw.println(r.setAdj); 13500 pw.print(prefix); 13501 pw.print(" "); 13502 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13503 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13504 pw.print(" lastPss="); pw.print(r.lastPss); 13505 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13506 pw.print(prefix); 13507 pw.print(" "); 13508 pw.print("cached="); pw.print(r.cached); 13509 pw.print(" empty="); pw.print(r.empty); 13510 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13511 13512 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13513 if (r.lastWakeTime != 0) { 13514 long wtime; 13515 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13516 synchronized (stats) { 13517 wtime = stats.getProcessWakeTime(r.info.uid, 13518 r.pid, curRealtime); 13519 } 13520 long timeUsed = wtime - r.lastWakeTime; 13521 pw.print(prefix); 13522 pw.print(" "); 13523 pw.print("keep awake over "); 13524 TimeUtils.formatDuration(realtimeSince, pw); 13525 pw.print(" used "); 13526 TimeUtils.formatDuration(timeUsed, pw); 13527 pw.print(" ("); 13528 pw.print((timeUsed*100)/realtimeSince); 13529 pw.println("%)"); 13530 } 13531 if (r.lastCpuTime != 0) { 13532 long timeUsed = r.curCpuTime - r.lastCpuTime; 13533 pw.print(prefix); 13534 pw.print(" "); 13535 pw.print("run cpu over "); 13536 TimeUtils.formatDuration(uptimeSince, pw); 13537 pw.print(" used "); 13538 TimeUtils.formatDuration(timeUsed, pw); 13539 pw.print(" ("); 13540 pw.print((timeUsed*100)/uptimeSince); 13541 pw.println("%)"); 13542 } 13543 } 13544 } 13545 } 13546 return true; 13547 } 13548 13549 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13550 ArrayList<ProcessRecord> procs; 13551 synchronized (this) { 13552 if (args != null && args.length > start 13553 && args[start].charAt(0) != '-') { 13554 procs = new ArrayList<ProcessRecord>(); 13555 int pid = -1; 13556 try { 13557 pid = Integer.parseInt(args[start]); 13558 } catch (NumberFormatException e) { 13559 } 13560 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13561 ProcessRecord proc = mLruProcesses.get(i); 13562 if (proc.pid == pid) { 13563 procs.add(proc); 13564 } else if (proc.processName.equals(args[start])) { 13565 procs.add(proc); 13566 } 13567 } 13568 if (procs.size() <= 0) { 13569 return null; 13570 } 13571 } else { 13572 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13573 } 13574 } 13575 return procs; 13576 } 13577 13578 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13579 PrintWriter pw, String[] args) { 13580 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13581 if (procs == null) { 13582 pw.println("No process found for: " + args[0]); 13583 return; 13584 } 13585 13586 long uptime = SystemClock.uptimeMillis(); 13587 long realtime = SystemClock.elapsedRealtime(); 13588 pw.println("Applications Graphics Acceleration Info:"); 13589 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13590 13591 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13592 ProcessRecord r = procs.get(i); 13593 if (r.thread != null) { 13594 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13595 pw.flush(); 13596 try { 13597 TransferPipe tp = new TransferPipe(); 13598 try { 13599 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13600 tp.go(fd); 13601 } finally { 13602 tp.kill(); 13603 } 13604 } catch (IOException e) { 13605 pw.println("Failure while dumping the app: " + r); 13606 pw.flush(); 13607 } catch (RemoteException e) { 13608 pw.println("Got a RemoteException while dumping the app " + r); 13609 pw.flush(); 13610 } 13611 } 13612 } 13613 } 13614 13615 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13616 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13617 if (procs == null) { 13618 pw.println("No process found for: " + args[0]); 13619 return; 13620 } 13621 13622 pw.println("Applications Database Info:"); 13623 13624 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13625 ProcessRecord r = procs.get(i); 13626 if (r.thread != null) { 13627 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13628 pw.flush(); 13629 try { 13630 TransferPipe tp = new TransferPipe(); 13631 try { 13632 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13633 tp.go(fd); 13634 } finally { 13635 tp.kill(); 13636 } 13637 } catch (IOException e) { 13638 pw.println("Failure while dumping the app: " + r); 13639 pw.flush(); 13640 } catch (RemoteException e) { 13641 pw.println("Got a RemoteException while dumping the app " + r); 13642 pw.flush(); 13643 } 13644 } 13645 } 13646 } 13647 13648 final static class MemItem { 13649 final boolean isProc; 13650 final String label; 13651 final String shortLabel; 13652 final long pss; 13653 final int id; 13654 final boolean hasActivities; 13655 ArrayList<MemItem> subitems; 13656 13657 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13658 boolean _hasActivities) { 13659 isProc = true; 13660 label = _label; 13661 shortLabel = _shortLabel; 13662 pss = _pss; 13663 id = _id; 13664 hasActivities = _hasActivities; 13665 } 13666 13667 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13668 isProc = false; 13669 label = _label; 13670 shortLabel = _shortLabel; 13671 pss = _pss; 13672 id = _id; 13673 hasActivities = false; 13674 } 13675 } 13676 13677 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13678 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13679 if (sort && !isCompact) { 13680 Collections.sort(items, new Comparator<MemItem>() { 13681 @Override 13682 public int compare(MemItem lhs, MemItem rhs) { 13683 if (lhs.pss < rhs.pss) { 13684 return 1; 13685 } else if (lhs.pss > rhs.pss) { 13686 return -1; 13687 } 13688 return 0; 13689 } 13690 }); 13691 } 13692 13693 for (int i=0; i<items.size(); i++) { 13694 MemItem mi = items.get(i); 13695 if (!isCompact) { 13696 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13697 } else if (mi.isProc) { 13698 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13699 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13700 pw.println(mi.hasActivities ? ",a" : ",e"); 13701 } else { 13702 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13703 pw.println(mi.pss); 13704 } 13705 if (mi.subitems != null) { 13706 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13707 true, isCompact); 13708 } 13709 } 13710 } 13711 13712 // These are in KB. 13713 static final long[] DUMP_MEM_BUCKETS = new long[] { 13714 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13715 120*1024, 160*1024, 200*1024, 13716 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13717 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13718 }; 13719 13720 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13721 boolean stackLike) { 13722 int start = label.lastIndexOf('.'); 13723 if (start >= 0) start++; 13724 else start = 0; 13725 int end = label.length(); 13726 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13727 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13728 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13729 out.append(bucket); 13730 out.append(stackLike ? "MB." : "MB "); 13731 out.append(label, start, end); 13732 return; 13733 } 13734 } 13735 out.append(memKB/1024); 13736 out.append(stackLike ? "MB." : "MB "); 13737 out.append(label, start, end); 13738 } 13739 13740 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13741 ProcessList.NATIVE_ADJ, 13742 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13743 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13744 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13745 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13746 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13747 }; 13748 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13749 "Native", 13750 "System", "Persistent", "Foreground", 13751 "Visible", "Perceptible", 13752 "Heavy Weight", "Backup", 13753 "A Services", "Home", 13754 "Previous", "B Services", "Cached" 13755 }; 13756 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13757 "native", 13758 "sys", "pers", "fore", 13759 "vis", "percept", 13760 "heavy", "backup", 13761 "servicea", "home", 13762 "prev", "serviceb", "cached" 13763 }; 13764 13765 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13766 long realtime, boolean isCheckinRequest, boolean isCompact) { 13767 if (isCheckinRequest || isCompact) { 13768 // short checkin version 13769 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13770 } else { 13771 pw.println("Applications Memory Usage (kB):"); 13772 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13773 } 13774 } 13775 13776 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13777 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13778 boolean dumpDetails = false; 13779 boolean dumpFullDetails = false; 13780 boolean dumpDalvik = false; 13781 boolean oomOnly = false; 13782 boolean isCompact = false; 13783 boolean localOnly = false; 13784 13785 int opti = 0; 13786 while (opti < args.length) { 13787 String opt = args[opti]; 13788 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13789 break; 13790 } 13791 opti++; 13792 if ("-a".equals(opt)) { 13793 dumpDetails = true; 13794 dumpFullDetails = true; 13795 dumpDalvik = true; 13796 } else if ("-d".equals(opt)) { 13797 dumpDalvik = true; 13798 } else if ("-c".equals(opt)) { 13799 isCompact = true; 13800 } else if ("--oom".equals(opt)) { 13801 oomOnly = true; 13802 } else if ("--local".equals(opt)) { 13803 localOnly = true; 13804 } else if ("-h".equals(opt)) { 13805 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13806 pw.println(" -a: include all available information for each process."); 13807 pw.println(" -d: include dalvik details when dumping process details."); 13808 pw.println(" -c: dump in a compact machine-parseable representation."); 13809 pw.println(" --oom: only show processes organized by oom adj."); 13810 pw.println(" --local: only collect details locally, don't call process."); 13811 pw.println("If [process] is specified it can be the name or "); 13812 pw.println("pid of a specific process to dump."); 13813 return; 13814 } else { 13815 pw.println("Unknown argument: " + opt + "; use -h for help"); 13816 } 13817 } 13818 13819 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13820 long uptime = SystemClock.uptimeMillis(); 13821 long realtime = SystemClock.elapsedRealtime(); 13822 final long[] tmpLong = new long[1]; 13823 13824 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13825 if (procs == null) { 13826 // No Java processes. Maybe they want to print a native process. 13827 if (args != null && args.length > opti 13828 && args[opti].charAt(0) != '-') { 13829 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13830 = new ArrayList<ProcessCpuTracker.Stats>(); 13831 updateCpuStatsNow(); 13832 int findPid = -1; 13833 try { 13834 findPid = Integer.parseInt(args[opti]); 13835 } catch (NumberFormatException e) { 13836 } 13837 synchronized (mProcessCpuTracker) { 13838 final int N = mProcessCpuTracker.countStats(); 13839 for (int i=0; i<N; i++) { 13840 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13841 if (st.pid == findPid || (st.baseName != null 13842 && st.baseName.equals(args[opti]))) { 13843 nativeProcs.add(st); 13844 } 13845 } 13846 } 13847 if (nativeProcs.size() > 0) { 13848 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13849 isCompact); 13850 Debug.MemoryInfo mi = null; 13851 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13852 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13853 final int pid = r.pid; 13854 if (!isCheckinRequest && dumpDetails) { 13855 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13856 } 13857 if (mi == null) { 13858 mi = new Debug.MemoryInfo(); 13859 } 13860 if (dumpDetails || (!brief && !oomOnly)) { 13861 Debug.getMemoryInfo(pid, mi); 13862 } else { 13863 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13864 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13865 } 13866 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13867 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13868 if (isCheckinRequest) { 13869 pw.println(); 13870 } 13871 } 13872 return; 13873 } 13874 } 13875 pw.println("No process found for: " + args[opti]); 13876 return; 13877 } 13878 13879 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13880 dumpDetails = true; 13881 } 13882 13883 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13884 13885 String[] innerArgs = new String[args.length-opti]; 13886 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13887 13888 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13889 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13890 long nativePss=0, dalvikPss=0, otherPss=0; 13891 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13892 13893 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13894 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13895 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13896 13897 long totalPss = 0; 13898 long cachedPss = 0; 13899 13900 Debug.MemoryInfo mi = null; 13901 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13902 final ProcessRecord r = procs.get(i); 13903 final IApplicationThread thread; 13904 final int pid; 13905 final int oomAdj; 13906 final boolean hasActivities; 13907 synchronized (this) { 13908 thread = r.thread; 13909 pid = r.pid; 13910 oomAdj = r.getSetAdjWithServices(); 13911 hasActivities = r.activities.size() > 0; 13912 } 13913 if (thread != null) { 13914 if (!isCheckinRequest && dumpDetails) { 13915 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13916 } 13917 if (mi == null) { 13918 mi = new Debug.MemoryInfo(); 13919 } 13920 if (dumpDetails || (!brief && !oomOnly)) { 13921 Debug.getMemoryInfo(pid, mi); 13922 } else { 13923 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13924 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13925 } 13926 if (dumpDetails) { 13927 if (localOnly) { 13928 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13929 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13930 if (isCheckinRequest) { 13931 pw.println(); 13932 } 13933 } else { 13934 try { 13935 pw.flush(); 13936 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13937 dumpDalvik, innerArgs); 13938 } catch (RemoteException e) { 13939 if (!isCheckinRequest) { 13940 pw.println("Got RemoteException!"); 13941 pw.flush(); 13942 } 13943 } 13944 } 13945 } 13946 13947 final long myTotalPss = mi.getTotalPss(); 13948 final long myTotalUss = mi.getTotalUss(); 13949 13950 synchronized (this) { 13951 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13952 // Record this for posterity if the process has been stable. 13953 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13954 } 13955 } 13956 13957 if (!isCheckinRequest && mi != null) { 13958 totalPss += myTotalPss; 13959 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13960 (hasActivities ? " / activities)" : ")"), 13961 r.processName, myTotalPss, pid, hasActivities); 13962 procMems.add(pssItem); 13963 procMemsMap.put(pid, pssItem); 13964 13965 nativePss += mi.nativePss; 13966 dalvikPss += mi.dalvikPss; 13967 otherPss += mi.otherPss; 13968 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13969 long mem = mi.getOtherPss(j); 13970 miscPss[j] += mem; 13971 otherPss -= mem; 13972 } 13973 13974 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13975 cachedPss += myTotalPss; 13976 } 13977 13978 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13979 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13980 || oomIndex == (oomPss.length-1)) { 13981 oomPss[oomIndex] += myTotalPss; 13982 if (oomProcs[oomIndex] == null) { 13983 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13984 } 13985 oomProcs[oomIndex].add(pssItem); 13986 break; 13987 } 13988 } 13989 } 13990 } 13991 } 13992 13993 long nativeProcTotalPss = 0; 13994 13995 if (!isCheckinRequest && procs.size() > 1) { 13996 // If we are showing aggregations, also look for native processes to 13997 // include so that our aggregations are more accurate. 13998 updateCpuStatsNow(); 13999 synchronized (mProcessCpuTracker) { 14000 final int N = mProcessCpuTracker.countStats(); 14001 for (int i=0; i<N; i++) { 14002 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14003 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14004 if (mi == null) { 14005 mi = new Debug.MemoryInfo(); 14006 } 14007 if (!brief && !oomOnly) { 14008 Debug.getMemoryInfo(st.pid, mi); 14009 } else { 14010 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14011 mi.nativePrivateDirty = (int)tmpLong[0]; 14012 } 14013 14014 final long myTotalPss = mi.getTotalPss(); 14015 totalPss += myTotalPss; 14016 nativeProcTotalPss += myTotalPss; 14017 14018 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14019 st.name, myTotalPss, st.pid, false); 14020 procMems.add(pssItem); 14021 14022 nativePss += mi.nativePss; 14023 dalvikPss += mi.dalvikPss; 14024 otherPss += mi.otherPss; 14025 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14026 long mem = mi.getOtherPss(j); 14027 miscPss[j] += mem; 14028 otherPss -= mem; 14029 } 14030 oomPss[0] += myTotalPss; 14031 if (oomProcs[0] == null) { 14032 oomProcs[0] = new ArrayList<MemItem>(); 14033 } 14034 oomProcs[0].add(pssItem); 14035 } 14036 } 14037 } 14038 14039 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14040 14041 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14042 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14043 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14044 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14045 String label = Debug.MemoryInfo.getOtherLabel(j); 14046 catMems.add(new MemItem(label, label, miscPss[j], j)); 14047 } 14048 14049 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14050 for (int j=0; j<oomPss.length; j++) { 14051 if (oomPss[j] != 0) { 14052 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14053 : DUMP_MEM_OOM_LABEL[j]; 14054 MemItem item = new MemItem(label, label, oomPss[j], 14055 DUMP_MEM_OOM_ADJ[j]); 14056 item.subitems = oomProcs[j]; 14057 oomMems.add(item); 14058 } 14059 } 14060 14061 if (!brief && !oomOnly && !isCompact) { 14062 pw.println(); 14063 pw.println("Total PSS by process:"); 14064 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14065 pw.println(); 14066 } 14067 if (!isCompact) { 14068 pw.println("Total PSS by OOM adjustment:"); 14069 } 14070 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14071 if (!brief && !oomOnly) { 14072 PrintWriter out = categoryPw != null ? categoryPw : pw; 14073 if (!isCompact) { 14074 out.println(); 14075 out.println("Total PSS by category:"); 14076 } 14077 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14078 } 14079 if (!isCompact) { 14080 pw.println(); 14081 } 14082 MemInfoReader memInfo = new MemInfoReader(); 14083 memInfo.readMemInfo(); 14084 if (nativeProcTotalPss > 0) { 14085 synchronized (this) { 14086 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14087 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14088 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14089 nativeProcTotalPss); 14090 } 14091 } 14092 if (!brief) { 14093 if (!isCompact) { 14094 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14095 pw.print(" kB (status "); 14096 switch (mLastMemoryLevel) { 14097 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14098 pw.println("normal)"); 14099 break; 14100 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14101 pw.println("moderate)"); 14102 break; 14103 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14104 pw.println("low)"); 14105 break; 14106 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14107 pw.println("critical)"); 14108 break; 14109 default: 14110 pw.print(mLastMemoryLevel); 14111 pw.println(")"); 14112 break; 14113 } 14114 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14115 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14116 pw.print(cachedPss); pw.print(" cached pss + "); 14117 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14118 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14119 } else { 14120 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14121 pw.print(cachedPss + memInfo.getCachedSizeKb() 14122 + memInfo.getFreeSizeKb()); pw.print(","); 14123 pw.println(totalPss - cachedPss); 14124 } 14125 } 14126 if (!isCompact) { 14127 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14128 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14129 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14130 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14131 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14132 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14133 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14134 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14135 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14136 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14137 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14138 } 14139 if (!brief) { 14140 if (memInfo.getZramTotalSizeKb() != 0) { 14141 if (!isCompact) { 14142 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14143 pw.print(" kB physical used for "); 14144 pw.print(memInfo.getSwapTotalSizeKb() 14145 - memInfo.getSwapFreeSizeKb()); 14146 pw.print(" kB in swap ("); 14147 pw.print(memInfo.getSwapTotalSizeKb()); 14148 pw.println(" kB total swap)"); 14149 } else { 14150 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14151 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14152 pw.println(memInfo.getSwapFreeSizeKb()); 14153 } 14154 } 14155 final int[] SINGLE_LONG_FORMAT = new int[] { 14156 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14157 }; 14158 long[] longOut = new long[1]; 14159 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14160 SINGLE_LONG_FORMAT, null, longOut, null); 14161 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14162 longOut[0] = 0; 14163 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14164 SINGLE_LONG_FORMAT, null, longOut, null); 14165 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14166 longOut[0] = 0; 14167 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14168 SINGLE_LONG_FORMAT, null, longOut, null); 14169 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14170 longOut[0] = 0; 14171 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14172 SINGLE_LONG_FORMAT, null, longOut, null); 14173 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14174 if (!isCompact) { 14175 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14176 pw.print(" KSM: "); pw.print(sharing); 14177 pw.print(" kB saved from shared "); 14178 pw.print(shared); pw.println(" kB"); 14179 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14180 pw.print(voltile); pw.println(" kB volatile"); 14181 } 14182 pw.print(" Tuning: "); 14183 pw.print(ActivityManager.staticGetMemoryClass()); 14184 pw.print(" (large "); 14185 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14186 pw.print("), oom "); 14187 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14188 pw.print(" kB"); 14189 pw.print(", restore limit "); 14190 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14191 pw.print(" kB"); 14192 if (ActivityManager.isLowRamDeviceStatic()) { 14193 pw.print(" (low-ram)"); 14194 } 14195 if (ActivityManager.isHighEndGfx()) { 14196 pw.print(" (high-end-gfx)"); 14197 } 14198 pw.println(); 14199 } else { 14200 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14201 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14202 pw.println(voltile); 14203 pw.print("tuning,"); 14204 pw.print(ActivityManager.staticGetMemoryClass()); 14205 pw.print(','); 14206 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14207 pw.print(','); 14208 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14209 if (ActivityManager.isLowRamDeviceStatic()) { 14210 pw.print(",low-ram"); 14211 } 14212 if (ActivityManager.isHighEndGfx()) { 14213 pw.print(",high-end-gfx"); 14214 } 14215 pw.println(); 14216 } 14217 } 14218 } 14219 } 14220 14221 /** 14222 * Searches array of arguments for the specified string 14223 * @param args array of argument strings 14224 * @param value value to search for 14225 * @return true if the value is contained in the array 14226 */ 14227 private static boolean scanArgs(String[] args, String value) { 14228 if (args != null) { 14229 for (String arg : args) { 14230 if (value.equals(arg)) { 14231 return true; 14232 } 14233 } 14234 } 14235 return false; 14236 } 14237 14238 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14239 ContentProviderRecord cpr, boolean always) { 14240 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14241 14242 if (!inLaunching || always) { 14243 synchronized (cpr) { 14244 cpr.launchingApp = null; 14245 cpr.notifyAll(); 14246 } 14247 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14248 String names[] = cpr.info.authority.split(";"); 14249 for (int j = 0; j < names.length; j++) { 14250 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14251 } 14252 } 14253 14254 for (int i=0; i<cpr.connections.size(); i++) { 14255 ContentProviderConnection conn = cpr.connections.get(i); 14256 if (conn.waiting) { 14257 // If this connection is waiting for the provider, then we don't 14258 // need to mess with its process unless we are always removing 14259 // or for some reason the provider is not currently launching. 14260 if (inLaunching && !always) { 14261 continue; 14262 } 14263 } 14264 ProcessRecord capp = conn.client; 14265 conn.dead = true; 14266 if (conn.stableCount > 0) { 14267 if (!capp.persistent && capp.thread != null 14268 && capp.pid != 0 14269 && capp.pid != MY_PID) { 14270 capp.kill("depends on provider " 14271 + cpr.name.flattenToShortString() 14272 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14273 } 14274 } else if (capp.thread != null && conn.provider.provider != null) { 14275 try { 14276 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14277 } catch (RemoteException e) { 14278 } 14279 // In the protocol here, we don't expect the client to correctly 14280 // clean up this connection, we'll just remove it. 14281 cpr.connections.remove(i); 14282 conn.client.conProviders.remove(conn); 14283 } 14284 } 14285 14286 if (inLaunching && always) { 14287 mLaunchingProviders.remove(cpr); 14288 } 14289 return inLaunching; 14290 } 14291 14292 /** 14293 * Main code for cleaning up a process when it has gone away. This is 14294 * called both as a result of the process dying, or directly when stopping 14295 * a process when running in single process mode. 14296 */ 14297 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14298 boolean restarting, boolean allowRestart, int index) { 14299 if (index >= 0) { 14300 removeLruProcessLocked(app); 14301 ProcessList.remove(app.pid); 14302 } 14303 14304 mProcessesToGc.remove(app); 14305 mPendingPssProcesses.remove(app); 14306 14307 // Dismiss any open dialogs. 14308 if (app.crashDialog != null && !app.forceCrashReport) { 14309 app.crashDialog.dismiss(); 14310 app.crashDialog = null; 14311 } 14312 if (app.anrDialog != null) { 14313 app.anrDialog.dismiss(); 14314 app.anrDialog = null; 14315 } 14316 if (app.waitDialog != null) { 14317 app.waitDialog.dismiss(); 14318 app.waitDialog = null; 14319 } 14320 14321 app.crashing = false; 14322 app.notResponding = false; 14323 14324 app.resetPackageList(mProcessStats); 14325 app.unlinkDeathRecipient(); 14326 app.makeInactive(mProcessStats); 14327 app.waitingToKill = null; 14328 app.forcingToForeground = null; 14329 updateProcessForegroundLocked(app, false, false); 14330 app.foregroundActivities = false; 14331 app.hasShownUi = false; 14332 app.treatLikeActivity = false; 14333 app.hasAboveClient = false; 14334 app.hasClientActivities = false; 14335 14336 mServices.killServicesLocked(app, allowRestart); 14337 14338 boolean restart = false; 14339 14340 // Remove published content providers. 14341 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14342 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14343 final boolean always = app.bad || !allowRestart; 14344 if (removeDyingProviderLocked(app, cpr, always) || always) { 14345 // We left the provider in the launching list, need to 14346 // restart it. 14347 restart = true; 14348 } 14349 14350 cpr.provider = null; 14351 cpr.proc = null; 14352 } 14353 app.pubProviders.clear(); 14354 14355 // Take care of any launching providers waiting for this process. 14356 if (checkAppInLaunchingProvidersLocked(app, false)) { 14357 restart = true; 14358 } 14359 14360 // Unregister from connected content providers. 14361 if (!app.conProviders.isEmpty()) { 14362 for (int i=0; i<app.conProviders.size(); i++) { 14363 ContentProviderConnection conn = app.conProviders.get(i); 14364 conn.provider.connections.remove(conn); 14365 } 14366 app.conProviders.clear(); 14367 } 14368 14369 // At this point there may be remaining entries in mLaunchingProviders 14370 // where we were the only one waiting, so they are no longer of use. 14371 // Look for these and clean up if found. 14372 // XXX Commented out for now. Trying to figure out a way to reproduce 14373 // the actual situation to identify what is actually going on. 14374 if (false) { 14375 for (int i=0; i<mLaunchingProviders.size(); i++) { 14376 ContentProviderRecord cpr = (ContentProviderRecord) 14377 mLaunchingProviders.get(i); 14378 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14379 synchronized (cpr) { 14380 cpr.launchingApp = null; 14381 cpr.notifyAll(); 14382 } 14383 } 14384 } 14385 } 14386 14387 skipCurrentReceiverLocked(app); 14388 14389 // Unregister any receivers. 14390 for (int i=app.receivers.size()-1; i>=0; i--) { 14391 removeReceiverLocked(app.receivers.valueAt(i)); 14392 } 14393 app.receivers.clear(); 14394 14395 // If the app is undergoing backup, tell the backup manager about it 14396 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14397 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14398 + mBackupTarget.appInfo + " died during backup"); 14399 try { 14400 IBackupManager bm = IBackupManager.Stub.asInterface( 14401 ServiceManager.getService(Context.BACKUP_SERVICE)); 14402 bm.agentDisconnected(app.info.packageName); 14403 } catch (RemoteException e) { 14404 // can't happen; backup manager is local 14405 } 14406 } 14407 14408 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14409 ProcessChangeItem item = mPendingProcessChanges.get(i); 14410 if (item.pid == app.pid) { 14411 mPendingProcessChanges.remove(i); 14412 mAvailProcessChanges.add(item); 14413 } 14414 } 14415 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14416 14417 // If the caller is restarting this app, then leave it in its 14418 // current lists and let the caller take care of it. 14419 if (restarting) { 14420 return; 14421 } 14422 14423 if (!app.persistent || app.isolated) { 14424 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14425 "Removing non-persistent process during cleanup: " + app); 14426 mProcessNames.remove(app.processName, app.uid); 14427 mIsolatedProcesses.remove(app.uid); 14428 if (mHeavyWeightProcess == app) { 14429 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14430 mHeavyWeightProcess.userId, 0)); 14431 mHeavyWeightProcess = null; 14432 } 14433 } else if (!app.removed) { 14434 // This app is persistent, so we need to keep its record around. 14435 // If it is not already on the pending app list, add it there 14436 // and start a new process for it. 14437 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14438 mPersistentStartingProcesses.add(app); 14439 restart = true; 14440 } 14441 } 14442 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14443 "Clean-up removing on hold: " + app); 14444 mProcessesOnHold.remove(app); 14445 14446 if (app == mHomeProcess) { 14447 mHomeProcess = null; 14448 } 14449 if (app == mPreviousProcess) { 14450 mPreviousProcess = null; 14451 } 14452 14453 if (restart && !app.isolated) { 14454 // We have components that still need to be running in the 14455 // process, so re-launch it. 14456 mProcessNames.put(app.processName, app.uid, app); 14457 startProcessLocked(app, "restart", app.processName); 14458 } else if (app.pid > 0 && app.pid != MY_PID) { 14459 // Goodbye! 14460 boolean removed; 14461 synchronized (mPidsSelfLocked) { 14462 mPidsSelfLocked.remove(app.pid); 14463 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14464 } 14465 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14466 if (app.isolated) { 14467 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14468 } 14469 app.setPid(0); 14470 } 14471 } 14472 14473 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14474 // Look through the content providers we are waiting to have launched, 14475 // and if any run in this process then either schedule a restart of 14476 // the process or kill the client waiting for it if this process has 14477 // gone bad. 14478 int NL = mLaunchingProviders.size(); 14479 boolean restart = false; 14480 for (int i=0; i<NL; i++) { 14481 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14482 if (cpr.launchingApp == app) { 14483 if (!alwaysBad && !app.bad) { 14484 restart = true; 14485 } else { 14486 removeDyingProviderLocked(app, cpr, true); 14487 // cpr should have been removed from mLaunchingProviders 14488 NL = mLaunchingProviders.size(); 14489 i--; 14490 } 14491 } 14492 } 14493 return restart; 14494 } 14495 14496 // ========================================================= 14497 // SERVICES 14498 // ========================================================= 14499 14500 @Override 14501 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14502 int flags) { 14503 enforceNotIsolatedCaller("getServices"); 14504 synchronized (this) { 14505 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14506 } 14507 } 14508 14509 @Override 14510 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14511 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14512 synchronized (this) { 14513 return mServices.getRunningServiceControlPanelLocked(name); 14514 } 14515 } 14516 14517 @Override 14518 public ComponentName startService(IApplicationThread caller, Intent service, 14519 String resolvedType, int userId) { 14520 enforceNotIsolatedCaller("startService"); 14521 // Refuse possible leaked file descriptors 14522 if (service != null && service.hasFileDescriptors() == true) { 14523 throw new IllegalArgumentException("File descriptors passed in Intent"); 14524 } 14525 14526 if (DEBUG_SERVICE) 14527 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14528 synchronized(this) { 14529 final int callingPid = Binder.getCallingPid(); 14530 final int callingUid = Binder.getCallingUid(); 14531 final long origId = Binder.clearCallingIdentity(); 14532 ComponentName res = mServices.startServiceLocked(caller, service, 14533 resolvedType, callingPid, callingUid, userId); 14534 Binder.restoreCallingIdentity(origId); 14535 return res; 14536 } 14537 } 14538 14539 ComponentName startServiceInPackage(int uid, 14540 Intent service, String resolvedType, int userId) { 14541 synchronized(this) { 14542 if (DEBUG_SERVICE) 14543 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14544 final long origId = Binder.clearCallingIdentity(); 14545 ComponentName res = mServices.startServiceLocked(null, service, 14546 resolvedType, -1, uid, userId); 14547 Binder.restoreCallingIdentity(origId); 14548 return res; 14549 } 14550 } 14551 14552 @Override 14553 public int stopService(IApplicationThread caller, Intent service, 14554 String resolvedType, int userId) { 14555 enforceNotIsolatedCaller("stopService"); 14556 // Refuse possible leaked file descriptors 14557 if (service != null && service.hasFileDescriptors() == true) { 14558 throw new IllegalArgumentException("File descriptors passed in Intent"); 14559 } 14560 14561 synchronized(this) { 14562 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14563 } 14564 } 14565 14566 @Override 14567 public IBinder peekService(Intent service, String resolvedType) { 14568 enforceNotIsolatedCaller("peekService"); 14569 // Refuse possible leaked file descriptors 14570 if (service != null && service.hasFileDescriptors() == true) { 14571 throw new IllegalArgumentException("File descriptors passed in Intent"); 14572 } 14573 synchronized(this) { 14574 return mServices.peekServiceLocked(service, resolvedType); 14575 } 14576 } 14577 14578 @Override 14579 public boolean stopServiceToken(ComponentName className, IBinder token, 14580 int startId) { 14581 synchronized(this) { 14582 return mServices.stopServiceTokenLocked(className, token, startId); 14583 } 14584 } 14585 14586 @Override 14587 public void setServiceForeground(ComponentName className, IBinder token, 14588 int id, Notification notification, boolean removeNotification) { 14589 synchronized(this) { 14590 mServices.setServiceForegroundLocked(className, token, id, notification, 14591 removeNotification); 14592 } 14593 } 14594 14595 @Override 14596 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14597 boolean requireFull, String name, String callerPackage) { 14598 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14599 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14600 } 14601 14602 int unsafeConvertIncomingUser(int userId) { 14603 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14604 ? mCurrentUserId : userId; 14605 } 14606 14607 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14608 int allowMode, String name, String callerPackage) { 14609 final int callingUserId = UserHandle.getUserId(callingUid); 14610 if (callingUserId == userId) { 14611 return userId; 14612 } 14613 14614 // Note that we may be accessing mCurrentUserId outside of a lock... 14615 // shouldn't be a big deal, if this is being called outside 14616 // of a locked context there is intrinsically a race with 14617 // the value the caller will receive and someone else changing it. 14618 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14619 // we will switch to the calling user if access to the current user fails. 14620 int targetUserId = unsafeConvertIncomingUser(userId); 14621 14622 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14623 final boolean allow; 14624 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14625 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14626 // If the caller has this permission, they always pass go. And collect $200. 14627 allow = true; 14628 } else if (allowMode == ALLOW_FULL_ONLY) { 14629 // We require full access, sucks to be you. 14630 allow = false; 14631 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14632 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14633 // If the caller does not have either permission, they are always doomed. 14634 allow = false; 14635 } else if (allowMode == ALLOW_NON_FULL) { 14636 // We are blanket allowing non-full access, you lucky caller! 14637 allow = true; 14638 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14639 // We may or may not allow this depending on whether the two users are 14640 // in the same profile. 14641 synchronized (mUserProfileGroupIdsSelfLocked) { 14642 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14643 UserInfo.NO_PROFILE_GROUP_ID); 14644 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14645 UserInfo.NO_PROFILE_GROUP_ID); 14646 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14647 && callingProfile == targetProfile; 14648 } 14649 } else { 14650 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14651 } 14652 if (!allow) { 14653 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14654 // In this case, they would like to just execute as their 14655 // owner user instead of failing. 14656 targetUserId = callingUserId; 14657 } else { 14658 StringBuilder builder = new StringBuilder(128); 14659 builder.append("Permission Denial: "); 14660 builder.append(name); 14661 if (callerPackage != null) { 14662 builder.append(" from "); 14663 builder.append(callerPackage); 14664 } 14665 builder.append(" asks to run as user "); 14666 builder.append(userId); 14667 builder.append(" but is calling from user "); 14668 builder.append(UserHandle.getUserId(callingUid)); 14669 builder.append("; this requires "); 14670 builder.append(INTERACT_ACROSS_USERS_FULL); 14671 if (allowMode != ALLOW_FULL_ONLY) { 14672 builder.append(" or "); 14673 builder.append(INTERACT_ACROSS_USERS); 14674 } 14675 String msg = builder.toString(); 14676 Slog.w(TAG, msg); 14677 throw new SecurityException(msg); 14678 } 14679 } 14680 } 14681 if (!allowAll && targetUserId < 0) { 14682 throw new IllegalArgumentException( 14683 "Call does not support special user #" + targetUserId); 14684 } 14685 // Check shell permission 14686 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14687 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14688 targetUserId)) { 14689 throw new SecurityException("Shell does not have permission to access user " 14690 + targetUserId + "\n " + Debug.getCallers(3)); 14691 } 14692 } 14693 return targetUserId; 14694 } 14695 14696 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14697 String className, int flags) { 14698 boolean result = false; 14699 // For apps that don't have pre-defined UIDs, check for permission 14700 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14701 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14702 if (ActivityManager.checkUidPermission( 14703 INTERACT_ACROSS_USERS, 14704 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14705 ComponentName comp = new ComponentName(aInfo.packageName, className); 14706 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14707 + " requests FLAG_SINGLE_USER, but app does not hold " 14708 + INTERACT_ACROSS_USERS; 14709 Slog.w(TAG, msg); 14710 throw new SecurityException(msg); 14711 } 14712 // Permission passed 14713 result = true; 14714 } 14715 } else if ("system".equals(componentProcessName)) { 14716 result = true; 14717 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14718 // Phone app and persistent apps are allowed to export singleuser providers. 14719 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14720 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14721 } 14722 if (DEBUG_MU) { 14723 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14724 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14725 } 14726 return result; 14727 } 14728 14729 /** 14730 * Checks to see if the caller is in the same app as the singleton 14731 * component, or the component is in a special app. It allows special apps 14732 * to export singleton components but prevents exporting singleton 14733 * components for regular apps. 14734 */ 14735 boolean isValidSingletonCall(int callingUid, int componentUid) { 14736 int componentAppId = UserHandle.getAppId(componentUid); 14737 return UserHandle.isSameApp(callingUid, componentUid) 14738 || componentAppId == Process.SYSTEM_UID 14739 || componentAppId == Process.PHONE_UID 14740 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14741 == PackageManager.PERMISSION_GRANTED; 14742 } 14743 14744 public int bindService(IApplicationThread caller, IBinder token, 14745 Intent service, String resolvedType, 14746 IServiceConnection connection, int flags, int userId) { 14747 enforceNotIsolatedCaller("bindService"); 14748 14749 // Refuse possible leaked file descriptors 14750 if (service != null && service.hasFileDescriptors() == true) { 14751 throw new IllegalArgumentException("File descriptors passed in Intent"); 14752 } 14753 14754 synchronized(this) { 14755 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14756 connection, flags, userId); 14757 } 14758 } 14759 14760 public boolean unbindService(IServiceConnection connection) { 14761 synchronized (this) { 14762 return mServices.unbindServiceLocked(connection); 14763 } 14764 } 14765 14766 public void publishService(IBinder token, Intent intent, IBinder service) { 14767 // Refuse possible leaked file descriptors 14768 if (intent != null && intent.hasFileDescriptors() == true) { 14769 throw new IllegalArgumentException("File descriptors passed in Intent"); 14770 } 14771 14772 synchronized(this) { 14773 if (!(token instanceof ServiceRecord)) { 14774 throw new IllegalArgumentException("Invalid service token"); 14775 } 14776 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14777 } 14778 } 14779 14780 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14781 // Refuse possible leaked file descriptors 14782 if (intent != null && intent.hasFileDescriptors() == true) { 14783 throw new IllegalArgumentException("File descriptors passed in Intent"); 14784 } 14785 14786 synchronized(this) { 14787 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14788 } 14789 } 14790 14791 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14792 synchronized(this) { 14793 if (!(token instanceof ServiceRecord)) { 14794 throw new IllegalArgumentException("Invalid service token"); 14795 } 14796 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14797 } 14798 } 14799 14800 // ========================================================= 14801 // BACKUP AND RESTORE 14802 // ========================================================= 14803 14804 // Cause the target app to be launched if necessary and its backup agent 14805 // instantiated. The backup agent will invoke backupAgentCreated() on the 14806 // activity manager to announce its creation. 14807 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14808 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14809 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14810 14811 synchronized(this) { 14812 // !!! TODO: currently no check here that we're already bound 14813 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14814 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14815 synchronized (stats) { 14816 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14817 } 14818 14819 // Backup agent is now in use, its package can't be stopped. 14820 try { 14821 AppGlobals.getPackageManager().setPackageStoppedState( 14822 app.packageName, false, UserHandle.getUserId(app.uid)); 14823 } catch (RemoteException e) { 14824 } catch (IllegalArgumentException e) { 14825 Slog.w(TAG, "Failed trying to unstop package " 14826 + app.packageName + ": " + e); 14827 } 14828 14829 BackupRecord r = new BackupRecord(ss, app, backupMode); 14830 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14831 ? new ComponentName(app.packageName, app.backupAgentName) 14832 : new ComponentName("android", "FullBackupAgent"); 14833 // startProcessLocked() returns existing proc's record if it's already running 14834 ProcessRecord proc = startProcessLocked(app.processName, app, 14835 false, 0, "backup", hostingName, false, false, false); 14836 if (proc == null) { 14837 Slog.e(TAG, "Unable to start backup agent process " + r); 14838 return false; 14839 } 14840 14841 r.app = proc; 14842 mBackupTarget = r; 14843 mBackupAppName = app.packageName; 14844 14845 // Try not to kill the process during backup 14846 updateOomAdjLocked(proc); 14847 14848 // If the process is already attached, schedule the creation of the backup agent now. 14849 // If it is not yet live, this will be done when it attaches to the framework. 14850 if (proc.thread != null) { 14851 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14852 try { 14853 proc.thread.scheduleCreateBackupAgent(app, 14854 compatibilityInfoForPackageLocked(app), backupMode); 14855 } catch (RemoteException e) { 14856 // Will time out on the backup manager side 14857 } 14858 } else { 14859 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14860 } 14861 // Invariants: at this point, the target app process exists and the application 14862 // is either already running or in the process of coming up. mBackupTarget and 14863 // mBackupAppName describe the app, so that when it binds back to the AM we 14864 // know that it's scheduled for a backup-agent operation. 14865 } 14866 14867 return true; 14868 } 14869 14870 @Override 14871 public void clearPendingBackup() { 14872 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14873 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14874 14875 synchronized (this) { 14876 mBackupTarget = null; 14877 mBackupAppName = null; 14878 } 14879 } 14880 14881 // A backup agent has just come up 14882 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14883 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14884 + " = " + agent); 14885 14886 synchronized(this) { 14887 if (!agentPackageName.equals(mBackupAppName)) { 14888 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14889 return; 14890 } 14891 } 14892 14893 long oldIdent = Binder.clearCallingIdentity(); 14894 try { 14895 IBackupManager bm = IBackupManager.Stub.asInterface( 14896 ServiceManager.getService(Context.BACKUP_SERVICE)); 14897 bm.agentConnected(agentPackageName, agent); 14898 } catch (RemoteException e) { 14899 // can't happen; the backup manager service is local 14900 } catch (Exception e) { 14901 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14902 e.printStackTrace(); 14903 } finally { 14904 Binder.restoreCallingIdentity(oldIdent); 14905 } 14906 } 14907 14908 // done with this agent 14909 public void unbindBackupAgent(ApplicationInfo appInfo) { 14910 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14911 if (appInfo == null) { 14912 Slog.w(TAG, "unbind backup agent for null app"); 14913 return; 14914 } 14915 14916 synchronized(this) { 14917 try { 14918 if (mBackupAppName == null) { 14919 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14920 return; 14921 } 14922 14923 if (!mBackupAppName.equals(appInfo.packageName)) { 14924 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14925 return; 14926 } 14927 14928 // Not backing this app up any more; reset its OOM adjustment 14929 final ProcessRecord proc = mBackupTarget.app; 14930 updateOomAdjLocked(proc); 14931 14932 // If the app crashed during backup, 'thread' will be null here 14933 if (proc.thread != null) { 14934 try { 14935 proc.thread.scheduleDestroyBackupAgent(appInfo, 14936 compatibilityInfoForPackageLocked(appInfo)); 14937 } catch (Exception e) { 14938 Slog.e(TAG, "Exception when unbinding backup agent:"); 14939 e.printStackTrace(); 14940 } 14941 } 14942 } finally { 14943 mBackupTarget = null; 14944 mBackupAppName = null; 14945 } 14946 } 14947 } 14948 // ========================================================= 14949 // BROADCASTS 14950 // ========================================================= 14951 14952 private final List getStickiesLocked(String action, IntentFilter filter, 14953 List cur, int userId) { 14954 final ContentResolver resolver = mContext.getContentResolver(); 14955 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14956 if (stickies == null) { 14957 return cur; 14958 } 14959 final ArrayList<Intent> list = stickies.get(action); 14960 if (list == null) { 14961 return cur; 14962 } 14963 int N = list.size(); 14964 for (int i=0; i<N; i++) { 14965 Intent intent = list.get(i); 14966 if (filter.match(resolver, intent, true, TAG) >= 0) { 14967 if (cur == null) { 14968 cur = new ArrayList<Intent>(); 14969 } 14970 cur.add(intent); 14971 } 14972 } 14973 return cur; 14974 } 14975 14976 boolean isPendingBroadcastProcessLocked(int pid) { 14977 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14978 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14979 } 14980 14981 void skipPendingBroadcastLocked(int pid) { 14982 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14983 for (BroadcastQueue queue : mBroadcastQueues) { 14984 queue.skipPendingBroadcastLocked(pid); 14985 } 14986 } 14987 14988 // The app just attached; send any pending broadcasts that it should receive 14989 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14990 boolean didSomething = false; 14991 for (BroadcastQueue queue : mBroadcastQueues) { 14992 didSomething |= queue.sendPendingBroadcastsLocked(app); 14993 } 14994 return didSomething; 14995 } 14996 14997 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14998 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14999 enforceNotIsolatedCaller("registerReceiver"); 15000 int callingUid; 15001 int callingPid; 15002 synchronized(this) { 15003 ProcessRecord callerApp = null; 15004 if (caller != null) { 15005 callerApp = getRecordForAppLocked(caller); 15006 if (callerApp == null) { 15007 throw new SecurityException( 15008 "Unable to find app for caller " + caller 15009 + " (pid=" + Binder.getCallingPid() 15010 + ") when registering receiver " + receiver); 15011 } 15012 if (callerApp.info.uid != Process.SYSTEM_UID && 15013 !callerApp.pkgList.containsKey(callerPackage) && 15014 !"android".equals(callerPackage)) { 15015 throw new SecurityException("Given caller package " + callerPackage 15016 + " is not running in process " + callerApp); 15017 } 15018 callingUid = callerApp.info.uid; 15019 callingPid = callerApp.pid; 15020 } else { 15021 callerPackage = null; 15022 callingUid = Binder.getCallingUid(); 15023 callingPid = Binder.getCallingPid(); 15024 } 15025 15026 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15027 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15028 15029 List allSticky = null; 15030 15031 // Look for any matching sticky broadcasts... 15032 Iterator actions = filter.actionsIterator(); 15033 if (actions != null) { 15034 while (actions.hasNext()) { 15035 String action = (String)actions.next(); 15036 allSticky = getStickiesLocked(action, filter, allSticky, 15037 UserHandle.USER_ALL); 15038 allSticky = getStickiesLocked(action, filter, allSticky, 15039 UserHandle.getUserId(callingUid)); 15040 } 15041 } else { 15042 allSticky = getStickiesLocked(null, filter, allSticky, 15043 UserHandle.USER_ALL); 15044 allSticky = getStickiesLocked(null, filter, allSticky, 15045 UserHandle.getUserId(callingUid)); 15046 } 15047 15048 // The first sticky in the list is returned directly back to 15049 // the client. 15050 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15051 15052 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15053 + ": " + sticky); 15054 15055 if (receiver == null) { 15056 return sticky; 15057 } 15058 15059 ReceiverList rl 15060 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15061 if (rl == null) { 15062 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15063 userId, receiver); 15064 if (rl.app != null) { 15065 rl.app.receivers.add(rl); 15066 } else { 15067 try { 15068 receiver.asBinder().linkToDeath(rl, 0); 15069 } catch (RemoteException e) { 15070 return sticky; 15071 } 15072 rl.linkedToDeath = true; 15073 } 15074 mRegisteredReceivers.put(receiver.asBinder(), rl); 15075 } else if (rl.uid != callingUid) { 15076 throw new IllegalArgumentException( 15077 "Receiver requested to register for uid " + callingUid 15078 + " was previously registered for uid " + rl.uid); 15079 } else if (rl.pid != callingPid) { 15080 throw new IllegalArgumentException( 15081 "Receiver requested to register for pid " + callingPid 15082 + " was previously registered for pid " + rl.pid); 15083 } else if (rl.userId != userId) { 15084 throw new IllegalArgumentException( 15085 "Receiver requested to register for user " + userId 15086 + " was previously registered for user " + rl.userId); 15087 } 15088 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15089 permission, callingUid, userId); 15090 rl.add(bf); 15091 if (!bf.debugCheck()) { 15092 Slog.w(TAG, "==> For Dynamic broadast"); 15093 } 15094 mReceiverResolver.addFilter(bf); 15095 15096 // Enqueue broadcasts for all existing stickies that match 15097 // this filter. 15098 if (allSticky != null) { 15099 ArrayList receivers = new ArrayList(); 15100 receivers.add(bf); 15101 15102 int N = allSticky.size(); 15103 for (int i=0; i<N; i++) { 15104 Intent intent = (Intent)allSticky.get(i); 15105 BroadcastQueue queue = broadcastQueueForIntent(intent); 15106 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15107 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15108 null, null, false, true, true, -1); 15109 queue.enqueueParallelBroadcastLocked(r); 15110 queue.scheduleBroadcastsLocked(); 15111 } 15112 } 15113 15114 return sticky; 15115 } 15116 } 15117 15118 public void unregisterReceiver(IIntentReceiver receiver) { 15119 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15120 15121 final long origId = Binder.clearCallingIdentity(); 15122 try { 15123 boolean doTrim = false; 15124 15125 synchronized(this) { 15126 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15127 if (rl != null) { 15128 if (rl.curBroadcast != null) { 15129 BroadcastRecord r = rl.curBroadcast; 15130 final boolean doNext = finishReceiverLocked( 15131 receiver.asBinder(), r.resultCode, r.resultData, 15132 r.resultExtras, r.resultAbort); 15133 if (doNext) { 15134 doTrim = true; 15135 r.queue.processNextBroadcast(false); 15136 } 15137 } 15138 15139 if (rl.app != null) { 15140 rl.app.receivers.remove(rl); 15141 } 15142 removeReceiverLocked(rl); 15143 if (rl.linkedToDeath) { 15144 rl.linkedToDeath = false; 15145 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15146 } 15147 } 15148 } 15149 15150 // If we actually concluded any broadcasts, we might now be able 15151 // to trim the recipients' apps from our working set 15152 if (doTrim) { 15153 trimApplications(); 15154 return; 15155 } 15156 15157 } finally { 15158 Binder.restoreCallingIdentity(origId); 15159 } 15160 } 15161 15162 void removeReceiverLocked(ReceiverList rl) { 15163 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15164 int N = rl.size(); 15165 for (int i=0; i<N; i++) { 15166 mReceiverResolver.removeFilter(rl.get(i)); 15167 } 15168 } 15169 15170 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15171 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15172 ProcessRecord r = mLruProcesses.get(i); 15173 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15174 try { 15175 r.thread.dispatchPackageBroadcast(cmd, packages); 15176 } catch (RemoteException ex) { 15177 } 15178 } 15179 } 15180 } 15181 15182 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15183 int callingUid, int[] users) { 15184 List<ResolveInfo> receivers = null; 15185 try { 15186 HashSet<ComponentName> singleUserReceivers = null; 15187 boolean scannedFirstReceivers = false; 15188 for (int user : users) { 15189 // Skip users that have Shell restrictions 15190 if (callingUid == Process.SHELL_UID 15191 && getUserManagerLocked().hasUserRestriction( 15192 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15193 continue; 15194 } 15195 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15196 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15197 if (user != 0 && newReceivers != null) { 15198 // If this is not the primary user, we need to check for 15199 // any receivers that should be filtered out. 15200 for (int i=0; i<newReceivers.size(); i++) { 15201 ResolveInfo ri = newReceivers.get(i); 15202 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15203 newReceivers.remove(i); 15204 i--; 15205 } 15206 } 15207 } 15208 if (newReceivers != null && newReceivers.size() == 0) { 15209 newReceivers = null; 15210 } 15211 if (receivers == null) { 15212 receivers = newReceivers; 15213 } else if (newReceivers != null) { 15214 // We need to concatenate the additional receivers 15215 // found with what we have do far. This would be easy, 15216 // but we also need to de-dup any receivers that are 15217 // singleUser. 15218 if (!scannedFirstReceivers) { 15219 // Collect any single user receivers we had already retrieved. 15220 scannedFirstReceivers = true; 15221 for (int i=0; i<receivers.size(); i++) { 15222 ResolveInfo ri = receivers.get(i); 15223 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15224 ComponentName cn = new ComponentName( 15225 ri.activityInfo.packageName, ri.activityInfo.name); 15226 if (singleUserReceivers == null) { 15227 singleUserReceivers = new HashSet<ComponentName>(); 15228 } 15229 singleUserReceivers.add(cn); 15230 } 15231 } 15232 } 15233 // Add the new results to the existing results, tracking 15234 // and de-dupping single user receivers. 15235 for (int i=0; i<newReceivers.size(); i++) { 15236 ResolveInfo ri = newReceivers.get(i); 15237 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15238 ComponentName cn = new ComponentName( 15239 ri.activityInfo.packageName, ri.activityInfo.name); 15240 if (singleUserReceivers == null) { 15241 singleUserReceivers = new HashSet<ComponentName>(); 15242 } 15243 if (!singleUserReceivers.contains(cn)) { 15244 singleUserReceivers.add(cn); 15245 receivers.add(ri); 15246 } 15247 } else { 15248 receivers.add(ri); 15249 } 15250 } 15251 } 15252 } 15253 } catch (RemoteException ex) { 15254 // pm is in same process, this will never happen. 15255 } 15256 return receivers; 15257 } 15258 15259 private final int broadcastIntentLocked(ProcessRecord callerApp, 15260 String callerPackage, Intent intent, String resolvedType, 15261 IIntentReceiver resultTo, int resultCode, String resultData, 15262 Bundle map, String requiredPermission, int appOp, 15263 boolean ordered, boolean sticky, int callingPid, int callingUid, 15264 int userId) { 15265 intent = new Intent(intent); 15266 15267 // By default broadcasts do not go to stopped apps. 15268 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15269 15270 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15271 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15272 + " ordered=" + ordered + " userid=" + userId); 15273 if ((resultTo != null) && !ordered) { 15274 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15275 } 15276 15277 userId = handleIncomingUser(callingPid, callingUid, userId, 15278 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15279 15280 // Make sure that the user who is receiving this broadcast is started. 15281 // If not, we will just skip it. 15282 15283 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15284 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15285 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15286 Slog.w(TAG, "Skipping broadcast of " + intent 15287 + ": user " + userId + " is stopped"); 15288 return ActivityManager.BROADCAST_SUCCESS; 15289 } 15290 } 15291 15292 /* 15293 * Prevent non-system code (defined here to be non-persistent 15294 * processes) from sending protected broadcasts. 15295 */ 15296 int callingAppId = UserHandle.getAppId(callingUid); 15297 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15298 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15299 || callingAppId == Process.NFC_UID || callingUid == 0) { 15300 // Always okay. 15301 } else if (callerApp == null || !callerApp.persistent) { 15302 try { 15303 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15304 intent.getAction())) { 15305 String msg = "Permission Denial: not allowed to send broadcast " 15306 + intent.getAction() + " from pid=" 15307 + callingPid + ", uid=" + callingUid; 15308 Slog.w(TAG, msg); 15309 throw new SecurityException(msg); 15310 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15311 // Special case for compatibility: we don't want apps to send this, 15312 // but historically it has not been protected and apps may be using it 15313 // to poke their own app widget. So, instead of making it protected, 15314 // just limit it to the caller. 15315 if (callerApp == null) { 15316 String msg = "Permission Denial: not allowed to send broadcast " 15317 + intent.getAction() + " from unknown caller."; 15318 Slog.w(TAG, msg); 15319 throw new SecurityException(msg); 15320 } else if (intent.getComponent() != null) { 15321 // They are good enough to send to an explicit component... verify 15322 // it is being sent to the calling app. 15323 if (!intent.getComponent().getPackageName().equals( 15324 callerApp.info.packageName)) { 15325 String msg = "Permission Denial: not allowed to send broadcast " 15326 + intent.getAction() + " to " 15327 + intent.getComponent().getPackageName() + " from " 15328 + callerApp.info.packageName; 15329 Slog.w(TAG, msg); 15330 throw new SecurityException(msg); 15331 } 15332 } else { 15333 // Limit broadcast to their own package. 15334 intent.setPackage(callerApp.info.packageName); 15335 } 15336 } 15337 } catch (RemoteException e) { 15338 Slog.w(TAG, "Remote exception", e); 15339 return ActivityManager.BROADCAST_SUCCESS; 15340 } 15341 } 15342 15343 // Handle special intents: if this broadcast is from the package 15344 // manager about a package being removed, we need to remove all of 15345 // its activities from the history stack. 15346 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15347 intent.getAction()); 15348 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15349 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15350 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15351 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15352 || uidRemoved) { 15353 if (checkComponentPermission( 15354 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15355 callingPid, callingUid, -1, true) 15356 == PackageManager.PERMISSION_GRANTED) { 15357 if (uidRemoved) { 15358 final Bundle intentExtras = intent.getExtras(); 15359 final int uid = intentExtras != null 15360 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15361 if (uid >= 0) { 15362 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15363 synchronized (bs) { 15364 bs.removeUidStatsLocked(uid); 15365 } 15366 mAppOpsService.uidRemoved(uid); 15367 } 15368 } else { 15369 // If resources are unavailable just force stop all 15370 // those packages and flush the attribute cache as well. 15371 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15372 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15373 if (list != null && (list.length > 0)) { 15374 for (String pkg : list) { 15375 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15376 "storage unmount"); 15377 } 15378 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15379 sendPackageBroadcastLocked( 15380 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15381 } 15382 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15383 intent.getAction())) { 15384 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15385 } else { 15386 Uri data = intent.getData(); 15387 String ssp; 15388 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15389 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15390 intent.getAction()); 15391 boolean fullUninstall = removed && 15392 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15393 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15394 forceStopPackageLocked(ssp, UserHandle.getAppId( 15395 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15396 false, fullUninstall, userId, 15397 removed ? "pkg removed" : "pkg changed"); 15398 } 15399 if (removed) { 15400 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15401 new String[] {ssp}, userId); 15402 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15403 mAppOpsService.packageRemoved( 15404 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15405 15406 // Remove all permissions granted from/to this package 15407 removeUriPermissionsForPackageLocked(ssp, userId, true); 15408 } 15409 } 15410 } 15411 } 15412 } 15413 } else { 15414 String msg = "Permission Denial: " + intent.getAction() 15415 + " broadcast from " + callerPackage + " (pid=" + callingPid 15416 + ", uid=" + callingUid + ")" 15417 + " requires " 15418 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15419 Slog.w(TAG, msg); 15420 throw new SecurityException(msg); 15421 } 15422 15423 // Special case for adding a package: by default turn on compatibility 15424 // mode. 15425 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15426 Uri data = intent.getData(); 15427 String ssp; 15428 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15429 mCompatModePackages.handlePackageAddedLocked(ssp, 15430 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15431 } 15432 } 15433 15434 /* 15435 * If this is the time zone changed action, queue up a message that will reset the timezone 15436 * of all currently running processes. This message will get queued up before the broadcast 15437 * happens. 15438 */ 15439 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15440 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15441 } 15442 15443 /* 15444 * If the user set the time, let all running processes know. 15445 */ 15446 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15447 final int is24Hour = intent.getBooleanExtra( 15448 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15449 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15450 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15451 synchronized (stats) { 15452 stats.noteCurrentTimeChangedLocked(); 15453 } 15454 } 15455 15456 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15457 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15458 } 15459 15460 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15461 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15462 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15463 } 15464 15465 // Add to the sticky list if requested. 15466 if (sticky) { 15467 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15468 callingPid, callingUid) 15469 != PackageManager.PERMISSION_GRANTED) { 15470 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15471 + callingPid + ", uid=" + callingUid 15472 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15473 Slog.w(TAG, msg); 15474 throw new SecurityException(msg); 15475 } 15476 if (requiredPermission != null) { 15477 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15478 + " and enforce permission " + requiredPermission); 15479 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15480 } 15481 if (intent.getComponent() != null) { 15482 throw new SecurityException( 15483 "Sticky broadcasts can't target a specific component"); 15484 } 15485 // We use userId directly here, since the "all" target is maintained 15486 // as a separate set of sticky broadcasts. 15487 if (userId != UserHandle.USER_ALL) { 15488 // But first, if this is not a broadcast to all users, then 15489 // make sure it doesn't conflict with an existing broadcast to 15490 // all users. 15491 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15492 UserHandle.USER_ALL); 15493 if (stickies != null) { 15494 ArrayList<Intent> list = stickies.get(intent.getAction()); 15495 if (list != null) { 15496 int N = list.size(); 15497 int i; 15498 for (i=0; i<N; i++) { 15499 if (intent.filterEquals(list.get(i))) { 15500 throw new IllegalArgumentException( 15501 "Sticky broadcast " + intent + " for user " 15502 + userId + " conflicts with existing global broadcast"); 15503 } 15504 } 15505 } 15506 } 15507 } 15508 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15509 if (stickies == null) { 15510 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15511 mStickyBroadcasts.put(userId, stickies); 15512 } 15513 ArrayList<Intent> list = stickies.get(intent.getAction()); 15514 if (list == null) { 15515 list = new ArrayList<Intent>(); 15516 stickies.put(intent.getAction(), list); 15517 } 15518 int N = list.size(); 15519 int i; 15520 for (i=0; i<N; i++) { 15521 if (intent.filterEquals(list.get(i))) { 15522 // This sticky already exists, replace it. 15523 list.set(i, new Intent(intent)); 15524 break; 15525 } 15526 } 15527 if (i >= N) { 15528 list.add(new Intent(intent)); 15529 } 15530 } 15531 15532 int[] users; 15533 if (userId == UserHandle.USER_ALL) { 15534 // Caller wants broadcast to go to all started users. 15535 users = mStartedUserArray; 15536 } else { 15537 // Caller wants broadcast to go to one specific user. 15538 users = new int[] {userId}; 15539 } 15540 15541 // Figure out who all will receive this broadcast. 15542 List receivers = null; 15543 List<BroadcastFilter> registeredReceivers = null; 15544 // Need to resolve the intent to interested receivers... 15545 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15546 == 0) { 15547 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15548 } 15549 if (intent.getComponent() == null) { 15550 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15551 // Query one target user at a time, excluding shell-restricted users 15552 UserManagerService ums = getUserManagerLocked(); 15553 for (int i = 0; i < users.length; i++) { 15554 if (ums.hasUserRestriction( 15555 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15556 continue; 15557 } 15558 List<BroadcastFilter> registeredReceiversForUser = 15559 mReceiverResolver.queryIntent(intent, 15560 resolvedType, false, users[i]); 15561 if (registeredReceivers == null) { 15562 registeredReceivers = registeredReceiversForUser; 15563 } else if (registeredReceiversForUser != null) { 15564 registeredReceivers.addAll(registeredReceiversForUser); 15565 } 15566 } 15567 } else { 15568 registeredReceivers = mReceiverResolver.queryIntent(intent, 15569 resolvedType, false, userId); 15570 } 15571 } 15572 15573 final boolean replacePending = 15574 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15575 15576 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15577 + " replacePending=" + replacePending); 15578 15579 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15580 if (!ordered && NR > 0) { 15581 // If we are not serializing this broadcast, then send the 15582 // registered receivers separately so they don't wait for the 15583 // components to be launched. 15584 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15585 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15586 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15587 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15588 ordered, sticky, false, userId); 15589 if (DEBUG_BROADCAST) Slog.v( 15590 TAG, "Enqueueing parallel broadcast " + r); 15591 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15592 if (!replaced) { 15593 queue.enqueueParallelBroadcastLocked(r); 15594 queue.scheduleBroadcastsLocked(); 15595 } 15596 registeredReceivers = null; 15597 NR = 0; 15598 } 15599 15600 // Merge into one list. 15601 int ir = 0; 15602 if (receivers != null) { 15603 // A special case for PACKAGE_ADDED: do not allow the package 15604 // being added to see this broadcast. This prevents them from 15605 // using this as a back door to get run as soon as they are 15606 // installed. Maybe in the future we want to have a special install 15607 // broadcast or such for apps, but we'd like to deliberately make 15608 // this decision. 15609 String skipPackages[] = null; 15610 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15611 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15612 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15613 Uri data = intent.getData(); 15614 if (data != null) { 15615 String pkgName = data.getSchemeSpecificPart(); 15616 if (pkgName != null) { 15617 skipPackages = new String[] { pkgName }; 15618 } 15619 } 15620 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15621 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15622 } 15623 if (skipPackages != null && (skipPackages.length > 0)) { 15624 for (String skipPackage : skipPackages) { 15625 if (skipPackage != null) { 15626 int NT = receivers.size(); 15627 for (int it=0; it<NT; it++) { 15628 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15629 if (curt.activityInfo.packageName.equals(skipPackage)) { 15630 receivers.remove(it); 15631 it--; 15632 NT--; 15633 } 15634 } 15635 } 15636 } 15637 } 15638 15639 int NT = receivers != null ? receivers.size() : 0; 15640 int it = 0; 15641 ResolveInfo curt = null; 15642 BroadcastFilter curr = null; 15643 while (it < NT && ir < NR) { 15644 if (curt == null) { 15645 curt = (ResolveInfo)receivers.get(it); 15646 } 15647 if (curr == null) { 15648 curr = registeredReceivers.get(ir); 15649 } 15650 if (curr.getPriority() >= curt.priority) { 15651 // Insert this broadcast record into the final list. 15652 receivers.add(it, curr); 15653 ir++; 15654 curr = null; 15655 it++; 15656 NT++; 15657 } else { 15658 // Skip to the next ResolveInfo in the final list. 15659 it++; 15660 curt = null; 15661 } 15662 } 15663 } 15664 while (ir < NR) { 15665 if (receivers == null) { 15666 receivers = new ArrayList(); 15667 } 15668 receivers.add(registeredReceivers.get(ir)); 15669 ir++; 15670 } 15671 15672 if ((receivers != null && receivers.size() > 0) 15673 || resultTo != null) { 15674 BroadcastQueue queue = broadcastQueueForIntent(intent); 15675 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15676 callerPackage, callingPid, callingUid, resolvedType, 15677 requiredPermission, appOp, receivers, resultTo, resultCode, 15678 resultData, map, ordered, sticky, false, userId); 15679 if (DEBUG_BROADCAST) Slog.v( 15680 TAG, "Enqueueing ordered broadcast " + r 15681 + ": prev had " + queue.mOrderedBroadcasts.size()); 15682 if (DEBUG_BROADCAST) { 15683 int seq = r.intent.getIntExtra("seq", -1); 15684 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15685 } 15686 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15687 if (!replaced) { 15688 queue.enqueueOrderedBroadcastLocked(r); 15689 queue.scheduleBroadcastsLocked(); 15690 } 15691 } 15692 15693 return ActivityManager.BROADCAST_SUCCESS; 15694 } 15695 15696 final Intent verifyBroadcastLocked(Intent intent) { 15697 // Refuse possible leaked file descriptors 15698 if (intent != null && intent.hasFileDescriptors() == true) { 15699 throw new IllegalArgumentException("File descriptors passed in Intent"); 15700 } 15701 15702 int flags = intent.getFlags(); 15703 15704 if (!mProcessesReady) { 15705 // if the caller really truly claims to know what they're doing, go 15706 // ahead and allow the broadcast without launching any receivers 15707 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15708 intent = new Intent(intent); 15709 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15710 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15711 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15712 + " before boot completion"); 15713 throw new IllegalStateException("Cannot broadcast before boot completed"); 15714 } 15715 } 15716 15717 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15718 throw new IllegalArgumentException( 15719 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15720 } 15721 15722 return intent; 15723 } 15724 15725 public final int broadcastIntent(IApplicationThread caller, 15726 Intent intent, String resolvedType, IIntentReceiver resultTo, 15727 int resultCode, String resultData, Bundle map, 15728 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15729 enforceNotIsolatedCaller("broadcastIntent"); 15730 synchronized(this) { 15731 intent = verifyBroadcastLocked(intent); 15732 15733 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15734 final int callingPid = Binder.getCallingPid(); 15735 final int callingUid = Binder.getCallingUid(); 15736 final long origId = Binder.clearCallingIdentity(); 15737 int res = broadcastIntentLocked(callerApp, 15738 callerApp != null ? callerApp.info.packageName : null, 15739 intent, resolvedType, resultTo, 15740 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15741 callingPid, callingUid, userId); 15742 Binder.restoreCallingIdentity(origId); 15743 return res; 15744 } 15745 } 15746 15747 int broadcastIntentInPackage(String packageName, int uid, 15748 Intent intent, String resolvedType, IIntentReceiver resultTo, 15749 int resultCode, String resultData, Bundle map, 15750 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15751 synchronized(this) { 15752 intent = verifyBroadcastLocked(intent); 15753 15754 final long origId = Binder.clearCallingIdentity(); 15755 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15756 resultTo, resultCode, resultData, map, requiredPermission, 15757 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15758 Binder.restoreCallingIdentity(origId); 15759 return res; 15760 } 15761 } 15762 15763 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15764 // Refuse possible leaked file descriptors 15765 if (intent != null && intent.hasFileDescriptors() == true) { 15766 throw new IllegalArgumentException("File descriptors passed in Intent"); 15767 } 15768 15769 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15770 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15771 15772 synchronized(this) { 15773 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15774 != PackageManager.PERMISSION_GRANTED) { 15775 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15776 + Binder.getCallingPid() 15777 + ", uid=" + Binder.getCallingUid() 15778 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15779 Slog.w(TAG, msg); 15780 throw new SecurityException(msg); 15781 } 15782 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15783 if (stickies != null) { 15784 ArrayList<Intent> list = stickies.get(intent.getAction()); 15785 if (list != null) { 15786 int N = list.size(); 15787 int i; 15788 for (i=0; i<N; i++) { 15789 if (intent.filterEquals(list.get(i))) { 15790 list.remove(i); 15791 break; 15792 } 15793 } 15794 if (list.size() <= 0) { 15795 stickies.remove(intent.getAction()); 15796 } 15797 } 15798 if (stickies.size() <= 0) { 15799 mStickyBroadcasts.remove(userId); 15800 } 15801 } 15802 } 15803 } 15804 15805 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15806 String resultData, Bundle resultExtras, boolean resultAbort) { 15807 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15808 if (r == null) { 15809 Slog.w(TAG, "finishReceiver called but not found on queue"); 15810 return false; 15811 } 15812 15813 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15814 } 15815 15816 void backgroundServicesFinishedLocked(int userId) { 15817 for (BroadcastQueue queue : mBroadcastQueues) { 15818 queue.backgroundServicesFinishedLocked(userId); 15819 } 15820 } 15821 15822 public void finishReceiver(IBinder who, int resultCode, String resultData, 15823 Bundle resultExtras, boolean resultAbort) { 15824 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15825 15826 // Refuse possible leaked file descriptors 15827 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15828 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15829 } 15830 15831 final long origId = Binder.clearCallingIdentity(); 15832 try { 15833 boolean doNext = false; 15834 BroadcastRecord r; 15835 15836 synchronized(this) { 15837 r = broadcastRecordForReceiverLocked(who); 15838 if (r != null) { 15839 doNext = r.queue.finishReceiverLocked(r, resultCode, 15840 resultData, resultExtras, resultAbort, true); 15841 } 15842 } 15843 15844 if (doNext) { 15845 r.queue.processNextBroadcast(false); 15846 } 15847 trimApplications(); 15848 } finally { 15849 Binder.restoreCallingIdentity(origId); 15850 } 15851 } 15852 15853 // ========================================================= 15854 // INSTRUMENTATION 15855 // ========================================================= 15856 15857 public boolean startInstrumentation(ComponentName className, 15858 String profileFile, int flags, Bundle arguments, 15859 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15860 int userId, String abiOverride) { 15861 enforceNotIsolatedCaller("startInstrumentation"); 15862 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15863 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15864 // Refuse possible leaked file descriptors 15865 if (arguments != null && arguments.hasFileDescriptors()) { 15866 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15867 } 15868 15869 synchronized(this) { 15870 InstrumentationInfo ii = null; 15871 ApplicationInfo ai = null; 15872 try { 15873 ii = mContext.getPackageManager().getInstrumentationInfo( 15874 className, STOCK_PM_FLAGS); 15875 ai = AppGlobals.getPackageManager().getApplicationInfo( 15876 ii.targetPackage, STOCK_PM_FLAGS, userId); 15877 } catch (PackageManager.NameNotFoundException e) { 15878 } catch (RemoteException e) { 15879 } 15880 if (ii == null) { 15881 reportStartInstrumentationFailure(watcher, className, 15882 "Unable to find instrumentation info for: " + className); 15883 return false; 15884 } 15885 if (ai == null) { 15886 reportStartInstrumentationFailure(watcher, className, 15887 "Unable to find instrumentation target package: " + ii.targetPackage); 15888 return false; 15889 } 15890 15891 int match = mContext.getPackageManager().checkSignatures( 15892 ii.targetPackage, ii.packageName); 15893 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15894 String msg = "Permission Denial: starting instrumentation " 15895 + className + " from pid=" 15896 + Binder.getCallingPid() 15897 + ", uid=" + Binder.getCallingPid() 15898 + " not allowed because package " + ii.packageName 15899 + " does not have a signature matching the target " 15900 + ii.targetPackage; 15901 reportStartInstrumentationFailure(watcher, className, msg); 15902 throw new SecurityException(msg); 15903 } 15904 15905 final long origId = Binder.clearCallingIdentity(); 15906 // Instrumentation can kill and relaunch even persistent processes 15907 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15908 "start instr"); 15909 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15910 app.instrumentationClass = className; 15911 app.instrumentationInfo = ai; 15912 app.instrumentationProfileFile = profileFile; 15913 app.instrumentationArguments = arguments; 15914 app.instrumentationWatcher = watcher; 15915 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15916 app.instrumentationResultClass = className; 15917 Binder.restoreCallingIdentity(origId); 15918 } 15919 15920 return true; 15921 } 15922 15923 /** 15924 * Report errors that occur while attempting to start Instrumentation. Always writes the 15925 * error to the logs, but if somebody is watching, send the report there too. This enables 15926 * the "am" command to report errors with more information. 15927 * 15928 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15929 * @param cn The component name of the instrumentation. 15930 * @param report The error report. 15931 */ 15932 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15933 ComponentName cn, String report) { 15934 Slog.w(TAG, report); 15935 try { 15936 if (watcher != null) { 15937 Bundle results = new Bundle(); 15938 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15939 results.putString("Error", report); 15940 watcher.instrumentationStatus(cn, -1, results); 15941 } 15942 } catch (RemoteException e) { 15943 Slog.w(TAG, e); 15944 } 15945 } 15946 15947 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15948 if (app.instrumentationWatcher != null) { 15949 try { 15950 // NOTE: IInstrumentationWatcher *must* be oneway here 15951 app.instrumentationWatcher.instrumentationFinished( 15952 app.instrumentationClass, 15953 resultCode, 15954 results); 15955 } catch (RemoteException e) { 15956 } 15957 } 15958 if (app.instrumentationUiAutomationConnection != null) { 15959 try { 15960 app.instrumentationUiAutomationConnection.shutdown(); 15961 } catch (RemoteException re) { 15962 /* ignore */ 15963 } 15964 // Only a UiAutomation can set this flag and now that 15965 // it is finished we make sure it is reset to its default. 15966 mUserIsMonkey = false; 15967 } 15968 app.instrumentationWatcher = null; 15969 app.instrumentationUiAutomationConnection = null; 15970 app.instrumentationClass = null; 15971 app.instrumentationInfo = null; 15972 app.instrumentationProfileFile = null; 15973 app.instrumentationArguments = null; 15974 15975 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15976 "finished inst"); 15977 } 15978 15979 public void finishInstrumentation(IApplicationThread target, 15980 int resultCode, Bundle results) { 15981 int userId = UserHandle.getCallingUserId(); 15982 // Refuse possible leaked file descriptors 15983 if (results != null && results.hasFileDescriptors()) { 15984 throw new IllegalArgumentException("File descriptors passed in Intent"); 15985 } 15986 15987 synchronized(this) { 15988 ProcessRecord app = getRecordForAppLocked(target); 15989 if (app == null) { 15990 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15991 return; 15992 } 15993 final long origId = Binder.clearCallingIdentity(); 15994 finishInstrumentationLocked(app, resultCode, results); 15995 Binder.restoreCallingIdentity(origId); 15996 } 15997 } 15998 15999 // ========================================================= 16000 // CONFIGURATION 16001 // ========================================================= 16002 16003 public ConfigurationInfo getDeviceConfigurationInfo() { 16004 ConfigurationInfo config = new ConfigurationInfo(); 16005 synchronized (this) { 16006 config.reqTouchScreen = mConfiguration.touchscreen; 16007 config.reqKeyboardType = mConfiguration.keyboard; 16008 config.reqNavigation = mConfiguration.navigation; 16009 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16010 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16011 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16012 } 16013 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16014 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16015 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16016 } 16017 config.reqGlEsVersion = GL_ES_VERSION; 16018 } 16019 return config; 16020 } 16021 16022 ActivityStack getFocusedStack() { 16023 return mStackSupervisor.getFocusedStack(); 16024 } 16025 16026 public Configuration getConfiguration() { 16027 Configuration ci; 16028 synchronized(this) { 16029 ci = new Configuration(mConfiguration); 16030 } 16031 return ci; 16032 } 16033 16034 public void updatePersistentConfiguration(Configuration values) { 16035 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16036 "updateConfiguration()"); 16037 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16038 "updateConfiguration()"); 16039 if (values == null) { 16040 throw new NullPointerException("Configuration must not be null"); 16041 } 16042 16043 synchronized(this) { 16044 final long origId = Binder.clearCallingIdentity(); 16045 updateConfigurationLocked(values, null, true, false); 16046 Binder.restoreCallingIdentity(origId); 16047 } 16048 } 16049 16050 public void updateConfiguration(Configuration values) { 16051 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16052 "updateConfiguration()"); 16053 16054 synchronized(this) { 16055 if (values == null && mWindowManager != null) { 16056 // sentinel: fetch the current configuration from the window manager 16057 values = mWindowManager.computeNewConfiguration(); 16058 } 16059 16060 if (mWindowManager != null) { 16061 mProcessList.applyDisplaySize(mWindowManager); 16062 } 16063 16064 final long origId = Binder.clearCallingIdentity(); 16065 if (values != null) { 16066 Settings.System.clearConfiguration(values); 16067 } 16068 updateConfigurationLocked(values, null, false, false); 16069 Binder.restoreCallingIdentity(origId); 16070 } 16071 } 16072 16073 /** 16074 * Do either or both things: (1) change the current configuration, and (2) 16075 * make sure the given activity is running with the (now) current 16076 * configuration. Returns true if the activity has been left running, or 16077 * false if <var>starting</var> is being destroyed to match the new 16078 * configuration. 16079 * @param persistent TODO 16080 */ 16081 boolean updateConfigurationLocked(Configuration values, 16082 ActivityRecord starting, boolean persistent, boolean initLocale) { 16083 int changes = 0; 16084 16085 if (values != null) { 16086 Configuration newConfig = new Configuration(mConfiguration); 16087 changes = newConfig.updateFrom(values); 16088 if (changes != 0) { 16089 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16090 Slog.i(TAG, "Updating configuration to: " + values); 16091 } 16092 16093 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16094 16095 if (values.locale != null && !initLocale) { 16096 saveLocaleLocked(values.locale, 16097 !values.locale.equals(mConfiguration.locale), 16098 values.userSetLocale); 16099 } 16100 16101 mConfigurationSeq++; 16102 if (mConfigurationSeq <= 0) { 16103 mConfigurationSeq = 1; 16104 } 16105 newConfig.seq = mConfigurationSeq; 16106 mConfiguration = newConfig; 16107 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16108 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16109 //mUsageStatsService.noteStartConfig(newConfig); 16110 16111 final Configuration configCopy = new Configuration(mConfiguration); 16112 16113 // TODO: If our config changes, should we auto dismiss any currently 16114 // showing dialogs? 16115 mShowDialogs = shouldShowDialogs(newConfig); 16116 16117 AttributeCache ac = AttributeCache.instance(); 16118 if (ac != null) { 16119 ac.updateConfiguration(configCopy); 16120 } 16121 16122 // Make sure all resources in our process are updated 16123 // right now, so that anyone who is going to retrieve 16124 // resource values after we return will be sure to get 16125 // the new ones. This is especially important during 16126 // boot, where the first config change needs to guarantee 16127 // all resources have that config before following boot 16128 // code is executed. 16129 mSystemThread.applyConfigurationToResources(configCopy); 16130 16131 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16132 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16133 msg.obj = new Configuration(configCopy); 16134 mHandler.sendMessage(msg); 16135 } 16136 16137 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16138 ProcessRecord app = mLruProcesses.get(i); 16139 try { 16140 if (app.thread != null) { 16141 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16142 + app.processName + " new config " + mConfiguration); 16143 app.thread.scheduleConfigurationChanged(configCopy); 16144 } 16145 } catch (Exception e) { 16146 } 16147 } 16148 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16149 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16150 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16151 | Intent.FLAG_RECEIVER_FOREGROUND); 16152 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16153 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16154 Process.SYSTEM_UID, UserHandle.USER_ALL); 16155 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16156 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16157 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16158 broadcastIntentLocked(null, null, intent, 16159 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16160 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16161 } 16162 } 16163 } 16164 16165 boolean kept = true; 16166 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16167 // mainStack is null during startup. 16168 if (mainStack != null) { 16169 if (changes != 0 && starting == null) { 16170 // If the configuration changed, and the caller is not already 16171 // in the process of starting an activity, then find the top 16172 // activity to check if its configuration needs to change. 16173 starting = mainStack.topRunningActivityLocked(null); 16174 } 16175 16176 if (starting != null) { 16177 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16178 // And we need to make sure at this point that all other activities 16179 // are made visible with the correct configuration. 16180 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16181 } 16182 } 16183 16184 if (values != null && mWindowManager != null) { 16185 mWindowManager.setNewConfiguration(mConfiguration); 16186 } 16187 16188 return kept; 16189 } 16190 16191 /** 16192 * Decide based on the configuration whether we should shouw the ANR, 16193 * crash, etc dialogs. The idea is that if there is no affordnace to 16194 * press the on-screen buttons, we shouldn't show the dialog. 16195 * 16196 * A thought: SystemUI might also want to get told about this, the Power 16197 * dialog / global actions also might want different behaviors. 16198 */ 16199 private static final boolean shouldShowDialogs(Configuration config) { 16200 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16201 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16202 } 16203 16204 /** 16205 * Save the locale. You must be inside a synchronized (this) block. 16206 */ 16207 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16208 if(isDiff) { 16209 SystemProperties.set("user.language", l.getLanguage()); 16210 SystemProperties.set("user.region", l.getCountry()); 16211 } 16212 16213 if(isPersist) { 16214 SystemProperties.set("persist.sys.language", l.getLanguage()); 16215 SystemProperties.set("persist.sys.country", l.getCountry()); 16216 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16217 } 16218 } 16219 16220 @Override 16221 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16222 synchronized (this) { 16223 ActivityRecord srec = ActivityRecord.forToken(token); 16224 if (srec.task != null && srec.task.stack != null) { 16225 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16226 } 16227 } 16228 return false; 16229 } 16230 16231 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16232 Intent resultData) { 16233 16234 synchronized (this) { 16235 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16236 if (stack != null) { 16237 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16238 } 16239 return false; 16240 } 16241 } 16242 16243 public int getLaunchedFromUid(IBinder activityToken) { 16244 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16245 if (srec == null) { 16246 return -1; 16247 } 16248 return srec.launchedFromUid; 16249 } 16250 16251 public String getLaunchedFromPackage(IBinder activityToken) { 16252 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16253 if (srec == null) { 16254 return null; 16255 } 16256 return srec.launchedFromPackage; 16257 } 16258 16259 // ========================================================= 16260 // LIFETIME MANAGEMENT 16261 // ========================================================= 16262 16263 // Returns which broadcast queue the app is the current [or imminent] receiver 16264 // on, or 'null' if the app is not an active broadcast recipient. 16265 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16266 BroadcastRecord r = app.curReceiver; 16267 if (r != null) { 16268 return r.queue; 16269 } 16270 16271 // It's not the current receiver, but it might be starting up to become one 16272 synchronized (this) { 16273 for (BroadcastQueue queue : mBroadcastQueues) { 16274 r = queue.mPendingBroadcast; 16275 if (r != null && r.curApp == app) { 16276 // found it; report which queue it's in 16277 return queue; 16278 } 16279 } 16280 } 16281 16282 return null; 16283 } 16284 16285 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16286 boolean doingAll, long now) { 16287 if (mAdjSeq == app.adjSeq) { 16288 // This adjustment has already been computed. 16289 return app.curRawAdj; 16290 } 16291 16292 if (app.thread == null) { 16293 app.adjSeq = mAdjSeq; 16294 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16295 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16296 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16297 } 16298 16299 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16300 app.adjSource = null; 16301 app.adjTarget = null; 16302 app.empty = false; 16303 app.cached = false; 16304 16305 final int activitiesSize = app.activities.size(); 16306 16307 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16308 // The max adjustment doesn't allow this app to be anything 16309 // below foreground, so it is not worth doing work for it. 16310 app.adjType = "fixed"; 16311 app.adjSeq = mAdjSeq; 16312 app.curRawAdj = app.maxAdj; 16313 app.foregroundActivities = false; 16314 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16315 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16316 // System processes can do UI, and when they do we want to have 16317 // them trim their memory after the user leaves the UI. To 16318 // facilitate this, here we need to determine whether or not it 16319 // is currently showing UI. 16320 app.systemNoUi = true; 16321 if (app == TOP_APP) { 16322 app.systemNoUi = false; 16323 } else if (activitiesSize > 0) { 16324 for (int j = 0; j < activitiesSize; j++) { 16325 final ActivityRecord r = app.activities.get(j); 16326 if (r.visible) { 16327 app.systemNoUi = false; 16328 } 16329 } 16330 } 16331 if (!app.systemNoUi) { 16332 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16333 } 16334 return (app.curAdj=app.maxAdj); 16335 } 16336 16337 app.systemNoUi = false; 16338 16339 // Determine the importance of the process, starting with most 16340 // important to least, and assign an appropriate OOM adjustment. 16341 int adj; 16342 int schedGroup; 16343 int procState; 16344 boolean foregroundActivities = false; 16345 BroadcastQueue queue; 16346 if (app == TOP_APP) { 16347 // The last app on the list is the foreground app. 16348 adj = ProcessList.FOREGROUND_APP_ADJ; 16349 schedGroup = Process.THREAD_GROUP_DEFAULT; 16350 app.adjType = "top-activity"; 16351 foregroundActivities = true; 16352 procState = ActivityManager.PROCESS_STATE_TOP; 16353 } else if (app.instrumentationClass != null) { 16354 // Don't want to kill running instrumentation. 16355 adj = ProcessList.FOREGROUND_APP_ADJ; 16356 schedGroup = Process.THREAD_GROUP_DEFAULT; 16357 app.adjType = "instrumentation"; 16358 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16359 } else if ((queue = isReceivingBroadcast(app)) != null) { 16360 // An app that is currently receiving a broadcast also 16361 // counts as being in the foreground for OOM killer purposes. 16362 // It's placed in a sched group based on the nature of the 16363 // broadcast as reflected by which queue it's active in. 16364 adj = ProcessList.FOREGROUND_APP_ADJ; 16365 schedGroup = (queue == mFgBroadcastQueue) 16366 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16367 app.adjType = "broadcast"; 16368 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16369 } else if (app.executingServices.size() > 0) { 16370 // An app that is currently executing a service callback also 16371 // counts as being in the foreground. 16372 adj = ProcessList.FOREGROUND_APP_ADJ; 16373 schedGroup = app.execServicesFg ? 16374 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16375 app.adjType = "exec-service"; 16376 procState = ActivityManager.PROCESS_STATE_SERVICE; 16377 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16378 } else { 16379 // As far as we know the process is empty. We may change our mind later. 16380 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16381 // At this point we don't actually know the adjustment. Use the cached adj 16382 // value that the caller wants us to. 16383 adj = cachedAdj; 16384 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16385 app.cached = true; 16386 app.empty = true; 16387 app.adjType = "cch-empty"; 16388 } 16389 16390 // Examine all activities if not already foreground. 16391 if (!foregroundActivities && activitiesSize > 0) { 16392 for (int j = 0; j < activitiesSize; j++) { 16393 final ActivityRecord r = app.activities.get(j); 16394 if (r.app != app) { 16395 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16396 + app + "?!?"); 16397 continue; 16398 } 16399 if (r.visible) { 16400 // App has a visible activity; only upgrade adjustment. 16401 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16402 adj = ProcessList.VISIBLE_APP_ADJ; 16403 app.adjType = "visible"; 16404 } 16405 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16406 procState = ActivityManager.PROCESS_STATE_TOP; 16407 } 16408 schedGroup = Process.THREAD_GROUP_DEFAULT; 16409 app.cached = false; 16410 app.empty = false; 16411 foregroundActivities = true; 16412 break; 16413 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16414 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16415 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16416 app.adjType = "pausing"; 16417 } 16418 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16419 procState = ActivityManager.PROCESS_STATE_TOP; 16420 } 16421 schedGroup = Process.THREAD_GROUP_DEFAULT; 16422 app.cached = false; 16423 app.empty = false; 16424 foregroundActivities = true; 16425 } else if (r.state == ActivityState.STOPPING) { 16426 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16427 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16428 app.adjType = "stopping"; 16429 } 16430 // For the process state, we will at this point consider the 16431 // process to be cached. It will be cached either as an activity 16432 // or empty depending on whether the activity is finishing. We do 16433 // this so that we can treat the process as cached for purposes of 16434 // memory trimming (determing current memory level, trim command to 16435 // send to process) since there can be an arbitrary number of stopping 16436 // processes and they should soon all go into the cached state. 16437 if (!r.finishing) { 16438 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16439 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16440 } 16441 } 16442 app.cached = false; 16443 app.empty = false; 16444 foregroundActivities = true; 16445 } else { 16446 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16447 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16448 app.adjType = "cch-act"; 16449 } 16450 } 16451 } 16452 } 16453 16454 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16455 if (app.foregroundServices) { 16456 // The user is aware of this app, so make it visible. 16457 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16458 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16459 app.cached = false; 16460 app.adjType = "fg-service"; 16461 schedGroup = Process.THREAD_GROUP_DEFAULT; 16462 } else if (app.forcingToForeground != null) { 16463 // The user is aware of this app, so make it visible. 16464 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16465 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16466 app.cached = false; 16467 app.adjType = "force-fg"; 16468 app.adjSource = app.forcingToForeground; 16469 schedGroup = Process.THREAD_GROUP_DEFAULT; 16470 } 16471 } 16472 16473 if (app == mHeavyWeightProcess) { 16474 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16475 // We don't want to kill the current heavy-weight process. 16476 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16477 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16478 app.cached = false; 16479 app.adjType = "heavy"; 16480 } 16481 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16482 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16483 } 16484 } 16485 16486 if (app == mHomeProcess) { 16487 if (adj > ProcessList.HOME_APP_ADJ) { 16488 // This process is hosting what we currently consider to be the 16489 // home app, so we don't want to let it go into the background. 16490 adj = ProcessList.HOME_APP_ADJ; 16491 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16492 app.cached = false; 16493 app.adjType = "home"; 16494 } 16495 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16496 procState = ActivityManager.PROCESS_STATE_HOME; 16497 } 16498 } 16499 16500 if (app == mPreviousProcess && app.activities.size() > 0) { 16501 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16502 // This was the previous process that showed UI to the user. 16503 // We want to try to keep it around more aggressively, to give 16504 // a good experience around switching between two apps. 16505 adj = ProcessList.PREVIOUS_APP_ADJ; 16506 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16507 app.cached = false; 16508 app.adjType = "previous"; 16509 } 16510 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16511 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16512 } 16513 } 16514 16515 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16516 + " reason=" + app.adjType); 16517 16518 // By default, we use the computed adjustment. It may be changed if 16519 // there are applications dependent on our services or providers, but 16520 // this gives us a baseline and makes sure we don't get into an 16521 // infinite recursion. 16522 app.adjSeq = mAdjSeq; 16523 app.curRawAdj = adj; 16524 app.hasStartedServices = false; 16525 16526 if (mBackupTarget != null && app == mBackupTarget.app) { 16527 // If possible we want to avoid killing apps while they're being backed up 16528 if (adj > ProcessList.BACKUP_APP_ADJ) { 16529 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16530 adj = ProcessList.BACKUP_APP_ADJ; 16531 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16532 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16533 } 16534 app.adjType = "backup"; 16535 app.cached = false; 16536 } 16537 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16538 procState = ActivityManager.PROCESS_STATE_BACKUP; 16539 } 16540 } 16541 16542 boolean mayBeTop = false; 16543 16544 for (int is = app.services.size()-1; 16545 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16546 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16547 || procState > ActivityManager.PROCESS_STATE_TOP); 16548 is--) { 16549 ServiceRecord s = app.services.valueAt(is); 16550 if (s.startRequested) { 16551 app.hasStartedServices = true; 16552 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16553 procState = ActivityManager.PROCESS_STATE_SERVICE; 16554 } 16555 if (app.hasShownUi && app != mHomeProcess) { 16556 // If this process has shown some UI, let it immediately 16557 // go to the LRU list because it may be pretty heavy with 16558 // UI stuff. We'll tag it with a label just to help 16559 // debug and understand what is going on. 16560 if (adj > ProcessList.SERVICE_ADJ) { 16561 app.adjType = "cch-started-ui-services"; 16562 } 16563 } else { 16564 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16565 // This service has seen some activity within 16566 // recent memory, so we will keep its process ahead 16567 // of the background processes. 16568 if (adj > ProcessList.SERVICE_ADJ) { 16569 adj = ProcessList.SERVICE_ADJ; 16570 app.adjType = "started-services"; 16571 app.cached = false; 16572 } 16573 } 16574 // If we have let the service slide into the background 16575 // state, still have some text describing what it is doing 16576 // even though the service no longer has an impact. 16577 if (adj > ProcessList.SERVICE_ADJ) { 16578 app.adjType = "cch-started-services"; 16579 } 16580 } 16581 } 16582 for (int conni = s.connections.size()-1; 16583 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16584 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16585 || procState > ActivityManager.PROCESS_STATE_TOP); 16586 conni--) { 16587 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16588 for (int i = 0; 16589 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16590 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16591 || procState > ActivityManager.PROCESS_STATE_TOP); 16592 i++) { 16593 // XXX should compute this based on the max of 16594 // all connected clients. 16595 ConnectionRecord cr = clist.get(i); 16596 if (cr.binding.client == app) { 16597 // Binding to ourself is not interesting. 16598 continue; 16599 } 16600 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16601 ProcessRecord client = cr.binding.client; 16602 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16603 TOP_APP, doingAll, now); 16604 int clientProcState = client.curProcState; 16605 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16606 // If the other app is cached for any reason, for purposes here 16607 // we are going to consider it empty. The specific cached state 16608 // doesn't propagate except under certain conditions. 16609 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16610 } 16611 String adjType = null; 16612 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16613 // Not doing bind OOM management, so treat 16614 // this guy more like a started service. 16615 if (app.hasShownUi && app != mHomeProcess) { 16616 // If this process has shown some UI, let it immediately 16617 // go to the LRU list because it may be pretty heavy with 16618 // UI stuff. We'll tag it with a label just to help 16619 // debug and understand what is going on. 16620 if (adj > clientAdj) { 16621 adjType = "cch-bound-ui-services"; 16622 } 16623 app.cached = false; 16624 clientAdj = adj; 16625 clientProcState = procState; 16626 } else { 16627 if (now >= (s.lastActivity 16628 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16629 // This service has not seen activity within 16630 // recent memory, so allow it to drop to the 16631 // LRU list if there is no other reason to keep 16632 // it around. We'll also tag it with a label just 16633 // to help debug and undertand what is going on. 16634 if (adj > clientAdj) { 16635 adjType = "cch-bound-services"; 16636 } 16637 clientAdj = adj; 16638 } 16639 } 16640 } 16641 if (adj > clientAdj) { 16642 // If this process has recently shown UI, and 16643 // the process that is binding to it is less 16644 // important than being visible, then we don't 16645 // care about the binding as much as we care 16646 // about letting this process get into the LRU 16647 // list to be killed and restarted if needed for 16648 // memory. 16649 if (app.hasShownUi && app != mHomeProcess 16650 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16651 adjType = "cch-bound-ui-services"; 16652 } else { 16653 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16654 |Context.BIND_IMPORTANT)) != 0) { 16655 adj = clientAdj; 16656 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16657 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16658 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16659 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16660 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16661 adj = clientAdj; 16662 } else { 16663 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16664 adj = ProcessList.VISIBLE_APP_ADJ; 16665 } 16666 } 16667 if (!client.cached) { 16668 app.cached = false; 16669 } 16670 adjType = "service"; 16671 } 16672 } 16673 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16674 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16675 schedGroup = Process.THREAD_GROUP_DEFAULT; 16676 } 16677 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16678 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16679 // Special handling of clients who are in the top state. 16680 // We *may* want to consider this process to be in the 16681 // top state as well, but only if there is not another 16682 // reason for it to be running. Being on the top is a 16683 // special state, meaning you are specifically running 16684 // for the current top app. If the process is already 16685 // running in the background for some other reason, it 16686 // is more important to continue considering it to be 16687 // in the background state. 16688 mayBeTop = true; 16689 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16690 } else { 16691 // Special handling for above-top states (persistent 16692 // processes). These should not bring the current process 16693 // into the top state, since they are not on top. Instead 16694 // give them the best state after that. 16695 clientProcState = 16696 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16697 } 16698 } 16699 } else { 16700 if (clientProcState < 16701 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16702 clientProcState = 16703 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16704 } 16705 } 16706 if (procState > clientProcState) { 16707 procState = clientProcState; 16708 } 16709 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16710 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16711 app.pendingUiClean = true; 16712 } 16713 if (adjType != null) { 16714 app.adjType = adjType; 16715 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16716 .REASON_SERVICE_IN_USE; 16717 app.adjSource = cr.binding.client; 16718 app.adjSourceProcState = clientProcState; 16719 app.adjTarget = s.name; 16720 } 16721 } 16722 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16723 app.treatLikeActivity = true; 16724 } 16725 final ActivityRecord a = cr.activity; 16726 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16727 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16728 (a.visible || a.state == ActivityState.RESUMED 16729 || a.state == ActivityState.PAUSING)) { 16730 adj = ProcessList.FOREGROUND_APP_ADJ; 16731 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16732 schedGroup = Process.THREAD_GROUP_DEFAULT; 16733 } 16734 app.cached = false; 16735 app.adjType = "service"; 16736 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16737 .REASON_SERVICE_IN_USE; 16738 app.adjSource = a; 16739 app.adjSourceProcState = procState; 16740 app.adjTarget = s.name; 16741 } 16742 } 16743 } 16744 } 16745 } 16746 16747 for (int provi = app.pubProviders.size()-1; 16748 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16749 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16750 || procState > ActivityManager.PROCESS_STATE_TOP); 16751 provi--) { 16752 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16753 for (int i = cpr.connections.size()-1; 16754 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16755 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16756 || procState > ActivityManager.PROCESS_STATE_TOP); 16757 i--) { 16758 ContentProviderConnection conn = cpr.connections.get(i); 16759 ProcessRecord client = conn.client; 16760 if (client == app) { 16761 // Being our own client is not interesting. 16762 continue; 16763 } 16764 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16765 int clientProcState = client.curProcState; 16766 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16767 // If the other app is cached for any reason, for purposes here 16768 // we are going to consider it empty. 16769 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16770 } 16771 if (adj > clientAdj) { 16772 if (app.hasShownUi && app != mHomeProcess 16773 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16774 app.adjType = "cch-ui-provider"; 16775 } else { 16776 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16777 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16778 app.adjType = "provider"; 16779 } 16780 app.cached &= client.cached; 16781 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16782 .REASON_PROVIDER_IN_USE; 16783 app.adjSource = client; 16784 app.adjSourceProcState = clientProcState; 16785 app.adjTarget = cpr.name; 16786 } 16787 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16788 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16789 // Special handling of clients who are in the top state. 16790 // We *may* want to consider this process to be in the 16791 // top state as well, but only if there is not another 16792 // reason for it to be running. Being on the top is a 16793 // special state, meaning you are specifically running 16794 // for the current top app. If the process is already 16795 // running in the background for some other reason, it 16796 // is more important to continue considering it to be 16797 // in the background state. 16798 mayBeTop = true; 16799 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16800 } else { 16801 // Special handling for above-top states (persistent 16802 // processes). These should not bring the current process 16803 // into the top state, since they are not on top. Instead 16804 // give them the best state after that. 16805 clientProcState = 16806 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16807 } 16808 } 16809 if (procState > clientProcState) { 16810 procState = clientProcState; 16811 } 16812 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16813 schedGroup = Process.THREAD_GROUP_DEFAULT; 16814 } 16815 } 16816 // If the provider has external (non-framework) process 16817 // dependencies, ensure that its adjustment is at least 16818 // FOREGROUND_APP_ADJ. 16819 if (cpr.hasExternalProcessHandles()) { 16820 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16821 adj = ProcessList.FOREGROUND_APP_ADJ; 16822 schedGroup = Process.THREAD_GROUP_DEFAULT; 16823 app.cached = false; 16824 app.adjType = "provider"; 16825 app.adjTarget = cpr.name; 16826 } 16827 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16828 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16829 } 16830 } 16831 } 16832 16833 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16834 // A client of one of our services or providers is in the top state. We 16835 // *may* want to be in the top state, but not if we are already running in 16836 // the background for some other reason. For the decision here, we are going 16837 // to pick out a few specific states that we want to remain in when a client 16838 // is top (states that tend to be longer-term) and otherwise allow it to go 16839 // to the top state. 16840 switch (procState) { 16841 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16842 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16843 case ActivityManager.PROCESS_STATE_SERVICE: 16844 // These all are longer-term states, so pull them up to the top 16845 // of the background states, but not all the way to the top state. 16846 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16847 break; 16848 default: 16849 // Otherwise, top is a better choice, so take it. 16850 procState = ActivityManager.PROCESS_STATE_TOP; 16851 break; 16852 } 16853 } 16854 16855 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16856 if (app.hasClientActivities) { 16857 // This is a cached process, but with client activities. Mark it so. 16858 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16859 app.adjType = "cch-client-act"; 16860 } else if (app.treatLikeActivity) { 16861 // This is a cached process, but somebody wants us to treat it like it has 16862 // an activity, okay! 16863 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16864 app.adjType = "cch-as-act"; 16865 } 16866 } 16867 16868 if (adj == ProcessList.SERVICE_ADJ) { 16869 if (doingAll) { 16870 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16871 mNewNumServiceProcs++; 16872 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16873 if (!app.serviceb) { 16874 // This service isn't far enough down on the LRU list to 16875 // normally be a B service, but if we are low on RAM and it 16876 // is large we want to force it down since we would prefer to 16877 // keep launcher over it. 16878 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16879 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16880 app.serviceHighRam = true; 16881 app.serviceb = true; 16882 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16883 } else { 16884 mNewNumAServiceProcs++; 16885 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16886 } 16887 } else { 16888 app.serviceHighRam = false; 16889 } 16890 } 16891 if (app.serviceb) { 16892 adj = ProcessList.SERVICE_B_ADJ; 16893 } 16894 } 16895 16896 app.curRawAdj = adj; 16897 16898 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16899 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16900 if (adj > app.maxAdj) { 16901 adj = app.maxAdj; 16902 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16903 schedGroup = Process.THREAD_GROUP_DEFAULT; 16904 } 16905 } 16906 16907 // Do final modification to adj. Everything we do between here and applying 16908 // the final setAdj must be done in this function, because we will also use 16909 // it when computing the final cached adj later. Note that we don't need to 16910 // worry about this for max adj above, since max adj will always be used to 16911 // keep it out of the cached vaues. 16912 app.curAdj = app.modifyRawOomAdj(adj); 16913 app.curSchedGroup = schedGroup; 16914 app.curProcState = procState; 16915 app.foregroundActivities = foregroundActivities; 16916 16917 return app.curRawAdj; 16918 } 16919 16920 /** 16921 * Schedule PSS collection of a process. 16922 */ 16923 void requestPssLocked(ProcessRecord proc, int procState) { 16924 if (mPendingPssProcesses.contains(proc)) { 16925 return; 16926 } 16927 if (mPendingPssProcesses.size() == 0) { 16928 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16929 } 16930 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16931 proc.pssProcState = procState; 16932 mPendingPssProcesses.add(proc); 16933 } 16934 16935 /** 16936 * Schedule PSS collection of all processes. 16937 */ 16938 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16939 if (!always) { 16940 if (now < (mLastFullPssTime + 16941 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16942 return; 16943 } 16944 } 16945 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16946 mLastFullPssTime = now; 16947 mFullPssPending = true; 16948 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16949 mPendingPssProcesses.clear(); 16950 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16951 ProcessRecord app = mLruProcesses.get(i); 16952 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16953 app.pssProcState = app.setProcState; 16954 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16955 isSleeping(), now); 16956 mPendingPssProcesses.add(app); 16957 } 16958 } 16959 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16960 } 16961 16962 /** 16963 * Ask a given process to GC right now. 16964 */ 16965 final void performAppGcLocked(ProcessRecord app) { 16966 try { 16967 app.lastRequestedGc = SystemClock.uptimeMillis(); 16968 if (app.thread != null) { 16969 if (app.reportLowMemory) { 16970 app.reportLowMemory = false; 16971 app.thread.scheduleLowMemory(); 16972 } else { 16973 app.thread.processInBackground(); 16974 } 16975 } 16976 } catch (Exception e) { 16977 // whatever. 16978 } 16979 } 16980 16981 /** 16982 * Returns true if things are idle enough to perform GCs. 16983 */ 16984 private final boolean canGcNowLocked() { 16985 boolean processingBroadcasts = false; 16986 for (BroadcastQueue q : mBroadcastQueues) { 16987 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16988 processingBroadcasts = true; 16989 } 16990 } 16991 return !processingBroadcasts 16992 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16993 } 16994 16995 /** 16996 * Perform GCs on all processes that are waiting for it, but only 16997 * if things are idle. 16998 */ 16999 final void performAppGcsLocked() { 17000 final int N = mProcessesToGc.size(); 17001 if (N <= 0) { 17002 return; 17003 } 17004 if (canGcNowLocked()) { 17005 while (mProcessesToGc.size() > 0) { 17006 ProcessRecord proc = mProcessesToGc.remove(0); 17007 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17008 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17009 <= SystemClock.uptimeMillis()) { 17010 // To avoid spamming the system, we will GC processes one 17011 // at a time, waiting a few seconds between each. 17012 performAppGcLocked(proc); 17013 scheduleAppGcsLocked(); 17014 return; 17015 } else { 17016 // It hasn't been long enough since we last GCed this 17017 // process... put it in the list to wait for its time. 17018 addProcessToGcListLocked(proc); 17019 break; 17020 } 17021 } 17022 } 17023 17024 scheduleAppGcsLocked(); 17025 } 17026 } 17027 17028 /** 17029 * If all looks good, perform GCs on all processes waiting for them. 17030 */ 17031 final void performAppGcsIfAppropriateLocked() { 17032 if (canGcNowLocked()) { 17033 performAppGcsLocked(); 17034 return; 17035 } 17036 // Still not idle, wait some more. 17037 scheduleAppGcsLocked(); 17038 } 17039 17040 /** 17041 * Schedule the execution of all pending app GCs. 17042 */ 17043 final void scheduleAppGcsLocked() { 17044 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17045 17046 if (mProcessesToGc.size() > 0) { 17047 // Schedule a GC for the time to the next process. 17048 ProcessRecord proc = mProcessesToGc.get(0); 17049 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17050 17051 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17052 long now = SystemClock.uptimeMillis(); 17053 if (when < (now+GC_TIMEOUT)) { 17054 when = now + GC_TIMEOUT; 17055 } 17056 mHandler.sendMessageAtTime(msg, when); 17057 } 17058 } 17059 17060 /** 17061 * Add a process to the array of processes waiting to be GCed. Keeps the 17062 * list in sorted order by the last GC time. The process can't already be 17063 * on the list. 17064 */ 17065 final void addProcessToGcListLocked(ProcessRecord proc) { 17066 boolean added = false; 17067 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17068 if (mProcessesToGc.get(i).lastRequestedGc < 17069 proc.lastRequestedGc) { 17070 added = true; 17071 mProcessesToGc.add(i+1, proc); 17072 break; 17073 } 17074 } 17075 if (!added) { 17076 mProcessesToGc.add(0, proc); 17077 } 17078 } 17079 17080 /** 17081 * Set up to ask a process to GC itself. This will either do it 17082 * immediately, or put it on the list of processes to gc the next 17083 * time things are idle. 17084 */ 17085 final void scheduleAppGcLocked(ProcessRecord app) { 17086 long now = SystemClock.uptimeMillis(); 17087 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17088 return; 17089 } 17090 if (!mProcessesToGc.contains(app)) { 17091 addProcessToGcListLocked(app); 17092 scheduleAppGcsLocked(); 17093 } 17094 } 17095 17096 final void checkExcessivePowerUsageLocked(boolean doKills) { 17097 updateCpuStatsNow(); 17098 17099 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17100 boolean doWakeKills = doKills; 17101 boolean doCpuKills = doKills; 17102 if (mLastPowerCheckRealtime == 0) { 17103 doWakeKills = false; 17104 } 17105 if (mLastPowerCheckUptime == 0) { 17106 doCpuKills = false; 17107 } 17108 if (stats.isScreenOn()) { 17109 doWakeKills = false; 17110 } 17111 final long curRealtime = SystemClock.elapsedRealtime(); 17112 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17113 final long curUptime = SystemClock.uptimeMillis(); 17114 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17115 mLastPowerCheckRealtime = curRealtime; 17116 mLastPowerCheckUptime = curUptime; 17117 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17118 doWakeKills = false; 17119 } 17120 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17121 doCpuKills = false; 17122 } 17123 int i = mLruProcesses.size(); 17124 while (i > 0) { 17125 i--; 17126 ProcessRecord app = mLruProcesses.get(i); 17127 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17128 long wtime; 17129 synchronized (stats) { 17130 wtime = stats.getProcessWakeTime(app.info.uid, 17131 app.pid, curRealtime); 17132 } 17133 long wtimeUsed = wtime - app.lastWakeTime; 17134 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17135 if (DEBUG_POWER) { 17136 StringBuilder sb = new StringBuilder(128); 17137 sb.append("Wake for "); 17138 app.toShortString(sb); 17139 sb.append(": over "); 17140 TimeUtils.formatDuration(realtimeSince, sb); 17141 sb.append(" used "); 17142 TimeUtils.formatDuration(wtimeUsed, sb); 17143 sb.append(" ("); 17144 sb.append((wtimeUsed*100)/realtimeSince); 17145 sb.append("%)"); 17146 Slog.i(TAG, sb.toString()); 17147 sb.setLength(0); 17148 sb.append("CPU for "); 17149 app.toShortString(sb); 17150 sb.append(": over "); 17151 TimeUtils.formatDuration(uptimeSince, sb); 17152 sb.append(" used "); 17153 TimeUtils.formatDuration(cputimeUsed, sb); 17154 sb.append(" ("); 17155 sb.append((cputimeUsed*100)/uptimeSince); 17156 sb.append("%)"); 17157 Slog.i(TAG, sb.toString()); 17158 } 17159 // If a process has held a wake lock for more 17160 // than 50% of the time during this period, 17161 // that sounds bad. Kill! 17162 if (doWakeKills && realtimeSince > 0 17163 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17164 synchronized (stats) { 17165 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17166 realtimeSince, wtimeUsed); 17167 } 17168 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17169 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17170 } else if (doCpuKills && uptimeSince > 0 17171 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17172 synchronized (stats) { 17173 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17174 uptimeSince, cputimeUsed); 17175 } 17176 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17177 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17178 } else { 17179 app.lastWakeTime = wtime; 17180 app.lastCpuTime = app.curCpuTime; 17181 } 17182 } 17183 } 17184 } 17185 17186 private final boolean applyOomAdjLocked(ProcessRecord app, 17187 ProcessRecord TOP_APP, boolean doingAll, long now) { 17188 boolean success = true; 17189 17190 if (app.curRawAdj != app.setRawAdj) { 17191 app.setRawAdj = app.curRawAdj; 17192 } 17193 17194 int changes = 0; 17195 17196 if (app.curAdj != app.setAdj) { 17197 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17198 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17199 TAG, "Set " + app.pid + " " + app.processName + 17200 " adj " + app.curAdj + ": " + app.adjType); 17201 app.setAdj = app.curAdj; 17202 } 17203 17204 if (app.setSchedGroup != app.curSchedGroup) { 17205 app.setSchedGroup = app.curSchedGroup; 17206 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17207 "Setting process group of " + app.processName 17208 + " to " + app.curSchedGroup); 17209 if (app.waitingToKill != null && 17210 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17211 app.kill(app.waitingToKill, true); 17212 success = false; 17213 } else { 17214 if (true) { 17215 long oldId = Binder.clearCallingIdentity(); 17216 try { 17217 Process.setProcessGroup(app.pid, app.curSchedGroup); 17218 } catch (Exception e) { 17219 Slog.w(TAG, "Failed setting process group of " + app.pid 17220 + " to " + app.curSchedGroup); 17221 e.printStackTrace(); 17222 } finally { 17223 Binder.restoreCallingIdentity(oldId); 17224 } 17225 } else { 17226 if (app.thread != null) { 17227 try { 17228 app.thread.setSchedulingGroup(app.curSchedGroup); 17229 } catch (RemoteException e) { 17230 } 17231 } 17232 } 17233 Process.setSwappiness(app.pid, 17234 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17235 } 17236 } 17237 if (app.repForegroundActivities != app.foregroundActivities) { 17238 app.repForegroundActivities = app.foregroundActivities; 17239 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17240 } 17241 if (app.repProcState != app.curProcState) { 17242 app.repProcState = app.curProcState; 17243 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17244 if (app.thread != null) { 17245 try { 17246 if (false) { 17247 //RuntimeException h = new RuntimeException("here"); 17248 Slog.i(TAG, "Sending new process state " + app.repProcState 17249 + " to " + app /*, h*/); 17250 } 17251 app.thread.setProcessState(app.repProcState); 17252 } catch (RemoteException e) { 17253 } 17254 } 17255 } 17256 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17257 app.setProcState)) { 17258 app.lastStateTime = now; 17259 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17260 isSleeping(), now); 17261 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17262 + ProcessList.makeProcStateString(app.setProcState) + " to " 17263 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17264 + (app.nextPssTime-now) + ": " + app); 17265 } else { 17266 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17267 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17268 requestPssLocked(app, app.setProcState); 17269 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17270 isSleeping(), now); 17271 } else if (false && DEBUG_PSS) { 17272 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17273 } 17274 } 17275 if (app.setProcState != app.curProcState) { 17276 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17277 "Proc state change of " + app.processName 17278 + " to " + app.curProcState); 17279 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17280 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17281 if (setImportant && !curImportant) { 17282 // This app is no longer something we consider important enough to allow to 17283 // use arbitrary amounts of battery power. Note 17284 // its current wake lock time to later know to kill it if 17285 // it is not behaving well. 17286 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17287 synchronized (stats) { 17288 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17289 app.pid, SystemClock.elapsedRealtime()); 17290 } 17291 app.lastCpuTime = app.curCpuTime; 17292 17293 } 17294 app.setProcState = app.curProcState; 17295 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17296 app.notCachedSinceIdle = false; 17297 } 17298 if (!doingAll) { 17299 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17300 } else { 17301 app.procStateChanged = true; 17302 } 17303 } 17304 17305 if (changes != 0) { 17306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17307 int i = mPendingProcessChanges.size()-1; 17308 ProcessChangeItem item = null; 17309 while (i >= 0) { 17310 item = mPendingProcessChanges.get(i); 17311 if (item.pid == app.pid) { 17312 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17313 break; 17314 } 17315 i--; 17316 } 17317 if (i < 0) { 17318 // No existing item in pending changes; need a new one. 17319 final int NA = mAvailProcessChanges.size(); 17320 if (NA > 0) { 17321 item = mAvailProcessChanges.remove(NA-1); 17322 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17323 } else { 17324 item = new ProcessChangeItem(); 17325 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17326 } 17327 item.changes = 0; 17328 item.pid = app.pid; 17329 item.uid = app.info.uid; 17330 if (mPendingProcessChanges.size() == 0) { 17331 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17332 "*** Enqueueing dispatch processes changed!"); 17333 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17334 } 17335 mPendingProcessChanges.add(item); 17336 } 17337 item.changes |= changes; 17338 item.processState = app.repProcState; 17339 item.foregroundActivities = app.repForegroundActivities; 17340 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17341 + Integer.toHexString(System.identityHashCode(item)) 17342 + " " + app.toShortString() + ": changes=" + item.changes 17343 + " procState=" + item.processState 17344 + " foreground=" + item.foregroundActivities 17345 + " type=" + app.adjType + " source=" + app.adjSource 17346 + " target=" + app.adjTarget); 17347 } 17348 17349 return success; 17350 } 17351 17352 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17353 if (proc.thread != null) { 17354 if (proc.baseProcessTracker != null) { 17355 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17356 } 17357 if (proc.repProcState >= 0) { 17358 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17359 proc.repProcState); 17360 } 17361 } 17362 } 17363 17364 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17365 ProcessRecord TOP_APP, boolean doingAll, long now) { 17366 if (app.thread == null) { 17367 return false; 17368 } 17369 17370 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17371 17372 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17373 } 17374 17375 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17376 boolean oomAdj) { 17377 if (isForeground != proc.foregroundServices) { 17378 proc.foregroundServices = isForeground; 17379 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17380 proc.info.uid); 17381 if (isForeground) { 17382 if (curProcs == null) { 17383 curProcs = new ArrayList<ProcessRecord>(); 17384 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17385 } 17386 if (!curProcs.contains(proc)) { 17387 curProcs.add(proc); 17388 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17389 proc.info.packageName, proc.info.uid); 17390 } 17391 } else { 17392 if (curProcs != null) { 17393 if (curProcs.remove(proc)) { 17394 mBatteryStatsService.noteEvent( 17395 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17396 proc.info.packageName, proc.info.uid); 17397 if (curProcs.size() <= 0) { 17398 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17399 } 17400 } 17401 } 17402 } 17403 if (oomAdj) { 17404 updateOomAdjLocked(); 17405 } 17406 } 17407 } 17408 17409 private final ActivityRecord resumedAppLocked() { 17410 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17411 String pkg; 17412 int uid; 17413 if (act != null) { 17414 pkg = act.packageName; 17415 uid = act.info.applicationInfo.uid; 17416 } else { 17417 pkg = null; 17418 uid = -1; 17419 } 17420 // Has the UID or resumed package name changed? 17421 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17422 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17423 if (mCurResumedPackage != null) { 17424 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17425 mCurResumedPackage, mCurResumedUid); 17426 } 17427 mCurResumedPackage = pkg; 17428 mCurResumedUid = uid; 17429 if (mCurResumedPackage != null) { 17430 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17431 mCurResumedPackage, mCurResumedUid); 17432 } 17433 } 17434 return act; 17435 } 17436 17437 final boolean updateOomAdjLocked(ProcessRecord app) { 17438 final ActivityRecord TOP_ACT = resumedAppLocked(); 17439 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17440 final boolean wasCached = app.cached; 17441 17442 mAdjSeq++; 17443 17444 // This is the desired cached adjusment we want to tell it to use. 17445 // If our app is currently cached, we know it, and that is it. Otherwise, 17446 // we don't know it yet, and it needs to now be cached we will then 17447 // need to do a complete oom adj. 17448 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17449 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17450 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17451 SystemClock.uptimeMillis()); 17452 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17453 // Changed to/from cached state, so apps after it in the LRU 17454 // list may also be changed. 17455 updateOomAdjLocked(); 17456 } 17457 return success; 17458 } 17459 17460 final void updateOomAdjLocked() { 17461 final ActivityRecord TOP_ACT = resumedAppLocked(); 17462 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17463 final long now = SystemClock.uptimeMillis(); 17464 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17465 final int N = mLruProcesses.size(); 17466 17467 if (false) { 17468 RuntimeException e = new RuntimeException(); 17469 e.fillInStackTrace(); 17470 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17471 } 17472 17473 mAdjSeq++; 17474 mNewNumServiceProcs = 0; 17475 mNewNumAServiceProcs = 0; 17476 17477 final int emptyProcessLimit; 17478 final int cachedProcessLimit; 17479 if (mProcessLimit <= 0) { 17480 emptyProcessLimit = cachedProcessLimit = 0; 17481 } else if (mProcessLimit == 1) { 17482 emptyProcessLimit = 1; 17483 cachedProcessLimit = 0; 17484 } else { 17485 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17486 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17487 } 17488 17489 // Let's determine how many processes we have running vs. 17490 // how many slots we have for background processes; we may want 17491 // to put multiple processes in a slot of there are enough of 17492 // them. 17493 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17494 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17495 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17496 if (numEmptyProcs > cachedProcessLimit) { 17497 // If there are more empty processes than our limit on cached 17498 // processes, then use the cached process limit for the factor. 17499 // This ensures that the really old empty processes get pushed 17500 // down to the bottom, so if we are running low on memory we will 17501 // have a better chance at keeping around more cached processes 17502 // instead of a gazillion empty processes. 17503 numEmptyProcs = cachedProcessLimit; 17504 } 17505 int emptyFactor = numEmptyProcs/numSlots; 17506 if (emptyFactor < 1) emptyFactor = 1; 17507 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17508 if (cachedFactor < 1) cachedFactor = 1; 17509 int stepCached = 0; 17510 int stepEmpty = 0; 17511 int numCached = 0; 17512 int numEmpty = 0; 17513 int numTrimming = 0; 17514 17515 mNumNonCachedProcs = 0; 17516 mNumCachedHiddenProcs = 0; 17517 17518 // First update the OOM adjustment for each of the 17519 // application processes based on their current state. 17520 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17521 int nextCachedAdj = curCachedAdj+1; 17522 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17523 int nextEmptyAdj = curEmptyAdj+2; 17524 for (int i=N-1; i>=0; i--) { 17525 ProcessRecord app = mLruProcesses.get(i); 17526 if (!app.killedByAm && app.thread != null) { 17527 app.procStateChanged = false; 17528 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17529 17530 // If we haven't yet assigned the final cached adj 17531 // to the process, do that now. 17532 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17533 switch (app.curProcState) { 17534 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17535 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17536 // This process is a cached process holding activities... 17537 // assign it the next cached value for that type, and then 17538 // step that cached level. 17539 app.curRawAdj = curCachedAdj; 17540 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17541 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17542 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17543 + ")"); 17544 if (curCachedAdj != nextCachedAdj) { 17545 stepCached++; 17546 if (stepCached >= cachedFactor) { 17547 stepCached = 0; 17548 curCachedAdj = nextCachedAdj; 17549 nextCachedAdj += 2; 17550 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17551 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17552 } 17553 } 17554 } 17555 break; 17556 default: 17557 // For everything else, assign next empty cached process 17558 // level and bump that up. Note that this means that 17559 // long-running services that have dropped down to the 17560 // cached level will be treated as empty (since their process 17561 // state is still as a service), which is what we want. 17562 app.curRawAdj = curEmptyAdj; 17563 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17564 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17565 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17566 + ")"); 17567 if (curEmptyAdj != nextEmptyAdj) { 17568 stepEmpty++; 17569 if (stepEmpty >= emptyFactor) { 17570 stepEmpty = 0; 17571 curEmptyAdj = nextEmptyAdj; 17572 nextEmptyAdj += 2; 17573 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17574 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17575 } 17576 } 17577 } 17578 break; 17579 } 17580 } 17581 17582 applyOomAdjLocked(app, TOP_APP, true, now); 17583 17584 // Count the number of process types. 17585 switch (app.curProcState) { 17586 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17587 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17588 mNumCachedHiddenProcs++; 17589 numCached++; 17590 if (numCached > cachedProcessLimit) { 17591 app.kill("cached #" + numCached, true); 17592 } 17593 break; 17594 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17595 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17596 && app.lastActivityTime < oldTime) { 17597 app.kill("empty for " 17598 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17599 / 1000) + "s", true); 17600 } else { 17601 numEmpty++; 17602 if (numEmpty > emptyProcessLimit) { 17603 app.kill("empty #" + numEmpty, true); 17604 } 17605 } 17606 break; 17607 default: 17608 mNumNonCachedProcs++; 17609 break; 17610 } 17611 17612 if (app.isolated && app.services.size() <= 0) { 17613 // If this is an isolated process, and there are no 17614 // services running in it, then the process is no longer 17615 // needed. We agressively kill these because we can by 17616 // definition not re-use the same process again, and it is 17617 // good to avoid having whatever code was running in them 17618 // left sitting around after no longer needed. 17619 app.kill("isolated not needed", true); 17620 } 17621 17622 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17623 && !app.killedByAm) { 17624 numTrimming++; 17625 } 17626 } 17627 } 17628 17629 mNumServiceProcs = mNewNumServiceProcs; 17630 17631 // Now determine the memory trimming level of background processes. 17632 // Unfortunately we need to start at the back of the list to do this 17633 // properly. We only do this if the number of background apps we 17634 // are managing to keep around is less than half the maximum we desire; 17635 // if we are keeping a good number around, we'll let them use whatever 17636 // memory they want. 17637 final int numCachedAndEmpty = numCached + numEmpty; 17638 int memFactor; 17639 if (numCached <= ProcessList.TRIM_CACHED_APPS 17640 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17641 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17642 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17643 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17644 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17645 } else { 17646 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17647 } 17648 } else { 17649 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17650 } 17651 // We always allow the memory level to go up (better). We only allow it to go 17652 // down if we are in a state where that is allowed, *and* the total number of processes 17653 // has gone down since last time. 17654 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17655 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17656 + " last=" + mLastNumProcesses); 17657 if (memFactor > mLastMemoryLevel) { 17658 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17659 memFactor = mLastMemoryLevel; 17660 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17661 } 17662 } 17663 mLastMemoryLevel = memFactor; 17664 mLastNumProcesses = mLruProcesses.size(); 17665 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17666 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17667 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17668 if (mLowRamStartTime == 0) { 17669 mLowRamStartTime = now; 17670 } 17671 int step = 0; 17672 int fgTrimLevel; 17673 switch (memFactor) { 17674 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17675 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17676 break; 17677 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17678 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17679 break; 17680 default: 17681 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17682 break; 17683 } 17684 int factor = numTrimming/3; 17685 int minFactor = 2; 17686 if (mHomeProcess != null) minFactor++; 17687 if (mPreviousProcess != null) minFactor++; 17688 if (factor < minFactor) factor = minFactor; 17689 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17690 for (int i=N-1; i>=0; i--) { 17691 ProcessRecord app = mLruProcesses.get(i); 17692 if (allChanged || app.procStateChanged) { 17693 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17694 app.procStateChanged = false; 17695 } 17696 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17697 && !app.killedByAm) { 17698 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17699 try { 17700 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17701 "Trimming memory of " + app.processName 17702 + " to " + curLevel); 17703 app.thread.scheduleTrimMemory(curLevel); 17704 } catch (RemoteException e) { 17705 } 17706 if (false) { 17707 // For now we won't do this; our memory trimming seems 17708 // to be good enough at this point that destroying 17709 // activities causes more harm than good. 17710 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17711 && app != mHomeProcess && app != mPreviousProcess) { 17712 // Need to do this on its own message because the stack may not 17713 // be in a consistent state at this point. 17714 // For these apps we will also finish their activities 17715 // to help them free memory. 17716 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17717 } 17718 } 17719 } 17720 app.trimMemoryLevel = curLevel; 17721 step++; 17722 if (step >= factor) { 17723 step = 0; 17724 switch (curLevel) { 17725 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17726 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17727 break; 17728 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17729 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17730 break; 17731 } 17732 } 17733 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17734 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17735 && app.thread != null) { 17736 try { 17737 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17738 "Trimming memory of heavy-weight " + app.processName 17739 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17740 app.thread.scheduleTrimMemory( 17741 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17742 } catch (RemoteException e) { 17743 } 17744 } 17745 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17746 } else { 17747 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17748 || app.systemNoUi) && app.pendingUiClean) { 17749 // If this application is now in the background and it 17750 // had done UI, then give it the special trim level to 17751 // have it free UI resources. 17752 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17753 if (app.trimMemoryLevel < level && app.thread != null) { 17754 try { 17755 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17756 "Trimming memory of bg-ui " + app.processName 17757 + " to " + level); 17758 app.thread.scheduleTrimMemory(level); 17759 } catch (RemoteException e) { 17760 } 17761 } 17762 app.pendingUiClean = false; 17763 } 17764 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17765 try { 17766 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17767 "Trimming memory of fg " + app.processName 17768 + " to " + fgTrimLevel); 17769 app.thread.scheduleTrimMemory(fgTrimLevel); 17770 } catch (RemoteException e) { 17771 } 17772 } 17773 app.trimMemoryLevel = fgTrimLevel; 17774 } 17775 } 17776 } else { 17777 if (mLowRamStartTime != 0) { 17778 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17779 mLowRamStartTime = 0; 17780 } 17781 for (int i=N-1; i>=0; i--) { 17782 ProcessRecord app = mLruProcesses.get(i); 17783 if (allChanged || app.procStateChanged) { 17784 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17785 app.procStateChanged = false; 17786 } 17787 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17788 || app.systemNoUi) && app.pendingUiClean) { 17789 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17790 && app.thread != null) { 17791 try { 17792 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17793 "Trimming memory of ui hidden " + app.processName 17794 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17795 app.thread.scheduleTrimMemory( 17796 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17797 } catch (RemoteException e) { 17798 } 17799 } 17800 app.pendingUiClean = false; 17801 } 17802 app.trimMemoryLevel = 0; 17803 } 17804 } 17805 17806 if (mAlwaysFinishActivities) { 17807 // Need to do this on its own message because the stack may not 17808 // be in a consistent state at this point. 17809 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17810 } 17811 17812 if (allChanged) { 17813 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17814 } 17815 17816 if (mProcessStats.shouldWriteNowLocked(now)) { 17817 mHandler.post(new Runnable() { 17818 @Override public void run() { 17819 synchronized (ActivityManagerService.this) { 17820 mProcessStats.writeStateAsyncLocked(); 17821 } 17822 } 17823 }); 17824 } 17825 17826 if (DEBUG_OOM_ADJ) { 17827 if (false) { 17828 RuntimeException here = new RuntimeException("here"); 17829 here.fillInStackTrace(); 17830 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17831 } else { 17832 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17833 } 17834 } 17835 } 17836 17837 final void trimApplications() { 17838 synchronized (this) { 17839 int i; 17840 17841 // First remove any unused application processes whose package 17842 // has been removed. 17843 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17844 final ProcessRecord app = mRemovedProcesses.get(i); 17845 if (app.activities.size() == 0 17846 && app.curReceiver == null && app.services.size() == 0) { 17847 Slog.i( 17848 TAG, "Exiting empty application process " 17849 + app.processName + " (" 17850 + (app.thread != null ? app.thread.asBinder() : null) 17851 + ")\n"); 17852 if (app.pid > 0 && app.pid != MY_PID) { 17853 app.kill("empty", false); 17854 } else { 17855 try { 17856 app.thread.scheduleExit(); 17857 } catch (Exception e) { 17858 // Ignore exceptions. 17859 } 17860 } 17861 cleanUpApplicationRecordLocked(app, false, true, -1); 17862 mRemovedProcesses.remove(i); 17863 17864 if (app.persistent) { 17865 addAppLocked(app.info, false, null /* ABI override */); 17866 } 17867 } 17868 } 17869 17870 // Now update the oom adj for all processes. 17871 updateOomAdjLocked(); 17872 } 17873 } 17874 17875 /** This method sends the specified signal to each of the persistent apps */ 17876 public void signalPersistentProcesses(int sig) throws RemoteException { 17877 if (sig != Process.SIGNAL_USR1) { 17878 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17879 } 17880 17881 synchronized (this) { 17882 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17883 != PackageManager.PERMISSION_GRANTED) { 17884 throw new SecurityException("Requires permission " 17885 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17886 } 17887 17888 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17889 ProcessRecord r = mLruProcesses.get(i); 17890 if (r.thread != null && r.persistent) { 17891 Process.sendSignal(r.pid, sig); 17892 } 17893 } 17894 } 17895 } 17896 17897 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17898 if (proc == null || proc == mProfileProc) { 17899 proc = mProfileProc; 17900 profileType = mProfileType; 17901 clearProfilerLocked(); 17902 } 17903 if (proc == null) { 17904 return; 17905 } 17906 try { 17907 proc.thread.profilerControl(false, null, profileType); 17908 } catch (RemoteException e) { 17909 throw new IllegalStateException("Process disappeared"); 17910 } 17911 } 17912 17913 private void clearProfilerLocked() { 17914 if (mProfileFd != null) { 17915 try { 17916 mProfileFd.close(); 17917 } catch (IOException e) { 17918 } 17919 } 17920 mProfileApp = null; 17921 mProfileProc = null; 17922 mProfileFile = null; 17923 mProfileType = 0; 17924 mAutoStopProfiler = false; 17925 mSamplingInterval = 0; 17926 } 17927 17928 public boolean profileControl(String process, int userId, boolean start, 17929 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17930 17931 try { 17932 synchronized (this) { 17933 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17934 // its own permission. 17935 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17936 != PackageManager.PERMISSION_GRANTED) { 17937 throw new SecurityException("Requires permission " 17938 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17939 } 17940 17941 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17942 throw new IllegalArgumentException("null profile info or fd"); 17943 } 17944 17945 ProcessRecord proc = null; 17946 if (process != null) { 17947 proc = findProcessLocked(process, userId, "profileControl"); 17948 } 17949 17950 if (start && (proc == null || proc.thread == null)) { 17951 throw new IllegalArgumentException("Unknown process: " + process); 17952 } 17953 17954 if (start) { 17955 stopProfilerLocked(null, 0); 17956 setProfileApp(proc.info, proc.processName, profilerInfo); 17957 mProfileProc = proc; 17958 mProfileType = profileType; 17959 ParcelFileDescriptor fd = profilerInfo.profileFd; 17960 try { 17961 fd = fd.dup(); 17962 } catch (IOException e) { 17963 fd = null; 17964 } 17965 profilerInfo.profileFd = fd; 17966 proc.thread.profilerControl(start, profilerInfo, profileType); 17967 fd = null; 17968 mProfileFd = null; 17969 } else { 17970 stopProfilerLocked(proc, profileType); 17971 if (profilerInfo != null && profilerInfo.profileFd != null) { 17972 try { 17973 profilerInfo.profileFd.close(); 17974 } catch (IOException e) { 17975 } 17976 } 17977 } 17978 17979 return true; 17980 } 17981 } catch (RemoteException e) { 17982 throw new IllegalStateException("Process disappeared"); 17983 } finally { 17984 if (profilerInfo != null && profilerInfo.profileFd != null) { 17985 try { 17986 profilerInfo.profileFd.close(); 17987 } catch (IOException e) { 17988 } 17989 } 17990 } 17991 } 17992 17993 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17994 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17995 userId, true, ALLOW_FULL_ONLY, callName, null); 17996 ProcessRecord proc = null; 17997 try { 17998 int pid = Integer.parseInt(process); 17999 synchronized (mPidsSelfLocked) { 18000 proc = mPidsSelfLocked.get(pid); 18001 } 18002 } catch (NumberFormatException e) { 18003 } 18004 18005 if (proc == null) { 18006 ArrayMap<String, SparseArray<ProcessRecord>> all 18007 = mProcessNames.getMap(); 18008 SparseArray<ProcessRecord> procs = all.get(process); 18009 if (procs != null && procs.size() > 0) { 18010 proc = procs.valueAt(0); 18011 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18012 for (int i=1; i<procs.size(); i++) { 18013 ProcessRecord thisProc = procs.valueAt(i); 18014 if (thisProc.userId == userId) { 18015 proc = thisProc; 18016 break; 18017 } 18018 } 18019 } 18020 } 18021 } 18022 18023 return proc; 18024 } 18025 18026 public boolean dumpHeap(String process, int userId, boolean managed, 18027 String path, ParcelFileDescriptor fd) throws RemoteException { 18028 18029 try { 18030 synchronized (this) { 18031 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18032 // its own permission (same as profileControl). 18033 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18034 != PackageManager.PERMISSION_GRANTED) { 18035 throw new SecurityException("Requires permission " 18036 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18037 } 18038 18039 if (fd == null) { 18040 throw new IllegalArgumentException("null fd"); 18041 } 18042 18043 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18044 if (proc == null || proc.thread == null) { 18045 throw new IllegalArgumentException("Unknown process: " + process); 18046 } 18047 18048 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18049 if (!isDebuggable) { 18050 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18051 throw new SecurityException("Process not debuggable: " + proc); 18052 } 18053 } 18054 18055 proc.thread.dumpHeap(managed, path, fd); 18056 fd = null; 18057 return true; 18058 } 18059 } catch (RemoteException e) { 18060 throw new IllegalStateException("Process disappeared"); 18061 } finally { 18062 if (fd != null) { 18063 try { 18064 fd.close(); 18065 } catch (IOException e) { 18066 } 18067 } 18068 } 18069 } 18070 18071 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18072 public void monitor() { 18073 synchronized (this) { } 18074 } 18075 18076 void onCoreSettingsChange(Bundle settings) { 18077 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18078 ProcessRecord processRecord = mLruProcesses.get(i); 18079 try { 18080 if (processRecord.thread != null) { 18081 processRecord.thread.setCoreSettings(settings); 18082 } 18083 } catch (RemoteException re) { 18084 /* ignore */ 18085 } 18086 } 18087 } 18088 18089 // Multi-user methods 18090 18091 /** 18092 * Start user, if its not already running, but don't bring it to foreground. 18093 */ 18094 @Override 18095 public boolean startUserInBackground(final int userId) { 18096 return startUser(userId, /* foreground */ false); 18097 } 18098 18099 /** 18100 * Start user, if its not already running, and bring it to foreground. 18101 */ 18102 boolean startUserInForeground(final int userId, Dialog dlg) { 18103 boolean result = startUser(userId, /* foreground */ true); 18104 dlg.dismiss(); 18105 return result; 18106 } 18107 18108 /** 18109 * Refreshes the list of users related to the current user when either a 18110 * user switch happens or when a new related user is started in the 18111 * background. 18112 */ 18113 private void updateCurrentProfileIdsLocked() { 18114 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18115 mCurrentUserId, false /* enabledOnly */); 18116 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18117 for (int i = 0; i < currentProfileIds.length; i++) { 18118 currentProfileIds[i] = profiles.get(i).id; 18119 } 18120 mCurrentProfileIds = currentProfileIds; 18121 18122 synchronized (mUserProfileGroupIdsSelfLocked) { 18123 mUserProfileGroupIdsSelfLocked.clear(); 18124 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18125 for (int i = 0; i < users.size(); i++) { 18126 UserInfo user = users.get(i); 18127 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18128 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18129 } 18130 } 18131 } 18132 } 18133 18134 private Set getProfileIdsLocked(int userId) { 18135 Set userIds = new HashSet<Integer>(); 18136 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18137 userId, false /* enabledOnly */); 18138 for (UserInfo user : profiles) { 18139 userIds.add(Integer.valueOf(user.id)); 18140 } 18141 return userIds; 18142 } 18143 18144 @Override 18145 public boolean switchUser(final int userId) { 18146 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18147 String userName; 18148 synchronized (this) { 18149 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18150 if (userInfo == null) { 18151 Slog.w(TAG, "No user info for user #" + userId); 18152 return false; 18153 } 18154 if (userInfo.isManagedProfile()) { 18155 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18156 return false; 18157 } 18158 userName = userInfo.name; 18159 mTargetUserId = userId; 18160 } 18161 mHandler.removeMessages(START_USER_SWITCH_MSG); 18162 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18163 return true; 18164 } 18165 18166 private void showUserSwitchDialog(int userId, String userName) { 18167 // The dialog will show and then initiate the user switch by calling startUserInForeground 18168 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18169 true /* above system */); 18170 d.show(); 18171 } 18172 18173 private boolean startUser(final int userId, final boolean foreground) { 18174 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18175 != PackageManager.PERMISSION_GRANTED) { 18176 String msg = "Permission Denial: switchUser() from pid=" 18177 + Binder.getCallingPid() 18178 + ", uid=" + Binder.getCallingUid() 18179 + " requires " + INTERACT_ACROSS_USERS_FULL; 18180 Slog.w(TAG, msg); 18181 throw new SecurityException(msg); 18182 } 18183 18184 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18185 18186 final long ident = Binder.clearCallingIdentity(); 18187 try { 18188 synchronized (this) { 18189 final int oldUserId = mCurrentUserId; 18190 if (oldUserId == userId) { 18191 return true; 18192 } 18193 18194 mStackSupervisor.setLockTaskModeLocked(null, false); 18195 18196 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18197 if (userInfo == null) { 18198 Slog.w(TAG, "No user info for user #" + userId); 18199 return false; 18200 } 18201 if (foreground && userInfo.isManagedProfile()) { 18202 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18203 return false; 18204 } 18205 18206 if (foreground) { 18207 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18208 R.anim.screen_user_enter); 18209 } 18210 18211 boolean needStart = false; 18212 18213 // If the user we are switching to is not currently started, then 18214 // we need to start it now. 18215 if (mStartedUsers.get(userId) == null) { 18216 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18217 updateStartedUserArrayLocked(); 18218 needStart = true; 18219 } 18220 18221 final Integer userIdInt = Integer.valueOf(userId); 18222 mUserLru.remove(userIdInt); 18223 mUserLru.add(userIdInt); 18224 18225 if (foreground) { 18226 mCurrentUserId = userId; 18227 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18228 updateCurrentProfileIdsLocked(); 18229 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18230 // Once the internal notion of the active user has switched, we lock the device 18231 // with the option to show the user switcher on the keyguard. 18232 mWindowManager.lockNow(null); 18233 } else { 18234 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18235 updateCurrentProfileIdsLocked(); 18236 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18237 mUserLru.remove(currentUserIdInt); 18238 mUserLru.add(currentUserIdInt); 18239 } 18240 18241 final UserStartedState uss = mStartedUsers.get(userId); 18242 18243 // Make sure user is in the started state. If it is currently 18244 // stopping, we need to knock that off. 18245 if (uss.mState == UserStartedState.STATE_STOPPING) { 18246 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18247 // so we can just fairly silently bring the user back from 18248 // the almost-dead. 18249 uss.mState = UserStartedState.STATE_RUNNING; 18250 updateStartedUserArrayLocked(); 18251 needStart = true; 18252 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18253 // This means ACTION_SHUTDOWN has been sent, so we will 18254 // need to treat this as a new boot of the user. 18255 uss.mState = UserStartedState.STATE_BOOTING; 18256 updateStartedUserArrayLocked(); 18257 needStart = true; 18258 } 18259 18260 if (uss.mState == UserStartedState.STATE_BOOTING) { 18261 // Booting up a new user, need to tell system services about it. 18262 // Note that this is on the same handler as scheduling of broadcasts, 18263 // which is important because it needs to go first. 18264 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18265 } 18266 18267 if (foreground) { 18268 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18269 oldUserId)); 18270 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18271 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18272 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18273 oldUserId, userId, uss)); 18274 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18275 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18276 } 18277 18278 if (needStart) { 18279 // Send USER_STARTED broadcast 18280 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18281 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18282 | Intent.FLAG_RECEIVER_FOREGROUND); 18283 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18284 broadcastIntentLocked(null, null, intent, 18285 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18286 false, false, MY_PID, Process.SYSTEM_UID, userId); 18287 } 18288 18289 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18290 if (userId != UserHandle.USER_OWNER) { 18291 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18292 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18293 broadcastIntentLocked(null, null, intent, null, 18294 new IIntentReceiver.Stub() { 18295 public void performReceive(Intent intent, int resultCode, 18296 String data, Bundle extras, boolean ordered, 18297 boolean sticky, int sendingUser) { 18298 onUserInitialized(uss, foreground, oldUserId, userId); 18299 } 18300 }, 0, null, null, null, AppOpsManager.OP_NONE, 18301 true, false, MY_PID, Process.SYSTEM_UID, 18302 userId); 18303 uss.initializing = true; 18304 } else { 18305 getUserManagerLocked().makeInitialized(userInfo.id); 18306 } 18307 } 18308 18309 if (foreground) { 18310 if (!uss.initializing) { 18311 moveUserToForeground(uss, oldUserId, userId); 18312 } 18313 } else { 18314 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18315 } 18316 18317 if (needStart) { 18318 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18320 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18321 broadcastIntentLocked(null, null, intent, 18322 null, new IIntentReceiver.Stub() { 18323 @Override 18324 public void performReceive(Intent intent, int resultCode, String data, 18325 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18326 throws RemoteException { 18327 } 18328 }, 0, null, null, 18329 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18330 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18331 } 18332 } 18333 } finally { 18334 Binder.restoreCallingIdentity(ident); 18335 } 18336 18337 return true; 18338 } 18339 18340 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18341 long ident = Binder.clearCallingIdentity(); 18342 try { 18343 Intent intent; 18344 if (oldUserId >= 0) { 18345 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18346 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18347 int count = profiles.size(); 18348 for (int i = 0; i < count; i++) { 18349 int profileUserId = profiles.get(i).id; 18350 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18351 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18352 | Intent.FLAG_RECEIVER_FOREGROUND); 18353 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18354 broadcastIntentLocked(null, null, intent, 18355 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18356 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18357 } 18358 } 18359 if (newUserId >= 0) { 18360 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18361 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18362 int count = profiles.size(); 18363 for (int i = 0; i < count; i++) { 18364 int profileUserId = profiles.get(i).id; 18365 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18366 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18367 | Intent.FLAG_RECEIVER_FOREGROUND); 18368 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18369 broadcastIntentLocked(null, null, intent, 18370 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18371 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18372 } 18373 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18374 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18375 | Intent.FLAG_RECEIVER_FOREGROUND); 18376 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18377 broadcastIntentLocked(null, null, intent, 18378 null, null, 0, null, null, 18379 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18380 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18381 } 18382 } finally { 18383 Binder.restoreCallingIdentity(ident); 18384 } 18385 } 18386 18387 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18388 final int newUserId) { 18389 final int N = mUserSwitchObservers.beginBroadcast(); 18390 if (N > 0) { 18391 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18392 int mCount = 0; 18393 @Override 18394 public void sendResult(Bundle data) throws RemoteException { 18395 synchronized (ActivityManagerService.this) { 18396 if (mCurUserSwitchCallback == this) { 18397 mCount++; 18398 if (mCount == N) { 18399 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18400 } 18401 } 18402 } 18403 } 18404 }; 18405 synchronized (this) { 18406 uss.switching = true; 18407 mCurUserSwitchCallback = callback; 18408 } 18409 for (int i=0; i<N; i++) { 18410 try { 18411 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18412 newUserId, callback); 18413 } catch (RemoteException e) { 18414 } 18415 } 18416 } else { 18417 synchronized (this) { 18418 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18419 } 18420 } 18421 mUserSwitchObservers.finishBroadcast(); 18422 } 18423 18424 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18425 synchronized (this) { 18426 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18427 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18428 } 18429 } 18430 18431 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18432 mCurUserSwitchCallback = null; 18433 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18434 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18435 oldUserId, newUserId, uss)); 18436 } 18437 18438 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18439 synchronized (this) { 18440 if (foreground) { 18441 moveUserToForeground(uss, oldUserId, newUserId); 18442 } 18443 } 18444 18445 completeSwitchAndInitalize(uss, newUserId, true, false); 18446 } 18447 18448 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18449 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18450 if (homeInFront) { 18451 startHomeActivityLocked(newUserId); 18452 } else { 18453 mStackSupervisor.resumeTopActivitiesLocked(); 18454 } 18455 EventLogTags.writeAmSwitchUser(newUserId); 18456 getUserManagerLocked().userForeground(newUserId); 18457 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18458 } 18459 18460 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18461 completeSwitchAndInitalize(uss, newUserId, false, true); 18462 } 18463 18464 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18465 boolean clearInitializing, boolean clearSwitching) { 18466 boolean unfrozen = false; 18467 synchronized (this) { 18468 if (clearInitializing) { 18469 uss.initializing = false; 18470 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18471 } 18472 if (clearSwitching) { 18473 uss.switching = false; 18474 } 18475 if (!uss.switching && !uss.initializing) { 18476 mWindowManager.stopFreezingScreen(); 18477 unfrozen = true; 18478 } 18479 } 18480 if (unfrozen) { 18481 final int N = mUserSwitchObservers.beginBroadcast(); 18482 for (int i=0; i<N; i++) { 18483 try { 18484 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18485 } catch (RemoteException e) { 18486 } 18487 } 18488 mUserSwitchObservers.finishBroadcast(); 18489 } 18490 } 18491 18492 void scheduleStartProfilesLocked() { 18493 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18494 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18495 DateUtils.SECOND_IN_MILLIS); 18496 } 18497 } 18498 18499 void startProfilesLocked() { 18500 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18501 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18502 mCurrentUserId, false /* enabledOnly */); 18503 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18504 for (UserInfo user : profiles) { 18505 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18506 && user.id != mCurrentUserId) { 18507 toStart.add(user); 18508 } 18509 } 18510 final int n = toStart.size(); 18511 int i = 0; 18512 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18513 startUserInBackground(toStart.get(i).id); 18514 } 18515 if (i < n) { 18516 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18517 } 18518 } 18519 18520 void finishUserBoot(UserStartedState uss) { 18521 synchronized (this) { 18522 if (uss.mState == UserStartedState.STATE_BOOTING 18523 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18524 uss.mState = UserStartedState.STATE_RUNNING; 18525 final int userId = uss.mHandle.getIdentifier(); 18526 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18527 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18528 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18529 broadcastIntentLocked(null, null, intent, 18530 null, null, 0, null, null, 18531 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18532 true, false, MY_PID, Process.SYSTEM_UID, userId); 18533 } 18534 } 18535 } 18536 18537 void finishUserSwitch(UserStartedState uss) { 18538 synchronized (this) { 18539 finishUserBoot(uss); 18540 18541 startProfilesLocked(); 18542 18543 int num = mUserLru.size(); 18544 int i = 0; 18545 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18546 Integer oldUserId = mUserLru.get(i); 18547 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18548 if (oldUss == null) { 18549 // Shouldn't happen, but be sane if it does. 18550 mUserLru.remove(i); 18551 num--; 18552 continue; 18553 } 18554 if (oldUss.mState == UserStartedState.STATE_STOPPING 18555 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18556 // This user is already stopping, doesn't count. 18557 num--; 18558 i++; 18559 continue; 18560 } 18561 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18562 // Owner and current can't be stopped, but count as running. 18563 i++; 18564 continue; 18565 } 18566 // This is a user to be stopped. 18567 stopUserLocked(oldUserId, null); 18568 num--; 18569 i++; 18570 } 18571 } 18572 } 18573 18574 @Override 18575 public int stopUser(final int userId, final IStopUserCallback callback) { 18576 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18577 != PackageManager.PERMISSION_GRANTED) { 18578 String msg = "Permission Denial: switchUser() from pid=" 18579 + Binder.getCallingPid() 18580 + ", uid=" + Binder.getCallingUid() 18581 + " requires " + INTERACT_ACROSS_USERS_FULL; 18582 Slog.w(TAG, msg); 18583 throw new SecurityException(msg); 18584 } 18585 if (userId <= 0) { 18586 throw new IllegalArgumentException("Can't stop primary user " + userId); 18587 } 18588 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18589 synchronized (this) { 18590 return stopUserLocked(userId, callback); 18591 } 18592 } 18593 18594 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18595 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18596 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18597 return ActivityManager.USER_OP_IS_CURRENT; 18598 } 18599 18600 final UserStartedState uss = mStartedUsers.get(userId); 18601 if (uss == null) { 18602 // User is not started, nothing to do... but we do need to 18603 // callback if requested. 18604 if (callback != null) { 18605 mHandler.post(new Runnable() { 18606 @Override 18607 public void run() { 18608 try { 18609 callback.userStopped(userId); 18610 } catch (RemoteException e) { 18611 } 18612 } 18613 }); 18614 } 18615 return ActivityManager.USER_OP_SUCCESS; 18616 } 18617 18618 if (callback != null) { 18619 uss.mStopCallbacks.add(callback); 18620 } 18621 18622 if (uss.mState != UserStartedState.STATE_STOPPING 18623 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18624 uss.mState = UserStartedState.STATE_STOPPING; 18625 updateStartedUserArrayLocked(); 18626 18627 long ident = Binder.clearCallingIdentity(); 18628 try { 18629 // We are going to broadcast ACTION_USER_STOPPING and then 18630 // once that is done send a final ACTION_SHUTDOWN and then 18631 // stop the user. 18632 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18633 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18634 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18635 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18636 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18637 // This is the result receiver for the final shutdown broadcast. 18638 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18639 @Override 18640 public void performReceive(Intent intent, int resultCode, String data, 18641 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18642 finishUserStop(uss); 18643 } 18644 }; 18645 // This is the result receiver for the initial stopping broadcast. 18646 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18647 @Override 18648 public void performReceive(Intent intent, int resultCode, String data, 18649 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18650 // On to the next. 18651 synchronized (ActivityManagerService.this) { 18652 if (uss.mState != UserStartedState.STATE_STOPPING) { 18653 // Whoops, we are being started back up. Abort, abort! 18654 return; 18655 } 18656 uss.mState = UserStartedState.STATE_SHUTDOWN; 18657 } 18658 mBatteryStatsService.noteEvent( 18659 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18660 Integer.toString(userId), userId); 18661 mSystemServiceManager.stopUser(userId); 18662 broadcastIntentLocked(null, null, shutdownIntent, 18663 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18664 true, false, MY_PID, Process.SYSTEM_UID, userId); 18665 } 18666 }; 18667 // Kick things off. 18668 broadcastIntentLocked(null, null, stoppingIntent, 18669 null, stoppingReceiver, 0, null, null, 18670 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18671 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18672 } finally { 18673 Binder.restoreCallingIdentity(ident); 18674 } 18675 } 18676 18677 return ActivityManager.USER_OP_SUCCESS; 18678 } 18679 18680 void finishUserStop(UserStartedState uss) { 18681 final int userId = uss.mHandle.getIdentifier(); 18682 boolean stopped; 18683 ArrayList<IStopUserCallback> callbacks; 18684 synchronized (this) { 18685 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18686 if (mStartedUsers.get(userId) != uss) { 18687 stopped = false; 18688 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18689 stopped = false; 18690 } else { 18691 stopped = true; 18692 // User can no longer run. 18693 mStartedUsers.remove(userId); 18694 mUserLru.remove(Integer.valueOf(userId)); 18695 updateStartedUserArrayLocked(); 18696 18697 // Clean up all state and processes associated with the user. 18698 // Kill all the processes for the user. 18699 forceStopUserLocked(userId, "finish user"); 18700 } 18701 18702 // Explicitly remove the old information in mRecentTasks. 18703 removeRecentTasksForUserLocked(userId); 18704 } 18705 18706 for (int i=0; i<callbacks.size(); i++) { 18707 try { 18708 if (stopped) callbacks.get(i).userStopped(userId); 18709 else callbacks.get(i).userStopAborted(userId); 18710 } catch (RemoteException e) { 18711 } 18712 } 18713 18714 if (stopped) { 18715 mSystemServiceManager.cleanupUser(userId); 18716 synchronized (this) { 18717 mStackSupervisor.removeUserLocked(userId); 18718 } 18719 } 18720 } 18721 18722 @Override 18723 public UserInfo getCurrentUser() { 18724 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18725 != PackageManager.PERMISSION_GRANTED) && ( 18726 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18727 != PackageManager.PERMISSION_GRANTED)) { 18728 String msg = "Permission Denial: getCurrentUser() from pid=" 18729 + Binder.getCallingPid() 18730 + ", uid=" + Binder.getCallingUid() 18731 + " requires " + INTERACT_ACROSS_USERS; 18732 Slog.w(TAG, msg); 18733 throw new SecurityException(msg); 18734 } 18735 synchronized (this) { 18736 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18737 return getUserManagerLocked().getUserInfo(userId); 18738 } 18739 } 18740 18741 int getCurrentUserIdLocked() { 18742 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18743 } 18744 18745 @Override 18746 public boolean isUserRunning(int userId, boolean orStopped) { 18747 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18748 != PackageManager.PERMISSION_GRANTED) { 18749 String msg = "Permission Denial: isUserRunning() from pid=" 18750 + Binder.getCallingPid() 18751 + ", uid=" + Binder.getCallingUid() 18752 + " requires " + INTERACT_ACROSS_USERS; 18753 Slog.w(TAG, msg); 18754 throw new SecurityException(msg); 18755 } 18756 synchronized (this) { 18757 return isUserRunningLocked(userId, orStopped); 18758 } 18759 } 18760 18761 boolean isUserRunningLocked(int userId, boolean orStopped) { 18762 UserStartedState state = mStartedUsers.get(userId); 18763 if (state == null) { 18764 return false; 18765 } 18766 if (orStopped) { 18767 return true; 18768 } 18769 return state.mState != UserStartedState.STATE_STOPPING 18770 && state.mState != UserStartedState.STATE_SHUTDOWN; 18771 } 18772 18773 @Override 18774 public int[] getRunningUserIds() { 18775 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18776 != PackageManager.PERMISSION_GRANTED) { 18777 String msg = "Permission Denial: isUserRunning() from pid=" 18778 + Binder.getCallingPid() 18779 + ", uid=" + Binder.getCallingUid() 18780 + " requires " + INTERACT_ACROSS_USERS; 18781 Slog.w(TAG, msg); 18782 throw new SecurityException(msg); 18783 } 18784 synchronized (this) { 18785 return mStartedUserArray; 18786 } 18787 } 18788 18789 private void updateStartedUserArrayLocked() { 18790 int num = 0; 18791 for (int i=0; i<mStartedUsers.size(); i++) { 18792 UserStartedState uss = mStartedUsers.valueAt(i); 18793 // This list does not include stopping users. 18794 if (uss.mState != UserStartedState.STATE_STOPPING 18795 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18796 num++; 18797 } 18798 } 18799 mStartedUserArray = new int[num]; 18800 num = 0; 18801 for (int i=0; i<mStartedUsers.size(); i++) { 18802 UserStartedState uss = mStartedUsers.valueAt(i); 18803 if (uss.mState != UserStartedState.STATE_STOPPING 18804 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18805 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18806 num++; 18807 } 18808 } 18809 } 18810 18811 @Override 18812 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18813 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18814 != PackageManager.PERMISSION_GRANTED) { 18815 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18816 + Binder.getCallingPid() 18817 + ", uid=" + Binder.getCallingUid() 18818 + " requires " + INTERACT_ACROSS_USERS_FULL; 18819 Slog.w(TAG, msg); 18820 throw new SecurityException(msg); 18821 } 18822 18823 mUserSwitchObservers.register(observer); 18824 } 18825 18826 @Override 18827 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18828 mUserSwitchObservers.unregister(observer); 18829 } 18830 18831 private boolean userExists(int userId) { 18832 if (userId == 0) { 18833 return true; 18834 } 18835 UserManagerService ums = getUserManagerLocked(); 18836 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18837 } 18838 18839 int[] getUsersLocked() { 18840 UserManagerService ums = getUserManagerLocked(); 18841 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18842 } 18843 18844 UserManagerService getUserManagerLocked() { 18845 if (mUserManager == null) { 18846 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18847 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18848 } 18849 return mUserManager; 18850 } 18851 18852 private int applyUserId(int uid, int userId) { 18853 return UserHandle.getUid(userId, uid); 18854 } 18855 18856 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18857 if (info == null) return null; 18858 ApplicationInfo newInfo = new ApplicationInfo(info); 18859 newInfo.uid = applyUserId(info.uid, userId); 18860 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18861 + info.packageName; 18862 return newInfo; 18863 } 18864 18865 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18866 if (aInfo == null 18867 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18868 return aInfo; 18869 } 18870 18871 ActivityInfo info = new ActivityInfo(aInfo); 18872 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18873 return info; 18874 } 18875 18876 private final class LocalService extends ActivityManagerInternal { 18877 @Override 18878 public void goingToSleep() { 18879 ActivityManagerService.this.goingToSleep(); 18880 } 18881 18882 @Override 18883 public void wakingUp() { 18884 ActivityManagerService.this.wakingUp(); 18885 } 18886 18887 @Override 18888 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18889 String processName, String abiOverride, int uid, Runnable crashHandler) { 18890 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18891 processName, abiOverride, uid, crashHandler); 18892 } 18893 } 18894 18895 /** 18896 * An implementation of IAppTask, that allows an app to manage its own tasks via 18897 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18898 * only the process that calls getAppTasks() can call the AppTask methods. 18899 */ 18900 class AppTaskImpl extends IAppTask.Stub { 18901 private int mTaskId; 18902 private int mCallingUid; 18903 18904 public AppTaskImpl(int taskId, int callingUid) { 18905 mTaskId = taskId; 18906 mCallingUid = callingUid; 18907 } 18908 18909 private void checkCaller() { 18910 if (mCallingUid != Binder.getCallingUid()) { 18911 throw new SecurityException("Caller " + mCallingUid 18912 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18913 } 18914 } 18915 18916 @Override 18917 public void finishAndRemoveTask() { 18918 checkCaller(); 18919 18920 synchronized (ActivityManagerService.this) { 18921 long origId = Binder.clearCallingIdentity(); 18922 try { 18923 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18924 if (tr == null) { 18925 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18926 } 18927 // Only kill the process if we are not a new document 18928 int flags = tr.getBaseIntent().getFlags(); 18929 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18930 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18931 removeTaskByIdLocked(mTaskId, 18932 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18933 } finally { 18934 Binder.restoreCallingIdentity(origId); 18935 } 18936 } 18937 } 18938 18939 @Override 18940 public ActivityManager.RecentTaskInfo getTaskInfo() { 18941 checkCaller(); 18942 18943 synchronized (ActivityManagerService.this) { 18944 long origId = Binder.clearCallingIdentity(); 18945 try { 18946 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18947 if (tr == null) { 18948 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18949 } 18950 return createRecentTaskInfoFromTaskRecord(tr); 18951 } finally { 18952 Binder.restoreCallingIdentity(origId); 18953 } 18954 } 18955 } 18956 18957 @Override 18958 public void moveToFront() { 18959 checkCaller(); 18960 18961 final TaskRecord tr; 18962 synchronized (ActivityManagerService.this) { 18963 tr = recentTaskForIdLocked(mTaskId); 18964 if (tr == null) { 18965 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18966 } 18967 if (tr.getRootActivity() != null) { 18968 moveTaskToFrontLocked(tr.taskId, 0, null); 18969 } 18970 } 18971 18972 startActivityFromRecentsInner(tr.taskId, null); 18973 } 18974 18975 @Override 18976 public int startActivity(IBinder whoThread, String callingPackage, 18977 Intent intent, String resolvedType, Bundle options) { 18978 checkCaller(); 18979 18980 int callingUser = UserHandle.getCallingUserId(); 18981 TaskRecord tr; 18982 IApplicationThread appThread; 18983 synchronized (ActivityManagerService.this) { 18984 tr = recentTaskForIdLocked(mTaskId); 18985 if (tr == null) { 18986 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18987 } 18988 appThread = ApplicationThreadNative.asInterface(whoThread); 18989 if (appThread == null) { 18990 throw new IllegalArgumentException("Bad app thread " + appThread); 18991 } 18992 } 18993 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18994 resolvedType, null, null, null, null, 0, 0, null, null, 18995 null, options, callingUser, null, tr); 18996 } 18997 18998 @Override 18999 public void setExcludeFromRecents(boolean exclude) { 19000 checkCaller(); 19001 19002 synchronized (ActivityManagerService.this) { 19003 long origId = Binder.clearCallingIdentity(); 19004 try { 19005 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19006 if (tr == null) { 19007 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19008 } 19009 Intent intent = tr.getBaseIntent(); 19010 if (exclude) { 19011 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19012 } else { 19013 intent.setFlags(intent.getFlags() 19014 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19015 } 19016 } finally { 19017 Binder.restoreCallingIdentity(origId); 19018 } 19019 } 19020 } 19021 } 19022} 19023