ActivityManagerService.java revision 023b6812abbca465773acd6141ff672d525a83ee
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199import dalvik.system.VMRuntime; 200 201import java.io.BufferedInputStream; 202import java.io.BufferedOutputStream; 203import java.io.DataInputStream; 204import java.io.DataOutputStream; 205import java.io.File; 206import java.io.FileDescriptor; 207import java.io.FileInputStream; 208import java.io.FileNotFoundException; 209import java.io.FileOutputStream; 210import java.io.IOException; 211import java.io.InputStreamReader; 212import java.io.PrintWriter; 213import java.io.StringWriter; 214import java.lang.ref.WeakReference; 215import java.util.ArrayList; 216import java.util.Arrays; 217import java.util.Collections; 218import java.util.Comparator; 219import java.util.HashMap; 220import java.util.HashSet; 221import java.util.Iterator; 222import java.util.List; 223import java.util.Locale; 224import java.util.Map; 225import java.util.Set; 226import java.util.concurrent.atomic.AtomicBoolean; 227import java.util.concurrent.atomic.AtomicLong; 228 229public final class ActivityManagerService extends ActivityManagerNative 230 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 231 232 private static final String USER_DATA_DIR = "/data/user/"; 233 // File that stores last updated system version and called preboot receivers 234 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 235 236 static final String TAG = "ActivityManager"; 237 static final String TAG_MU = "ActivityManagerServiceMU"; 238 static final boolean DEBUG = false; 239 static final boolean localLOGV = DEBUG; 240 static final boolean DEBUG_BACKUP = localLOGV || false; 241 static final boolean DEBUG_BROADCAST = localLOGV || false; 242 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_CLEANUP = localLOGV || false; 245 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 246 static final boolean DEBUG_FOCUS = false; 247 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 248 static final boolean DEBUG_MU = localLOGV || false; 249 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 250 static final boolean DEBUG_LRU = localLOGV || false; 251 static final boolean DEBUG_PAUSE = localLOGV || false; 252 static final boolean DEBUG_POWER = localLOGV || false; 253 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 254 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 255 static final boolean DEBUG_PROCESSES = localLOGV || false; 256 static final boolean DEBUG_PROVIDER = localLOGV || false; 257 static final boolean DEBUG_RESULTS = localLOGV || false; 258 static final boolean DEBUG_SERVICE = localLOGV || false; 259 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 260 static final boolean DEBUG_STACK = localLOGV || false; 261 static final boolean DEBUG_SWITCH = localLOGV || false; 262 static final boolean DEBUG_TASKS = localLOGV || false; 263 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 264 static final boolean DEBUG_TRANSITION = localLOGV || false; 265 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 266 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 267 static final boolean DEBUG_VISBILITY = localLOGV || false; 268 static final boolean DEBUG_PSS = localLOGV || false; 269 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 270 static final boolean DEBUG_RECENTS = localLOGV || false; 271 static final boolean VALIDATE_TOKENS = false; 272 static final boolean SHOW_ACTIVITY_START_TIME = true; 273 274 // Control over CPU and battery monitoring. 275 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 276 static final boolean MONITOR_CPU_USAGE = true; 277 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 278 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 279 static final boolean MONITOR_THREAD_CPU_USAGE = false; 280 281 // The flags that are set for all calls we make to the package manager. 282 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 283 284 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 285 286 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mCallFinishBooting = false; 892 boolean mBootAnimationComplete = false; 893 boolean mWaitingUpdate = false; 894 boolean mDidUpdate = false; 895 boolean mOnBattery = false; 896 boolean mLaunchWarningShown = false; 897 898 Context mContext; 899 900 int mFactoryTest; 901 902 boolean mCheckedForSetup; 903 904 /** 905 * The time at which we will allow normal application switches again, 906 * after a call to {@link #stopAppSwitches()}. 907 */ 908 long mAppSwitchesAllowedTime; 909 910 /** 911 * This is set to true after the first switch after mAppSwitchesAllowedTime 912 * is set; any switches after that will clear the time. 913 */ 914 boolean mDidAppSwitch; 915 916 /** 917 * Last time (in realtime) at which we checked for power usage. 918 */ 919 long mLastPowerCheckRealtime; 920 921 /** 922 * Last time (in uptime) at which we checked for power usage. 923 */ 924 long mLastPowerCheckUptime; 925 926 /** 927 * Set while we are wanting to sleep, to prevent any 928 * activities from being started/resumed. 929 */ 930 private boolean mSleeping = false; 931 932 /** 933 * Set while we are running a voice interaction. This overrides 934 * sleeping while it is active. 935 */ 936 private boolean mRunningVoice = false; 937 938 /** 939 * State of external calls telling us if the device is asleep. 940 */ 941 private boolean mWentToSleep = false; 942 943 /** 944 * State of external call telling us if the lock screen is shown. 945 */ 946 private boolean mLockScreenShown = false; 947 948 /** 949 * Set if we are shutting down the system, similar to sleeping. 950 */ 951 boolean mShuttingDown = false; 952 953 /** 954 * Current sequence id for oom_adj computation traversal. 955 */ 956 int mAdjSeq = 0; 957 958 /** 959 * Current sequence id for process LRU updating. 960 */ 961 int mLruSeq = 0; 962 963 /** 964 * Keep track of the non-cached/empty process we last found, to help 965 * determine how to distribute cached/empty processes next time. 966 */ 967 int mNumNonCachedProcs = 0; 968 969 /** 970 * Keep track of the number of cached hidden procs, to balance oom adj 971 * distribution between those and empty procs. 972 */ 973 int mNumCachedHiddenProcs = 0; 974 975 /** 976 * Keep track of the number of service processes we last found, to 977 * determine on the next iteration which should be B services. 978 */ 979 int mNumServiceProcs = 0; 980 int mNewNumAServiceProcs = 0; 981 int mNewNumServiceProcs = 0; 982 983 /** 984 * Allow the current computed overall memory level of the system to go down? 985 * This is set to false when we are killing processes for reasons other than 986 * memory management, so that the now smaller process list will not be taken as 987 * an indication that memory is tighter. 988 */ 989 boolean mAllowLowerMemLevel = false; 990 991 /** 992 * The last computed memory level, for holding when we are in a state that 993 * processes are going away for other reasons. 994 */ 995 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 996 997 /** 998 * The last total number of process we have, to determine if changes actually look 999 * like a shrinking number of process due to lower RAM. 1000 */ 1001 int mLastNumProcesses; 1002 1003 /** 1004 * The uptime of the last time we performed idle maintenance. 1005 */ 1006 long mLastIdleTime = SystemClock.uptimeMillis(); 1007 1008 /** 1009 * Total time spent with RAM that has been added in the past since the last idle time. 1010 */ 1011 long mLowRamTimeSinceLastIdle = 0; 1012 1013 /** 1014 * If RAM is currently low, when that horrible situation started. 1015 */ 1016 long mLowRamStartTime = 0; 1017 1018 /** 1019 * For reporting to battery stats the current top application. 1020 */ 1021 private String mCurResumedPackage = null; 1022 private int mCurResumedUid = -1; 1023 1024 /** 1025 * For reporting to battery stats the apps currently running foreground 1026 * service. The ProcessMap is package/uid tuples; each of these contain 1027 * an array of the currently foreground processes. 1028 */ 1029 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1030 = new ProcessMap<ArrayList<ProcessRecord>>(); 1031 1032 /** 1033 * This is set if we had to do a delayed dexopt of an app before launching 1034 * it, to increase the ANR timeouts in that case. 1035 */ 1036 boolean mDidDexOpt; 1037 1038 /** 1039 * Set if the systemServer made a call to enterSafeMode. 1040 */ 1041 boolean mSafeMode; 1042 1043 String mDebugApp = null; 1044 boolean mWaitForDebugger = false; 1045 boolean mDebugTransient = false; 1046 String mOrigDebugApp = null; 1047 boolean mOrigWaitForDebugger = false; 1048 boolean mAlwaysFinishActivities = false; 1049 IActivityController mController = null; 1050 String mProfileApp = null; 1051 ProcessRecord mProfileProc = null; 1052 String mProfileFile; 1053 ParcelFileDescriptor mProfileFd; 1054 int mSamplingInterval = 0; 1055 boolean mAutoStopProfiler = false; 1056 int mProfileType = 0; 1057 String mOpenGlTraceApp = null; 1058 1059 static class ProcessChangeItem { 1060 static final int CHANGE_ACTIVITIES = 1<<0; 1061 static final int CHANGE_PROCESS_STATE = 1<<1; 1062 int changes; 1063 int uid; 1064 int pid; 1065 int processState; 1066 boolean foregroundActivities; 1067 } 1068 1069 final RemoteCallbackList<IProcessObserver> mProcessObservers 1070 = new RemoteCallbackList<IProcessObserver>(); 1071 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1072 1073 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1074 = new ArrayList<ProcessChangeItem>(); 1075 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1076 = new ArrayList<ProcessChangeItem>(); 1077 1078 /** 1079 * Runtime CPU use collection thread. This object's lock is used to 1080 * perform synchronization with the thread (notifying it to run). 1081 */ 1082 final Thread mProcessCpuThread; 1083 1084 /** 1085 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1086 * Must acquire this object's lock when accessing it. 1087 * NOTE: this lock will be held while doing long operations (trawling 1088 * through all processes in /proc), so it should never be acquired by 1089 * any critical paths such as when holding the main activity manager lock. 1090 */ 1091 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1092 MONITOR_THREAD_CPU_USAGE); 1093 final AtomicLong mLastCpuTime = new AtomicLong(0); 1094 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1095 1096 long mLastWriteTime = 0; 1097 1098 /** 1099 * Used to retain an update lock when the foreground activity is in 1100 * immersive mode. 1101 */ 1102 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1103 1104 /** 1105 * Set to true after the system has finished booting. 1106 */ 1107 boolean mBooted = false; 1108 1109 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1110 int mProcessLimitOverride = -1; 1111 1112 WindowManagerService mWindowManager; 1113 1114 final ActivityThread mSystemThread; 1115 1116 // Holds the current foreground user's id 1117 int mCurrentUserId = 0; 1118 // Holds the target user's id during a user switch 1119 int mTargetUserId = UserHandle.USER_NULL; 1120 // If there are multiple profiles for the current user, their ids are here 1121 // Currently only the primary user can have managed profiles 1122 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1123 1124 /** 1125 * Mapping from each known user ID to the profile group ID it is associated with. 1126 */ 1127 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1128 1129 private UserManagerService mUserManager; 1130 1131 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1132 final ProcessRecord mApp; 1133 final int mPid; 1134 final IApplicationThread mAppThread; 1135 1136 AppDeathRecipient(ProcessRecord app, int pid, 1137 IApplicationThread thread) { 1138 if (localLOGV) Slog.v( 1139 TAG, "New death recipient " + this 1140 + " for thread " + thread.asBinder()); 1141 mApp = app; 1142 mPid = pid; 1143 mAppThread = thread; 1144 } 1145 1146 @Override 1147 public void binderDied() { 1148 if (localLOGV) Slog.v( 1149 TAG, "Death received in " + this 1150 + " for thread " + mAppThread.asBinder()); 1151 synchronized(ActivityManagerService.this) { 1152 appDiedLocked(mApp, mPid, mAppThread); 1153 } 1154 } 1155 } 1156 1157 static final int SHOW_ERROR_MSG = 1; 1158 static final int SHOW_NOT_RESPONDING_MSG = 2; 1159 static final int SHOW_FACTORY_ERROR_MSG = 3; 1160 static final int UPDATE_CONFIGURATION_MSG = 4; 1161 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1162 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1163 static final int SERVICE_TIMEOUT_MSG = 12; 1164 static final int UPDATE_TIME_ZONE = 13; 1165 static final int SHOW_UID_ERROR_MSG = 14; 1166 static final int IM_FEELING_LUCKY_MSG = 15; 1167 static final int PROC_START_TIMEOUT_MSG = 20; 1168 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1169 static final int KILL_APPLICATION_MSG = 22; 1170 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1171 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1172 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1173 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1174 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1175 static final int CLEAR_DNS_CACHE_MSG = 28; 1176 static final int UPDATE_HTTP_PROXY_MSG = 29; 1177 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1178 static final int DISPATCH_PROCESSES_CHANGED = 31; 1179 static final int DISPATCH_PROCESS_DIED = 32; 1180 static final int REPORT_MEM_USAGE_MSG = 33; 1181 static final int REPORT_USER_SWITCH_MSG = 34; 1182 static final int CONTINUE_USER_SWITCH_MSG = 35; 1183 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1184 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1185 static final int PERSIST_URI_GRANTS_MSG = 38; 1186 static final int REQUEST_ALL_PSS_MSG = 39; 1187 static final int START_PROFILES_MSG = 40; 1188 static final int UPDATE_TIME = 41; 1189 static final int SYSTEM_USER_START_MSG = 42; 1190 static final int SYSTEM_USER_CURRENT_MSG = 43; 1191 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1192 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1193 static final int START_USER_SWITCH_MSG = 46; 1194 1195 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1196 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1197 static final int FIRST_COMPAT_MODE_MSG = 300; 1198 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1199 1200 AlertDialog mUidAlert; 1201 CompatModeDialog mCompatModeDialog; 1202 long mLastMemUsageReportTime = 0; 1203 1204 private LockToAppRequestDialog mLockToAppRequest; 1205 1206 /** 1207 * Flag whether the current user is a "monkey", i.e. whether 1208 * the UI is driven by a UI automation tool. 1209 */ 1210 private boolean mUserIsMonkey; 1211 1212 /** Flag whether the device has a Recents UI */ 1213 boolean mHasRecents; 1214 1215 /** The dimensions of the thumbnails in the Recents UI. */ 1216 int mThumbnailWidth; 1217 int mThumbnailHeight; 1218 1219 final ServiceThread mHandlerThread; 1220 final MainHandler mHandler; 1221 1222 final class MainHandler extends Handler { 1223 public MainHandler(Looper looper) { 1224 super(looper, null, true); 1225 } 1226 1227 @Override 1228 public void handleMessage(Message msg) { 1229 switch (msg.what) { 1230 case SHOW_ERROR_MSG: { 1231 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1232 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1233 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1234 synchronized (ActivityManagerService.this) { 1235 ProcessRecord proc = (ProcessRecord)data.get("app"); 1236 AppErrorResult res = (AppErrorResult) data.get("result"); 1237 if (proc != null && proc.crashDialog != null) { 1238 Slog.e(TAG, "App already has crash dialog: " + proc); 1239 if (res != null) { 1240 res.set(0); 1241 } 1242 return; 1243 } 1244 boolean isBackground = (UserHandle.getAppId(proc.uid) 1245 >= Process.FIRST_APPLICATION_UID 1246 && proc.pid != MY_PID); 1247 for (int userId : mCurrentProfileIds) { 1248 isBackground &= (proc.userId != userId); 1249 } 1250 if (isBackground && !showBackground) { 1251 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1258 Dialog d = new AppErrorDialog(mContext, 1259 ActivityManagerService.this, res, proc); 1260 d.show(); 1261 proc.crashDialog = d; 1262 } else { 1263 // The device is asleep, so just pretend that the user 1264 // saw a crash dialog and hit "force quit". 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 } 1269 } 1270 1271 ensureBootCompleted(); 1272 } break; 1273 case SHOW_NOT_RESPONDING_MSG: { 1274 synchronized (ActivityManagerService.this) { 1275 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1276 ProcessRecord proc = (ProcessRecord)data.get("app"); 1277 if (proc != null && proc.anrDialog != null) { 1278 Slog.e(TAG, "App already has anr dialog: " + proc); 1279 return; 1280 } 1281 1282 Intent intent = new Intent("android.intent.action.ANR"); 1283 if (!mProcessesReady) { 1284 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1285 | Intent.FLAG_RECEIVER_FOREGROUND); 1286 } 1287 broadcastIntentLocked(null, null, intent, 1288 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1289 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1290 1291 if (mShowDialogs) { 1292 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1293 mContext, proc, (ActivityRecord)data.get("activity"), 1294 msg.arg1 != 0); 1295 d.show(); 1296 proc.anrDialog = d; 1297 } else { 1298 // Just kill the app if there is no dialog to be shown. 1299 killAppAtUsersRequest(proc, null); 1300 } 1301 } 1302 1303 ensureBootCompleted(); 1304 } break; 1305 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1306 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1307 synchronized (ActivityManagerService.this) { 1308 ProcessRecord proc = (ProcessRecord) data.get("app"); 1309 if (proc == null) { 1310 Slog.e(TAG, "App not found when showing strict mode dialog."); 1311 break; 1312 } 1313 if (proc.crashDialog != null) { 1314 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1315 return; 1316 } 1317 AppErrorResult res = (AppErrorResult) data.get("result"); 1318 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1319 Dialog d = new StrictModeViolationDialog(mContext, 1320 ActivityManagerService.this, res, proc); 1321 d.show(); 1322 proc.crashDialog = d; 1323 } else { 1324 // The device is asleep, so just pretend that the user 1325 // saw a crash dialog and hit "force quit". 1326 res.set(0); 1327 } 1328 } 1329 ensureBootCompleted(); 1330 } break; 1331 case SHOW_FACTORY_ERROR_MSG: { 1332 Dialog d = new FactoryErrorDialog( 1333 mContext, msg.getData().getCharSequence("msg")); 1334 d.show(); 1335 ensureBootCompleted(); 1336 } break; 1337 case UPDATE_CONFIGURATION_MSG: { 1338 final ContentResolver resolver = mContext.getContentResolver(); 1339 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1340 } break; 1341 case GC_BACKGROUND_PROCESSES_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 performAppGcsIfAppropriateLocked(); 1344 } 1345 } break; 1346 case WAIT_FOR_DEBUGGER_MSG: { 1347 synchronized (ActivityManagerService.this) { 1348 ProcessRecord app = (ProcessRecord)msg.obj; 1349 if (msg.arg1 != 0) { 1350 if (!app.waitedForDebugger) { 1351 Dialog d = new AppWaitingForDebuggerDialog( 1352 ActivityManagerService.this, 1353 mContext, app); 1354 app.waitDialog = d; 1355 app.waitedForDebugger = true; 1356 d.show(); 1357 } 1358 } else { 1359 if (app.waitDialog != null) { 1360 app.waitDialog.dismiss(); 1361 app.waitDialog = null; 1362 } 1363 } 1364 } 1365 } break; 1366 case SERVICE_TIMEOUT_MSG: { 1367 if (mDidDexOpt) { 1368 mDidDexOpt = false; 1369 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1370 nmsg.obj = msg.obj; 1371 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1372 return; 1373 } 1374 mServices.serviceTimeout((ProcessRecord)msg.obj); 1375 } break; 1376 case UPDATE_TIME_ZONE: { 1377 synchronized (ActivityManagerService.this) { 1378 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1379 ProcessRecord r = mLruProcesses.get(i); 1380 if (r.thread != null) { 1381 try { 1382 r.thread.updateTimeZone(); 1383 } catch (RemoteException ex) { 1384 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1385 } 1386 } 1387 } 1388 } 1389 } break; 1390 case CLEAR_DNS_CACHE_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1393 ProcessRecord r = mLruProcesses.get(i); 1394 if (r.thread != null) { 1395 try { 1396 r.thread.clearDnsCache(); 1397 } catch (RemoteException ex) { 1398 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1399 } 1400 } 1401 } 1402 } 1403 } break; 1404 case UPDATE_HTTP_PROXY_MSG: { 1405 ProxyInfo proxy = (ProxyInfo)msg.obj; 1406 String host = ""; 1407 String port = ""; 1408 String exclList = ""; 1409 Uri pacFileUrl = Uri.EMPTY; 1410 if (proxy != null) { 1411 host = proxy.getHost(); 1412 port = Integer.toString(proxy.getPort()); 1413 exclList = proxy.getExclusionListAsString(); 1414 pacFileUrl = proxy.getPacFileUrl(); 1415 } 1416 synchronized (ActivityManagerService.this) { 1417 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1418 ProcessRecord r = mLruProcesses.get(i); 1419 if (r.thread != null) { 1420 try { 1421 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1422 } catch (RemoteException ex) { 1423 Slog.w(TAG, "Failed to update http proxy for: " + 1424 r.info.processName); 1425 } 1426 } 1427 } 1428 } 1429 } break; 1430 case SHOW_UID_ERROR_MSG: { 1431 String title = "System UIDs Inconsistent"; 1432 String text = "UIDs on the system are inconsistent, you need to wipe your" 1433 + " data partition or your device will be unstable."; 1434 Log.e(TAG, title + ": " + text); 1435 if (mShowDialogs) { 1436 // XXX This is a temporary dialog, no need to localize. 1437 AlertDialog d = new BaseErrorDialog(mContext); 1438 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1439 d.setCancelable(false); 1440 d.setTitle(title); 1441 d.setMessage(text); 1442 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1443 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1444 mUidAlert = d; 1445 d.show(); 1446 } 1447 } break; 1448 case IM_FEELING_LUCKY_MSG: { 1449 if (mUidAlert != null) { 1450 mUidAlert.dismiss(); 1451 mUidAlert = null; 1452 } 1453 } break; 1454 case PROC_START_TIMEOUT_MSG: { 1455 if (mDidDexOpt) { 1456 mDidDexOpt = false; 1457 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1458 nmsg.obj = msg.obj; 1459 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1460 return; 1461 } 1462 ProcessRecord app = (ProcessRecord)msg.obj; 1463 synchronized (ActivityManagerService.this) { 1464 processStartTimedOutLocked(app); 1465 } 1466 } break; 1467 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1470 } 1471 } break; 1472 case KILL_APPLICATION_MSG: { 1473 synchronized (ActivityManagerService.this) { 1474 int appid = msg.arg1; 1475 boolean restart = (msg.arg2 == 1); 1476 Bundle bundle = (Bundle)msg.obj; 1477 String pkg = bundle.getString("pkg"); 1478 String reason = bundle.getString("reason"); 1479 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1480 false, UserHandle.USER_ALL, reason); 1481 } 1482 } break; 1483 case FINALIZE_PENDING_INTENT_MSG: { 1484 ((PendingIntentRecord)msg.obj).completeFinalize(); 1485 } break; 1486 case POST_HEAVY_NOTIFICATION_MSG: { 1487 INotificationManager inm = NotificationManager.getService(); 1488 if (inm == null) { 1489 return; 1490 } 1491 1492 ActivityRecord root = (ActivityRecord)msg.obj; 1493 ProcessRecord process = root.app; 1494 if (process == null) { 1495 return; 1496 } 1497 1498 try { 1499 Context context = mContext.createPackageContext(process.info.packageName, 0); 1500 String text = mContext.getString(R.string.heavy_weight_notification, 1501 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1502 Notification notification = new Notification(); 1503 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1504 notification.when = 0; 1505 notification.flags = Notification.FLAG_ONGOING_EVENT; 1506 notification.tickerText = text; 1507 notification.defaults = 0; // please be quiet 1508 notification.sound = null; 1509 notification.vibrate = null; 1510 notification.color = mContext.getResources().getColor( 1511 com.android.internal.R.color.system_notification_accent_color); 1512 notification.setLatestEventInfo(context, text, 1513 mContext.getText(R.string.heavy_weight_notification_detail), 1514 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1515 PendingIntent.FLAG_CANCEL_CURRENT, null, 1516 new UserHandle(root.userId))); 1517 1518 try { 1519 int[] outId = new int[1]; 1520 inm.enqueueNotificationWithTag("android", "android", null, 1521 R.string.heavy_weight_notification, 1522 notification, outId, root.userId); 1523 } catch (RuntimeException e) { 1524 Slog.w(ActivityManagerService.TAG, 1525 "Error showing notification for heavy-weight app", e); 1526 } catch (RemoteException e) { 1527 } 1528 } catch (NameNotFoundException e) { 1529 Slog.w(TAG, "Unable to create context for heavy notification", e); 1530 } 1531 } break; 1532 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1533 INotificationManager inm = NotificationManager.getService(); 1534 if (inm == null) { 1535 return; 1536 } 1537 try { 1538 inm.cancelNotificationWithTag("android", null, 1539 R.string.heavy_weight_notification, msg.arg1); 1540 } catch (RuntimeException e) { 1541 Slog.w(ActivityManagerService.TAG, 1542 "Error canceling notification for service", e); 1543 } catch (RemoteException e) { 1544 } 1545 } break; 1546 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1547 synchronized (ActivityManagerService.this) { 1548 checkExcessivePowerUsageLocked(true); 1549 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1550 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1551 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1552 } 1553 } break; 1554 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1555 synchronized (ActivityManagerService.this) { 1556 ActivityRecord ar = (ActivityRecord)msg.obj; 1557 if (mCompatModeDialog != null) { 1558 if (mCompatModeDialog.mAppInfo.packageName.equals( 1559 ar.info.applicationInfo.packageName)) { 1560 return; 1561 } 1562 mCompatModeDialog.dismiss(); 1563 mCompatModeDialog = null; 1564 } 1565 if (ar != null && false) { 1566 if (mCompatModePackages.getPackageAskCompatModeLocked( 1567 ar.packageName)) { 1568 int mode = mCompatModePackages.computeCompatModeLocked( 1569 ar.info.applicationInfo); 1570 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1571 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1572 mCompatModeDialog = new CompatModeDialog( 1573 ActivityManagerService.this, mContext, 1574 ar.info.applicationInfo); 1575 mCompatModeDialog.show(); 1576 } 1577 } 1578 } 1579 } 1580 break; 1581 } 1582 case DISPATCH_PROCESSES_CHANGED: { 1583 dispatchProcessesChanged(); 1584 break; 1585 } 1586 case DISPATCH_PROCESS_DIED: { 1587 final int pid = msg.arg1; 1588 final int uid = msg.arg2; 1589 dispatchProcessDied(pid, uid); 1590 break; 1591 } 1592 case REPORT_MEM_USAGE_MSG: { 1593 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1594 Thread thread = new Thread() { 1595 @Override public void run() { 1596 final SparseArray<ProcessMemInfo> infoMap 1597 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1598 for (int i=0, N=memInfos.size(); i<N; i++) { 1599 ProcessMemInfo mi = memInfos.get(i); 1600 infoMap.put(mi.pid, mi); 1601 } 1602 updateCpuStatsNow(); 1603 synchronized (mProcessCpuTracker) { 1604 final int N = mProcessCpuTracker.countStats(); 1605 for (int i=0; i<N; i++) { 1606 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1607 if (st.vsize > 0) { 1608 long pss = Debug.getPss(st.pid, null); 1609 if (pss > 0) { 1610 if (infoMap.indexOfKey(st.pid) < 0) { 1611 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1612 ProcessList.NATIVE_ADJ, -1, "native", null); 1613 mi.pss = pss; 1614 memInfos.add(mi); 1615 } 1616 } 1617 } 1618 } 1619 } 1620 1621 long totalPss = 0; 1622 for (int i=0, N=memInfos.size(); i<N; i++) { 1623 ProcessMemInfo mi = memInfos.get(i); 1624 if (mi.pss == 0) { 1625 mi.pss = Debug.getPss(mi.pid, null); 1626 } 1627 totalPss += mi.pss; 1628 } 1629 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1630 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1631 if (lhs.oomAdj != rhs.oomAdj) { 1632 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1633 } 1634 if (lhs.pss != rhs.pss) { 1635 return lhs.pss < rhs.pss ? 1 : -1; 1636 } 1637 return 0; 1638 } 1639 }); 1640 1641 StringBuilder tag = new StringBuilder(128); 1642 StringBuilder stack = new StringBuilder(128); 1643 tag.append("Low on memory -- "); 1644 appendMemBucket(tag, totalPss, "total", false); 1645 appendMemBucket(stack, totalPss, "total", true); 1646 1647 StringBuilder logBuilder = new StringBuilder(1024); 1648 logBuilder.append("Low on memory:\n"); 1649 1650 boolean firstLine = true; 1651 int lastOomAdj = Integer.MIN_VALUE; 1652 for (int i=0, N=memInfos.size(); i<N; i++) { 1653 ProcessMemInfo mi = memInfos.get(i); 1654 1655 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1656 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1657 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1658 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1659 if (lastOomAdj != mi.oomAdj) { 1660 lastOomAdj = mi.oomAdj; 1661 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1662 tag.append(" / "); 1663 } 1664 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1665 if (firstLine) { 1666 stack.append(":"); 1667 firstLine = false; 1668 } 1669 stack.append("\n\t at "); 1670 } else { 1671 stack.append("$"); 1672 } 1673 } else { 1674 tag.append(" "); 1675 stack.append("$"); 1676 } 1677 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1678 appendMemBucket(tag, mi.pss, mi.name, false); 1679 } 1680 appendMemBucket(stack, mi.pss, mi.name, true); 1681 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1682 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1683 stack.append("("); 1684 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1685 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1686 stack.append(DUMP_MEM_OOM_LABEL[k]); 1687 stack.append(":"); 1688 stack.append(DUMP_MEM_OOM_ADJ[k]); 1689 } 1690 } 1691 stack.append(")"); 1692 } 1693 } 1694 1695 logBuilder.append(" "); 1696 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1697 logBuilder.append(' '); 1698 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1699 logBuilder.append(' '); 1700 ProcessList.appendRamKb(logBuilder, mi.pss); 1701 logBuilder.append(" kB: "); 1702 logBuilder.append(mi.name); 1703 logBuilder.append(" ("); 1704 logBuilder.append(mi.pid); 1705 logBuilder.append(") "); 1706 logBuilder.append(mi.adjType); 1707 logBuilder.append('\n'); 1708 if (mi.adjReason != null) { 1709 logBuilder.append(" "); 1710 logBuilder.append(mi.adjReason); 1711 logBuilder.append('\n'); 1712 } 1713 } 1714 1715 logBuilder.append(" "); 1716 ProcessList.appendRamKb(logBuilder, totalPss); 1717 logBuilder.append(" kB: TOTAL\n"); 1718 1719 long[] infos = new long[Debug.MEMINFO_COUNT]; 1720 Debug.getMemInfo(infos); 1721 logBuilder.append(" MemInfo: "); 1722 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1723 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1724 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1725 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1726 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1727 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1728 logBuilder.append(" ZRAM: "); 1729 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1730 logBuilder.append(" kB RAM, "); 1731 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1732 logBuilder.append(" kB swap total, "); 1733 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1734 logBuilder.append(" kB swap free\n"); 1735 } 1736 Slog.i(TAG, logBuilder.toString()); 1737 1738 StringBuilder dropBuilder = new StringBuilder(1024); 1739 /* 1740 StringWriter oomSw = new StringWriter(); 1741 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1742 StringWriter catSw = new StringWriter(); 1743 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1744 String[] emptyArgs = new String[] { }; 1745 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1746 oomPw.flush(); 1747 String oomString = oomSw.toString(); 1748 */ 1749 dropBuilder.append(stack); 1750 dropBuilder.append('\n'); 1751 dropBuilder.append('\n'); 1752 dropBuilder.append(logBuilder); 1753 dropBuilder.append('\n'); 1754 /* 1755 dropBuilder.append(oomString); 1756 dropBuilder.append('\n'); 1757 */ 1758 StringWriter catSw = new StringWriter(); 1759 synchronized (ActivityManagerService.this) { 1760 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1761 String[] emptyArgs = new String[] { }; 1762 catPw.println(); 1763 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1764 catPw.println(); 1765 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1766 false, false, null); 1767 catPw.println(); 1768 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1769 catPw.flush(); 1770 } 1771 dropBuilder.append(catSw.toString()); 1772 addErrorToDropBox("lowmem", null, "system_server", null, 1773 null, tag.toString(), dropBuilder.toString(), null, null); 1774 //Slog.i(TAG, "Sent to dropbox:"); 1775 //Slog.i(TAG, dropBuilder.toString()); 1776 synchronized (ActivityManagerService.this) { 1777 long now = SystemClock.uptimeMillis(); 1778 if (mLastMemUsageReportTime < now) { 1779 mLastMemUsageReportTime = now; 1780 } 1781 } 1782 } 1783 }; 1784 thread.start(); 1785 break; 1786 } 1787 case START_USER_SWITCH_MSG: { 1788 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1789 break; 1790 } 1791 case REPORT_USER_SWITCH_MSG: { 1792 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1793 break; 1794 } 1795 case CONTINUE_USER_SWITCH_MSG: { 1796 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1797 break; 1798 } 1799 case USER_SWITCH_TIMEOUT_MSG: { 1800 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1801 break; 1802 } 1803 case IMMERSIVE_MODE_LOCK_MSG: { 1804 final boolean nextState = (msg.arg1 != 0); 1805 if (mUpdateLock.isHeld() != nextState) { 1806 if (DEBUG_IMMERSIVE) { 1807 final ActivityRecord r = (ActivityRecord) msg.obj; 1808 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1809 } 1810 if (nextState) { 1811 mUpdateLock.acquire(); 1812 } else { 1813 mUpdateLock.release(); 1814 } 1815 } 1816 break; 1817 } 1818 case PERSIST_URI_GRANTS_MSG: { 1819 writeGrantedUriPermissions(); 1820 break; 1821 } 1822 case REQUEST_ALL_PSS_MSG: { 1823 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1824 break; 1825 } 1826 case START_PROFILES_MSG: { 1827 synchronized (ActivityManagerService.this) { 1828 startProfilesLocked(); 1829 } 1830 break; 1831 } 1832 case UPDATE_TIME: { 1833 synchronized (ActivityManagerService.this) { 1834 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1835 ProcessRecord r = mLruProcesses.get(i); 1836 if (r.thread != null) { 1837 try { 1838 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1839 } catch (RemoteException ex) { 1840 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1841 } 1842 } 1843 } 1844 } 1845 break; 1846 } 1847 case SYSTEM_USER_START_MSG: { 1848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1849 Integer.toString(msg.arg1), msg.arg1); 1850 mSystemServiceManager.startUser(msg.arg1); 1851 break; 1852 } 1853 case SYSTEM_USER_CURRENT_MSG: { 1854 mBatteryStatsService.noteEvent( 1855 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1856 Integer.toString(msg.arg2), msg.arg2); 1857 mBatteryStatsService.noteEvent( 1858 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1859 Integer.toString(msg.arg1), msg.arg1); 1860 mSystemServiceManager.switchUser(msg.arg1); 1861 mLockToAppRequest.clearPrompt(); 1862 break; 1863 } 1864 case ENTER_ANIMATION_COMPLETE_MSG: { 1865 synchronized (ActivityManagerService.this) { 1866 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1867 if (r != null && r.app != null && r.app.thread != null) { 1868 try { 1869 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1870 } catch (RemoteException e) { 1871 } 1872 } 1873 } 1874 break; 1875 } 1876 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1877 enableScreenAfterBoot(); 1878 break; 1879 } 1880 } 1881 } 1882 }; 1883 1884 static final int COLLECT_PSS_BG_MSG = 1; 1885 1886 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1887 @Override 1888 public void handleMessage(Message msg) { 1889 switch (msg.what) { 1890 case COLLECT_PSS_BG_MSG: { 1891 long start = SystemClock.uptimeMillis(); 1892 MemInfoReader memInfo = null; 1893 synchronized (ActivityManagerService.this) { 1894 if (mFullPssPending) { 1895 mFullPssPending = false; 1896 memInfo = new MemInfoReader(); 1897 } 1898 } 1899 if (memInfo != null) { 1900 updateCpuStatsNow(); 1901 long nativeTotalPss = 0; 1902 synchronized (mProcessCpuTracker) { 1903 final int N = mProcessCpuTracker.countStats(); 1904 for (int j=0; j<N; j++) { 1905 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1906 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1907 // This is definitely an application process; skip it. 1908 continue; 1909 } 1910 synchronized (mPidsSelfLocked) { 1911 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1912 // This is one of our own processes; skip it. 1913 continue; 1914 } 1915 } 1916 nativeTotalPss += Debug.getPss(st.pid, null); 1917 } 1918 } 1919 memInfo.readMemInfo(); 1920 synchronized (ActivityManagerService.this) { 1921 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1922 + (SystemClock.uptimeMillis()-start) + "ms"); 1923 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1924 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1925 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1926 +memInfo.getSlabSizeKb(), 1927 nativeTotalPss); 1928 } 1929 } 1930 1931 int i=0, num=0; 1932 long[] tmp = new long[1]; 1933 do { 1934 ProcessRecord proc; 1935 int procState; 1936 int pid; 1937 synchronized (ActivityManagerService.this) { 1938 if (i >= mPendingPssProcesses.size()) { 1939 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1940 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1941 mPendingPssProcesses.clear(); 1942 return; 1943 } 1944 proc = mPendingPssProcesses.get(i); 1945 procState = proc.pssProcState; 1946 if (proc.thread != null && procState == proc.setProcState) { 1947 pid = proc.pid; 1948 } else { 1949 proc = null; 1950 pid = 0; 1951 } 1952 i++; 1953 } 1954 if (proc != null) { 1955 long pss = Debug.getPss(pid, tmp); 1956 synchronized (ActivityManagerService.this) { 1957 if (proc.thread != null && proc.setProcState == procState 1958 && proc.pid == pid) { 1959 num++; 1960 proc.lastPssTime = SystemClock.uptimeMillis(); 1961 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1962 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1963 + ": " + pss + " lastPss=" + proc.lastPss 1964 + " state=" + ProcessList.makeProcStateString(procState)); 1965 if (proc.initialIdlePss == 0) { 1966 proc.initialIdlePss = pss; 1967 } 1968 proc.lastPss = pss; 1969 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1970 proc.lastCachedPss = pss; 1971 } 1972 } 1973 } 1974 } 1975 } while (true); 1976 } 1977 } 1978 } 1979 }; 1980 1981 /** 1982 * Monitor for package changes and update our internal state. 1983 */ 1984 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1985 @Override 1986 public void onPackageRemoved(String packageName, int uid) { 1987 // Remove all tasks with activities in the specified package from the list of recent tasks 1988 synchronized (ActivityManagerService.this) { 1989 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1990 TaskRecord tr = mRecentTasks.get(i); 1991 ComponentName cn = tr.intent.getComponent(); 1992 if (cn != null && cn.getPackageName().equals(packageName)) { 1993 // If the package name matches, remove the task and kill the process 1994 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1995 } 1996 } 1997 } 1998 } 1999 2000 @Override 2001 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2002 onPackageModified(packageName); 2003 return true; 2004 } 2005 2006 @Override 2007 public void onPackageModified(String packageName) { 2008 final PackageManager pm = mContext.getPackageManager(); 2009 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2010 new ArrayList<Pair<Intent, Integer>>(); 2011 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2012 // Copy the list of recent tasks so that we don't hold onto the lock on 2013 // ActivityManagerService for long periods while checking if components exist. 2014 synchronized (ActivityManagerService.this) { 2015 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2016 TaskRecord tr = mRecentTasks.get(i); 2017 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2018 } 2019 } 2020 // Check the recent tasks and filter out all tasks with components that no longer exist. 2021 Intent tmpI = new Intent(); 2022 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2023 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2024 ComponentName cn = p.first.getComponent(); 2025 if (cn != null && cn.getPackageName().equals(packageName)) { 2026 try { 2027 // Add the task to the list to remove if the component no longer exists 2028 tmpI.setComponent(cn); 2029 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2030 tasksToRemove.add(p.second); 2031 } 2032 } catch (Exception e) {} 2033 } 2034 } 2035 // Prune all the tasks with removed components from the list of recent tasks 2036 synchronized (ActivityManagerService.this) { 2037 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2038 // Remove the task but don't kill the process (since other components in that 2039 // package may still be running and in the background) 2040 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2041 } 2042 } 2043 } 2044 2045 @Override 2046 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2047 // Force stop the specified packages 2048 if (packages != null) { 2049 for (String pkg : packages) { 2050 synchronized (ActivityManagerService.this) { 2051 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2052 "finished booting")) { 2053 return true; 2054 } 2055 } 2056 } 2057 } 2058 return false; 2059 } 2060 }; 2061 2062 public void setSystemProcess() { 2063 try { 2064 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2065 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2066 ServiceManager.addService("meminfo", new MemBinder(this)); 2067 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2068 ServiceManager.addService("dbinfo", new DbBinder(this)); 2069 if (MONITOR_CPU_USAGE) { 2070 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2071 } 2072 ServiceManager.addService("permission", new PermissionController(this)); 2073 2074 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2075 "android", STOCK_PM_FLAGS); 2076 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2077 2078 synchronized (this) { 2079 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2080 app.persistent = true; 2081 app.pid = MY_PID; 2082 app.maxAdj = ProcessList.SYSTEM_ADJ; 2083 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2084 mProcessNames.put(app.processName, app.uid, app); 2085 synchronized (mPidsSelfLocked) { 2086 mPidsSelfLocked.put(app.pid, app); 2087 } 2088 updateLruProcessLocked(app, false, null); 2089 updateOomAdjLocked(); 2090 } 2091 } catch (PackageManager.NameNotFoundException e) { 2092 throw new RuntimeException( 2093 "Unable to find android system package", e); 2094 } 2095 } 2096 2097 public void setWindowManager(WindowManagerService wm) { 2098 mWindowManager = wm; 2099 mStackSupervisor.setWindowManager(wm); 2100 } 2101 2102 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2103 mUsageStatsService = usageStatsManager; 2104 } 2105 2106 public void startObservingNativeCrashes() { 2107 final NativeCrashListener ncl = new NativeCrashListener(this); 2108 ncl.start(); 2109 } 2110 2111 public IAppOpsService getAppOpsService() { 2112 return mAppOpsService; 2113 } 2114 2115 static class MemBinder extends Binder { 2116 ActivityManagerService mActivityManagerService; 2117 MemBinder(ActivityManagerService activityManagerService) { 2118 mActivityManagerService = activityManagerService; 2119 } 2120 2121 @Override 2122 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2123 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2124 != PackageManager.PERMISSION_GRANTED) { 2125 pw.println("Permission Denial: can't dump meminfo from from pid=" 2126 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2127 + " without permission " + android.Manifest.permission.DUMP); 2128 return; 2129 } 2130 2131 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2132 } 2133 } 2134 2135 static class GraphicsBinder extends Binder { 2136 ActivityManagerService mActivityManagerService; 2137 GraphicsBinder(ActivityManagerService activityManagerService) { 2138 mActivityManagerService = activityManagerService; 2139 } 2140 2141 @Override 2142 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2143 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2144 != PackageManager.PERMISSION_GRANTED) { 2145 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2146 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2147 + " without permission " + android.Manifest.permission.DUMP); 2148 return; 2149 } 2150 2151 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2152 } 2153 } 2154 2155 static class DbBinder extends Binder { 2156 ActivityManagerService mActivityManagerService; 2157 DbBinder(ActivityManagerService activityManagerService) { 2158 mActivityManagerService = activityManagerService; 2159 } 2160 2161 @Override 2162 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2163 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2164 != PackageManager.PERMISSION_GRANTED) { 2165 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2166 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2167 + " without permission " + android.Manifest.permission.DUMP); 2168 return; 2169 } 2170 2171 mActivityManagerService.dumpDbInfo(fd, pw, args); 2172 } 2173 } 2174 2175 static class CpuBinder extends Binder { 2176 ActivityManagerService mActivityManagerService; 2177 CpuBinder(ActivityManagerService activityManagerService) { 2178 mActivityManagerService = activityManagerService; 2179 } 2180 2181 @Override 2182 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2183 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2184 != PackageManager.PERMISSION_GRANTED) { 2185 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2186 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2187 + " without permission " + android.Manifest.permission.DUMP); 2188 return; 2189 } 2190 2191 synchronized (mActivityManagerService.mProcessCpuTracker) { 2192 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2193 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2194 SystemClock.uptimeMillis())); 2195 } 2196 } 2197 } 2198 2199 public static final class Lifecycle extends SystemService { 2200 private final ActivityManagerService mService; 2201 2202 public Lifecycle(Context context) { 2203 super(context); 2204 mService = new ActivityManagerService(context); 2205 } 2206 2207 @Override 2208 public void onStart() { 2209 mService.start(); 2210 } 2211 2212 public ActivityManagerService getService() { 2213 return mService; 2214 } 2215 } 2216 2217 // Note: This method is invoked on the main thread but may need to attach various 2218 // handlers to other threads. So take care to be explicit about the looper. 2219 public ActivityManagerService(Context systemContext) { 2220 mContext = systemContext; 2221 mFactoryTest = FactoryTest.getMode(); 2222 mSystemThread = ActivityThread.currentActivityThread(); 2223 2224 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2225 2226 mHandlerThread = new ServiceThread(TAG, 2227 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2228 mHandlerThread.start(); 2229 mHandler = new MainHandler(mHandlerThread.getLooper()); 2230 2231 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2232 "foreground", BROADCAST_FG_TIMEOUT, false); 2233 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2234 "background", BROADCAST_BG_TIMEOUT, true); 2235 mBroadcastQueues[0] = mFgBroadcastQueue; 2236 mBroadcastQueues[1] = mBgBroadcastQueue; 2237 2238 mServices = new ActiveServices(this); 2239 mProviderMap = new ProviderMap(this); 2240 2241 // TODO: Move creation of battery stats service outside of activity manager service. 2242 File dataDir = Environment.getDataDirectory(); 2243 File systemDir = new File(dataDir, "system"); 2244 systemDir.mkdirs(); 2245 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2246 mBatteryStatsService.getActiveStatistics().readLocked(); 2247 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2248 mOnBattery = DEBUG_POWER ? true 2249 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2250 mBatteryStatsService.getActiveStatistics().setCallback(this); 2251 2252 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2253 2254 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2255 2256 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2257 2258 // User 0 is the first and only user that runs at boot. 2259 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2260 mUserLru.add(Integer.valueOf(0)); 2261 updateStartedUserArrayLocked(); 2262 2263 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2264 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2265 2266 mConfiguration.setToDefaults(); 2267 mConfiguration.setLocale(Locale.getDefault()); 2268 2269 mConfigurationSeq = mConfiguration.seq = 1; 2270 mProcessCpuTracker.init(); 2271 2272 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2273 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2274 mStackSupervisor = new ActivityStackSupervisor(this); 2275 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2276 2277 mProcessCpuThread = new Thread("CpuTracker") { 2278 @Override 2279 public void run() { 2280 while (true) { 2281 try { 2282 try { 2283 synchronized(this) { 2284 final long now = SystemClock.uptimeMillis(); 2285 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2286 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2287 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2288 // + ", write delay=" + nextWriteDelay); 2289 if (nextWriteDelay < nextCpuDelay) { 2290 nextCpuDelay = nextWriteDelay; 2291 } 2292 if (nextCpuDelay > 0) { 2293 mProcessCpuMutexFree.set(true); 2294 this.wait(nextCpuDelay); 2295 } 2296 } 2297 } catch (InterruptedException e) { 2298 } 2299 updateCpuStatsNow(); 2300 } catch (Exception e) { 2301 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2302 } 2303 } 2304 } 2305 }; 2306 2307 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2308 2309 Watchdog.getInstance().addMonitor(this); 2310 Watchdog.getInstance().addThread(mHandler); 2311 } 2312 2313 public void setSystemServiceManager(SystemServiceManager mgr) { 2314 mSystemServiceManager = mgr; 2315 } 2316 2317 private void start() { 2318 Process.removeAllProcessGroups(); 2319 mProcessCpuThread.start(); 2320 2321 mBatteryStatsService.publish(mContext); 2322 mAppOpsService.publish(mContext); 2323 Slog.d("AppOps", "AppOpsService published"); 2324 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2325 } 2326 2327 public void initPowerManagement() { 2328 mStackSupervisor.initPowerManagement(); 2329 mBatteryStatsService.initPowerManagement(); 2330 } 2331 2332 @Override 2333 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2334 throws RemoteException { 2335 if (code == SYSPROPS_TRANSACTION) { 2336 // We need to tell all apps about the system property change. 2337 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2338 synchronized(this) { 2339 final int NP = mProcessNames.getMap().size(); 2340 for (int ip=0; ip<NP; ip++) { 2341 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2342 final int NA = apps.size(); 2343 for (int ia=0; ia<NA; ia++) { 2344 ProcessRecord app = apps.valueAt(ia); 2345 if (app.thread != null) { 2346 procs.add(app.thread.asBinder()); 2347 } 2348 } 2349 } 2350 } 2351 2352 int N = procs.size(); 2353 for (int i=0; i<N; i++) { 2354 Parcel data2 = Parcel.obtain(); 2355 try { 2356 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2357 } catch (RemoteException e) { 2358 } 2359 data2.recycle(); 2360 } 2361 } 2362 try { 2363 return super.onTransact(code, data, reply, flags); 2364 } catch (RuntimeException e) { 2365 // The activity manager only throws security exceptions, so let's 2366 // log all others. 2367 if (!(e instanceof SecurityException)) { 2368 Slog.wtf(TAG, "Activity Manager Crash", e); 2369 } 2370 throw e; 2371 } 2372 } 2373 2374 void updateCpuStats() { 2375 final long now = SystemClock.uptimeMillis(); 2376 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2377 return; 2378 } 2379 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2380 synchronized (mProcessCpuThread) { 2381 mProcessCpuThread.notify(); 2382 } 2383 } 2384 } 2385 2386 void updateCpuStatsNow() { 2387 synchronized (mProcessCpuTracker) { 2388 mProcessCpuMutexFree.set(false); 2389 final long now = SystemClock.uptimeMillis(); 2390 boolean haveNewCpuStats = false; 2391 2392 if (MONITOR_CPU_USAGE && 2393 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2394 mLastCpuTime.set(now); 2395 haveNewCpuStats = true; 2396 mProcessCpuTracker.update(); 2397 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2398 //Slog.i(TAG, "Total CPU usage: " 2399 // + mProcessCpu.getTotalCpuPercent() + "%"); 2400 2401 // Slog the cpu usage if the property is set. 2402 if ("true".equals(SystemProperties.get("events.cpu"))) { 2403 int user = mProcessCpuTracker.getLastUserTime(); 2404 int system = mProcessCpuTracker.getLastSystemTime(); 2405 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2406 int irq = mProcessCpuTracker.getLastIrqTime(); 2407 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2408 int idle = mProcessCpuTracker.getLastIdleTime(); 2409 2410 int total = user + system + iowait + irq + softIrq + idle; 2411 if (total == 0) total = 1; 2412 2413 EventLog.writeEvent(EventLogTags.CPU, 2414 ((user+system+iowait+irq+softIrq) * 100) / total, 2415 (user * 100) / total, 2416 (system * 100) / total, 2417 (iowait * 100) / total, 2418 (irq * 100) / total, 2419 (softIrq * 100) / total); 2420 } 2421 } 2422 2423 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2424 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2425 synchronized(bstats) { 2426 synchronized(mPidsSelfLocked) { 2427 if (haveNewCpuStats) { 2428 if (mOnBattery) { 2429 int perc = bstats.startAddingCpuLocked(); 2430 int totalUTime = 0; 2431 int totalSTime = 0; 2432 final int N = mProcessCpuTracker.countStats(); 2433 for (int i=0; i<N; i++) { 2434 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2435 if (!st.working) { 2436 continue; 2437 } 2438 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2439 int otherUTime = (st.rel_utime*perc)/100; 2440 int otherSTime = (st.rel_stime*perc)/100; 2441 totalUTime += otherUTime; 2442 totalSTime += otherSTime; 2443 if (pr != null) { 2444 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2445 if (ps == null || !ps.isActive()) { 2446 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2447 pr.info.uid, pr.processName); 2448 } 2449 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2450 st.rel_stime-otherSTime); 2451 ps.addSpeedStepTimes(cpuSpeedTimes); 2452 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2453 } else { 2454 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2455 if (ps == null || !ps.isActive()) { 2456 st.batteryStats = ps = bstats.getProcessStatsLocked( 2457 bstats.mapUid(st.uid), st.name); 2458 } 2459 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2460 st.rel_stime-otherSTime); 2461 ps.addSpeedStepTimes(cpuSpeedTimes); 2462 } 2463 } 2464 bstats.finishAddingCpuLocked(perc, totalUTime, 2465 totalSTime, cpuSpeedTimes); 2466 } 2467 } 2468 } 2469 2470 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2471 mLastWriteTime = now; 2472 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2473 } 2474 } 2475 } 2476 } 2477 2478 @Override 2479 public void batteryNeedsCpuUpdate() { 2480 updateCpuStatsNow(); 2481 } 2482 2483 @Override 2484 public void batteryPowerChanged(boolean onBattery) { 2485 // When plugging in, update the CPU stats first before changing 2486 // the plug state. 2487 updateCpuStatsNow(); 2488 synchronized (this) { 2489 synchronized(mPidsSelfLocked) { 2490 mOnBattery = DEBUG_POWER ? true : onBattery; 2491 } 2492 } 2493 } 2494 2495 /** 2496 * Initialize the application bind args. These are passed to each 2497 * process when the bindApplication() IPC is sent to the process. They're 2498 * lazily setup to make sure the services are running when they're asked for. 2499 */ 2500 private HashMap<String, IBinder> getCommonServicesLocked() { 2501 if (mAppBindArgs == null) { 2502 mAppBindArgs = new HashMap<String, IBinder>(); 2503 2504 // Setup the application init args 2505 mAppBindArgs.put("package", ServiceManager.getService("package")); 2506 mAppBindArgs.put("window", ServiceManager.getService("window")); 2507 mAppBindArgs.put(Context.ALARM_SERVICE, 2508 ServiceManager.getService(Context.ALARM_SERVICE)); 2509 } 2510 return mAppBindArgs; 2511 } 2512 2513 final void setFocusedActivityLocked(ActivityRecord r) { 2514 if (mFocusedActivity != r) { 2515 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2516 mFocusedActivity = r; 2517 if (r.task != null && r.task.voiceInteractor != null) { 2518 startRunningVoiceLocked(); 2519 } else { 2520 finishRunningVoiceLocked(); 2521 } 2522 mStackSupervisor.setFocusedStack(r); 2523 if (r != null) { 2524 mWindowManager.setFocusedApp(r.appToken, true); 2525 } 2526 applyUpdateLockStateLocked(r); 2527 } 2528 } 2529 2530 final void clearFocusedActivity(ActivityRecord r) { 2531 if (mFocusedActivity == r) { 2532 mFocusedActivity = null; 2533 } 2534 } 2535 2536 @Override 2537 public void setFocusedStack(int stackId) { 2538 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2539 synchronized (ActivityManagerService.this) { 2540 ActivityStack stack = mStackSupervisor.getStack(stackId); 2541 if (stack != null) { 2542 ActivityRecord r = stack.topRunningActivityLocked(null); 2543 if (r != null) { 2544 setFocusedActivityLocked(r); 2545 } 2546 } 2547 } 2548 } 2549 2550 @Override 2551 public void notifyActivityDrawn(IBinder token) { 2552 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2553 synchronized (this) { 2554 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2555 if (r != null) { 2556 r.task.stack.notifyActivityDrawnLocked(r); 2557 } 2558 } 2559 } 2560 2561 final void applyUpdateLockStateLocked(ActivityRecord r) { 2562 // Modifications to the UpdateLock state are done on our handler, outside 2563 // the activity manager's locks. The new state is determined based on the 2564 // state *now* of the relevant activity record. The object is passed to 2565 // the handler solely for logging detail, not to be consulted/modified. 2566 final boolean nextState = r != null && r.immersive; 2567 mHandler.sendMessage( 2568 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2569 } 2570 2571 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2572 Message msg = Message.obtain(); 2573 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2574 msg.obj = r.task.askedCompatMode ? null : r; 2575 mHandler.sendMessage(msg); 2576 } 2577 2578 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2579 String what, Object obj, ProcessRecord srcApp) { 2580 app.lastActivityTime = now; 2581 2582 if (app.activities.size() > 0) { 2583 // Don't want to touch dependent processes that are hosting activities. 2584 return index; 2585 } 2586 2587 int lrui = mLruProcesses.lastIndexOf(app); 2588 if (lrui < 0) { 2589 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2590 + what + " " + obj + " from " + srcApp); 2591 return index; 2592 } 2593 2594 if (lrui >= index) { 2595 // Don't want to cause this to move dependent processes *back* in the 2596 // list as if they were less frequently used. 2597 return index; 2598 } 2599 2600 if (lrui >= mLruProcessActivityStart) { 2601 // Don't want to touch dependent processes that are hosting activities. 2602 return index; 2603 } 2604 2605 mLruProcesses.remove(lrui); 2606 if (index > 0) { 2607 index--; 2608 } 2609 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2610 + " in LRU list: " + app); 2611 mLruProcesses.add(index, app); 2612 return index; 2613 } 2614 2615 final void removeLruProcessLocked(ProcessRecord app) { 2616 int lrui = mLruProcesses.lastIndexOf(app); 2617 if (lrui >= 0) { 2618 if (lrui <= mLruProcessActivityStart) { 2619 mLruProcessActivityStart--; 2620 } 2621 if (lrui <= mLruProcessServiceStart) { 2622 mLruProcessServiceStart--; 2623 } 2624 mLruProcesses.remove(lrui); 2625 } 2626 } 2627 2628 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2629 ProcessRecord client) { 2630 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2631 || app.treatLikeActivity; 2632 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2633 if (!activityChange && hasActivity) { 2634 // The process has activities, so we are only allowing activity-based adjustments 2635 // to move it. It should be kept in the front of the list with other 2636 // processes that have activities, and we don't want those to change their 2637 // order except due to activity operations. 2638 return; 2639 } 2640 2641 mLruSeq++; 2642 final long now = SystemClock.uptimeMillis(); 2643 app.lastActivityTime = now; 2644 2645 // First a quick reject: if the app is already at the position we will 2646 // put it, then there is nothing to do. 2647 if (hasActivity) { 2648 final int N = mLruProcesses.size(); 2649 if (N > 0 && mLruProcesses.get(N-1) == app) { 2650 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2651 return; 2652 } 2653 } else { 2654 if (mLruProcessServiceStart > 0 2655 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2656 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2657 return; 2658 } 2659 } 2660 2661 int lrui = mLruProcesses.lastIndexOf(app); 2662 2663 if (app.persistent && lrui >= 0) { 2664 // We don't care about the position of persistent processes, as long as 2665 // they are in the list. 2666 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2667 return; 2668 } 2669 2670 /* In progress: compute new position first, so we can avoid doing work 2671 if the process is not actually going to move. Not yet working. 2672 int addIndex; 2673 int nextIndex; 2674 boolean inActivity = false, inService = false; 2675 if (hasActivity) { 2676 // Process has activities, put it at the very tipsy-top. 2677 addIndex = mLruProcesses.size(); 2678 nextIndex = mLruProcessServiceStart; 2679 inActivity = true; 2680 } else if (hasService) { 2681 // Process has services, put it at the top of the service list. 2682 addIndex = mLruProcessActivityStart; 2683 nextIndex = mLruProcessServiceStart; 2684 inActivity = true; 2685 inService = true; 2686 } else { 2687 // Process not otherwise of interest, it goes to the top of the non-service area. 2688 addIndex = mLruProcessServiceStart; 2689 if (client != null) { 2690 int clientIndex = mLruProcesses.lastIndexOf(client); 2691 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2692 + app); 2693 if (clientIndex >= 0 && addIndex > clientIndex) { 2694 addIndex = clientIndex; 2695 } 2696 } 2697 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2698 } 2699 2700 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2701 + mLruProcessActivityStart + "): " + app); 2702 */ 2703 2704 if (lrui >= 0) { 2705 if (lrui < mLruProcessActivityStart) { 2706 mLruProcessActivityStart--; 2707 } 2708 if (lrui < mLruProcessServiceStart) { 2709 mLruProcessServiceStart--; 2710 } 2711 /* 2712 if (addIndex > lrui) { 2713 addIndex--; 2714 } 2715 if (nextIndex > lrui) { 2716 nextIndex--; 2717 } 2718 */ 2719 mLruProcesses.remove(lrui); 2720 } 2721 2722 /* 2723 mLruProcesses.add(addIndex, app); 2724 if (inActivity) { 2725 mLruProcessActivityStart++; 2726 } 2727 if (inService) { 2728 mLruProcessActivityStart++; 2729 } 2730 */ 2731 2732 int nextIndex; 2733 if (hasActivity) { 2734 final int N = mLruProcesses.size(); 2735 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2736 // Process doesn't have activities, but has clients with 2737 // activities... move it up, but one below the top (the top 2738 // should always have a real activity). 2739 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2740 mLruProcesses.add(N-1, app); 2741 // To keep it from spamming the LRU list (by making a bunch of clients), 2742 // we will push down any other entries owned by the app. 2743 final int uid = app.info.uid; 2744 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2745 ProcessRecord subProc = mLruProcesses.get(i); 2746 if (subProc.info.uid == uid) { 2747 // We want to push this one down the list. If the process after 2748 // it is for the same uid, however, don't do so, because we don't 2749 // want them internally to be re-ordered. 2750 if (mLruProcesses.get(i-1).info.uid != uid) { 2751 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2752 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2753 ProcessRecord tmp = mLruProcesses.get(i); 2754 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2755 mLruProcesses.set(i-1, tmp); 2756 i--; 2757 } 2758 } else { 2759 // A gap, we can stop here. 2760 break; 2761 } 2762 } 2763 } else { 2764 // Process has activities, put it at the very tipsy-top. 2765 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2766 mLruProcesses.add(app); 2767 } 2768 nextIndex = mLruProcessServiceStart; 2769 } else if (hasService) { 2770 // Process has services, put it at the top of the service list. 2771 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2772 mLruProcesses.add(mLruProcessActivityStart, app); 2773 nextIndex = mLruProcessServiceStart; 2774 mLruProcessActivityStart++; 2775 } else { 2776 // Process not otherwise of interest, it goes to the top of the non-service area. 2777 int index = mLruProcessServiceStart; 2778 if (client != null) { 2779 // If there is a client, don't allow the process to be moved up higher 2780 // in the list than that client. 2781 int clientIndex = mLruProcesses.lastIndexOf(client); 2782 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2783 + " when updating " + app); 2784 if (clientIndex <= lrui) { 2785 // Don't allow the client index restriction to push it down farther in the 2786 // list than it already is. 2787 clientIndex = lrui; 2788 } 2789 if (clientIndex >= 0 && index > clientIndex) { 2790 index = clientIndex; 2791 } 2792 } 2793 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2794 mLruProcesses.add(index, app); 2795 nextIndex = index-1; 2796 mLruProcessActivityStart++; 2797 mLruProcessServiceStart++; 2798 } 2799 2800 // If the app is currently using a content provider or service, 2801 // bump those processes as well. 2802 for (int j=app.connections.size()-1; j>=0; j--) { 2803 ConnectionRecord cr = app.connections.valueAt(j); 2804 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2805 && cr.binding.service.app != null 2806 && cr.binding.service.app.lruSeq != mLruSeq 2807 && !cr.binding.service.app.persistent) { 2808 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2809 "service connection", cr, app); 2810 } 2811 } 2812 for (int j=app.conProviders.size()-1; j>=0; j--) { 2813 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2814 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2815 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2816 "provider reference", cpr, app); 2817 } 2818 } 2819 } 2820 2821 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2822 if (uid == Process.SYSTEM_UID) { 2823 // The system gets to run in any process. If there are multiple 2824 // processes with the same uid, just pick the first (this 2825 // should never happen). 2826 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2827 if (procs == null) return null; 2828 final int N = procs.size(); 2829 for (int i = 0; i < N; i++) { 2830 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2831 } 2832 } 2833 ProcessRecord proc = mProcessNames.get(processName, uid); 2834 if (false && proc != null && !keepIfLarge 2835 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2836 && proc.lastCachedPss >= 4000) { 2837 // Turn this condition on to cause killing to happen regularly, for testing. 2838 if (proc.baseProcessTracker != null) { 2839 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2840 } 2841 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2842 } else if (proc != null && !keepIfLarge 2843 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2844 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2845 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2846 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2847 if (proc.baseProcessTracker != null) { 2848 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2849 } 2850 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2851 } 2852 } 2853 return proc; 2854 } 2855 2856 void ensurePackageDexOpt(String packageName) { 2857 IPackageManager pm = AppGlobals.getPackageManager(); 2858 try { 2859 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2860 mDidDexOpt = true; 2861 } 2862 } catch (RemoteException e) { 2863 } 2864 } 2865 2866 boolean isNextTransitionForward() { 2867 int transit = mWindowManager.getPendingAppTransition(); 2868 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2869 || transit == AppTransition.TRANSIT_TASK_OPEN 2870 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2871 } 2872 2873 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2874 String processName, String abiOverride, int uid, Runnable crashHandler) { 2875 synchronized(this) { 2876 ApplicationInfo info = new ApplicationInfo(); 2877 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2878 // For isolated processes, the former contains the parent's uid and the latter the 2879 // actual uid of the isolated process. 2880 // In the special case introduced by this method (which is, starting an isolated 2881 // process directly from the SystemServer without an actual parent app process) the 2882 // closest thing to a parent's uid is SYSTEM_UID. 2883 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2884 // the |isolated| logic in the ProcessRecord constructor. 2885 info.uid = Process.SYSTEM_UID; 2886 info.processName = processName; 2887 info.className = entryPoint; 2888 info.packageName = "android"; 2889 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2890 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2891 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2892 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2893 crashHandler); 2894 return proc != null ? proc.pid : 0; 2895 } 2896 } 2897 2898 final ProcessRecord startProcessLocked(String processName, 2899 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2900 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2901 boolean isolated, boolean keepIfLarge) { 2902 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2903 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2904 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2905 null /* crashHandler */); 2906 } 2907 2908 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2909 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2910 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2911 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2912 long startTime = SystemClock.elapsedRealtime(); 2913 ProcessRecord app; 2914 if (!isolated) { 2915 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2916 checkTime(startTime, "startProcess: after getProcessRecord"); 2917 } else { 2918 // If this is an isolated process, it can't re-use an existing process. 2919 app = null; 2920 } 2921 // We don't have to do anything more if: 2922 // (1) There is an existing application record; and 2923 // (2) The caller doesn't think it is dead, OR there is no thread 2924 // object attached to it so we know it couldn't have crashed; and 2925 // (3) There is a pid assigned to it, so it is either starting or 2926 // already running. 2927 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2928 + " app=" + app + " knownToBeDead=" + knownToBeDead 2929 + " thread=" + (app != null ? app.thread : null) 2930 + " pid=" + (app != null ? app.pid : -1)); 2931 if (app != null && app.pid > 0) { 2932 if (!knownToBeDead || app.thread == null) { 2933 // We already have the app running, or are waiting for it to 2934 // come up (we have a pid but not yet its thread), so keep it. 2935 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2936 // If this is a new package in the process, add the package to the list 2937 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2938 checkTime(startTime, "startProcess: done, added package to proc"); 2939 return app; 2940 } 2941 2942 // An application record is attached to a previous process, 2943 // clean it up now. 2944 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2945 checkTime(startTime, "startProcess: bad proc running, killing"); 2946 Process.killProcessGroup(app.info.uid, app.pid); 2947 handleAppDiedLocked(app, true, true); 2948 checkTime(startTime, "startProcess: done killing old proc"); 2949 } 2950 2951 String hostingNameStr = hostingName != null 2952 ? hostingName.flattenToShortString() : null; 2953 2954 if (!isolated) { 2955 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2956 // If we are in the background, then check to see if this process 2957 // is bad. If so, we will just silently fail. 2958 if (mBadProcesses.get(info.processName, info.uid) != null) { 2959 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2960 + "/" + info.processName); 2961 return null; 2962 } 2963 } else { 2964 // When the user is explicitly starting a process, then clear its 2965 // crash count so that we won't make it bad until they see at 2966 // least one crash dialog again, and make the process good again 2967 // if it had been bad. 2968 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2969 + "/" + info.processName); 2970 mProcessCrashTimes.remove(info.processName, info.uid); 2971 if (mBadProcesses.get(info.processName, info.uid) != null) { 2972 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2973 UserHandle.getUserId(info.uid), info.uid, 2974 info.processName); 2975 mBadProcesses.remove(info.processName, info.uid); 2976 if (app != null) { 2977 app.bad = false; 2978 } 2979 } 2980 } 2981 } 2982 2983 if (app == null) { 2984 checkTime(startTime, "startProcess: creating new process record"); 2985 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2986 app.crashHandler = crashHandler; 2987 if (app == null) { 2988 Slog.w(TAG, "Failed making new process record for " 2989 + processName + "/" + info.uid + " isolated=" + isolated); 2990 return null; 2991 } 2992 mProcessNames.put(processName, app.uid, app); 2993 if (isolated) { 2994 mIsolatedProcesses.put(app.uid, app); 2995 } 2996 checkTime(startTime, "startProcess: done creating new process record"); 2997 } else { 2998 // If this is a new package in the process, add the package to the list 2999 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3000 checkTime(startTime, "startProcess: added package to existing proc"); 3001 } 3002 3003 // If the system is not ready yet, then hold off on starting this 3004 // process until it is. 3005 if (!mProcessesReady 3006 && !isAllowedWhileBooting(info) 3007 && !allowWhileBooting) { 3008 if (!mProcessesOnHold.contains(app)) { 3009 mProcessesOnHold.add(app); 3010 } 3011 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3012 checkTime(startTime, "startProcess: returning with proc on hold"); 3013 return app; 3014 } 3015 3016 checkTime(startTime, "startProcess: stepping in to startProcess"); 3017 startProcessLocked( 3018 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3019 checkTime(startTime, "startProcess: done starting proc!"); 3020 return (app.pid != 0) ? app : null; 3021 } 3022 3023 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3024 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3025 } 3026 3027 private final void startProcessLocked(ProcessRecord app, 3028 String hostingType, String hostingNameStr) { 3029 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3030 null /* entryPoint */, null /* entryPointArgs */); 3031 } 3032 3033 private final void startProcessLocked(ProcessRecord app, String hostingType, 3034 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3035 long startTime = SystemClock.elapsedRealtime(); 3036 if (app.pid > 0 && app.pid != MY_PID) { 3037 checkTime(startTime, "startProcess: removing from pids map"); 3038 synchronized (mPidsSelfLocked) { 3039 mPidsSelfLocked.remove(app.pid); 3040 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3041 } 3042 checkTime(startTime, "startProcess: done removing from pids map"); 3043 app.setPid(0); 3044 } 3045 3046 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3047 "startProcessLocked removing on hold: " + app); 3048 mProcessesOnHold.remove(app); 3049 3050 checkTime(startTime, "startProcess: starting to update cpu stats"); 3051 updateCpuStats(); 3052 checkTime(startTime, "startProcess: done updating cpu stats"); 3053 3054 try { 3055 int uid = app.uid; 3056 3057 int[] gids = null; 3058 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3059 if (!app.isolated) { 3060 int[] permGids = null; 3061 try { 3062 checkTime(startTime, "startProcess: getting gids from package manager"); 3063 final PackageManager pm = mContext.getPackageManager(); 3064 permGids = pm.getPackageGids(app.info.packageName); 3065 3066 if (Environment.isExternalStorageEmulated()) { 3067 checkTime(startTime, "startProcess: checking external storage perm"); 3068 if (pm.checkPermission( 3069 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3070 app.info.packageName) == PERMISSION_GRANTED) { 3071 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3072 } else { 3073 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3074 } 3075 } 3076 } catch (PackageManager.NameNotFoundException e) { 3077 Slog.w(TAG, "Unable to retrieve gids", e); 3078 } 3079 3080 /* 3081 * Add shared application and profile GIDs so applications can share some 3082 * resources like shared libraries and access user-wide resources 3083 */ 3084 if (permGids == null) { 3085 gids = new int[2]; 3086 } else { 3087 gids = new int[permGids.length + 2]; 3088 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3089 } 3090 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3091 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3092 } 3093 checkTime(startTime, "startProcess: building args"); 3094 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3095 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3096 && mTopComponent != null 3097 && app.processName.equals(mTopComponent.getPackageName())) { 3098 uid = 0; 3099 } 3100 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3101 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3102 uid = 0; 3103 } 3104 } 3105 int debugFlags = 0; 3106 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3107 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3108 // Also turn on CheckJNI for debuggable apps. It's quite 3109 // awkward to turn on otherwise. 3110 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3111 } 3112 // Run the app in safe mode if its manifest requests so or the 3113 // system is booted in safe mode. 3114 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3115 mSafeMode == true) { 3116 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3117 } 3118 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3119 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3120 } 3121 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3122 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3123 } 3124 if ("1".equals(SystemProperties.get("debug.assert"))) { 3125 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3126 } 3127 3128 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3129 if (requiredAbi == null) { 3130 requiredAbi = Build.SUPPORTED_ABIS[0]; 3131 } 3132 3133 String instructionSet = null; 3134 if (app.info.primaryCpuAbi != null) { 3135 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3136 } 3137 3138 // Start the process. It will either succeed and return a result containing 3139 // the PID of the new process, or else throw a RuntimeException. 3140 boolean isActivityProcess = (entryPoint == null); 3141 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3142 checkTime(startTime, "startProcess: asking zygote to start proc"); 3143 Process.ProcessStartResult startResult = Process.start(entryPoint, 3144 app.processName, uid, uid, gids, debugFlags, mountExternal, 3145 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3146 entryPointArgs); 3147 checkTime(startTime, "startProcess: returned from zygote!"); 3148 3149 if (app.isolated) { 3150 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3151 } 3152 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3153 checkTime(startTime, "startProcess: done updating battery stats"); 3154 3155 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3156 UserHandle.getUserId(uid), startResult.pid, uid, 3157 app.processName, hostingType, 3158 hostingNameStr != null ? hostingNameStr : ""); 3159 3160 if (app.persistent) { 3161 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3162 } 3163 3164 checkTime(startTime, "startProcess: building log message"); 3165 StringBuilder buf = mStringBuilder; 3166 buf.setLength(0); 3167 buf.append("Start proc "); 3168 buf.append(app.processName); 3169 if (!isActivityProcess) { 3170 buf.append(" ["); 3171 buf.append(entryPoint); 3172 buf.append("]"); 3173 } 3174 buf.append(" for "); 3175 buf.append(hostingType); 3176 if (hostingNameStr != null) { 3177 buf.append(" "); 3178 buf.append(hostingNameStr); 3179 } 3180 buf.append(": pid="); 3181 buf.append(startResult.pid); 3182 buf.append(" uid="); 3183 buf.append(uid); 3184 buf.append(" gids={"); 3185 if (gids != null) { 3186 for (int gi=0; gi<gids.length; gi++) { 3187 if (gi != 0) buf.append(", "); 3188 buf.append(gids[gi]); 3189 3190 } 3191 } 3192 buf.append("}"); 3193 if (requiredAbi != null) { 3194 buf.append(" abi="); 3195 buf.append(requiredAbi); 3196 } 3197 Slog.i(TAG, buf.toString()); 3198 app.setPid(startResult.pid); 3199 app.usingWrapper = startResult.usingWrapper; 3200 app.removed = false; 3201 app.killedByAm = false; 3202 checkTime(startTime, "startProcess: starting to update pids map"); 3203 synchronized (mPidsSelfLocked) { 3204 this.mPidsSelfLocked.put(startResult.pid, app); 3205 if (isActivityProcess) { 3206 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3207 msg.obj = app; 3208 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3209 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3210 } 3211 } 3212 checkTime(startTime, "startProcess: done updating pids map"); 3213 } catch (RuntimeException e) { 3214 // XXX do better error recovery. 3215 app.setPid(0); 3216 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3217 if (app.isolated) { 3218 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3219 } 3220 Slog.e(TAG, "Failure starting process " + app.processName, e); 3221 } 3222 } 3223 3224 void updateUsageStats(ActivityRecord component, boolean resumed) { 3225 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3226 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3227 if (resumed) { 3228 if (mUsageStatsService != null) { 3229 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3230 UsageEvents.Event.MOVE_TO_FOREGROUND); 3231 } 3232 synchronized (stats) { 3233 stats.noteActivityResumedLocked(component.app.uid); 3234 } 3235 } else { 3236 if (mUsageStatsService != null) { 3237 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3238 UsageEvents.Event.MOVE_TO_BACKGROUND); 3239 } 3240 synchronized (stats) { 3241 stats.noteActivityPausedLocked(component.app.uid); 3242 } 3243 } 3244 } 3245 3246 Intent getHomeIntent() { 3247 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3248 intent.setComponent(mTopComponent); 3249 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3250 intent.addCategory(Intent.CATEGORY_HOME); 3251 } 3252 return intent; 3253 } 3254 3255 boolean startHomeActivityLocked(int userId) { 3256 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3257 && mTopAction == null) { 3258 // We are running in factory test mode, but unable to find 3259 // the factory test app, so just sit around displaying the 3260 // error message and don't try to start anything. 3261 return false; 3262 } 3263 Intent intent = getHomeIntent(); 3264 ActivityInfo aInfo = 3265 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3266 if (aInfo != null) { 3267 intent.setComponent(new ComponentName( 3268 aInfo.applicationInfo.packageName, aInfo.name)); 3269 // Don't do this if the home app is currently being 3270 // instrumented. 3271 aInfo = new ActivityInfo(aInfo); 3272 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3273 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3274 aInfo.applicationInfo.uid, true); 3275 if (app == null || app.instrumentationClass == null) { 3276 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3277 mStackSupervisor.startHomeActivity(intent, aInfo); 3278 } 3279 } 3280 3281 return true; 3282 } 3283 3284 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3285 ActivityInfo ai = null; 3286 ComponentName comp = intent.getComponent(); 3287 try { 3288 if (comp != null) { 3289 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3290 } else { 3291 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3292 intent, 3293 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3294 flags, userId); 3295 3296 if (info != null) { 3297 ai = info.activityInfo; 3298 } 3299 } 3300 } catch (RemoteException e) { 3301 // ignore 3302 } 3303 3304 return ai; 3305 } 3306 3307 /** 3308 * Starts the "new version setup screen" if appropriate. 3309 */ 3310 void startSetupActivityLocked() { 3311 // Only do this once per boot. 3312 if (mCheckedForSetup) { 3313 return; 3314 } 3315 3316 // We will show this screen if the current one is a different 3317 // version than the last one shown, and we are not running in 3318 // low-level factory test mode. 3319 final ContentResolver resolver = mContext.getContentResolver(); 3320 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3321 Settings.Global.getInt(resolver, 3322 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3323 mCheckedForSetup = true; 3324 3325 // See if we should be showing the platform update setup UI. 3326 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3327 List<ResolveInfo> ris = mContext.getPackageManager() 3328 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3329 3330 // We don't allow third party apps to replace this. 3331 ResolveInfo ri = null; 3332 for (int i=0; ris != null && i<ris.size(); i++) { 3333 if ((ris.get(i).activityInfo.applicationInfo.flags 3334 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3335 ri = ris.get(i); 3336 break; 3337 } 3338 } 3339 3340 if (ri != null) { 3341 String vers = ri.activityInfo.metaData != null 3342 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3343 : null; 3344 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3345 vers = ri.activityInfo.applicationInfo.metaData.getString( 3346 Intent.METADATA_SETUP_VERSION); 3347 } 3348 String lastVers = Settings.Secure.getString( 3349 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3350 if (vers != null && !vers.equals(lastVers)) { 3351 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3352 intent.setComponent(new ComponentName( 3353 ri.activityInfo.packageName, ri.activityInfo.name)); 3354 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3355 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3356 null); 3357 } 3358 } 3359 } 3360 } 3361 3362 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3363 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3364 } 3365 3366 void enforceNotIsolatedCaller(String caller) { 3367 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3368 throw new SecurityException("Isolated process not allowed to call " + caller); 3369 } 3370 } 3371 3372 @Override 3373 public int getFrontActivityScreenCompatMode() { 3374 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3375 synchronized (this) { 3376 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3377 } 3378 } 3379 3380 @Override 3381 public void setFrontActivityScreenCompatMode(int mode) { 3382 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3383 "setFrontActivityScreenCompatMode"); 3384 synchronized (this) { 3385 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3386 } 3387 } 3388 3389 @Override 3390 public int getPackageScreenCompatMode(String packageName) { 3391 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3392 synchronized (this) { 3393 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3394 } 3395 } 3396 3397 @Override 3398 public void setPackageScreenCompatMode(String packageName, int mode) { 3399 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3400 "setPackageScreenCompatMode"); 3401 synchronized (this) { 3402 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3403 } 3404 } 3405 3406 @Override 3407 public boolean getPackageAskScreenCompat(String packageName) { 3408 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3409 synchronized (this) { 3410 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3411 } 3412 } 3413 3414 @Override 3415 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3416 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3417 "setPackageAskScreenCompat"); 3418 synchronized (this) { 3419 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3420 } 3421 } 3422 3423 private void dispatchProcessesChanged() { 3424 int N; 3425 synchronized (this) { 3426 N = mPendingProcessChanges.size(); 3427 if (mActiveProcessChanges.length < N) { 3428 mActiveProcessChanges = new ProcessChangeItem[N]; 3429 } 3430 mPendingProcessChanges.toArray(mActiveProcessChanges); 3431 mAvailProcessChanges.addAll(mPendingProcessChanges); 3432 mPendingProcessChanges.clear(); 3433 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3434 } 3435 3436 int i = mProcessObservers.beginBroadcast(); 3437 while (i > 0) { 3438 i--; 3439 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3440 if (observer != null) { 3441 try { 3442 for (int j=0; j<N; j++) { 3443 ProcessChangeItem item = mActiveProcessChanges[j]; 3444 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3445 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3446 + item.pid + " uid=" + item.uid + ": " 3447 + item.foregroundActivities); 3448 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3449 item.foregroundActivities); 3450 } 3451 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3452 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3453 + item.pid + " uid=" + item.uid + ": " + item.processState); 3454 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3455 } 3456 } 3457 } catch (RemoteException e) { 3458 } 3459 } 3460 } 3461 mProcessObservers.finishBroadcast(); 3462 } 3463 3464 private void dispatchProcessDied(int pid, int uid) { 3465 int i = mProcessObservers.beginBroadcast(); 3466 while (i > 0) { 3467 i--; 3468 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3469 if (observer != null) { 3470 try { 3471 observer.onProcessDied(pid, uid); 3472 } catch (RemoteException e) { 3473 } 3474 } 3475 } 3476 mProcessObservers.finishBroadcast(); 3477 } 3478 3479 @Override 3480 public final int startActivity(IApplicationThread caller, String callingPackage, 3481 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3482 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3483 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3484 resultWho, requestCode, startFlags, profilerInfo, options, 3485 UserHandle.getCallingUserId()); 3486 } 3487 3488 @Override 3489 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3490 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3491 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3492 enforceNotIsolatedCaller("startActivity"); 3493 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3494 false, ALLOW_FULL_ONLY, "startActivity", null); 3495 // TODO: Switch to user app stacks here. 3496 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3497 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3498 profilerInfo, null, null, options, userId, null, null); 3499 } 3500 3501 @Override 3502 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3503 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3504 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3505 3506 // This is very dangerous -- it allows you to perform a start activity (including 3507 // permission grants) as any app that may launch one of your own activities. So 3508 // we will only allow this to be done from activities that are part of the core framework, 3509 // and then only when they are running as the system. 3510 final ActivityRecord sourceRecord; 3511 final int targetUid; 3512 final String targetPackage; 3513 synchronized (this) { 3514 if (resultTo == null) { 3515 throw new SecurityException("Must be called from an activity"); 3516 } 3517 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3518 if (sourceRecord == null) { 3519 throw new SecurityException("Called with bad activity token: " + resultTo); 3520 } 3521 if (!sourceRecord.info.packageName.equals("android")) { 3522 throw new SecurityException( 3523 "Must be called from an activity that is declared in the android package"); 3524 } 3525 if (sourceRecord.app == null) { 3526 throw new SecurityException("Called without a process attached to activity"); 3527 } 3528 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3529 // This is still okay, as long as this activity is running under the 3530 // uid of the original calling activity. 3531 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3532 throw new SecurityException( 3533 "Calling activity in uid " + sourceRecord.app.uid 3534 + " must be system uid or original calling uid " 3535 + sourceRecord.launchedFromUid); 3536 } 3537 } 3538 targetUid = sourceRecord.launchedFromUid; 3539 targetPackage = sourceRecord.launchedFromPackage; 3540 } 3541 3542 // TODO: Switch to user app stacks here. 3543 try { 3544 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3545 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3546 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3547 return ret; 3548 } catch (SecurityException e) { 3549 // XXX need to figure out how to propagate to original app. 3550 // A SecurityException here is generally actually a fault of the original 3551 // calling activity (such as a fairly granting permissions), so propagate it 3552 // back to them. 3553 /* 3554 StringBuilder msg = new StringBuilder(); 3555 msg.append("While launching"); 3556 msg.append(intent.toString()); 3557 msg.append(": "); 3558 msg.append(e.getMessage()); 3559 */ 3560 throw e; 3561 } 3562 } 3563 3564 @Override 3565 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3566 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3567 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3568 enforceNotIsolatedCaller("startActivityAndWait"); 3569 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3570 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3571 WaitResult res = new WaitResult(); 3572 // TODO: Switch to user app stacks here. 3573 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3574 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3575 options, userId, null, null); 3576 return res; 3577 } 3578 3579 @Override 3580 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3581 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3582 int startFlags, Configuration config, Bundle options, int userId) { 3583 enforceNotIsolatedCaller("startActivityWithConfig"); 3584 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3585 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3586 // TODO: Switch to user app stacks here. 3587 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3588 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3589 null, null, config, options, userId, null, null); 3590 return ret; 3591 } 3592 3593 @Override 3594 public int startActivityIntentSender(IApplicationThread caller, 3595 IntentSender intent, Intent fillInIntent, String resolvedType, 3596 IBinder resultTo, String resultWho, int requestCode, 3597 int flagsMask, int flagsValues, Bundle options) { 3598 enforceNotIsolatedCaller("startActivityIntentSender"); 3599 // Refuse possible leaked file descriptors 3600 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3601 throw new IllegalArgumentException("File descriptors passed in Intent"); 3602 } 3603 3604 IIntentSender sender = intent.getTarget(); 3605 if (!(sender instanceof PendingIntentRecord)) { 3606 throw new IllegalArgumentException("Bad PendingIntent object"); 3607 } 3608 3609 PendingIntentRecord pir = (PendingIntentRecord)sender; 3610 3611 synchronized (this) { 3612 // If this is coming from the currently resumed activity, it is 3613 // effectively saying that app switches are allowed at this point. 3614 final ActivityStack stack = getFocusedStack(); 3615 if (stack.mResumedActivity != null && 3616 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3617 mAppSwitchesAllowedTime = 0; 3618 } 3619 } 3620 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3621 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3622 return ret; 3623 } 3624 3625 @Override 3626 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3627 Intent intent, String resolvedType, IVoiceInteractionSession session, 3628 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3629 Bundle options, int userId) { 3630 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3631 != PackageManager.PERMISSION_GRANTED) { 3632 String msg = "Permission Denial: startVoiceActivity() from pid=" 3633 + Binder.getCallingPid() 3634 + ", uid=" + Binder.getCallingUid() 3635 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3636 Slog.w(TAG, msg); 3637 throw new SecurityException(msg); 3638 } 3639 if (session == null || interactor == null) { 3640 throw new NullPointerException("null session or interactor"); 3641 } 3642 userId = handleIncomingUser(callingPid, callingUid, userId, 3643 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3644 // TODO: Switch to user app stacks here. 3645 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3646 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3647 null, options, userId, null, null); 3648 } 3649 3650 @Override 3651 public boolean startNextMatchingActivity(IBinder callingActivity, 3652 Intent intent, Bundle options) { 3653 // Refuse possible leaked file descriptors 3654 if (intent != null && intent.hasFileDescriptors() == true) { 3655 throw new IllegalArgumentException("File descriptors passed in Intent"); 3656 } 3657 3658 synchronized (this) { 3659 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3660 if (r == null) { 3661 ActivityOptions.abort(options); 3662 return false; 3663 } 3664 if (r.app == null || r.app.thread == null) { 3665 // The caller is not running... d'oh! 3666 ActivityOptions.abort(options); 3667 return false; 3668 } 3669 intent = new Intent(intent); 3670 // The caller is not allowed to change the data. 3671 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3672 // And we are resetting to find the next component... 3673 intent.setComponent(null); 3674 3675 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3676 3677 ActivityInfo aInfo = null; 3678 try { 3679 List<ResolveInfo> resolves = 3680 AppGlobals.getPackageManager().queryIntentActivities( 3681 intent, r.resolvedType, 3682 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3683 UserHandle.getCallingUserId()); 3684 3685 // Look for the original activity in the list... 3686 final int N = resolves != null ? resolves.size() : 0; 3687 for (int i=0; i<N; i++) { 3688 ResolveInfo rInfo = resolves.get(i); 3689 if (rInfo.activityInfo.packageName.equals(r.packageName) 3690 && rInfo.activityInfo.name.equals(r.info.name)) { 3691 // We found the current one... the next matching is 3692 // after it. 3693 i++; 3694 if (i<N) { 3695 aInfo = resolves.get(i).activityInfo; 3696 } 3697 if (debug) { 3698 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3699 + "/" + r.info.name); 3700 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3701 + "/" + aInfo.name); 3702 } 3703 break; 3704 } 3705 } 3706 } catch (RemoteException e) { 3707 } 3708 3709 if (aInfo == null) { 3710 // Nobody who is next! 3711 ActivityOptions.abort(options); 3712 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3713 return false; 3714 } 3715 3716 intent.setComponent(new ComponentName( 3717 aInfo.applicationInfo.packageName, aInfo.name)); 3718 intent.setFlags(intent.getFlags()&~( 3719 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3720 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3721 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3722 Intent.FLAG_ACTIVITY_NEW_TASK)); 3723 3724 // Okay now we need to start the new activity, replacing the 3725 // currently running activity. This is a little tricky because 3726 // we want to start the new one as if the current one is finished, 3727 // but not finish the current one first so that there is no flicker. 3728 // And thus... 3729 final boolean wasFinishing = r.finishing; 3730 r.finishing = true; 3731 3732 // Propagate reply information over to the new activity. 3733 final ActivityRecord resultTo = r.resultTo; 3734 final String resultWho = r.resultWho; 3735 final int requestCode = r.requestCode; 3736 r.resultTo = null; 3737 if (resultTo != null) { 3738 resultTo.removeResultsLocked(r, resultWho, requestCode); 3739 } 3740 3741 final long origId = Binder.clearCallingIdentity(); 3742 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3743 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3744 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3745 options, false, null, null, null); 3746 Binder.restoreCallingIdentity(origId); 3747 3748 r.finishing = wasFinishing; 3749 if (res != ActivityManager.START_SUCCESS) { 3750 return false; 3751 } 3752 return true; 3753 } 3754 } 3755 3756 @Override 3757 public final int startActivityFromRecents(int taskId, Bundle options) { 3758 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3759 String msg = "Permission Denial: startActivityFromRecents called without " + 3760 START_TASKS_FROM_RECENTS; 3761 Slog.w(TAG, msg); 3762 throw new SecurityException(msg); 3763 } 3764 return startActivityFromRecentsInner(taskId, options); 3765 } 3766 3767 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3768 final TaskRecord task; 3769 final int callingUid; 3770 final String callingPackage; 3771 final Intent intent; 3772 final int userId; 3773 synchronized (this) { 3774 task = recentTaskForIdLocked(taskId); 3775 if (task == null) { 3776 throw new IllegalArgumentException("Task " + taskId + " not found."); 3777 } 3778 callingUid = task.mCallingUid; 3779 callingPackage = task.mCallingPackage; 3780 intent = task.intent; 3781 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3782 userId = task.userId; 3783 } 3784 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3785 options, userId, null, task); 3786 } 3787 3788 final int startActivityInPackage(int uid, String callingPackage, 3789 Intent intent, String resolvedType, IBinder resultTo, 3790 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3791 IActivityContainer container, TaskRecord inTask) { 3792 3793 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3794 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3795 3796 // TODO: Switch to user app stacks here. 3797 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3798 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3799 null, null, null, options, userId, container, inTask); 3800 return ret; 3801 } 3802 3803 @Override 3804 public final int startActivities(IApplicationThread caller, String callingPackage, 3805 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3806 int userId) { 3807 enforceNotIsolatedCaller("startActivities"); 3808 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3809 false, ALLOW_FULL_ONLY, "startActivity", null); 3810 // TODO: Switch to user app stacks here. 3811 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3812 resolvedTypes, resultTo, options, userId); 3813 return ret; 3814 } 3815 3816 final int startActivitiesInPackage(int uid, String callingPackage, 3817 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3818 Bundle options, int userId) { 3819 3820 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3821 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3822 // TODO: Switch to user app stacks here. 3823 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3824 resultTo, options, userId); 3825 return ret; 3826 } 3827 3828 //explicitly remove thd old information in mRecentTasks when removing existing user. 3829 private void removeRecentTasksForUserLocked(int userId) { 3830 if(userId <= 0) { 3831 Slog.i(TAG, "Can't remove recent task on user " + userId); 3832 return; 3833 } 3834 3835 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3836 TaskRecord tr = mRecentTasks.get(i); 3837 if (tr.userId == userId) { 3838 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3839 + " when finishing user" + userId); 3840 mRecentTasks.remove(i); 3841 tr.removedFromRecents(mTaskPersister); 3842 } 3843 } 3844 3845 // Remove tasks from persistent storage. 3846 mTaskPersister.wakeup(null, true); 3847 } 3848 3849 /** 3850 * Update the recent tasks lists: make sure tasks should still be here (their 3851 * applications / activities still exist), update their availability, fixup ordering 3852 * of affiliations. 3853 */ 3854 void cleanupRecentTasksLocked(int userId) { 3855 if (mRecentTasks == null) { 3856 // Happens when called from the packagemanager broadcast before boot. 3857 return; 3858 } 3859 3860 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3861 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3862 final IPackageManager pm = AppGlobals.getPackageManager(); 3863 final ActivityInfo dummyAct = new ActivityInfo(); 3864 final ApplicationInfo dummyApp = new ApplicationInfo(); 3865 3866 int N = mRecentTasks.size(); 3867 3868 int[] users = userId == UserHandle.USER_ALL 3869 ? getUsersLocked() : new int[] { userId }; 3870 for (int user : users) { 3871 for (int i = 0; i < N; i++) { 3872 TaskRecord task = mRecentTasks.get(i); 3873 if (task.userId != user) { 3874 // Only look at tasks for the user ID of interest. 3875 continue; 3876 } 3877 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3878 // This situation is broken, and we should just get rid of it now. 3879 mRecentTasks.remove(i); 3880 task.removedFromRecents(mTaskPersister); 3881 i--; 3882 N--; 3883 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3884 continue; 3885 } 3886 // Check whether this activity is currently available. 3887 if (task.realActivity != null) { 3888 ActivityInfo ai = availActCache.get(task.realActivity); 3889 if (ai == null) { 3890 try { 3891 ai = pm.getActivityInfo(task.realActivity, 3892 PackageManager.GET_UNINSTALLED_PACKAGES 3893 | PackageManager.GET_DISABLED_COMPONENTS, user); 3894 } catch (RemoteException e) { 3895 // Will never happen. 3896 continue; 3897 } 3898 if (ai == null) { 3899 ai = dummyAct; 3900 } 3901 availActCache.put(task.realActivity, ai); 3902 } 3903 if (ai == dummyAct) { 3904 // This could be either because the activity no longer exists, or the 3905 // app is temporarily gone. For the former we want to remove the recents 3906 // entry; for the latter we want to mark it as unavailable. 3907 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3908 if (app == null) { 3909 try { 3910 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3911 PackageManager.GET_UNINSTALLED_PACKAGES 3912 | PackageManager.GET_DISABLED_COMPONENTS, user); 3913 } catch (RemoteException e) { 3914 // Will never happen. 3915 continue; 3916 } 3917 if (app == null) { 3918 app = dummyApp; 3919 } 3920 availAppCache.put(task.realActivity.getPackageName(), app); 3921 } 3922 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3923 // Doesn't exist any more! Good-bye. 3924 mRecentTasks.remove(i); 3925 task.removedFromRecents(mTaskPersister); 3926 i--; 3927 N--; 3928 Slog.w(TAG, "Removing no longer valid recent: " + task); 3929 continue; 3930 } else { 3931 // Otherwise just not available for now. 3932 if (task.isAvailable) { 3933 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3934 + task); 3935 } 3936 task.isAvailable = false; 3937 } 3938 } else { 3939 if (!ai.enabled || !ai.applicationInfo.enabled 3940 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3941 if (task.isAvailable) { 3942 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3943 + task + " (enabled=" + ai.enabled + "/" 3944 + ai.applicationInfo.enabled + " flags=" 3945 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3946 } 3947 task.isAvailable = false; 3948 } else { 3949 if (!task.isAvailable) { 3950 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3951 + task); 3952 } 3953 task.isAvailable = true; 3954 } 3955 } 3956 } 3957 } 3958 } 3959 3960 // Verify the affiliate chain for each task. 3961 for (int i = 0; i < N; ) { 3962 TaskRecord task = mRecentTasks.remove(i); 3963 if (mTmpRecents.contains(task)) { 3964 continue; 3965 } 3966 int affiliatedTaskId = task.mAffiliatedTaskId; 3967 while (true) { 3968 TaskRecord next = task.mNextAffiliate; 3969 if (next == null) { 3970 break; 3971 } 3972 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3973 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3974 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3975 task.setNextAffiliate(null); 3976 if (next.mPrevAffiliate == task) { 3977 next.setPrevAffiliate(null); 3978 } 3979 break; 3980 } 3981 if (next.mPrevAffiliate != task) { 3982 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3983 next.mPrevAffiliate + " task=" + task); 3984 next.setPrevAffiliate(null); 3985 task.setNextAffiliate(null); 3986 break; 3987 } 3988 if (!mRecentTasks.contains(next)) { 3989 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3990 task.setNextAffiliate(null); 3991 // We know that next.mPrevAffiliate is always task, from above, so clear 3992 // its previous affiliate. 3993 next.setPrevAffiliate(null); 3994 break; 3995 } 3996 task = next; 3997 } 3998 // task is now the end of the list 3999 do { 4000 mRecentTasks.remove(task); 4001 mRecentTasks.add(i++, task); 4002 mTmpRecents.add(task); 4003 task.inRecents = true; 4004 } while ((task = task.mPrevAffiliate) != null); 4005 } 4006 mTmpRecents.clear(); 4007 // mRecentTasks is now in sorted, affiliated order. 4008 } 4009 4010 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4011 int N = mRecentTasks.size(); 4012 TaskRecord top = task; 4013 int topIndex = taskIndex; 4014 while (top.mNextAffiliate != null && topIndex > 0) { 4015 top = top.mNextAffiliate; 4016 topIndex--; 4017 } 4018 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4019 + topIndex + " from intial " + taskIndex); 4020 // Find the end of the chain, doing a sanity check along the way. 4021 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4022 int endIndex = topIndex; 4023 TaskRecord prev = top; 4024 while (endIndex < N) { 4025 TaskRecord cur = mRecentTasks.get(endIndex); 4026 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4027 + endIndex + " " + cur); 4028 if (cur == top) { 4029 // Verify start of the chain. 4030 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4031 Slog.wtf(TAG, "Bad chain @" + endIndex 4032 + ": first task has next affiliate: " + prev); 4033 sane = false; 4034 break; 4035 } 4036 } else { 4037 // Verify middle of the chain's next points back to the one before. 4038 if (cur.mNextAffiliate != prev 4039 || cur.mNextAffiliateTaskId != prev.taskId) { 4040 Slog.wtf(TAG, "Bad chain @" + endIndex 4041 + ": middle task " + cur + " @" + endIndex 4042 + " has bad next affiliate " 4043 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4044 + ", expected " + prev); 4045 sane = false; 4046 break; 4047 } 4048 } 4049 if (cur.mPrevAffiliateTaskId == -1) { 4050 // Chain ends here. 4051 if (cur.mPrevAffiliate != null) { 4052 Slog.wtf(TAG, "Bad chain @" + endIndex 4053 + ": last task " + cur + " has previous affiliate " 4054 + cur.mPrevAffiliate); 4055 sane = false; 4056 } 4057 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4058 break; 4059 } else { 4060 // Verify middle of the chain's prev points to a valid item. 4061 if (cur.mPrevAffiliate == null) { 4062 Slog.wtf(TAG, "Bad chain @" + endIndex 4063 + ": task " + cur + " has previous affiliate " 4064 + cur.mPrevAffiliate + " but should be id " 4065 + cur.mPrevAffiliate); 4066 sane = false; 4067 break; 4068 } 4069 } 4070 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4071 Slog.wtf(TAG, "Bad chain @" + endIndex 4072 + ": task " + cur + " has affiliated id " 4073 + cur.mAffiliatedTaskId + " but should be " 4074 + task.mAffiliatedTaskId); 4075 sane = false; 4076 break; 4077 } 4078 prev = cur; 4079 endIndex++; 4080 if (endIndex >= N) { 4081 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4082 + ": last task " + prev); 4083 sane = false; 4084 break; 4085 } 4086 } 4087 if (sane) { 4088 if (endIndex < taskIndex) { 4089 Slog.wtf(TAG, "Bad chain @" + endIndex 4090 + ": did not extend to task " + task + " @" + taskIndex); 4091 sane = false; 4092 } 4093 } 4094 if (sane) { 4095 // All looks good, we can just move all of the affiliated tasks 4096 // to the top. 4097 for (int i=topIndex; i<=endIndex; i++) { 4098 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4099 + " from " + i + " to " + (i-topIndex)); 4100 TaskRecord cur = mRecentTasks.remove(i); 4101 mRecentTasks.add(i-topIndex, cur); 4102 } 4103 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4104 + " to " + endIndex); 4105 return true; 4106 } 4107 4108 // Whoops, couldn't do it. 4109 return false; 4110 } 4111 4112 final void addRecentTaskLocked(TaskRecord task) { 4113 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4114 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4115 4116 int N = mRecentTasks.size(); 4117 // Quick case: check if the top-most recent task is the same. 4118 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4119 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4120 return; 4121 } 4122 // Another quick case: check if this is part of a set of affiliated 4123 // tasks that are at the top. 4124 if (isAffiliated && N > 0 && task.inRecents 4125 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4126 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4127 + " at top when adding " + task); 4128 return; 4129 } 4130 // Another quick case: never add voice sessions. 4131 if (task.voiceSession != null) { 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4133 return; 4134 } 4135 4136 boolean needAffiliationFix = false; 4137 4138 // Slightly less quick case: the task is already in recents, so all we need 4139 // to do is move it. 4140 if (task.inRecents) { 4141 int taskIndex = mRecentTasks.indexOf(task); 4142 if (taskIndex >= 0) { 4143 if (!isAffiliated) { 4144 // Simple case: this is not an affiliated task, so we just move it to the front. 4145 mRecentTasks.remove(taskIndex); 4146 mRecentTasks.add(0, task); 4147 notifyTaskPersisterLocked(task, false); 4148 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4149 + " from " + taskIndex); 4150 return; 4151 } else { 4152 // More complicated: need to keep all affiliated tasks together. 4153 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4154 // All went well. 4155 return; 4156 } 4157 4158 // Uh oh... something bad in the affiliation chain, try to rebuild 4159 // everything and then go through our general path of adding a new task. 4160 needAffiliationFix = true; 4161 } 4162 } else { 4163 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4164 needAffiliationFix = true; 4165 } 4166 } 4167 4168 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4169 trimRecentsForTask(task, true); 4170 4171 N = mRecentTasks.size(); 4172 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4173 final TaskRecord tr = mRecentTasks.remove(N - 1); 4174 tr.removedFromRecents(mTaskPersister); 4175 N--; 4176 } 4177 task.inRecents = true; 4178 if (!isAffiliated || needAffiliationFix) { 4179 // If this is a simple non-affiliated task, or we had some failure trying to 4180 // handle it as part of an affilated task, then just place it at the top. 4181 mRecentTasks.add(0, task); 4182 } else if (isAffiliated) { 4183 // If this is a new affiliated task, then move all of the affiliated tasks 4184 // to the front and insert this new one. 4185 TaskRecord other = task.mNextAffiliate; 4186 if (other == null) { 4187 other = task.mPrevAffiliate; 4188 } 4189 if (other != null) { 4190 int otherIndex = mRecentTasks.indexOf(other); 4191 if (otherIndex >= 0) { 4192 // Insert new task at appropriate location. 4193 int taskIndex; 4194 if (other == task.mNextAffiliate) { 4195 // We found the index of our next affiliation, which is who is 4196 // before us in the list, so add after that point. 4197 taskIndex = otherIndex+1; 4198 } else { 4199 // We found the index of our previous affiliation, which is who is 4200 // after us in the list, so add at their position. 4201 taskIndex = otherIndex; 4202 } 4203 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4204 + taskIndex + ": " + task); 4205 mRecentTasks.add(taskIndex, task); 4206 4207 // Now move everything to the front. 4208 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4209 // All went well. 4210 return; 4211 } 4212 4213 // Uh oh... something bad in the affiliation chain, try to rebuild 4214 // everything and then go through our general path of adding a new task. 4215 needAffiliationFix = true; 4216 } else { 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4218 + other); 4219 needAffiliationFix = true; 4220 } 4221 } else { 4222 if (DEBUG_RECENTS) Slog.d(TAG, 4223 "addRecent: adding affiliated task without next/prev:" + task); 4224 needAffiliationFix = true; 4225 } 4226 } 4227 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4228 4229 if (needAffiliationFix) { 4230 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4231 cleanupRecentTasksLocked(task.userId); 4232 } 4233 } 4234 4235 /** 4236 * If needed, remove oldest existing entries in recents that are for the same kind 4237 * of task as the given one. 4238 */ 4239 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4240 int N = mRecentTasks.size(); 4241 final Intent intent = task.intent; 4242 final boolean document = intent != null && intent.isDocument(); 4243 4244 int maxRecents = task.maxRecents - 1; 4245 for (int i=0; i<N; i++) { 4246 final TaskRecord tr = mRecentTasks.get(i); 4247 if (task != tr) { 4248 if (task.userId != tr.userId) { 4249 continue; 4250 } 4251 if (i > MAX_RECENT_BITMAPS) { 4252 tr.freeLastThumbnail(); 4253 } 4254 final Intent trIntent = tr.intent; 4255 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4256 (intent == null || !intent.filterEquals(trIntent))) { 4257 continue; 4258 } 4259 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4260 if (document && trIsDocument) { 4261 // These are the same document activity (not necessarily the same doc). 4262 if (maxRecents > 0) { 4263 --maxRecents; 4264 continue; 4265 } 4266 // Hit the maximum number of documents for this task. Fall through 4267 // and remove this document from recents. 4268 } else if (document || trIsDocument) { 4269 // Only one of these is a document. Not the droid we're looking for. 4270 continue; 4271 } 4272 } 4273 4274 if (!doTrim) { 4275 // If the caller is not actually asking for a trim, just tell them we reached 4276 // a point where the trim would happen. 4277 return i; 4278 } 4279 4280 // Either task and tr are the same or, their affinities match or their intents match 4281 // and neither of them is a document, or they are documents using the same activity 4282 // and their maxRecents has been reached. 4283 tr.disposeThumbnail(); 4284 mRecentTasks.remove(i); 4285 if (task != tr) { 4286 tr.removedFromRecents(mTaskPersister); 4287 } 4288 i--; 4289 N--; 4290 if (task.intent == null) { 4291 // If the new recent task we are adding is not fully 4292 // specified, then replace it with the existing recent task. 4293 task = tr; 4294 } 4295 notifyTaskPersisterLocked(tr, false); 4296 } 4297 4298 return -1; 4299 } 4300 4301 @Override 4302 public void reportActivityFullyDrawn(IBinder token) { 4303 synchronized (this) { 4304 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4305 if (r == null) { 4306 return; 4307 } 4308 r.reportFullyDrawnLocked(); 4309 } 4310 } 4311 4312 @Override 4313 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4314 synchronized (this) { 4315 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4316 if (r == null) { 4317 return; 4318 } 4319 final long origId = Binder.clearCallingIdentity(); 4320 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4321 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4322 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4323 if (config != null) { 4324 r.frozenBeforeDestroy = true; 4325 if (!updateConfigurationLocked(config, r, false, false)) { 4326 mStackSupervisor.resumeTopActivitiesLocked(); 4327 } 4328 } 4329 Binder.restoreCallingIdentity(origId); 4330 } 4331 } 4332 4333 @Override 4334 public int getRequestedOrientation(IBinder token) { 4335 synchronized (this) { 4336 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4337 if (r == null) { 4338 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4339 } 4340 return mWindowManager.getAppOrientation(r.appToken); 4341 } 4342 } 4343 4344 /** 4345 * This is the internal entry point for handling Activity.finish(). 4346 * 4347 * @param token The Binder token referencing the Activity we want to finish. 4348 * @param resultCode Result code, if any, from this Activity. 4349 * @param resultData Result data (Intent), if any, from this Activity. 4350 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4351 * the root Activity in the task. 4352 * 4353 * @return Returns true if the activity successfully finished, or false if it is still running. 4354 */ 4355 @Override 4356 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4357 boolean finishTask) { 4358 // Refuse possible leaked file descriptors 4359 if (resultData != null && resultData.hasFileDescriptors() == true) { 4360 throw new IllegalArgumentException("File descriptors passed in Intent"); 4361 } 4362 4363 synchronized(this) { 4364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4365 if (r == null) { 4366 return true; 4367 } 4368 // Keep track of the root activity of the task before we finish it 4369 TaskRecord tr = r.task; 4370 ActivityRecord rootR = tr.getRootActivity(); 4371 // Do not allow task to finish in Lock Task mode. 4372 if (tr == mStackSupervisor.mLockTaskModeTask) { 4373 if (rootR == r) { 4374 mStackSupervisor.showLockTaskToast(); 4375 return false; 4376 } 4377 } 4378 if (mController != null) { 4379 // Find the first activity that is not finishing. 4380 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4381 if (next != null) { 4382 // ask watcher if this is allowed 4383 boolean resumeOK = true; 4384 try { 4385 resumeOK = mController.activityResuming(next.packageName); 4386 } catch (RemoteException e) { 4387 mController = null; 4388 Watchdog.getInstance().setActivityController(null); 4389 } 4390 4391 if (!resumeOK) { 4392 return false; 4393 } 4394 } 4395 } 4396 final long origId = Binder.clearCallingIdentity(); 4397 try { 4398 boolean res; 4399 if (finishTask && r == rootR) { 4400 // If requested, remove the task that is associated to this activity only if it 4401 // was the root activity in the task. The result code and data is ignored because 4402 // we don't support returning them across task boundaries. 4403 res = removeTaskByIdLocked(tr.taskId, 0); 4404 } else { 4405 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4406 resultData, "app-request", true); 4407 } 4408 return res; 4409 } finally { 4410 Binder.restoreCallingIdentity(origId); 4411 } 4412 } 4413 } 4414 4415 @Override 4416 public final void finishHeavyWeightApp() { 4417 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4418 != PackageManager.PERMISSION_GRANTED) { 4419 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4420 + Binder.getCallingPid() 4421 + ", uid=" + Binder.getCallingUid() 4422 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4423 Slog.w(TAG, msg); 4424 throw new SecurityException(msg); 4425 } 4426 4427 synchronized(this) { 4428 if (mHeavyWeightProcess == null) { 4429 return; 4430 } 4431 4432 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4433 mHeavyWeightProcess.activities); 4434 for (int i=0; i<activities.size(); i++) { 4435 ActivityRecord r = activities.get(i); 4436 if (!r.finishing) { 4437 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4438 null, "finish-heavy", true); 4439 } 4440 } 4441 4442 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4443 mHeavyWeightProcess.userId, 0)); 4444 mHeavyWeightProcess = null; 4445 } 4446 } 4447 4448 @Override 4449 public void crashApplication(int uid, int initialPid, String packageName, 4450 String message) { 4451 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4452 != PackageManager.PERMISSION_GRANTED) { 4453 String msg = "Permission Denial: crashApplication() from pid=" 4454 + Binder.getCallingPid() 4455 + ", uid=" + Binder.getCallingUid() 4456 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4457 Slog.w(TAG, msg); 4458 throw new SecurityException(msg); 4459 } 4460 4461 synchronized(this) { 4462 ProcessRecord proc = null; 4463 4464 // Figure out which process to kill. We don't trust that initialPid 4465 // still has any relation to current pids, so must scan through the 4466 // list. 4467 synchronized (mPidsSelfLocked) { 4468 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4469 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4470 if (p.uid != uid) { 4471 continue; 4472 } 4473 if (p.pid == initialPid) { 4474 proc = p; 4475 break; 4476 } 4477 if (p.pkgList.containsKey(packageName)) { 4478 proc = p; 4479 } 4480 } 4481 } 4482 4483 if (proc == null) { 4484 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4485 + " initialPid=" + initialPid 4486 + " packageName=" + packageName); 4487 return; 4488 } 4489 4490 if (proc.thread != null) { 4491 if (proc.pid == Process.myPid()) { 4492 Log.w(TAG, "crashApplication: trying to crash self!"); 4493 return; 4494 } 4495 long ident = Binder.clearCallingIdentity(); 4496 try { 4497 proc.thread.scheduleCrash(message); 4498 } catch (RemoteException e) { 4499 } 4500 Binder.restoreCallingIdentity(ident); 4501 } 4502 } 4503 } 4504 4505 @Override 4506 public final void finishSubActivity(IBinder token, String resultWho, 4507 int requestCode) { 4508 synchronized(this) { 4509 final long origId = Binder.clearCallingIdentity(); 4510 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4511 if (r != null) { 4512 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4513 } 4514 Binder.restoreCallingIdentity(origId); 4515 } 4516 } 4517 4518 @Override 4519 public boolean finishActivityAffinity(IBinder token) { 4520 synchronized(this) { 4521 final long origId = Binder.clearCallingIdentity(); 4522 try { 4523 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4524 4525 ActivityRecord rootR = r.task.getRootActivity(); 4526 // Do not allow task to finish in Lock Task mode. 4527 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4528 if (rootR == r) { 4529 mStackSupervisor.showLockTaskToast(); 4530 return false; 4531 } 4532 } 4533 boolean res = false; 4534 if (r != null) { 4535 res = r.task.stack.finishActivityAffinityLocked(r); 4536 } 4537 return res; 4538 } finally { 4539 Binder.restoreCallingIdentity(origId); 4540 } 4541 } 4542 } 4543 4544 @Override 4545 public void finishVoiceTask(IVoiceInteractionSession session) { 4546 synchronized(this) { 4547 final long origId = Binder.clearCallingIdentity(); 4548 try { 4549 mStackSupervisor.finishVoiceTask(session); 4550 } finally { 4551 Binder.restoreCallingIdentity(origId); 4552 } 4553 } 4554 4555 } 4556 4557 @Override 4558 public boolean releaseActivityInstance(IBinder token) { 4559 synchronized(this) { 4560 final long origId = Binder.clearCallingIdentity(); 4561 try { 4562 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4563 if (r.task == null || r.task.stack == null) { 4564 return false; 4565 } 4566 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4567 } finally { 4568 Binder.restoreCallingIdentity(origId); 4569 } 4570 } 4571 } 4572 4573 @Override 4574 public void releaseSomeActivities(IApplicationThread appInt) { 4575 synchronized(this) { 4576 final long origId = Binder.clearCallingIdentity(); 4577 try { 4578 ProcessRecord app = getRecordForAppLocked(appInt); 4579 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4580 } finally { 4581 Binder.restoreCallingIdentity(origId); 4582 } 4583 } 4584 } 4585 4586 @Override 4587 public boolean willActivityBeVisible(IBinder token) { 4588 synchronized(this) { 4589 ActivityStack stack = ActivityRecord.getStackLocked(token); 4590 if (stack != null) { 4591 return stack.willActivityBeVisibleLocked(token); 4592 } 4593 return false; 4594 } 4595 } 4596 4597 @Override 4598 public void overridePendingTransition(IBinder token, String packageName, 4599 int enterAnim, int exitAnim) { 4600 synchronized(this) { 4601 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4602 if (self == null) { 4603 return; 4604 } 4605 4606 final long origId = Binder.clearCallingIdentity(); 4607 4608 if (self.state == ActivityState.RESUMED 4609 || self.state == ActivityState.PAUSING) { 4610 mWindowManager.overridePendingAppTransition(packageName, 4611 enterAnim, exitAnim, null); 4612 } 4613 4614 Binder.restoreCallingIdentity(origId); 4615 } 4616 } 4617 4618 /** 4619 * Main function for removing an existing process from the activity manager 4620 * as a result of that process going away. Clears out all connections 4621 * to the process. 4622 */ 4623 private final void handleAppDiedLocked(ProcessRecord app, 4624 boolean restarting, boolean allowRestart) { 4625 int pid = app.pid; 4626 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4627 if (!restarting) { 4628 removeLruProcessLocked(app); 4629 if (pid > 0) { 4630 ProcessList.remove(pid); 4631 } 4632 } 4633 4634 if (mProfileProc == app) { 4635 clearProfilerLocked(); 4636 } 4637 4638 // Remove this application's activities from active lists. 4639 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4640 4641 app.activities.clear(); 4642 4643 if (app.instrumentationClass != null) { 4644 Slog.w(TAG, "Crash of app " + app.processName 4645 + " running instrumentation " + app.instrumentationClass); 4646 Bundle info = new Bundle(); 4647 info.putString("shortMsg", "Process crashed."); 4648 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4649 } 4650 4651 if (!restarting) { 4652 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4653 // If there was nothing to resume, and we are not already 4654 // restarting this process, but there is a visible activity that 4655 // is hosted by the process... then make sure all visible 4656 // activities are running, taking care of restarting this 4657 // process. 4658 if (hasVisibleActivities) { 4659 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4660 } 4661 } 4662 } 4663 } 4664 4665 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4666 IBinder threadBinder = thread.asBinder(); 4667 // Find the application record. 4668 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4669 ProcessRecord rec = mLruProcesses.get(i); 4670 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4671 return i; 4672 } 4673 } 4674 return -1; 4675 } 4676 4677 final ProcessRecord getRecordForAppLocked( 4678 IApplicationThread thread) { 4679 if (thread == null) { 4680 return null; 4681 } 4682 4683 int appIndex = getLRURecordIndexForAppLocked(thread); 4684 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4685 } 4686 4687 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4688 // If there are no longer any background processes running, 4689 // and the app that died was not running instrumentation, 4690 // then tell everyone we are now low on memory. 4691 boolean haveBg = false; 4692 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4693 ProcessRecord rec = mLruProcesses.get(i); 4694 if (rec.thread != null 4695 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4696 haveBg = true; 4697 break; 4698 } 4699 } 4700 4701 if (!haveBg) { 4702 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4703 if (doReport) { 4704 long now = SystemClock.uptimeMillis(); 4705 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4706 doReport = false; 4707 } else { 4708 mLastMemUsageReportTime = now; 4709 } 4710 } 4711 final ArrayList<ProcessMemInfo> memInfos 4712 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4713 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4714 long now = SystemClock.uptimeMillis(); 4715 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4716 ProcessRecord rec = mLruProcesses.get(i); 4717 if (rec == dyingProc || rec.thread == null) { 4718 continue; 4719 } 4720 if (doReport) { 4721 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4722 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4723 } 4724 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4725 // The low memory report is overriding any current 4726 // state for a GC request. Make sure to do 4727 // heavy/important/visible/foreground processes first. 4728 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4729 rec.lastRequestedGc = 0; 4730 } else { 4731 rec.lastRequestedGc = rec.lastLowMemory; 4732 } 4733 rec.reportLowMemory = true; 4734 rec.lastLowMemory = now; 4735 mProcessesToGc.remove(rec); 4736 addProcessToGcListLocked(rec); 4737 } 4738 } 4739 if (doReport) { 4740 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4741 mHandler.sendMessage(msg); 4742 } 4743 scheduleAppGcsLocked(); 4744 } 4745 } 4746 4747 final void appDiedLocked(ProcessRecord app) { 4748 appDiedLocked(app, app.pid, app.thread); 4749 } 4750 4751 final void appDiedLocked(ProcessRecord app, int pid, 4752 IApplicationThread thread) { 4753 4754 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4755 synchronized (stats) { 4756 stats.noteProcessDiedLocked(app.info.uid, pid); 4757 } 4758 4759 Process.killProcessGroup(app.info.uid, pid); 4760 4761 // Clean up already done if the process has been re-started. 4762 if (app.pid == pid && app.thread != null && 4763 app.thread.asBinder() == thread.asBinder()) { 4764 boolean doLowMem = app.instrumentationClass == null; 4765 boolean doOomAdj = doLowMem; 4766 if (!app.killedByAm) { 4767 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4768 + ") has died."); 4769 mAllowLowerMemLevel = true; 4770 } else { 4771 // Note that we always want to do oom adj to update our state with the 4772 // new number of procs. 4773 mAllowLowerMemLevel = false; 4774 doLowMem = false; 4775 } 4776 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4777 if (DEBUG_CLEANUP) Slog.v( 4778 TAG, "Dying app: " + app + ", pid: " + pid 4779 + ", thread: " + thread.asBinder()); 4780 handleAppDiedLocked(app, false, true); 4781 4782 if (doOomAdj) { 4783 updateOomAdjLocked(); 4784 } 4785 if (doLowMem) { 4786 doLowMemReportIfNeededLocked(app); 4787 } 4788 } else if (app.pid != pid) { 4789 // A new process has already been started. 4790 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4791 + ") has died and restarted (pid " + app.pid + ")."); 4792 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4793 } else if (DEBUG_PROCESSES) { 4794 Slog.d(TAG, "Received spurious death notification for thread " 4795 + thread.asBinder()); 4796 } 4797 } 4798 4799 /** 4800 * If a stack trace dump file is configured, dump process stack traces. 4801 * @param clearTraces causes the dump file to be erased prior to the new 4802 * traces being written, if true; when false, the new traces will be 4803 * appended to any existing file content. 4804 * @param firstPids of dalvik VM processes to dump stack traces for first 4805 * @param lastPids of dalvik VM processes to dump stack traces for last 4806 * @param nativeProcs optional list of native process names to dump stack crawls 4807 * @return file containing stack traces, or null if no dump file is configured 4808 */ 4809 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4810 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4811 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4812 if (tracesPath == null || tracesPath.length() == 0) { 4813 return null; 4814 } 4815 4816 File tracesFile = new File(tracesPath); 4817 try { 4818 File tracesDir = tracesFile.getParentFile(); 4819 if (!tracesDir.exists()) { 4820 tracesFile.mkdirs(); 4821 if (!SELinux.restorecon(tracesDir)) { 4822 return null; 4823 } 4824 } 4825 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4826 4827 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4828 tracesFile.createNewFile(); 4829 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4830 } catch (IOException e) { 4831 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4832 return null; 4833 } 4834 4835 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4836 return tracesFile; 4837 } 4838 4839 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4840 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4841 // Use a FileObserver to detect when traces finish writing. 4842 // The order of traces is considered important to maintain for legibility. 4843 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4844 @Override 4845 public synchronized void onEvent(int event, String path) { notify(); } 4846 }; 4847 4848 try { 4849 observer.startWatching(); 4850 4851 // First collect all of the stacks of the most important pids. 4852 if (firstPids != null) { 4853 try { 4854 int num = firstPids.size(); 4855 for (int i = 0; i < num; i++) { 4856 synchronized (observer) { 4857 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4858 observer.wait(200); // Wait for write-close, give up after 200msec 4859 } 4860 } 4861 } catch (InterruptedException e) { 4862 Log.wtf(TAG, e); 4863 } 4864 } 4865 4866 // Next collect the stacks of the native pids 4867 if (nativeProcs != null) { 4868 int[] pids = Process.getPidsForCommands(nativeProcs); 4869 if (pids != null) { 4870 for (int pid : pids) { 4871 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4872 } 4873 } 4874 } 4875 4876 // Lastly, measure CPU usage. 4877 if (processCpuTracker != null) { 4878 processCpuTracker.init(); 4879 System.gc(); 4880 processCpuTracker.update(); 4881 try { 4882 synchronized (processCpuTracker) { 4883 processCpuTracker.wait(500); // measure over 1/2 second. 4884 } 4885 } catch (InterruptedException e) { 4886 } 4887 processCpuTracker.update(); 4888 4889 // We'll take the stack crawls of just the top apps using CPU. 4890 final int N = processCpuTracker.countWorkingStats(); 4891 int numProcs = 0; 4892 for (int i=0; i<N && numProcs<5; i++) { 4893 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4894 if (lastPids.indexOfKey(stats.pid) >= 0) { 4895 numProcs++; 4896 try { 4897 synchronized (observer) { 4898 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4899 observer.wait(200); // Wait for write-close, give up after 200msec 4900 } 4901 } catch (InterruptedException e) { 4902 Log.wtf(TAG, e); 4903 } 4904 4905 } 4906 } 4907 } 4908 } finally { 4909 observer.stopWatching(); 4910 } 4911 } 4912 4913 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4914 if (true || IS_USER_BUILD) { 4915 return; 4916 } 4917 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4918 if (tracesPath == null || tracesPath.length() == 0) { 4919 return; 4920 } 4921 4922 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4923 StrictMode.allowThreadDiskWrites(); 4924 try { 4925 final File tracesFile = new File(tracesPath); 4926 final File tracesDir = tracesFile.getParentFile(); 4927 final File tracesTmp = new File(tracesDir, "__tmp__"); 4928 try { 4929 if (!tracesDir.exists()) { 4930 tracesFile.mkdirs(); 4931 if (!SELinux.restorecon(tracesDir.getPath())) { 4932 return; 4933 } 4934 } 4935 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4936 4937 if (tracesFile.exists()) { 4938 tracesTmp.delete(); 4939 tracesFile.renameTo(tracesTmp); 4940 } 4941 StringBuilder sb = new StringBuilder(); 4942 Time tobj = new Time(); 4943 tobj.set(System.currentTimeMillis()); 4944 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4945 sb.append(": "); 4946 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4947 sb.append(" since "); 4948 sb.append(msg); 4949 FileOutputStream fos = new FileOutputStream(tracesFile); 4950 fos.write(sb.toString().getBytes()); 4951 if (app == null) { 4952 fos.write("\n*** No application process!".getBytes()); 4953 } 4954 fos.close(); 4955 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4956 } catch (IOException e) { 4957 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4958 return; 4959 } 4960 4961 if (app != null) { 4962 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4963 firstPids.add(app.pid); 4964 dumpStackTraces(tracesPath, firstPids, null, null, null); 4965 } 4966 4967 File lastTracesFile = null; 4968 File curTracesFile = null; 4969 for (int i=9; i>=0; i--) { 4970 String name = String.format(Locale.US, "slow%02d.txt", i); 4971 curTracesFile = new File(tracesDir, name); 4972 if (curTracesFile.exists()) { 4973 if (lastTracesFile != null) { 4974 curTracesFile.renameTo(lastTracesFile); 4975 } else { 4976 curTracesFile.delete(); 4977 } 4978 } 4979 lastTracesFile = curTracesFile; 4980 } 4981 tracesFile.renameTo(curTracesFile); 4982 if (tracesTmp.exists()) { 4983 tracesTmp.renameTo(tracesFile); 4984 } 4985 } finally { 4986 StrictMode.setThreadPolicy(oldPolicy); 4987 } 4988 } 4989 4990 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4991 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4992 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4993 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4994 4995 if (mController != null) { 4996 try { 4997 // 0 == continue, -1 = kill process immediately 4998 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4999 if (res < 0 && app.pid != MY_PID) { 5000 app.kill("anr", true); 5001 } 5002 } catch (RemoteException e) { 5003 mController = null; 5004 Watchdog.getInstance().setActivityController(null); 5005 } 5006 } 5007 5008 long anrTime = SystemClock.uptimeMillis(); 5009 if (MONITOR_CPU_USAGE) { 5010 updateCpuStatsNow(); 5011 } 5012 5013 synchronized (this) { 5014 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5015 if (mShuttingDown) { 5016 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5017 return; 5018 } else if (app.notResponding) { 5019 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5020 return; 5021 } else if (app.crashing) { 5022 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5023 return; 5024 } 5025 5026 // In case we come through here for the same app before completing 5027 // this one, mark as anring now so we will bail out. 5028 app.notResponding = true; 5029 5030 // Log the ANR to the event log. 5031 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5032 app.processName, app.info.flags, annotation); 5033 5034 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5035 firstPids.add(app.pid); 5036 5037 int parentPid = app.pid; 5038 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5039 if (parentPid != app.pid) firstPids.add(parentPid); 5040 5041 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5042 5043 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5044 ProcessRecord r = mLruProcesses.get(i); 5045 if (r != null && r.thread != null) { 5046 int pid = r.pid; 5047 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5048 if (r.persistent) { 5049 firstPids.add(pid); 5050 } else { 5051 lastPids.put(pid, Boolean.TRUE); 5052 } 5053 } 5054 } 5055 } 5056 } 5057 5058 // Log the ANR to the main log. 5059 StringBuilder info = new StringBuilder(); 5060 info.setLength(0); 5061 info.append("ANR in ").append(app.processName); 5062 if (activity != null && activity.shortComponentName != null) { 5063 info.append(" (").append(activity.shortComponentName).append(")"); 5064 } 5065 info.append("\n"); 5066 info.append("PID: ").append(app.pid).append("\n"); 5067 if (annotation != null) { 5068 info.append("Reason: ").append(annotation).append("\n"); 5069 } 5070 if (parent != null && parent != activity) { 5071 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5072 } 5073 5074 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5075 5076 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5077 NATIVE_STACKS_OF_INTEREST); 5078 5079 String cpuInfo = null; 5080 if (MONITOR_CPU_USAGE) { 5081 updateCpuStatsNow(); 5082 synchronized (mProcessCpuTracker) { 5083 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5084 } 5085 info.append(processCpuTracker.printCurrentLoad()); 5086 info.append(cpuInfo); 5087 } 5088 5089 info.append(processCpuTracker.printCurrentState(anrTime)); 5090 5091 Slog.e(TAG, info.toString()); 5092 if (tracesFile == null) { 5093 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5094 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5095 } 5096 5097 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5098 cpuInfo, tracesFile, null); 5099 5100 if (mController != null) { 5101 try { 5102 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5103 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5104 if (res != 0) { 5105 if (res < 0 && app.pid != MY_PID) { 5106 app.kill("anr", true); 5107 } else { 5108 synchronized (this) { 5109 mServices.scheduleServiceTimeoutLocked(app); 5110 } 5111 } 5112 return; 5113 } 5114 } catch (RemoteException e) { 5115 mController = null; 5116 Watchdog.getInstance().setActivityController(null); 5117 } 5118 } 5119 5120 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5121 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5122 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5123 5124 synchronized (this) { 5125 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5126 app.kill("bg anr", true); 5127 return; 5128 } 5129 5130 // Set the app's notResponding state, and look up the errorReportReceiver 5131 makeAppNotRespondingLocked(app, 5132 activity != null ? activity.shortComponentName : null, 5133 annotation != null ? "ANR " + annotation : "ANR", 5134 info.toString()); 5135 5136 // Bring up the infamous App Not Responding dialog 5137 Message msg = Message.obtain(); 5138 HashMap<String, Object> map = new HashMap<String, Object>(); 5139 msg.what = SHOW_NOT_RESPONDING_MSG; 5140 msg.obj = map; 5141 msg.arg1 = aboveSystem ? 1 : 0; 5142 map.put("app", app); 5143 if (activity != null) { 5144 map.put("activity", activity); 5145 } 5146 5147 mHandler.sendMessage(msg); 5148 } 5149 } 5150 5151 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5152 if (!mLaunchWarningShown) { 5153 mLaunchWarningShown = true; 5154 mHandler.post(new Runnable() { 5155 @Override 5156 public void run() { 5157 synchronized (ActivityManagerService.this) { 5158 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5159 d.show(); 5160 mHandler.postDelayed(new Runnable() { 5161 @Override 5162 public void run() { 5163 synchronized (ActivityManagerService.this) { 5164 d.dismiss(); 5165 mLaunchWarningShown = false; 5166 } 5167 } 5168 }, 4000); 5169 } 5170 } 5171 }); 5172 } 5173 } 5174 5175 @Override 5176 public boolean clearApplicationUserData(final String packageName, 5177 final IPackageDataObserver observer, int userId) { 5178 enforceNotIsolatedCaller("clearApplicationUserData"); 5179 int uid = Binder.getCallingUid(); 5180 int pid = Binder.getCallingPid(); 5181 userId = handleIncomingUser(pid, uid, 5182 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5183 long callingId = Binder.clearCallingIdentity(); 5184 try { 5185 IPackageManager pm = AppGlobals.getPackageManager(); 5186 int pkgUid = -1; 5187 synchronized(this) { 5188 try { 5189 pkgUid = pm.getPackageUid(packageName, userId); 5190 } catch (RemoteException e) { 5191 } 5192 if (pkgUid == -1) { 5193 Slog.w(TAG, "Invalid packageName: " + packageName); 5194 if (observer != null) { 5195 try { 5196 observer.onRemoveCompleted(packageName, false); 5197 } catch (RemoteException e) { 5198 Slog.i(TAG, "Observer no longer exists."); 5199 } 5200 } 5201 return false; 5202 } 5203 if (uid == pkgUid || checkComponentPermission( 5204 android.Manifest.permission.CLEAR_APP_USER_DATA, 5205 pid, uid, -1, true) 5206 == PackageManager.PERMISSION_GRANTED) { 5207 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5208 } else { 5209 throw new SecurityException("PID " + pid + " does not have permission " 5210 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5211 + " of package " + packageName); 5212 } 5213 5214 // Remove all tasks match the cleared application package and user 5215 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5216 final TaskRecord tr = mRecentTasks.get(i); 5217 final String taskPackageName = 5218 tr.getBaseIntent().getComponent().getPackageName(); 5219 if (tr.userId != userId) continue; 5220 if (!taskPackageName.equals(packageName)) continue; 5221 removeTaskByIdLocked(tr.taskId, 0); 5222 } 5223 } 5224 5225 try { 5226 // Clear application user data 5227 pm.clearApplicationUserData(packageName, observer, userId); 5228 5229 synchronized(this) { 5230 // Remove all permissions granted from/to this package 5231 removeUriPermissionsForPackageLocked(packageName, userId, true); 5232 } 5233 5234 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5235 Uri.fromParts("package", packageName, null)); 5236 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5237 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5238 null, null, 0, null, null, null, false, false, userId); 5239 } catch (RemoteException e) { 5240 } 5241 } finally { 5242 Binder.restoreCallingIdentity(callingId); 5243 } 5244 return true; 5245 } 5246 5247 @Override 5248 public void killBackgroundProcesses(final String packageName, int userId) { 5249 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5250 != PackageManager.PERMISSION_GRANTED && 5251 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5252 != PackageManager.PERMISSION_GRANTED) { 5253 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5254 + Binder.getCallingPid() 5255 + ", uid=" + Binder.getCallingUid() 5256 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5257 Slog.w(TAG, msg); 5258 throw new SecurityException(msg); 5259 } 5260 5261 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5262 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5263 long callingId = Binder.clearCallingIdentity(); 5264 try { 5265 IPackageManager pm = AppGlobals.getPackageManager(); 5266 synchronized(this) { 5267 int appId = -1; 5268 try { 5269 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5270 } catch (RemoteException e) { 5271 } 5272 if (appId == -1) { 5273 Slog.w(TAG, "Invalid packageName: " + packageName); 5274 return; 5275 } 5276 killPackageProcessesLocked(packageName, appId, userId, 5277 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5278 } 5279 } finally { 5280 Binder.restoreCallingIdentity(callingId); 5281 } 5282 } 5283 5284 @Override 5285 public void killAllBackgroundProcesses() { 5286 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5287 != PackageManager.PERMISSION_GRANTED) { 5288 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5289 + Binder.getCallingPid() 5290 + ", uid=" + Binder.getCallingUid() 5291 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5292 Slog.w(TAG, msg); 5293 throw new SecurityException(msg); 5294 } 5295 5296 long callingId = Binder.clearCallingIdentity(); 5297 try { 5298 synchronized(this) { 5299 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5300 final int NP = mProcessNames.getMap().size(); 5301 for (int ip=0; ip<NP; ip++) { 5302 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5303 final int NA = apps.size(); 5304 for (int ia=0; ia<NA; ia++) { 5305 ProcessRecord app = apps.valueAt(ia); 5306 if (app.persistent) { 5307 // we don't kill persistent processes 5308 continue; 5309 } 5310 if (app.removed) { 5311 procs.add(app); 5312 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5313 app.removed = true; 5314 procs.add(app); 5315 } 5316 } 5317 } 5318 5319 int N = procs.size(); 5320 for (int i=0; i<N; i++) { 5321 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5322 } 5323 mAllowLowerMemLevel = true; 5324 updateOomAdjLocked(); 5325 doLowMemReportIfNeededLocked(null); 5326 } 5327 } finally { 5328 Binder.restoreCallingIdentity(callingId); 5329 } 5330 } 5331 5332 @Override 5333 public void forceStopPackage(final String packageName, int userId) { 5334 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5335 != PackageManager.PERMISSION_GRANTED) { 5336 String msg = "Permission Denial: forceStopPackage() from pid=" 5337 + Binder.getCallingPid() 5338 + ", uid=" + Binder.getCallingUid() 5339 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5340 Slog.w(TAG, msg); 5341 throw new SecurityException(msg); 5342 } 5343 final int callingPid = Binder.getCallingPid(); 5344 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5345 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5346 long callingId = Binder.clearCallingIdentity(); 5347 try { 5348 IPackageManager pm = AppGlobals.getPackageManager(); 5349 synchronized(this) { 5350 int[] users = userId == UserHandle.USER_ALL 5351 ? getUsersLocked() : new int[] { userId }; 5352 for (int user : users) { 5353 int pkgUid = -1; 5354 try { 5355 pkgUid = pm.getPackageUid(packageName, user); 5356 } catch (RemoteException e) { 5357 } 5358 if (pkgUid == -1) { 5359 Slog.w(TAG, "Invalid packageName: " + packageName); 5360 continue; 5361 } 5362 try { 5363 pm.setPackageStoppedState(packageName, true, user); 5364 } catch (RemoteException e) { 5365 } catch (IllegalArgumentException e) { 5366 Slog.w(TAG, "Failed trying to unstop package " 5367 + packageName + ": " + e); 5368 } 5369 if (isUserRunningLocked(user, false)) { 5370 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5371 } 5372 } 5373 } 5374 } finally { 5375 Binder.restoreCallingIdentity(callingId); 5376 } 5377 } 5378 5379 @Override 5380 public void addPackageDependency(String packageName) { 5381 synchronized (this) { 5382 int callingPid = Binder.getCallingPid(); 5383 if (callingPid == Process.myPid()) { 5384 // Yeah, um, no. 5385 Slog.w(TAG, "Can't addPackageDependency on system process"); 5386 return; 5387 } 5388 ProcessRecord proc; 5389 synchronized (mPidsSelfLocked) { 5390 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5391 } 5392 if (proc != null) { 5393 if (proc.pkgDeps == null) { 5394 proc.pkgDeps = new ArraySet<String>(1); 5395 } 5396 proc.pkgDeps.add(packageName); 5397 } 5398 } 5399 } 5400 5401 /* 5402 * The pkg name and app id have to be specified. 5403 */ 5404 @Override 5405 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5406 if (pkg == null) { 5407 return; 5408 } 5409 // Make sure the uid is valid. 5410 if (appid < 0) { 5411 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5412 return; 5413 } 5414 int callerUid = Binder.getCallingUid(); 5415 // Only the system server can kill an application 5416 if (callerUid == Process.SYSTEM_UID) { 5417 // Post an aysnc message to kill the application 5418 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5419 msg.arg1 = appid; 5420 msg.arg2 = 0; 5421 Bundle bundle = new Bundle(); 5422 bundle.putString("pkg", pkg); 5423 bundle.putString("reason", reason); 5424 msg.obj = bundle; 5425 mHandler.sendMessage(msg); 5426 } else { 5427 throw new SecurityException(callerUid + " cannot kill pkg: " + 5428 pkg); 5429 } 5430 } 5431 5432 @Override 5433 public void closeSystemDialogs(String reason) { 5434 enforceNotIsolatedCaller("closeSystemDialogs"); 5435 5436 final int pid = Binder.getCallingPid(); 5437 final int uid = Binder.getCallingUid(); 5438 final long origId = Binder.clearCallingIdentity(); 5439 try { 5440 synchronized (this) { 5441 // Only allow this from foreground processes, so that background 5442 // applications can't abuse it to prevent system UI from being shown. 5443 if (uid >= Process.FIRST_APPLICATION_UID) { 5444 ProcessRecord proc; 5445 synchronized (mPidsSelfLocked) { 5446 proc = mPidsSelfLocked.get(pid); 5447 } 5448 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5449 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5450 + " from background process " + proc); 5451 return; 5452 } 5453 } 5454 closeSystemDialogsLocked(reason); 5455 } 5456 } finally { 5457 Binder.restoreCallingIdentity(origId); 5458 } 5459 } 5460 5461 void closeSystemDialogsLocked(String reason) { 5462 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5463 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5464 | Intent.FLAG_RECEIVER_FOREGROUND); 5465 if (reason != null) { 5466 intent.putExtra("reason", reason); 5467 } 5468 mWindowManager.closeSystemDialogs(reason); 5469 5470 mStackSupervisor.closeSystemDialogsLocked(); 5471 5472 broadcastIntentLocked(null, null, intent, null, 5473 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5474 Process.SYSTEM_UID, UserHandle.USER_ALL); 5475 } 5476 5477 @Override 5478 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5479 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5480 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5481 for (int i=pids.length-1; i>=0; i--) { 5482 ProcessRecord proc; 5483 int oomAdj; 5484 synchronized (this) { 5485 synchronized (mPidsSelfLocked) { 5486 proc = mPidsSelfLocked.get(pids[i]); 5487 oomAdj = proc != null ? proc.setAdj : 0; 5488 } 5489 } 5490 infos[i] = new Debug.MemoryInfo(); 5491 Debug.getMemoryInfo(pids[i], infos[i]); 5492 if (proc != null) { 5493 synchronized (this) { 5494 if (proc.thread != null && proc.setAdj == oomAdj) { 5495 // Record this for posterity if the process has been stable. 5496 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5497 infos[i].getTotalUss(), false, proc.pkgList); 5498 } 5499 } 5500 } 5501 } 5502 return infos; 5503 } 5504 5505 @Override 5506 public long[] getProcessPss(int[] pids) { 5507 enforceNotIsolatedCaller("getProcessPss"); 5508 long[] pss = new long[pids.length]; 5509 for (int i=pids.length-1; i>=0; i--) { 5510 ProcessRecord proc; 5511 int oomAdj; 5512 synchronized (this) { 5513 synchronized (mPidsSelfLocked) { 5514 proc = mPidsSelfLocked.get(pids[i]); 5515 oomAdj = proc != null ? proc.setAdj : 0; 5516 } 5517 } 5518 long[] tmpUss = new long[1]; 5519 pss[i] = Debug.getPss(pids[i], tmpUss); 5520 if (proc != null) { 5521 synchronized (this) { 5522 if (proc.thread != null && proc.setAdj == oomAdj) { 5523 // Record this for posterity if the process has been stable. 5524 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5525 } 5526 } 5527 } 5528 } 5529 return pss; 5530 } 5531 5532 @Override 5533 public void killApplicationProcess(String processName, int uid) { 5534 if (processName == null) { 5535 return; 5536 } 5537 5538 int callerUid = Binder.getCallingUid(); 5539 // Only the system server can kill an application 5540 if (callerUid == Process.SYSTEM_UID) { 5541 synchronized (this) { 5542 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5543 if (app != null && app.thread != null) { 5544 try { 5545 app.thread.scheduleSuicide(); 5546 } catch (RemoteException e) { 5547 // If the other end already died, then our work here is done. 5548 } 5549 } else { 5550 Slog.w(TAG, "Process/uid not found attempting kill of " 5551 + processName + " / " + uid); 5552 } 5553 } 5554 } else { 5555 throw new SecurityException(callerUid + " cannot kill app process: " + 5556 processName); 5557 } 5558 } 5559 5560 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5561 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5562 false, true, false, false, UserHandle.getUserId(uid), reason); 5563 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5564 Uri.fromParts("package", packageName, null)); 5565 if (!mProcessesReady) { 5566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5567 | Intent.FLAG_RECEIVER_FOREGROUND); 5568 } 5569 intent.putExtra(Intent.EXTRA_UID, uid); 5570 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5571 broadcastIntentLocked(null, null, intent, 5572 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5573 false, false, 5574 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5575 } 5576 5577 private void forceStopUserLocked(int userId, String reason) { 5578 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5579 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5580 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5581 | Intent.FLAG_RECEIVER_FOREGROUND); 5582 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5583 broadcastIntentLocked(null, null, intent, 5584 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5585 false, false, 5586 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5587 } 5588 5589 private final boolean killPackageProcessesLocked(String packageName, int appId, 5590 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5591 boolean doit, boolean evenPersistent, String reason) { 5592 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5593 5594 // Remove all processes this package may have touched: all with the 5595 // same UID (except for the system or root user), and all whose name 5596 // matches the package name. 5597 final int NP = mProcessNames.getMap().size(); 5598 for (int ip=0; ip<NP; ip++) { 5599 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5600 final int NA = apps.size(); 5601 for (int ia=0; ia<NA; ia++) { 5602 ProcessRecord app = apps.valueAt(ia); 5603 if (app.persistent && !evenPersistent) { 5604 // we don't kill persistent processes 5605 continue; 5606 } 5607 if (app.removed) { 5608 if (doit) { 5609 procs.add(app); 5610 } 5611 continue; 5612 } 5613 5614 // Skip process if it doesn't meet our oom adj requirement. 5615 if (app.setAdj < minOomAdj) { 5616 continue; 5617 } 5618 5619 // If no package is specified, we call all processes under the 5620 // give user id. 5621 if (packageName == null) { 5622 if (app.userId != userId) { 5623 continue; 5624 } 5625 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5626 continue; 5627 } 5628 // Package has been specified, we want to hit all processes 5629 // that match it. We need to qualify this by the processes 5630 // that are running under the specified app and user ID. 5631 } else { 5632 final boolean isDep = app.pkgDeps != null 5633 && app.pkgDeps.contains(packageName); 5634 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5635 continue; 5636 } 5637 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5638 continue; 5639 } 5640 if (!app.pkgList.containsKey(packageName) && !isDep) { 5641 continue; 5642 } 5643 } 5644 5645 // Process has passed all conditions, kill it! 5646 if (!doit) { 5647 return true; 5648 } 5649 app.removed = true; 5650 procs.add(app); 5651 } 5652 } 5653 5654 int N = procs.size(); 5655 for (int i=0; i<N; i++) { 5656 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5657 } 5658 updateOomAdjLocked(); 5659 return N > 0; 5660 } 5661 5662 private final boolean forceStopPackageLocked(String name, int appId, 5663 boolean callerWillRestart, boolean purgeCache, boolean doit, 5664 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5665 int i; 5666 int N; 5667 5668 if (userId == UserHandle.USER_ALL && name == null) { 5669 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5670 } 5671 5672 if (appId < 0 && name != null) { 5673 try { 5674 appId = UserHandle.getAppId( 5675 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5676 } catch (RemoteException e) { 5677 } 5678 } 5679 5680 if (doit) { 5681 if (name != null) { 5682 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5683 + " user=" + userId + ": " + reason); 5684 } else { 5685 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5686 } 5687 5688 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5689 for (int ip=pmap.size()-1; ip>=0; ip--) { 5690 SparseArray<Long> ba = pmap.valueAt(ip); 5691 for (i=ba.size()-1; i>=0; i--) { 5692 boolean remove = false; 5693 final int entUid = ba.keyAt(i); 5694 if (name != null) { 5695 if (userId == UserHandle.USER_ALL) { 5696 if (UserHandle.getAppId(entUid) == appId) { 5697 remove = true; 5698 } 5699 } else { 5700 if (entUid == UserHandle.getUid(userId, appId)) { 5701 remove = true; 5702 } 5703 } 5704 } else if (UserHandle.getUserId(entUid) == userId) { 5705 remove = true; 5706 } 5707 if (remove) { 5708 ba.removeAt(i); 5709 } 5710 } 5711 if (ba.size() == 0) { 5712 pmap.removeAt(ip); 5713 } 5714 } 5715 } 5716 5717 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5718 -100, callerWillRestart, true, doit, evenPersistent, 5719 name == null ? ("stop user " + userId) : ("stop " + name)); 5720 5721 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5722 if (!doit) { 5723 return true; 5724 } 5725 didSomething = true; 5726 } 5727 5728 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5729 if (!doit) { 5730 return true; 5731 } 5732 didSomething = true; 5733 } 5734 5735 if (name == null) { 5736 // Remove all sticky broadcasts from this user. 5737 mStickyBroadcasts.remove(userId); 5738 } 5739 5740 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5741 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5742 userId, providers)) { 5743 if (!doit) { 5744 return true; 5745 } 5746 didSomething = true; 5747 } 5748 N = providers.size(); 5749 for (i=0; i<N; i++) { 5750 removeDyingProviderLocked(null, providers.get(i), true); 5751 } 5752 5753 // Remove transient permissions granted from/to this package/user 5754 removeUriPermissionsForPackageLocked(name, userId, false); 5755 5756 if (name == null || uninstalling) { 5757 // Remove pending intents. For now we only do this when force 5758 // stopping users, because we have some problems when doing this 5759 // for packages -- app widgets are not currently cleaned up for 5760 // such packages, so they can be left with bad pending intents. 5761 if (mIntentSenderRecords.size() > 0) { 5762 Iterator<WeakReference<PendingIntentRecord>> it 5763 = mIntentSenderRecords.values().iterator(); 5764 while (it.hasNext()) { 5765 WeakReference<PendingIntentRecord> wpir = it.next(); 5766 if (wpir == null) { 5767 it.remove(); 5768 continue; 5769 } 5770 PendingIntentRecord pir = wpir.get(); 5771 if (pir == null) { 5772 it.remove(); 5773 continue; 5774 } 5775 if (name == null) { 5776 // Stopping user, remove all objects for the user. 5777 if (pir.key.userId != userId) { 5778 // Not the same user, skip it. 5779 continue; 5780 } 5781 } else { 5782 if (UserHandle.getAppId(pir.uid) != appId) { 5783 // Different app id, skip it. 5784 continue; 5785 } 5786 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5787 // Different user, skip it. 5788 continue; 5789 } 5790 if (!pir.key.packageName.equals(name)) { 5791 // Different package, skip it. 5792 continue; 5793 } 5794 } 5795 if (!doit) { 5796 return true; 5797 } 5798 didSomething = true; 5799 it.remove(); 5800 pir.canceled = true; 5801 if (pir.key.activity != null) { 5802 pir.key.activity.pendingResults.remove(pir.ref); 5803 } 5804 } 5805 } 5806 } 5807 5808 if (doit) { 5809 if (purgeCache && name != null) { 5810 AttributeCache ac = AttributeCache.instance(); 5811 if (ac != null) { 5812 ac.removePackage(name); 5813 } 5814 } 5815 if (mBooted) { 5816 mStackSupervisor.resumeTopActivitiesLocked(); 5817 mStackSupervisor.scheduleIdleLocked(); 5818 } 5819 } 5820 5821 return didSomething; 5822 } 5823 5824 private final boolean removeProcessLocked(ProcessRecord app, 5825 boolean callerWillRestart, boolean allowRestart, String reason) { 5826 final String name = app.processName; 5827 final int uid = app.uid; 5828 if (DEBUG_PROCESSES) Slog.d( 5829 TAG, "Force removing proc " + app.toShortString() + " (" + name 5830 + "/" + uid + ")"); 5831 5832 mProcessNames.remove(name, uid); 5833 mIsolatedProcesses.remove(app.uid); 5834 if (mHeavyWeightProcess == app) { 5835 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5836 mHeavyWeightProcess.userId, 0)); 5837 mHeavyWeightProcess = null; 5838 } 5839 boolean needRestart = false; 5840 if (app.pid > 0 && app.pid != MY_PID) { 5841 int pid = app.pid; 5842 synchronized (mPidsSelfLocked) { 5843 mPidsSelfLocked.remove(pid); 5844 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5845 } 5846 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5847 if (app.isolated) { 5848 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5849 } 5850 app.kill(reason, true); 5851 handleAppDiedLocked(app, true, allowRestart); 5852 removeLruProcessLocked(app); 5853 5854 if (app.persistent && !app.isolated) { 5855 if (!callerWillRestart) { 5856 addAppLocked(app.info, false, null /* ABI override */); 5857 } else { 5858 needRestart = true; 5859 } 5860 } 5861 } else { 5862 mRemovedProcesses.add(app); 5863 } 5864 5865 return needRestart; 5866 } 5867 5868 private final void processStartTimedOutLocked(ProcessRecord app) { 5869 final int pid = app.pid; 5870 boolean gone = false; 5871 synchronized (mPidsSelfLocked) { 5872 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5873 if (knownApp != null && knownApp.thread == null) { 5874 mPidsSelfLocked.remove(pid); 5875 gone = true; 5876 } 5877 } 5878 5879 if (gone) { 5880 Slog.w(TAG, "Process " + app + " failed to attach"); 5881 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5882 pid, app.uid, app.processName); 5883 mProcessNames.remove(app.processName, app.uid); 5884 mIsolatedProcesses.remove(app.uid); 5885 if (mHeavyWeightProcess == app) { 5886 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5887 mHeavyWeightProcess.userId, 0)); 5888 mHeavyWeightProcess = null; 5889 } 5890 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5891 if (app.isolated) { 5892 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5893 } 5894 // Take care of any launching providers waiting for this process. 5895 checkAppInLaunchingProvidersLocked(app, true); 5896 // Take care of any services that are waiting for the process. 5897 mServices.processStartTimedOutLocked(app); 5898 app.kill("start timeout", true); 5899 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5900 Slog.w(TAG, "Unattached app died before backup, skipping"); 5901 try { 5902 IBackupManager bm = IBackupManager.Stub.asInterface( 5903 ServiceManager.getService(Context.BACKUP_SERVICE)); 5904 bm.agentDisconnected(app.info.packageName); 5905 } catch (RemoteException e) { 5906 // Can't happen; the backup manager is local 5907 } 5908 } 5909 if (isPendingBroadcastProcessLocked(pid)) { 5910 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5911 skipPendingBroadcastLocked(pid); 5912 } 5913 } else { 5914 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5915 } 5916 } 5917 5918 private final boolean attachApplicationLocked(IApplicationThread thread, 5919 int pid) { 5920 5921 // Find the application record that is being attached... either via 5922 // the pid if we are running in multiple processes, or just pull the 5923 // next app record if we are emulating process with anonymous threads. 5924 ProcessRecord app; 5925 if (pid != MY_PID && pid >= 0) { 5926 synchronized (mPidsSelfLocked) { 5927 app = mPidsSelfLocked.get(pid); 5928 } 5929 } else { 5930 app = null; 5931 } 5932 5933 if (app == null) { 5934 Slog.w(TAG, "No pending application record for pid " + pid 5935 + " (IApplicationThread " + thread + "); dropping process"); 5936 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5937 if (pid > 0 && pid != MY_PID) { 5938 Process.killProcessQuiet(pid); 5939 //TODO: Process.killProcessGroup(app.info.uid, pid); 5940 } else { 5941 try { 5942 thread.scheduleExit(); 5943 } catch (Exception e) { 5944 // Ignore exceptions. 5945 } 5946 } 5947 return false; 5948 } 5949 5950 // If this application record is still attached to a previous 5951 // process, clean it up now. 5952 if (app.thread != null) { 5953 handleAppDiedLocked(app, true, true); 5954 } 5955 5956 // Tell the process all about itself. 5957 5958 if (localLOGV) Slog.v( 5959 TAG, "Binding process pid " + pid + " to record " + app); 5960 5961 final String processName = app.processName; 5962 try { 5963 AppDeathRecipient adr = new AppDeathRecipient( 5964 app, pid, thread); 5965 thread.asBinder().linkToDeath(adr, 0); 5966 app.deathRecipient = adr; 5967 } catch (RemoteException e) { 5968 app.resetPackageList(mProcessStats); 5969 startProcessLocked(app, "link fail", processName); 5970 return false; 5971 } 5972 5973 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5974 5975 app.makeActive(thread, mProcessStats); 5976 app.curAdj = app.setAdj = -100; 5977 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5978 app.forcingToForeground = null; 5979 updateProcessForegroundLocked(app, false, false); 5980 app.hasShownUi = false; 5981 app.debugging = false; 5982 app.cached = false; 5983 5984 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5985 5986 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5987 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5988 5989 if (!normalMode) { 5990 Slog.i(TAG, "Launching preboot mode app: " + app); 5991 } 5992 5993 if (localLOGV) Slog.v( 5994 TAG, "New app record " + app 5995 + " thread=" + thread.asBinder() + " pid=" + pid); 5996 try { 5997 int testMode = IApplicationThread.DEBUG_OFF; 5998 if (mDebugApp != null && mDebugApp.equals(processName)) { 5999 testMode = mWaitForDebugger 6000 ? IApplicationThread.DEBUG_WAIT 6001 : IApplicationThread.DEBUG_ON; 6002 app.debugging = true; 6003 if (mDebugTransient) { 6004 mDebugApp = mOrigDebugApp; 6005 mWaitForDebugger = mOrigWaitForDebugger; 6006 } 6007 } 6008 String profileFile = app.instrumentationProfileFile; 6009 ParcelFileDescriptor profileFd = null; 6010 int samplingInterval = 0; 6011 boolean profileAutoStop = false; 6012 if (mProfileApp != null && mProfileApp.equals(processName)) { 6013 mProfileProc = app; 6014 profileFile = mProfileFile; 6015 profileFd = mProfileFd; 6016 samplingInterval = mSamplingInterval; 6017 profileAutoStop = mAutoStopProfiler; 6018 } 6019 boolean enableOpenGlTrace = false; 6020 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6021 enableOpenGlTrace = true; 6022 mOpenGlTraceApp = null; 6023 } 6024 6025 // If the app is being launched for restore or full backup, set it up specially 6026 boolean isRestrictedBackupMode = false; 6027 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6028 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6029 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6030 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6031 } 6032 6033 ensurePackageDexOpt(app.instrumentationInfo != null 6034 ? app.instrumentationInfo.packageName 6035 : app.info.packageName); 6036 if (app.instrumentationClass != null) { 6037 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6038 } 6039 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6040 + processName + " with config " + mConfiguration); 6041 ApplicationInfo appInfo = app.instrumentationInfo != null 6042 ? app.instrumentationInfo : app.info; 6043 app.compat = compatibilityInfoForPackageLocked(appInfo); 6044 if (profileFd != null) { 6045 profileFd = profileFd.dup(); 6046 } 6047 ProfilerInfo profilerInfo = profileFile == null ? null 6048 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6049 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6050 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6051 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6052 isRestrictedBackupMode || !normalMode, app.persistent, 6053 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6054 mCoreSettingsObserver.getCoreSettingsLocked()); 6055 updateLruProcessLocked(app, false, null); 6056 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6057 } catch (Exception e) { 6058 // todo: Yikes! What should we do? For now we will try to 6059 // start another process, but that could easily get us in 6060 // an infinite loop of restarting processes... 6061 Slog.w(TAG, "Exception thrown during bind!", e); 6062 6063 app.resetPackageList(mProcessStats); 6064 app.unlinkDeathRecipient(); 6065 startProcessLocked(app, "bind fail", processName); 6066 return false; 6067 } 6068 6069 // Remove this record from the list of starting applications. 6070 mPersistentStartingProcesses.remove(app); 6071 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6072 "Attach application locked removing on hold: " + app); 6073 mProcessesOnHold.remove(app); 6074 6075 boolean badApp = false; 6076 boolean didSomething = false; 6077 6078 // See if the top visible activity is waiting to run in this process... 6079 if (normalMode) { 6080 try { 6081 if (mStackSupervisor.attachApplicationLocked(app)) { 6082 didSomething = true; 6083 } 6084 } catch (Exception e) { 6085 badApp = true; 6086 } 6087 } 6088 6089 // Find any services that should be running in this process... 6090 if (!badApp) { 6091 try { 6092 didSomething |= mServices.attachApplicationLocked(app, processName); 6093 } catch (Exception e) { 6094 badApp = true; 6095 } 6096 } 6097 6098 // Check if a next-broadcast receiver is in this process... 6099 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6100 try { 6101 didSomething |= sendPendingBroadcastsLocked(app); 6102 } catch (Exception e) { 6103 // If the app died trying to launch the receiver we declare it 'bad' 6104 badApp = true; 6105 } 6106 } 6107 6108 // Check whether the next backup agent is in this process... 6109 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6110 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6111 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6112 try { 6113 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6114 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6115 mBackupTarget.backupMode); 6116 } catch (Exception e) { 6117 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6118 e.printStackTrace(); 6119 } 6120 } 6121 6122 if (badApp) { 6123 // todo: Also need to kill application to deal with all 6124 // kinds of exceptions. 6125 handleAppDiedLocked(app, false, true); 6126 return false; 6127 } 6128 6129 if (!didSomething) { 6130 updateOomAdjLocked(); 6131 } 6132 6133 return true; 6134 } 6135 6136 @Override 6137 public final void attachApplication(IApplicationThread thread) { 6138 synchronized (this) { 6139 int callingPid = Binder.getCallingPid(); 6140 final long origId = Binder.clearCallingIdentity(); 6141 attachApplicationLocked(thread, callingPid); 6142 Binder.restoreCallingIdentity(origId); 6143 } 6144 } 6145 6146 @Override 6147 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6148 final long origId = Binder.clearCallingIdentity(); 6149 synchronized (this) { 6150 ActivityStack stack = ActivityRecord.getStackLocked(token); 6151 if (stack != null) { 6152 ActivityRecord r = 6153 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6154 if (stopProfiling) { 6155 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6156 try { 6157 mProfileFd.close(); 6158 } catch (IOException e) { 6159 } 6160 clearProfilerLocked(); 6161 } 6162 } 6163 } 6164 } 6165 Binder.restoreCallingIdentity(origId); 6166 } 6167 6168 void postEnableScreenAfterBootLocked() { 6169 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6170 } 6171 6172 void enableScreenAfterBoot() { 6173 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6174 SystemClock.uptimeMillis()); 6175 mWindowManager.enableScreenAfterBoot(); 6176 6177 synchronized (this) { 6178 updateEventDispatchingLocked(); 6179 } 6180 } 6181 6182 @Override 6183 public void showBootMessage(final CharSequence msg, final boolean always) { 6184 enforceNotIsolatedCaller("showBootMessage"); 6185 mWindowManager.showBootMessage(msg, always); 6186 } 6187 6188 @Override 6189 public void keyguardWaitingForActivityDrawn() { 6190 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6191 final long token = Binder.clearCallingIdentity(); 6192 try { 6193 synchronized (this) { 6194 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6195 mWindowManager.keyguardWaitingForActivityDrawn(); 6196 } 6197 } finally { 6198 Binder.restoreCallingIdentity(token); 6199 } 6200 } 6201 6202 final void finishBooting() { 6203 synchronized (this) { 6204 if (!mBootAnimationComplete) { 6205 mCallFinishBooting = true; 6206 return; 6207 } 6208 mCallFinishBooting = false; 6209 } 6210 6211 // Register receivers to handle package update events 6212 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6213 6214 // Let system services know. 6215 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6216 6217 synchronized (this) { 6218 // Ensure that any processes we had put on hold are now started 6219 // up. 6220 final int NP = mProcessesOnHold.size(); 6221 if (NP > 0) { 6222 ArrayList<ProcessRecord> procs = 6223 new ArrayList<ProcessRecord>(mProcessesOnHold); 6224 for (int ip=0; ip<NP; ip++) { 6225 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6226 + procs.get(ip)); 6227 startProcessLocked(procs.get(ip), "on-hold", null); 6228 } 6229 } 6230 6231 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6232 // Start looking for apps that are abusing wake locks. 6233 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6234 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6235 // Tell anyone interested that we are done booting! 6236 SystemProperties.set("sys.boot_completed", "1"); 6237 SystemProperties.set("dev.bootcomplete", "1"); 6238 for (int i=0; i<mStartedUsers.size(); i++) { 6239 UserStartedState uss = mStartedUsers.valueAt(i); 6240 if (uss.mState == UserStartedState.STATE_BOOTING) { 6241 uss.mState = UserStartedState.STATE_RUNNING; 6242 final int userId = mStartedUsers.keyAt(i); 6243 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6244 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6245 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6246 broadcastIntentLocked(null, null, intent, null, 6247 new IIntentReceiver.Stub() { 6248 @Override 6249 public void performReceive(Intent intent, int resultCode, 6250 String data, Bundle extras, boolean ordered, 6251 boolean sticky, int sendingUser) { 6252 synchronized (ActivityManagerService.this) { 6253 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6254 true, false); 6255 } 6256 } 6257 }, 6258 0, null, null, 6259 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6260 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6261 userId); 6262 } 6263 } 6264 scheduleStartProfilesLocked(); 6265 } 6266 } 6267 } 6268 6269 @Override 6270 public void bootAnimationComplete() { 6271 final boolean callFinishBooting; 6272 synchronized (this) { 6273 callFinishBooting = mCallFinishBooting; 6274 mBootAnimationComplete = true; 6275 } 6276 if (callFinishBooting) { 6277 finishBooting(); 6278 } 6279 } 6280 6281 final void ensureBootCompleted() { 6282 boolean booting; 6283 boolean enableScreen; 6284 synchronized (this) { 6285 booting = mBooting; 6286 mBooting = false; 6287 enableScreen = !mBooted; 6288 mBooted = true; 6289 } 6290 6291 if (booting) { 6292 finishBooting(); 6293 } 6294 6295 if (enableScreen) { 6296 enableScreenAfterBoot(); 6297 } 6298 } 6299 6300 @Override 6301 public final void activityResumed(IBinder token) { 6302 final long origId = Binder.clearCallingIdentity(); 6303 synchronized(this) { 6304 ActivityStack stack = ActivityRecord.getStackLocked(token); 6305 if (stack != null) { 6306 ActivityRecord.activityResumedLocked(token); 6307 } 6308 } 6309 Binder.restoreCallingIdentity(origId); 6310 } 6311 6312 @Override 6313 public final void activityPaused(IBinder token) { 6314 final long origId = Binder.clearCallingIdentity(); 6315 synchronized(this) { 6316 ActivityStack stack = ActivityRecord.getStackLocked(token); 6317 if (stack != null) { 6318 stack.activityPausedLocked(token, false); 6319 } 6320 } 6321 Binder.restoreCallingIdentity(origId); 6322 } 6323 6324 @Override 6325 public final void activityStopped(IBinder token, Bundle icicle, 6326 PersistableBundle persistentState, CharSequence description) { 6327 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6328 6329 // Refuse possible leaked file descriptors 6330 if (icicle != null && icicle.hasFileDescriptors()) { 6331 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6332 } 6333 6334 final long origId = Binder.clearCallingIdentity(); 6335 6336 synchronized (this) { 6337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6338 if (r != null) { 6339 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6340 } 6341 } 6342 6343 trimApplications(); 6344 6345 Binder.restoreCallingIdentity(origId); 6346 } 6347 6348 @Override 6349 public final void activityDestroyed(IBinder token) { 6350 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6351 synchronized (this) { 6352 ActivityStack stack = ActivityRecord.getStackLocked(token); 6353 if (stack != null) { 6354 stack.activityDestroyedLocked(token); 6355 } 6356 } 6357 } 6358 6359 @Override 6360 public final void backgroundResourcesReleased(IBinder token) { 6361 final long origId = Binder.clearCallingIdentity(); 6362 try { 6363 synchronized (this) { 6364 ActivityStack stack = ActivityRecord.getStackLocked(token); 6365 if (stack != null) { 6366 stack.backgroundResourcesReleased(token); 6367 } 6368 } 6369 } finally { 6370 Binder.restoreCallingIdentity(origId); 6371 } 6372 } 6373 6374 @Override 6375 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6376 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6377 } 6378 6379 @Override 6380 public final void notifyEnterAnimationComplete(IBinder token) { 6381 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6382 } 6383 6384 @Override 6385 public String getCallingPackage(IBinder token) { 6386 synchronized (this) { 6387 ActivityRecord r = getCallingRecordLocked(token); 6388 return r != null ? r.info.packageName : null; 6389 } 6390 } 6391 6392 @Override 6393 public ComponentName getCallingActivity(IBinder token) { 6394 synchronized (this) { 6395 ActivityRecord r = getCallingRecordLocked(token); 6396 return r != null ? r.intent.getComponent() : null; 6397 } 6398 } 6399 6400 private ActivityRecord getCallingRecordLocked(IBinder token) { 6401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6402 if (r == null) { 6403 return null; 6404 } 6405 return r.resultTo; 6406 } 6407 6408 @Override 6409 public ComponentName getActivityClassForToken(IBinder token) { 6410 synchronized(this) { 6411 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6412 if (r == null) { 6413 return null; 6414 } 6415 return r.intent.getComponent(); 6416 } 6417 } 6418 6419 @Override 6420 public String getPackageForToken(IBinder token) { 6421 synchronized(this) { 6422 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6423 if (r == null) { 6424 return null; 6425 } 6426 return r.packageName; 6427 } 6428 } 6429 6430 @Override 6431 public IIntentSender getIntentSender(int type, 6432 String packageName, IBinder token, String resultWho, 6433 int requestCode, Intent[] intents, String[] resolvedTypes, 6434 int flags, Bundle options, int userId) { 6435 enforceNotIsolatedCaller("getIntentSender"); 6436 // Refuse possible leaked file descriptors 6437 if (intents != null) { 6438 if (intents.length < 1) { 6439 throw new IllegalArgumentException("Intents array length must be >= 1"); 6440 } 6441 for (int i=0; i<intents.length; i++) { 6442 Intent intent = intents[i]; 6443 if (intent != null) { 6444 if (intent.hasFileDescriptors()) { 6445 throw new IllegalArgumentException("File descriptors passed in Intent"); 6446 } 6447 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6448 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6449 throw new IllegalArgumentException( 6450 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6451 } 6452 intents[i] = new Intent(intent); 6453 } 6454 } 6455 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6456 throw new IllegalArgumentException( 6457 "Intent array length does not match resolvedTypes length"); 6458 } 6459 } 6460 if (options != null) { 6461 if (options.hasFileDescriptors()) { 6462 throw new IllegalArgumentException("File descriptors passed in options"); 6463 } 6464 } 6465 6466 synchronized(this) { 6467 int callingUid = Binder.getCallingUid(); 6468 int origUserId = userId; 6469 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6470 type == ActivityManager.INTENT_SENDER_BROADCAST, 6471 ALLOW_NON_FULL, "getIntentSender", null); 6472 if (origUserId == UserHandle.USER_CURRENT) { 6473 // We don't want to evaluate this until the pending intent is 6474 // actually executed. However, we do want to always do the 6475 // security checking for it above. 6476 userId = UserHandle.USER_CURRENT; 6477 } 6478 try { 6479 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6480 int uid = AppGlobals.getPackageManager() 6481 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6482 if (!UserHandle.isSameApp(callingUid, uid)) { 6483 String msg = "Permission Denial: getIntentSender() from pid=" 6484 + Binder.getCallingPid() 6485 + ", uid=" + Binder.getCallingUid() 6486 + ", (need uid=" + uid + ")" 6487 + " is not allowed to send as package " + packageName; 6488 Slog.w(TAG, msg); 6489 throw new SecurityException(msg); 6490 } 6491 } 6492 6493 return getIntentSenderLocked(type, packageName, callingUid, userId, 6494 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6495 6496 } catch (RemoteException e) { 6497 throw new SecurityException(e); 6498 } 6499 } 6500 } 6501 6502 IIntentSender getIntentSenderLocked(int type, String packageName, 6503 int callingUid, int userId, IBinder token, String resultWho, 6504 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6505 Bundle options) { 6506 if (DEBUG_MU) 6507 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6508 ActivityRecord activity = null; 6509 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6510 activity = ActivityRecord.isInStackLocked(token); 6511 if (activity == null) { 6512 return null; 6513 } 6514 if (activity.finishing) { 6515 return null; 6516 } 6517 } 6518 6519 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6520 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6521 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6522 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6523 |PendingIntent.FLAG_UPDATE_CURRENT); 6524 6525 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6526 type, packageName, activity, resultWho, 6527 requestCode, intents, resolvedTypes, flags, options, userId); 6528 WeakReference<PendingIntentRecord> ref; 6529 ref = mIntentSenderRecords.get(key); 6530 PendingIntentRecord rec = ref != null ? ref.get() : null; 6531 if (rec != null) { 6532 if (!cancelCurrent) { 6533 if (updateCurrent) { 6534 if (rec.key.requestIntent != null) { 6535 rec.key.requestIntent.replaceExtras(intents != null ? 6536 intents[intents.length - 1] : null); 6537 } 6538 if (intents != null) { 6539 intents[intents.length-1] = rec.key.requestIntent; 6540 rec.key.allIntents = intents; 6541 rec.key.allResolvedTypes = resolvedTypes; 6542 } else { 6543 rec.key.allIntents = null; 6544 rec.key.allResolvedTypes = null; 6545 } 6546 } 6547 return rec; 6548 } 6549 rec.canceled = true; 6550 mIntentSenderRecords.remove(key); 6551 } 6552 if (noCreate) { 6553 return rec; 6554 } 6555 rec = new PendingIntentRecord(this, key, callingUid); 6556 mIntentSenderRecords.put(key, rec.ref); 6557 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6558 if (activity.pendingResults == null) { 6559 activity.pendingResults 6560 = new HashSet<WeakReference<PendingIntentRecord>>(); 6561 } 6562 activity.pendingResults.add(rec.ref); 6563 } 6564 return rec; 6565 } 6566 6567 @Override 6568 public void cancelIntentSender(IIntentSender sender) { 6569 if (!(sender instanceof PendingIntentRecord)) { 6570 return; 6571 } 6572 synchronized(this) { 6573 PendingIntentRecord rec = (PendingIntentRecord)sender; 6574 try { 6575 int uid = AppGlobals.getPackageManager() 6576 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6577 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6578 String msg = "Permission Denial: cancelIntentSender() from pid=" 6579 + Binder.getCallingPid() 6580 + ", uid=" + Binder.getCallingUid() 6581 + " is not allowed to cancel packges " 6582 + rec.key.packageName; 6583 Slog.w(TAG, msg); 6584 throw new SecurityException(msg); 6585 } 6586 } catch (RemoteException e) { 6587 throw new SecurityException(e); 6588 } 6589 cancelIntentSenderLocked(rec, true); 6590 } 6591 } 6592 6593 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6594 rec.canceled = true; 6595 mIntentSenderRecords.remove(rec.key); 6596 if (cleanActivity && rec.key.activity != null) { 6597 rec.key.activity.pendingResults.remove(rec.ref); 6598 } 6599 } 6600 6601 @Override 6602 public String getPackageForIntentSender(IIntentSender pendingResult) { 6603 if (!(pendingResult instanceof PendingIntentRecord)) { 6604 return null; 6605 } 6606 try { 6607 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6608 return res.key.packageName; 6609 } catch (ClassCastException e) { 6610 } 6611 return null; 6612 } 6613 6614 @Override 6615 public int getUidForIntentSender(IIntentSender sender) { 6616 if (sender instanceof PendingIntentRecord) { 6617 try { 6618 PendingIntentRecord res = (PendingIntentRecord)sender; 6619 return res.uid; 6620 } catch (ClassCastException e) { 6621 } 6622 } 6623 return -1; 6624 } 6625 6626 @Override 6627 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6628 if (!(pendingResult instanceof PendingIntentRecord)) { 6629 return false; 6630 } 6631 try { 6632 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6633 if (res.key.allIntents == null) { 6634 return false; 6635 } 6636 for (int i=0; i<res.key.allIntents.length; i++) { 6637 Intent intent = res.key.allIntents[i]; 6638 if (intent.getPackage() != null && intent.getComponent() != null) { 6639 return false; 6640 } 6641 } 6642 return true; 6643 } catch (ClassCastException e) { 6644 } 6645 return false; 6646 } 6647 6648 @Override 6649 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6650 if (!(pendingResult instanceof PendingIntentRecord)) { 6651 return false; 6652 } 6653 try { 6654 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6655 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6656 return true; 6657 } 6658 return false; 6659 } catch (ClassCastException e) { 6660 } 6661 return false; 6662 } 6663 6664 @Override 6665 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6666 if (!(pendingResult instanceof PendingIntentRecord)) { 6667 return null; 6668 } 6669 try { 6670 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6671 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6672 } catch (ClassCastException e) { 6673 } 6674 return null; 6675 } 6676 6677 @Override 6678 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6679 if (!(pendingResult instanceof PendingIntentRecord)) { 6680 return null; 6681 } 6682 try { 6683 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6684 Intent intent = res.key.requestIntent; 6685 if (intent != null) { 6686 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6687 || res.lastTagPrefix.equals(prefix))) { 6688 return res.lastTag; 6689 } 6690 res.lastTagPrefix = prefix; 6691 StringBuilder sb = new StringBuilder(128); 6692 if (prefix != null) { 6693 sb.append(prefix); 6694 } 6695 if (intent.getAction() != null) { 6696 sb.append(intent.getAction()); 6697 } else if (intent.getComponent() != null) { 6698 intent.getComponent().appendShortString(sb); 6699 } else { 6700 sb.append("?"); 6701 } 6702 return res.lastTag = sb.toString(); 6703 } 6704 } catch (ClassCastException e) { 6705 } 6706 return null; 6707 } 6708 6709 @Override 6710 public void setProcessLimit(int max) { 6711 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6712 "setProcessLimit()"); 6713 synchronized (this) { 6714 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6715 mProcessLimitOverride = max; 6716 } 6717 trimApplications(); 6718 } 6719 6720 @Override 6721 public int getProcessLimit() { 6722 synchronized (this) { 6723 return mProcessLimitOverride; 6724 } 6725 } 6726 6727 void foregroundTokenDied(ForegroundToken token) { 6728 synchronized (ActivityManagerService.this) { 6729 synchronized (mPidsSelfLocked) { 6730 ForegroundToken cur 6731 = mForegroundProcesses.get(token.pid); 6732 if (cur != token) { 6733 return; 6734 } 6735 mForegroundProcesses.remove(token.pid); 6736 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6737 if (pr == null) { 6738 return; 6739 } 6740 pr.forcingToForeground = null; 6741 updateProcessForegroundLocked(pr, false, false); 6742 } 6743 updateOomAdjLocked(); 6744 } 6745 } 6746 6747 @Override 6748 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6749 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6750 "setProcessForeground()"); 6751 synchronized(this) { 6752 boolean changed = false; 6753 6754 synchronized (mPidsSelfLocked) { 6755 ProcessRecord pr = mPidsSelfLocked.get(pid); 6756 if (pr == null && isForeground) { 6757 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6758 return; 6759 } 6760 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6761 if (oldToken != null) { 6762 oldToken.token.unlinkToDeath(oldToken, 0); 6763 mForegroundProcesses.remove(pid); 6764 if (pr != null) { 6765 pr.forcingToForeground = null; 6766 } 6767 changed = true; 6768 } 6769 if (isForeground && token != null) { 6770 ForegroundToken newToken = new ForegroundToken() { 6771 @Override 6772 public void binderDied() { 6773 foregroundTokenDied(this); 6774 } 6775 }; 6776 newToken.pid = pid; 6777 newToken.token = token; 6778 try { 6779 token.linkToDeath(newToken, 0); 6780 mForegroundProcesses.put(pid, newToken); 6781 pr.forcingToForeground = token; 6782 changed = true; 6783 } catch (RemoteException e) { 6784 // If the process died while doing this, we will later 6785 // do the cleanup with the process death link. 6786 } 6787 } 6788 } 6789 6790 if (changed) { 6791 updateOomAdjLocked(); 6792 } 6793 } 6794 } 6795 6796 // ========================================================= 6797 // PERMISSIONS 6798 // ========================================================= 6799 6800 static class PermissionController extends IPermissionController.Stub { 6801 ActivityManagerService mActivityManagerService; 6802 PermissionController(ActivityManagerService activityManagerService) { 6803 mActivityManagerService = activityManagerService; 6804 } 6805 6806 @Override 6807 public boolean checkPermission(String permission, int pid, int uid) { 6808 return mActivityManagerService.checkPermission(permission, pid, 6809 uid) == PackageManager.PERMISSION_GRANTED; 6810 } 6811 } 6812 6813 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6814 @Override 6815 public int checkComponentPermission(String permission, int pid, int uid, 6816 int owningUid, boolean exported) { 6817 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6818 owningUid, exported); 6819 } 6820 6821 @Override 6822 public Object getAMSLock() { 6823 return ActivityManagerService.this; 6824 } 6825 } 6826 6827 /** 6828 * This can be called with or without the global lock held. 6829 */ 6830 int checkComponentPermission(String permission, int pid, int uid, 6831 int owningUid, boolean exported) { 6832 // We might be performing an operation on behalf of an indirect binder 6833 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6834 // client identity accordingly before proceeding. 6835 Identity tlsIdentity = sCallerIdentity.get(); 6836 if (tlsIdentity != null) { 6837 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6838 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6839 uid = tlsIdentity.uid; 6840 pid = tlsIdentity.pid; 6841 } 6842 6843 if (pid == MY_PID) { 6844 return PackageManager.PERMISSION_GRANTED; 6845 } 6846 6847 return ActivityManager.checkComponentPermission(permission, uid, 6848 owningUid, exported); 6849 } 6850 6851 /** 6852 * As the only public entry point for permissions checking, this method 6853 * can enforce the semantic that requesting a check on a null global 6854 * permission is automatically denied. (Internally a null permission 6855 * string is used when calling {@link #checkComponentPermission} in cases 6856 * when only uid-based security is needed.) 6857 * 6858 * This can be called with or without the global lock held. 6859 */ 6860 @Override 6861 public int checkPermission(String permission, int pid, int uid) { 6862 if (permission == null) { 6863 return PackageManager.PERMISSION_DENIED; 6864 } 6865 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6866 } 6867 6868 /** 6869 * Binder IPC calls go through the public entry point. 6870 * This can be called with or without the global lock held. 6871 */ 6872 int checkCallingPermission(String permission) { 6873 return checkPermission(permission, 6874 Binder.getCallingPid(), 6875 UserHandle.getAppId(Binder.getCallingUid())); 6876 } 6877 6878 /** 6879 * This can be called with or without the global lock held. 6880 */ 6881 void enforceCallingPermission(String permission, String func) { 6882 if (checkCallingPermission(permission) 6883 == PackageManager.PERMISSION_GRANTED) { 6884 return; 6885 } 6886 6887 String msg = "Permission Denial: " + func + " from pid=" 6888 + Binder.getCallingPid() 6889 + ", uid=" + Binder.getCallingUid() 6890 + " requires " + permission; 6891 Slog.w(TAG, msg); 6892 throw new SecurityException(msg); 6893 } 6894 6895 /** 6896 * Determine if UID is holding permissions required to access {@link Uri} in 6897 * the given {@link ProviderInfo}. Final permission checking is always done 6898 * in {@link ContentProvider}. 6899 */ 6900 private final boolean checkHoldingPermissionsLocked( 6901 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6902 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6903 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6904 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6905 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6906 != PERMISSION_GRANTED) { 6907 return false; 6908 } 6909 } 6910 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6911 } 6912 6913 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6914 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6915 if (pi.applicationInfo.uid == uid) { 6916 return true; 6917 } else if (!pi.exported) { 6918 return false; 6919 } 6920 6921 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6922 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6923 try { 6924 // check if target holds top-level <provider> permissions 6925 if (!readMet && pi.readPermission != null && considerUidPermissions 6926 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6927 readMet = true; 6928 } 6929 if (!writeMet && pi.writePermission != null && considerUidPermissions 6930 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6931 writeMet = true; 6932 } 6933 6934 // track if unprotected read/write is allowed; any denied 6935 // <path-permission> below removes this ability 6936 boolean allowDefaultRead = pi.readPermission == null; 6937 boolean allowDefaultWrite = pi.writePermission == null; 6938 6939 // check if target holds any <path-permission> that match uri 6940 final PathPermission[] pps = pi.pathPermissions; 6941 if (pps != null) { 6942 final String path = grantUri.uri.getPath(); 6943 int i = pps.length; 6944 while (i > 0 && (!readMet || !writeMet)) { 6945 i--; 6946 PathPermission pp = pps[i]; 6947 if (pp.match(path)) { 6948 if (!readMet) { 6949 final String pprperm = pp.getReadPermission(); 6950 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6951 + pprperm + " for " + pp.getPath() 6952 + ": match=" + pp.match(path) 6953 + " check=" + pm.checkUidPermission(pprperm, uid)); 6954 if (pprperm != null) { 6955 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6956 == PERMISSION_GRANTED) { 6957 readMet = true; 6958 } else { 6959 allowDefaultRead = false; 6960 } 6961 } 6962 } 6963 if (!writeMet) { 6964 final String ppwperm = pp.getWritePermission(); 6965 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6966 + ppwperm + " for " + pp.getPath() 6967 + ": match=" + pp.match(path) 6968 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6969 if (ppwperm != null) { 6970 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6971 == PERMISSION_GRANTED) { 6972 writeMet = true; 6973 } else { 6974 allowDefaultWrite = false; 6975 } 6976 } 6977 } 6978 } 6979 } 6980 } 6981 6982 // grant unprotected <provider> read/write, if not blocked by 6983 // <path-permission> above 6984 if (allowDefaultRead) readMet = true; 6985 if (allowDefaultWrite) writeMet = true; 6986 6987 } catch (RemoteException e) { 6988 return false; 6989 } 6990 6991 return readMet && writeMet; 6992 } 6993 6994 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6995 ProviderInfo pi = null; 6996 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6997 if (cpr != null) { 6998 pi = cpr.info; 6999 } else { 7000 try { 7001 pi = AppGlobals.getPackageManager().resolveContentProvider( 7002 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7003 } catch (RemoteException ex) { 7004 } 7005 } 7006 return pi; 7007 } 7008 7009 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7010 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7011 if (targetUris != null) { 7012 return targetUris.get(grantUri); 7013 } 7014 return null; 7015 } 7016 7017 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7018 String targetPkg, int targetUid, GrantUri grantUri) { 7019 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7020 if (targetUris == null) { 7021 targetUris = Maps.newArrayMap(); 7022 mGrantedUriPermissions.put(targetUid, targetUris); 7023 } 7024 7025 UriPermission perm = targetUris.get(grantUri); 7026 if (perm == null) { 7027 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7028 targetUris.put(grantUri, perm); 7029 } 7030 7031 return perm; 7032 } 7033 7034 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7035 final int modeFlags) { 7036 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7037 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7038 : UriPermission.STRENGTH_OWNED; 7039 7040 // Root gets to do everything. 7041 if (uid == 0) { 7042 return true; 7043 } 7044 7045 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7046 if (perms == null) return false; 7047 7048 // First look for exact match 7049 final UriPermission exactPerm = perms.get(grantUri); 7050 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7051 return true; 7052 } 7053 7054 // No exact match, look for prefixes 7055 final int N = perms.size(); 7056 for (int i = 0; i < N; i++) { 7057 final UriPermission perm = perms.valueAt(i); 7058 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7059 && perm.getStrength(modeFlags) >= minStrength) { 7060 return true; 7061 } 7062 } 7063 7064 return false; 7065 } 7066 7067 /** 7068 * @param uri This uri must NOT contain an embedded userId. 7069 * @param userId The userId in which the uri is to be resolved. 7070 */ 7071 @Override 7072 public int checkUriPermission(Uri uri, int pid, int uid, 7073 final int modeFlags, int userId) { 7074 enforceNotIsolatedCaller("checkUriPermission"); 7075 7076 // Another redirected-binder-call permissions check as in 7077 // {@link checkComponentPermission}. 7078 Identity tlsIdentity = sCallerIdentity.get(); 7079 if (tlsIdentity != null) { 7080 uid = tlsIdentity.uid; 7081 pid = tlsIdentity.pid; 7082 } 7083 7084 // Our own process gets to do everything. 7085 if (pid == MY_PID) { 7086 return PackageManager.PERMISSION_GRANTED; 7087 } 7088 synchronized (this) { 7089 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7090 ? PackageManager.PERMISSION_GRANTED 7091 : PackageManager.PERMISSION_DENIED; 7092 } 7093 } 7094 7095 /** 7096 * Check if the targetPkg can be granted permission to access uri by 7097 * the callingUid using the given modeFlags. Throws a security exception 7098 * if callingUid is not allowed to do this. Returns the uid of the target 7099 * if the URI permission grant should be performed; returns -1 if it is not 7100 * needed (for example targetPkg already has permission to access the URI). 7101 * If you already know the uid of the target, you can supply it in 7102 * lastTargetUid else set that to -1. 7103 */ 7104 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7105 final int modeFlags, int lastTargetUid) { 7106 if (!Intent.isAccessUriMode(modeFlags)) { 7107 return -1; 7108 } 7109 7110 if (targetPkg != null) { 7111 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7112 "Checking grant " + targetPkg + " permission to " + grantUri); 7113 } 7114 7115 final IPackageManager pm = AppGlobals.getPackageManager(); 7116 7117 // If this is not a content: uri, we can't do anything with it. 7118 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7120 "Can't grant URI permission for non-content URI: " + grantUri); 7121 return -1; 7122 } 7123 7124 final String authority = grantUri.uri.getAuthority(); 7125 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7126 if (pi == null) { 7127 Slog.w(TAG, "No content provider found for permission check: " + 7128 grantUri.uri.toSafeString()); 7129 return -1; 7130 } 7131 7132 int targetUid = lastTargetUid; 7133 if (targetUid < 0 && targetPkg != null) { 7134 try { 7135 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7136 if (targetUid < 0) { 7137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7138 "Can't grant URI permission no uid for: " + targetPkg); 7139 return -1; 7140 } 7141 } catch (RemoteException ex) { 7142 return -1; 7143 } 7144 } 7145 7146 if (targetUid >= 0) { 7147 // First... does the target actually need this permission? 7148 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7149 // No need to grant the target this permission. 7150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7151 "Target " + targetPkg + " already has full permission to " + grantUri); 7152 return -1; 7153 } 7154 } else { 7155 // First... there is no target package, so can anyone access it? 7156 boolean allowed = pi.exported; 7157 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7158 if (pi.readPermission != null) { 7159 allowed = false; 7160 } 7161 } 7162 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7163 if (pi.writePermission != null) { 7164 allowed = false; 7165 } 7166 } 7167 if (allowed) { 7168 return -1; 7169 } 7170 } 7171 7172 /* There is a special cross user grant if: 7173 * - The target is on another user. 7174 * - Apps on the current user can access the uri without any uid permissions. 7175 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7176 * grant uri permissions. 7177 */ 7178 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7179 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7180 modeFlags, false /*without considering the uid permissions*/); 7181 7182 // Second... is the provider allowing granting of URI permissions? 7183 if (!specialCrossUserGrant) { 7184 if (!pi.grantUriPermissions) { 7185 throw new SecurityException("Provider " + pi.packageName 7186 + "/" + pi.name 7187 + " does not allow granting of Uri permissions (uri " 7188 + grantUri + ")"); 7189 } 7190 if (pi.uriPermissionPatterns != null) { 7191 final int N = pi.uriPermissionPatterns.length; 7192 boolean allowed = false; 7193 for (int i=0; i<N; i++) { 7194 if (pi.uriPermissionPatterns[i] != null 7195 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7196 allowed = true; 7197 break; 7198 } 7199 } 7200 if (!allowed) { 7201 throw new SecurityException("Provider " + pi.packageName 7202 + "/" + pi.name 7203 + " does not allow granting of permission to path of Uri " 7204 + grantUri); 7205 } 7206 } 7207 } 7208 7209 // Third... does the caller itself have permission to access 7210 // this uri? 7211 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7212 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7213 // Require they hold a strong enough Uri permission 7214 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7215 throw new SecurityException("Uid " + callingUid 7216 + " does not have permission to uri " + grantUri); 7217 } 7218 } 7219 } 7220 return targetUid; 7221 } 7222 7223 /** 7224 * @param uri This uri must NOT contain an embedded userId. 7225 * @param userId The userId in which the uri is to be resolved. 7226 */ 7227 @Override 7228 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7229 final int modeFlags, int userId) { 7230 enforceNotIsolatedCaller("checkGrantUriPermission"); 7231 synchronized(this) { 7232 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7233 new GrantUri(userId, uri, false), modeFlags, -1); 7234 } 7235 } 7236 7237 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7238 final int modeFlags, UriPermissionOwner owner) { 7239 if (!Intent.isAccessUriMode(modeFlags)) { 7240 return; 7241 } 7242 7243 // So here we are: the caller has the assumed permission 7244 // to the uri, and the target doesn't. Let's now give this to 7245 // the target. 7246 7247 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7248 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7249 7250 final String authority = grantUri.uri.getAuthority(); 7251 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7252 if (pi == null) { 7253 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7254 return; 7255 } 7256 7257 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7258 grantUri.prefix = true; 7259 } 7260 final UriPermission perm = findOrCreateUriPermissionLocked( 7261 pi.packageName, targetPkg, targetUid, grantUri); 7262 perm.grantModes(modeFlags, owner); 7263 } 7264 7265 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7266 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7267 if (targetPkg == null) { 7268 throw new NullPointerException("targetPkg"); 7269 } 7270 int targetUid; 7271 final IPackageManager pm = AppGlobals.getPackageManager(); 7272 try { 7273 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7274 } catch (RemoteException ex) { 7275 return; 7276 } 7277 7278 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7279 targetUid); 7280 if (targetUid < 0) { 7281 return; 7282 } 7283 7284 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7285 owner); 7286 } 7287 7288 static class NeededUriGrants extends ArrayList<GrantUri> { 7289 final String targetPkg; 7290 final int targetUid; 7291 final int flags; 7292 7293 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7294 this.targetPkg = targetPkg; 7295 this.targetUid = targetUid; 7296 this.flags = flags; 7297 } 7298 } 7299 7300 /** 7301 * Like checkGrantUriPermissionLocked, but takes an Intent. 7302 */ 7303 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7304 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7306 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7307 + " clip=" + (intent != null ? intent.getClipData() : null) 7308 + " from " + intent + "; flags=0x" 7309 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7310 7311 if (targetPkg == null) { 7312 throw new NullPointerException("targetPkg"); 7313 } 7314 7315 if (intent == null) { 7316 return null; 7317 } 7318 Uri data = intent.getData(); 7319 ClipData clip = intent.getClipData(); 7320 if (data == null && clip == null) { 7321 return null; 7322 } 7323 // Default userId for uris in the intent (if they don't specify it themselves) 7324 int contentUserHint = intent.getContentUserHint(); 7325 if (contentUserHint == UserHandle.USER_CURRENT) { 7326 contentUserHint = UserHandle.getUserId(callingUid); 7327 } 7328 final IPackageManager pm = AppGlobals.getPackageManager(); 7329 int targetUid; 7330 if (needed != null) { 7331 targetUid = needed.targetUid; 7332 } else { 7333 try { 7334 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7335 } catch (RemoteException ex) { 7336 return null; 7337 } 7338 if (targetUid < 0) { 7339 if (DEBUG_URI_PERMISSION) { 7340 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7341 + " on user " + targetUserId); 7342 } 7343 return null; 7344 } 7345 } 7346 if (data != null) { 7347 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7348 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7349 targetUid); 7350 if (targetUid > 0) { 7351 if (needed == null) { 7352 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7353 } 7354 needed.add(grantUri); 7355 } 7356 } 7357 if (clip != null) { 7358 for (int i=0; i<clip.getItemCount(); i++) { 7359 Uri uri = clip.getItemAt(i).getUri(); 7360 if (uri != null) { 7361 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7362 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7363 targetUid); 7364 if (targetUid > 0) { 7365 if (needed == null) { 7366 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7367 } 7368 needed.add(grantUri); 7369 } 7370 } else { 7371 Intent clipIntent = clip.getItemAt(i).getIntent(); 7372 if (clipIntent != null) { 7373 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7374 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7375 if (newNeeded != null) { 7376 needed = newNeeded; 7377 } 7378 } 7379 } 7380 } 7381 } 7382 7383 return needed; 7384 } 7385 7386 /** 7387 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7388 */ 7389 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7390 UriPermissionOwner owner) { 7391 if (needed != null) { 7392 for (int i=0; i<needed.size(); i++) { 7393 GrantUri grantUri = needed.get(i); 7394 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7395 grantUri, needed.flags, owner); 7396 } 7397 } 7398 } 7399 7400 void grantUriPermissionFromIntentLocked(int callingUid, 7401 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7402 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7403 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7404 if (needed == null) { 7405 return; 7406 } 7407 7408 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7409 } 7410 7411 /** 7412 * @param uri This uri must NOT contain an embedded userId. 7413 * @param userId The userId in which the uri is to be resolved. 7414 */ 7415 @Override 7416 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7417 final int modeFlags, int userId) { 7418 enforceNotIsolatedCaller("grantUriPermission"); 7419 GrantUri grantUri = new GrantUri(userId, uri, false); 7420 synchronized(this) { 7421 final ProcessRecord r = getRecordForAppLocked(caller); 7422 if (r == null) { 7423 throw new SecurityException("Unable to find app for caller " 7424 + caller 7425 + " when granting permission to uri " + grantUri); 7426 } 7427 if (targetPkg == null) { 7428 throw new IllegalArgumentException("null target"); 7429 } 7430 if (grantUri == null) { 7431 throw new IllegalArgumentException("null uri"); 7432 } 7433 7434 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7435 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7436 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7437 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7438 7439 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7440 UserHandle.getUserId(r.uid)); 7441 } 7442 } 7443 7444 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7445 if (perm.modeFlags == 0) { 7446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7447 perm.targetUid); 7448 if (perms != null) { 7449 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7450 "Removing " + perm.targetUid + " permission to " + perm.uri); 7451 7452 perms.remove(perm.uri); 7453 if (perms.isEmpty()) { 7454 mGrantedUriPermissions.remove(perm.targetUid); 7455 } 7456 } 7457 } 7458 } 7459 7460 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7461 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7462 7463 final IPackageManager pm = AppGlobals.getPackageManager(); 7464 final String authority = grantUri.uri.getAuthority(); 7465 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7466 if (pi == null) { 7467 Slog.w(TAG, "No content provider found for permission revoke: " 7468 + grantUri.toSafeString()); 7469 return; 7470 } 7471 7472 // Does the caller have this permission on the URI? 7473 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7474 // Have they don't have direct access to the URI, then revoke any URI 7475 // permissions that have been granted to them. 7476 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7477 if (perms != null) { 7478 boolean persistChanged = false; 7479 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7480 final UriPermission perm = it.next(); 7481 if (perm.uri.sourceUserId == grantUri.sourceUserId 7482 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7483 if (DEBUG_URI_PERMISSION) 7484 Slog.v(TAG, 7485 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7486 persistChanged |= perm.revokeModes( 7487 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7488 if (perm.modeFlags == 0) { 7489 it.remove(); 7490 } 7491 } 7492 } 7493 if (perms.isEmpty()) { 7494 mGrantedUriPermissions.remove(callingUid); 7495 } 7496 if (persistChanged) { 7497 schedulePersistUriGrants(); 7498 } 7499 } 7500 return; 7501 } 7502 7503 boolean persistChanged = false; 7504 7505 // Go through all of the permissions and remove any that match. 7506 int N = mGrantedUriPermissions.size(); 7507 for (int i = 0; i < N; i++) { 7508 final int targetUid = mGrantedUriPermissions.keyAt(i); 7509 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7510 7511 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7512 final UriPermission perm = it.next(); 7513 if (perm.uri.sourceUserId == grantUri.sourceUserId 7514 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7515 if (DEBUG_URI_PERMISSION) 7516 Slog.v(TAG, 7517 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7518 persistChanged |= perm.revokeModes( 7519 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7520 if (perm.modeFlags == 0) { 7521 it.remove(); 7522 } 7523 } 7524 } 7525 7526 if (perms.isEmpty()) { 7527 mGrantedUriPermissions.remove(targetUid); 7528 N--; 7529 i--; 7530 } 7531 } 7532 7533 if (persistChanged) { 7534 schedulePersistUriGrants(); 7535 } 7536 } 7537 7538 /** 7539 * @param uri This uri must NOT contain an embedded userId. 7540 * @param userId The userId in which the uri is to be resolved. 7541 */ 7542 @Override 7543 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7544 int userId) { 7545 enforceNotIsolatedCaller("revokeUriPermission"); 7546 synchronized(this) { 7547 final ProcessRecord r = getRecordForAppLocked(caller); 7548 if (r == null) { 7549 throw new SecurityException("Unable to find app for caller " 7550 + caller 7551 + " when revoking permission to uri " + uri); 7552 } 7553 if (uri == null) { 7554 Slog.w(TAG, "revokeUriPermission: null uri"); 7555 return; 7556 } 7557 7558 if (!Intent.isAccessUriMode(modeFlags)) { 7559 return; 7560 } 7561 7562 final IPackageManager pm = AppGlobals.getPackageManager(); 7563 final String authority = uri.getAuthority(); 7564 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7565 if (pi == null) { 7566 Slog.w(TAG, "No content provider found for permission revoke: " 7567 + uri.toSafeString()); 7568 return; 7569 } 7570 7571 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7572 } 7573 } 7574 7575 /** 7576 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7577 * given package. 7578 * 7579 * @param packageName Package name to match, or {@code null} to apply to all 7580 * packages. 7581 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7582 * to all users. 7583 * @param persistable If persistable grants should be removed. 7584 */ 7585 private void removeUriPermissionsForPackageLocked( 7586 String packageName, int userHandle, boolean persistable) { 7587 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7588 throw new IllegalArgumentException("Must narrow by either package or user"); 7589 } 7590 7591 boolean persistChanged = false; 7592 7593 int N = mGrantedUriPermissions.size(); 7594 for (int i = 0; i < N; i++) { 7595 final int targetUid = mGrantedUriPermissions.keyAt(i); 7596 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7597 7598 // Only inspect grants matching user 7599 if (userHandle == UserHandle.USER_ALL 7600 || userHandle == UserHandle.getUserId(targetUid)) { 7601 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7602 final UriPermission perm = it.next(); 7603 7604 // Only inspect grants matching package 7605 if (packageName == null || perm.sourcePkg.equals(packageName) 7606 || perm.targetPkg.equals(packageName)) { 7607 persistChanged |= perm.revokeModes( 7608 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7609 7610 // Only remove when no modes remain; any persisted grants 7611 // will keep this alive. 7612 if (perm.modeFlags == 0) { 7613 it.remove(); 7614 } 7615 } 7616 } 7617 7618 if (perms.isEmpty()) { 7619 mGrantedUriPermissions.remove(targetUid); 7620 N--; 7621 i--; 7622 } 7623 } 7624 } 7625 7626 if (persistChanged) { 7627 schedulePersistUriGrants(); 7628 } 7629 } 7630 7631 @Override 7632 public IBinder newUriPermissionOwner(String name) { 7633 enforceNotIsolatedCaller("newUriPermissionOwner"); 7634 synchronized(this) { 7635 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7636 return owner.getExternalTokenLocked(); 7637 } 7638 } 7639 7640 /** 7641 * @param uri This uri must NOT contain an embedded userId. 7642 * @param sourceUserId The userId in which the uri is to be resolved. 7643 * @param targetUserId The userId of the app that receives the grant. 7644 */ 7645 @Override 7646 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7647 final int modeFlags, int sourceUserId, int targetUserId) { 7648 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7649 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7650 synchronized(this) { 7651 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7652 if (owner == null) { 7653 throw new IllegalArgumentException("Unknown owner: " + token); 7654 } 7655 if (fromUid != Binder.getCallingUid()) { 7656 if (Binder.getCallingUid() != Process.myUid()) { 7657 // Only system code can grant URI permissions on behalf 7658 // of other users. 7659 throw new SecurityException("nice try"); 7660 } 7661 } 7662 if (targetPkg == null) { 7663 throw new IllegalArgumentException("null target"); 7664 } 7665 if (uri == null) { 7666 throw new IllegalArgumentException("null uri"); 7667 } 7668 7669 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7670 modeFlags, owner, targetUserId); 7671 } 7672 } 7673 7674 /** 7675 * @param uri This uri must NOT contain an embedded userId. 7676 * @param userId The userId in which the uri is to be resolved. 7677 */ 7678 @Override 7679 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7680 synchronized(this) { 7681 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7682 if (owner == null) { 7683 throw new IllegalArgumentException("Unknown owner: " + token); 7684 } 7685 7686 if (uri == null) { 7687 owner.removeUriPermissionsLocked(mode); 7688 } else { 7689 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7690 } 7691 } 7692 } 7693 7694 private void schedulePersistUriGrants() { 7695 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7696 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7697 10 * DateUtils.SECOND_IN_MILLIS); 7698 } 7699 } 7700 7701 private void writeGrantedUriPermissions() { 7702 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7703 7704 // Snapshot permissions so we can persist without lock 7705 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7706 synchronized (this) { 7707 final int size = mGrantedUriPermissions.size(); 7708 for (int i = 0; i < size; i++) { 7709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7710 for (UriPermission perm : perms.values()) { 7711 if (perm.persistedModeFlags != 0) { 7712 persist.add(perm.snapshot()); 7713 } 7714 } 7715 } 7716 } 7717 7718 FileOutputStream fos = null; 7719 try { 7720 fos = mGrantFile.startWrite(); 7721 7722 XmlSerializer out = new FastXmlSerializer(); 7723 out.setOutput(fos, "utf-8"); 7724 out.startDocument(null, true); 7725 out.startTag(null, TAG_URI_GRANTS); 7726 for (UriPermission.Snapshot perm : persist) { 7727 out.startTag(null, TAG_URI_GRANT); 7728 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7729 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7730 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7731 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7732 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7733 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7734 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7735 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7736 out.endTag(null, TAG_URI_GRANT); 7737 } 7738 out.endTag(null, TAG_URI_GRANTS); 7739 out.endDocument(); 7740 7741 mGrantFile.finishWrite(fos); 7742 } catch (IOException e) { 7743 if (fos != null) { 7744 mGrantFile.failWrite(fos); 7745 } 7746 } 7747 } 7748 7749 private void readGrantedUriPermissionsLocked() { 7750 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7751 7752 final long now = System.currentTimeMillis(); 7753 7754 FileInputStream fis = null; 7755 try { 7756 fis = mGrantFile.openRead(); 7757 final XmlPullParser in = Xml.newPullParser(); 7758 in.setInput(fis, null); 7759 7760 int type; 7761 while ((type = in.next()) != END_DOCUMENT) { 7762 final String tag = in.getName(); 7763 if (type == START_TAG) { 7764 if (TAG_URI_GRANT.equals(tag)) { 7765 final int sourceUserId; 7766 final int targetUserId; 7767 final int userHandle = readIntAttribute(in, 7768 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7769 if (userHandle != UserHandle.USER_NULL) { 7770 // For backwards compatibility. 7771 sourceUserId = userHandle; 7772 targetUserId = userHandle; 7773 } else { 7774 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7775 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7776 } 7777 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7778 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7779 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7780 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7781 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7782 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7783 7784 // Sanity check that provider still belongs to source package 7785 final ProviderInfo pi = getProviderInfoLocked( 7786 uri.getAuthority(), sourceUserId); 7787 if (pi != null && sourcePkg.equals(pi.packageName)) { 7788 int targetUid = -1; 7789 try { 7790 targetUid = AppGlobals.getPackageManager() 7791 .getPackageUid(targetPkg, targetUserId); 7792 } catch (RemoteException e) { 7793 } 7794 if (targetUid != -1) { 7795 final UriPermission perm = findOrCreateUriPermissionLocked( 7796 sourcePkg, targetPkg, targetUid, 7797 new GrantUri(sourceUserId, uri, prefix)); 7798 perm.initPersistedModes(modeFlags, createdTime); 7799 } 7800 } else { 7801 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7802 + " but instead found " + pi); 7803 } 7804 } 7805 } 7806 } 7807 } catch (FileNotFoundException e) { 7808 // Missing grants is okay 7809 } catch (IOException e) { 7810 Log.wtf(TAG, "Failed reading Uri grants", e); 7811 } catch (XmlPullParserException e) { 7812 Log.wtf(TAG, "Failed reading Uri grants", e); 7813 } finally { 7814 IoUtils.closeQuietly(fis); 7815 } 7816 } 7817 7818 /** 7819 * @param uri This uri must NOT contain an embedded userId. 7820 * @param userId The userId in which the uri is to be resolved. 7821 */ 7822 @Override 7823 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7824 enforceNotIsolatedCaller("takePersistableUriPermission"); 7825 7826 Preconditions.checkFlagsArgument(modeFlags, 7827 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7828 7829 synchronized (this) { 7830 final int callingUid = Binder.getCallingUid(); 7831 boolean persistChanged = false; 7832 GrantUri grantUri = new GrantUri(userId, uri, false); 7833 7834 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7835 new GrantUri(userId, uri, false)); 7836 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7837 new GrantUri(userId, uri, true)); 7838 7839 final boolean exactValid = (exactPerm != null) 7840 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7841 final boolean prefixValid = (prefixPerm != null) 7842 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7843 7844 if (!(exactValid || prefixValid)) { 7845 throw new SecurityException("No persistable permission grants found for UID " 7846 + callingUid + " and Uri " + grantUri.toSafeString()); 7847 } 7848 7849 if (exactValid) { 7850 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7851 } 7852 if (prefixValid) { 7853 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7854 } 7855 7856 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7857 7858 if (persistChanged) { 7859 schedulePersistUriGrants(); 7860 } 7861 } 7862 } 7863 7864 /** 7865 * @param uri This uri must NOT contain an embedded userId. 7866 * @param userId The userId in which the uri is to be resolved. 7867 */ 7868 @Override 7869 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7870 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7871 7872 Preconditions.checkFlagsArgument(modeFlags, 7873 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7874 7875 synchronized (this) { 7876 final int callingUid = Binder.getCallingUid(); 7877 boolean persistChanged = false; 7878 7879 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7880 new GrantUri(userId, uri, false)); 7881 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7882 new GrantUri(userId, uri, true)); 7883 if (exactPerm == null && prefixPerm == null) { 7884 throw new SecurityException("No permission grants found for UID " + callingUid 7885 + " and Uri " + uri.toSafeString()); 7886 } 7887 7888 if (exactPerm != null) { 7889 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7890 removeUriPermissionIfNeededLocked(exactPerm); 7891 } 7892 if (prefixPerm != null) { 7893 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7894 removeUriPermissionIfNeededLocked(prefixPerm); 7895 } 7896 7897 if (persistChanged) { 7898 schedulePersistUriGrants(); 7899 } 7900 } 7901 } 7902 7903 /** 7904 * Prune any older {@link UriPermission} for the given UID until outstanding 7905 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7906 * 7907 * @return if any mutations occured that require persisting. 7908 */ 7909 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7910 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7911 if (perms == null) return false; 7912 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7913 7914 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7915 for (UriPermission perm : perms.values()) { 7916 if (perm.persistedModeFlags != 0) { 7917 persisted.add(perm); 7918 } 7919 } 7920 7921 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7922 if (trimCount <= 0) return false; 7923 7924 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7925 for (int i = 0; i < trimCount; i++) { 7926 final UriPermission perm = persisted.get(i); 7927 7928 if (DEBUG_URI_PERMISSION) { 7929 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7930 } 7931 7932 perm.releasePersistableModes(~0); 7933 removeUriPermissionIfNeededLocked(perm); 7934 } 7935 7936 return true; 7937 } 7938 7939 @Override 7940 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7941 String packageName, boolean incoming) { 7942 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7943 Preconditions.checkNotNull(packageName, "packageName"); 7944 7945 final int callingUid = Binder.getCallingUid(); 7946 final IPackageManager pm = AppGlobals.getPackageManager(); 7947 try { 7948 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7949 if (packageUid != callingUid) { 7950 throw new SecurityException( 7951 "Package " + packageName + " does not belong to calling UID " + callingUid); 7952 } 7953 } catch (RemoteException e) { 7954 throw new SecurityException("Failed to verify package name ownership"); 7955 } 7956 7957 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7958 synchronized (this) { 7959 if (incoming) { 7960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7961 callingUid); 7962 if (perms == null) { 7963 Slog.w(TAG, "No permission grants found for " + packageName); 7964 } else { 7965 for (UriPermission perm : perms.values()) { 7966 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7967 result.add(perm.buildPersistedPublicApiObject()); 7968 } 7969 } 7970 } 7971 } else { 7972 final int size = mGrantedUriPermissions.size(); 7973 for (int i = 0; i < size; i++) { 7974 final ArrayMap<GrantUri, UriPermission> perms = 7975 mGrantedUriPermissions.valueAt(i); 7976 for (UriPermission perm : perms.values()) { 7977 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7978 result.add(perm.buildPersistedPublicApiObject()); 7979 } 7980 } 7981 } 7982 } 7983 } 7984 return new ParceledListSlice<android.content.UriPermission>(result); 7985 } 7986 7987 @Override 7988 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7989 synchronized (this) { 7990 ProcessRecord app = 7991 who != null ? getRecordForAppLocked(who) : null; 7992 if (app == null) return; 7993 7994 Message msg = Message.obtain(); 7995 msg.what = WAIT_FOR_DEBUGGER_MSG; 7996 msg.obj = app; 7997 msg.arg1 = waiting ? 1 : 0; 7998 mHandler.sendMessage(msg); 7999 } 8000 } 8001 8002 @Override 8003 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8004 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8005 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8006 outInfo.availMem = Process.getFreeMemory(); 8007 outInfo.totalMem = Process.getTotalMemory(); 8008 outInfo.threshold = homeAppMem; 8009 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8010 outInfo.hiddenAppThreshold = cachedAppMem; 8011 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8012 ProcessList.SERVICE_ADJ); 8013 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8014 ProcessList.VISIBLE_APP_ADJ); 8015 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8016 ProcessList.FOREGROUND_APP_ADJ); 8017 } 8018 8019 // ========================================================= 8020 // TASK MANAGEMENT 8021 // ========================================================= 8022 8023 @Override 8024 public List<IAppTask> getAppTasks(String callingPackage) { 8025 int callingUid = Binder.getCallingUid(); 8026 long ident = Binder.clearCallingIdentity(); 8027 8028 synchronized(this) { 8029 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8030 try { 8031 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8032 8033 final int N = mRecentTasks.size(); 8034 for (int i = 0; i < N; i++) { 8035 TaskRecord tr = mRecentTasks.get(i); 8036 // Skip tasks that do not match the caller. We don't need to verify 8037 // callingPackage, because we are also limiting to callingUid and know 8038 // that will limit to the correct security sandbox. 8039 if (tr.effectiveUid != callingUid) { 8040 continue; 8041 } 8042 Intent intent = tr.getBaseIntent(); 8043 if (intent == null || 8044 !callingPackage.equals(intent.getComponent().getPackageName())) { 8045 continue; 8046 } 8047 ActivityManager.RecentTaskInfo taskInfo = 8048 createRecentTaskInfoFromTaskRecord(tr); 8049 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8050 list.add(taskImpl); 8051 } 8052 } finally { 8053 Binder.restoreCallingIdentity(ident); 8054 } 8055 return list; 8056 } 8057 } 8058 8059 @Override 8060 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8061 final int callingUid = Binder.getCallingUid(); 8062 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8063 8064 synchronized(this) { 8065 if (localLOGV) Slog.v( 8066 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8067 8068 final boolean allowed = checkCallingPermission( 8069 android.Manifest.permission.GET_TASKS) 8070 == PackageManager.PERMISSION_GRANTED; 8071 if (!allowed) { 8072 Slog.w(TAG, "getTasks: caller " + callingUid 8073 + " does not hold GET_TASKS; limiting output"); 8074 } 8075 8076 // TODO: Improve with MRU list from all ActivityStacks. 8077 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8078 } 8079 8080 return list; 8081 } 8082 8083 TaskRecord getMostRecentTask() { 8084 return mRecentTasks.get(0); 8085 } 8086 8087 /** 8088 * Creates a new RecentTaskInfo from a TaskRecord. 8089 */ 8090 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8091 // Update the task description to reflect any changes in the task stack 8092 tr.updateTaskDescription(); 8093 8094 // Compose the recent task info 8095 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8096 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8097 rti.persistentId = tr.taskId; 8098 rti.baseIntent = new Intent(tr.getBaseIntent()); 8099 rti.origActivity = tr.origActivity; 8100 rti.description = tr.lastDescription; 8101 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8102 rti.userId = tr.userId; 8103 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8104 rti.firstActiveTime = tr.firstActiveTime; 8105 rti.lastActiveTime = tr.lastActiveTime; 8106 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8107 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8108 return rti; 8109 } 8110 8111 @Override 8112 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8113 final int callingUid = Binder.getCallingUid(); 8114 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8115 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8116 8117 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8118 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8119 synchronized (this) { 8120 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8121 == PackageManager.PERMISSION_GRANTED; 8122 if (!allowed) { 8123 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8124 + " does not hold GET_TASKS; limiting output"); 8125 } 8126 final boolean detailed = checkCallingPermission( 8127 android.Manifest.permission.GET_DETAILED_TASKS) 8128 == PackageManager.PERMISSION_GRANTED; 8129 8130 final int N = mRecentTasks.size(); 8131 ArrayList<ActivityManager.RecentTaskInfo> res 8132 = new ArrayList<ActivityManager.RecentTaskInfo>( 8133 maxNum < N ? maxNum : N); 8134 8135 final Set<Integer> includedUsers; 8136 if (includeProfiles) { 8137 includedUsers = getProfileIdsLocked(userId); 8138 } else { 8139 includedUsers = new HashSet<Integer>(); 8140 } 8141 includedUsers.add(Integer.valueOf(userId)); 8142 8143 for (int i=0; i<N && maxNum > 0; i++) { 8144 TaskRecord tr = mRecentTasks.get(i); 8145 // Only add calling user or related users recent tasks 8146 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8147 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8148 continue; 8149 } 8150 8151 // Return the entry if desired by the caller. We always return 8152 // the first entry, because callers always expect this to be the 8153 // foreground app. We may filter others if the caller has 8154 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8155 // we should exclude the entry. 8156 8157 if (i == 0 8158 || withExcluded 8159 || (tr.intent == null) 8160 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8161 == 0)) { 8162 if (!allowed) { 8163 // If the caller doesn't have the GET_TASKS permission, then only 8164 // allow them to see a small subset of tasks -- their own and home. 8165 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8166 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8167 continue; 8168 } 8169 } 8170 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8171 if (tr.stack != null && tr.stack.isHomeStack()) { 8172 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8173 continue; 8174 } 8175 } 8176 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8177 // Don't include auto remove tasks that are finished or finishing. 8178 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8179 + tr); 8180 continue; 8181 } 8182 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8183 && !tr.isAvailable) { 8184 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8185 continue; 8186 } 8187 8188 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8189 if (!detailed) { 8190 rti.baseIntent.replaceExtras((Bundle)null); 8191 } 8192 8193 res.add(rti); 8194 maxNum--; 8195 } 8196 } 8197 return res; 8198 } 8199 } 8200 8201 private TaskRecord recentTaskForIdLocked(int id) { 8202 final int N = mRecentTasks.size(); 8203 for (int i=0; i<N; i++) { 8204 TaskRecord tr = mRecentTasks.get(i); 8205 if (tr.taskId == id) { 8206 return tr; 8207 } 8208 } 8209 return null; 8210 } 8211 8212 @Override 8213 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8214 synchronized (this) { 8215 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8216 "getTaskThumbnail()"); 8217 TaskRecord tr = recentTaskForIdLocked(id); 8218 if (tr != null) { 8219 return tr.getTaskThumbnailLocked(); 8220 } 8221 } 8222 return null; 8223 } 8224 8225 @Override 8226 public int addAppTask(IBinder activityToken, Intent intent, 8227 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8228 final int callingUid = Binder.getCallingUid(); 8229 final long callingIdent = Binder.clearCallingIdentity(); 8230 8231 try { 8232 synchronized (this) { 8233 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8234 if (r == null) { 8235 throw new IllegalArgumentException("Activity does not exist; token=" 8236 + activityToken); 8237 } 8238 ComponentName comp = intent.getComponent(); 8239 if (comp == null) { 8240 throw new IllegalArgumentException("Intent " + intent 8241 + " must specify explicit component"); 8242 } 8243 if (thumbnail.getWidth() != mThumbnailWidth 8244 || thumbnail.getHeight() != mThumbnailHeight) { 8245 throw new IllegalArgumentException("Bad thumbnail size: got " 8246 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8247 + mThumbnailWidth + "x" + mThumbnailHeight); 8248 } 8249 if (intent.getSelector() != null) { 8250 intent.setSelector(null); 8251 } 8252 if (intent.getSourceBounds() != null) { 8253 intent.setSourceBounds(null); 8254 } 8255 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8256 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8257 // The caller has added this as an auto-remove task... that makes no 8258 // sense, so turn off auto-remove. 8259 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8260 } 8261 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8262 // Must be a new task. 8263 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8264 } 8265 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8266 mLastAddedTaskActivity = null; 8267 } 8268 ActivityInfo ainfo = mLastAddedTaskActivity; 8269 if (ainfo == null) { 8270 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8271 comp, 0, UserHandle.getUserId(callingUid)); 8272 if (ainfo.applicationInfo.uid != callingUid) { 8273 throw new SecurityException( 8274 "Can't add task for another application: target uid=" 8275 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8276 } 8277 } 8278 8279 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8280 intent, description); 8281 8282 int trimIdx = trimRecentsForTask(task, false); 8283 if (trimIdx >= 0) { 8284 // If this would have caused a trim, then we'll abort because that 8285 // means it would be added at the end of the list but then just removed. 8286 return -1; 8287 } 8288 8289 final int N = mRecentTasks.size(); 8290 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8291 final TaskRecord tr = mRecentTasks.remove(N - 1); 8292 tr.removedFromRecents(mTaskPersister); 8293 } 8294 8295 task.inRecents = true; 8296 mRecentTasks.add(task); 8297 r.task.stack.addTask(task, false, false); 8298 8299 task.setLastThumbnail(thumbnail); 8300 task.freeLastThumbnail(); 8301 8302 return task.taskId; 8303 } 8304 } finally { 8305 Binder.restoreCallingIdentity(callingIdent); 8306 } 8307 } 8308 8309 @Override 8310 public Point getAppTaskThumbnailSize() { 8311 synchronized (this) { 8312 return new Point(mThumbnailWidth, mThumbnailHeight); 8313 } 8314 } 8315 8316 @Override 8317 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8318 synchronized (this) { 8319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8320 if (r != null) { 8321 r.taskDescription = td; 8322 r.task.updateTaskDescription(); 8323 } 8324 } 8325 } 8326 8327 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8328 mRecentTasks.remove(tr); 8329 tr.removedFromRecents(mTaskPersister); 8330 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8331 Intent baseIntent = new Intent( 8332 tr.intent != null ? tr.intent : tr.affinityIntent); 8333 ComponentName component = baseIntent.getComponent(); 8334 if (component == null) { 8335 Slog.w(TAG, "Now component for base intent of task: " + tr); 8336 return; 8337 } 8338 8339 // Find any running services associated with this app. 8340 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8341 8342 if (killProcesses) { 8343 // Find any running processes associated with this app. 8344 final String pkg = component.getPackageName(); 8345 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8346 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8347 for (int i=0; i<pmap.size(); i++) { 8348 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8349 for (int j=0; j<uids.size(); j++) { 8350 ProcessRecord proc = uids.valueAt(j); 8351 if (proc.userId != tr.userId) { 8352 continue; 8353 } 8354 if (!proc.pkgList.containsKey(pkg)) { 8355 continue; 8356 } 8357 procs.add(proc); 8358 } 8359 } 8360 8361 // Kill the running processes. 8362 for (int i=0; i<procs.size(); i++) { 8363 ProcessRecord pr = procs.get(i); 8364 if (pr == mHomeProcess) { 8365 // Don't kill the home process along with tasks from the same package. 8366 continue; 8367 } 8368 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8369 pr.kill("remove task", true); 8370 } else { 8371 pr.waitingToKill = "remove task"; 8372 } 8373 } 8374 } 8375 } 8376 8377 /** 8378 * Removes the task with the specified task id. 8379 * 8380 * @param taskId Identifier of the task to be removed. 8381 * @param flags Additional operational flags. May be 0 or 8382 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8383 * @return Returns true if the given task was found and removed. 8384 */ 8385 private boolean removeTaskByIdLocked(int taskId, int flags) { 8386 TaskRecord tr = recentTaskForIdLocked(taskId); 8387 if (tr != null) { 8388 tr.removeTaskActivitiesLocked(); 8389 cleanUpRemovedTaskLocked(tr, flags); 8390 if (tr.isPersistable) { 8391 notifyTaskPersisterLocked(null, true); 8392 } 8393 return true; 8394 } 8395 return false; 8396 } 8397 8398 @Override 8399 public boolean removeTask(int taskId, int flags) { 8400 synchronized (this) { 8401 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8402 "removeTask()"); 8403 long ident = Binder.clearCallingIdentity(); 8404 try { 8405 return removeTaskByIdLocked(taskId, flags); 8406 } finally { 8407 Binder.restoreCallingIdentity(ident); 8408 } 8409 } 8410 } 8411 8412 /** 8413 * TODO: Add mController hook 8414 */ 8415 @Override 8416 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8417 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8418 "moveTaskToFront()"); 8419 8420 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8421 synchronized(this) { 8422 moveTaskToFrontLocked(taskId, flags, options); 8423 } 8424 } 8425 8426 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8427 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8428 Binder.getCallingUid(), "Task to front")) { 8429 ActivityOptions.abort(options); 8430 return; 8431 } 8432 final long origId = Binder.clearCallingIdentity(); 8433 try { 8434 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8435 if (task == null) { 8436 return; 8437 } 8438 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8439 mStackSupervisor.showLockTaskToast(); 8440 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8441 return; 8442 } 8443 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8444 if (prev != null && prev.isRecentsActivity()) { 8445 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8446 } 8447 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8448 } finally { 8449 Binder.restoreCallingIdentity(origId); 8450 } 8451 ActivityOptions.abort(options); 8452 } 8453 8454 @Override 8455 public void moveTaskToBack(int taskId) { 8456 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8457 "moveTaskToBack()"); 8458 8459 synchronized(this) { 8460 TaskRecord tr = recentTaskForIdLocked(taskId); 8461 if (tr != null) { 8462 if (tr == mStackSupervisor.mLockTaskModeTask) { 8463 mStackSupervisor.showLockTaskToast(); 8464 return; 8465 } 8466 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8467 ActivityStack stack = tr.stack; 8468 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8469 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8470 Binder.getCallingUid(), "Task to back")) { 8471 return; 8472 } 8473 } 8474 final long origId = Binder.clearCallingIdentity(); 8475 try { 8476 stack.moveTaskToBackLocked(taskId, null); 8477 } finally { 8478 Binder.restoreCallingIdentity(origId); 8479 } 8480 } 8481 } 8482 } 8483 8484 /** 8485 * Moves an activity, and all of the other activities within the same task, to the bottom 8486 * of the history stack. The activity's order within the task is unchanged. 8487 * 8488 * @param token A reference to the activity we wish to move 8489 * @param nonRoot If false then this only works if the activity is the root 8490 * of a task; if true it will work for any activity in a task. 8491 * @return Returns true if the move completed, false if not. 8492 */ 8493 @Override 8494 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8495 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8496 synchronized(this) { 8497 final long origId = Binder.clearCallingIdentity(); 8498 try { 8499 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8500 if (taskId >= 0) { 8501 if ((mStackSupervisor.mLockTaskModeTask != null) 8502 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8503 mStackSupervisor.showLockTaskToast(); 8504 return false; 8505 } 8506 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8507 } 8508 } finally { 8509 Binder.restoreCallingIdentity(origId); 8510 } 8511 } 8512 return false; 8513 } 8514 8515 @Override 8516 public void moveTaskBackwards(int task) { 8517 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8518 "moveTaskBackwards()"); 8519 8520 synchronized(this) { 8521 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8522 Binder.getCallingUid(), "Task backwards")) { 8523 return; 8524 } 8525 final long origId = Binder.clearCallingIdentity(); 8526 moveTaskBackwardsLocked(task); 8527 Binder.restoreCallingIdentity(origId); 8528 } 8529 } 8530 8531 private final void moveTaskBackwardsLocked(int task) { 8532 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8533 } 8534 8535 @Override 8536 public IBinder getHomeActivityToken() throws RemoteException { 8537 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8538 "getHomeActivityToken()"); 8539 synchronized (this) { 8540 return mStackSupervisor.getHomeActivityToken(); 8541 } 8542 } 8543 8544 @Override 8545 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8546 IActivityContainerCallback callback) throws RemoteException { 8547 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8548 "createActivityContainer()"); 8549 synchronized (this) { 8550 if (parentActivityToken == null) { 8551 throw new IllegalArgumentException("parent token must not be null"); 8552 } 8553 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8554 if (r == null) { 8555 return null; 8556 } 8557 if (callback == null) { 8558 throw new IllegalArgumentException("callback must not be null"); 8559 } 8560 return mStackSupervisor.createActivityContainer(r, callback); 8561 } 8562 } 8563 8564 @Override 8565 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8566 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8567 "deleteActivityContainer()"); 8568 synchronized (this) { 8569 mStackSupervisor.deleteActivityContainer(container); 8570 } 8571 } 8572 8573 @Override 8574 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8575 throws RemoteException { 8576 synchronized (this) { 8577 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8578 if (stack != null) { 8579 return stack.mActivityContainer; 8580 } 8581 return null; 8582 } 8583 } 8584 8585 @Override 8586 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8587 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8588 "moveTaskToStack()"); 8589 if (stackId == HOME_STACK_ID) { 8590 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8591 new RuntimeException("here").fillInStackTrace()); 8592 } 8593 synchronized (this) { 8594 long ident = Binder.clearCallingIdentity(); 8595 try { 8596 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8597 + stackId + " toTop=" + toTop); 8598 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8599 } finally { 8600 Binder.restoreCallingIdentity(ident); 8601 } 8602 } 8603 } 8604 8605 @Override 8606 public void resizeStack(int stackBoxId, Rect bounds) { 8607 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8608 "resizeStackBox()"); 8609 long ident = Binder.clearCallingIdentity(); 8610 try { 8611 mWindowManager.resizeStack(stackBoxId, bounds); 8612 } finally { 8613 Binder.restoreCallingIdentity(ident); 8614 } 8615 } 8616 8617 @Override 8618 public List<StackInfo> getAllStackInfos() { 8619 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8620 "getAllStackInfos()"); 8621 long ident = Binder.clearCallingIdentity(); 8622 try { 8623 synchronized (this) { 8624 return mStackSupervisor.getAllStackInfosLocked(); 8625 } 8626 } finally { 8627 Binder.restoreCallingIdentity(ident); 8628 } 8629 } 8630 8631 @Override 8632 public StackInfo getStackInfo(int stackId) { 8633 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8634 "getStackInfo()"); 8635 long ident = Binder.clearCallingIdentity(); 8636 try { 8637 synchronized (this) { 8638 return mStackSupervisor.getStackInfoLocked(stackId); 8639 } 8640 } finally { 8641 Binder.restoreCallingIdentity(ident); 8642 } 8643 } 8644 8645 @Override 8646 public boolean isInHomeStack(int taskId) { 8647 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8648 "getStackInfo()"); 8649 long ident = Binder.clearCallingIdentity(); 8650 try { 8651 synchronized (this) { 8652 TaskRecord tr = recentTaskForIdLocked(taskId); 8653 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8654 } 8655 } finally { 8656 Binder.restoreCallingIdentity(ident); 8657 } 8658 } 8659 8660 @Override 8661 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8662 synchronized(this) { 8663 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8664 } 8665 } 8666 8667 private boolean isLockTaskAuthorized(String pkg) { 8668 final DevicePolicyManager dpm = (DevicePolicyManager) 8669 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8670 try { 8671 int uid = mContext.getPackageManager().getPackageUid(pkg, 8672 Binder.getCallingUserHandle().getIdentifier()); 8673 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8674 } catch (NameNotFoundException e) { 8675 return false; 8676 } 8677 } 8678 8679 void startLockTaskMode(TaskRecord task) { 8680 final String pkg; 8681 synchronized (this) { 8682 pkg = task.intent.getComponent().getPackageName(); 8683 } 8684 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8685 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8686 final TaskRecord taskRecord = task; 8687 mHandler.post(new Runnable() { 8688 @Override 8689 public void run() { 8690 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8691 } 8692 }); 8693 return; 8694 } 8695 long ident = Binder.clearCallingIdentity(); 8696 try { 8697 synchronized (this) { 8698 // Since we lost lock on task, make sure it is still there. 8699 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8700 if (task != null) { 8701 if (!isSystemInitiated 8702 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8703 throw new IllegalArgumentException("Invalid task, not in foreground"); 8704 } 8705 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8706 } 8707 } 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public void startLockTaskMode(int taskId) { 8715 final TaskRecord task; 8716 long ident = Binder.clearCallingIdentity(); 8717 try { 8718 synchronized (this) { 8719 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8720 } 8721 } finally { 8722 Binder.restoreCallingIdentity(ident); 8723 } 8724 if (task != null) { 8725 startLockTaskMode(task); 8726 } 8727 } 8728 8729 @Override 8730 public void startLockTaskMode(IBinder token) { 8731 final TaskRecord task; 8732 long ident = Binder.clearCallingIdentity(); 8733 try { 8734 synchronized (this) { 8735 final ActivityRecord r = ActivityRecord.forToken(token); 8736 if (r == null) { 8737 return; 8738 } 8739 task = r.task; 8740 } 8741 } finally { 8742 Binder.restoreCallingIdentity(ident); 8743 } 8744 if (task != null) { 8745 startLockTaskMode(task); 8746 } 8747 } 8748 8749 @Override 8750 public void startLockTaskModeOnCurrent() throws RemoteException { 8751 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8752 "startLockTaskModeOnCurrent"); 8753 ActivityRecord r = null; 8754 synchronized (this) { 8755 r = mStackSupervisor.topRunningActivityLocked(); 8756 } 8757 startLockTaskMode(r.task); 8758 } 8759 8760 @Override 8761 public void stopLockTaskMode() { 8762 // Verify that the user matches the package of the intent for the TaskRecord 8763 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8764 // and stopLockTaskMode. 8765 final int callingUid = Binder.getCallingUid(); 8766 if (callingUid != Process.SYSTEM_UID) { 8767 try { 8768 String pkg = 8769 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8770 int uid = mContext.getPackageManager().getPackageUid(pkg, 8771 Binder.getCallingUserHandle().getIdentifier()); 8772 if (uid != callingUid) { 8773 throw new SecurityException("Invalid uid, expected " + uid); 8774 } 8775 } catch (NameNotFoundException e) { 8776 Log.d(TAG, "stopLockTaskMode " + e); 8777 return; 8778 } 8779 } 8780 long ident = Binder.clearCallingIdentity(); 8781 try { 8782 Log.d(TAG, "stopLockTaskMode"); 8783 // Stop lock task 8784 synchronized (this) { 8785 mStackSupervisor.setLockTaskModeLocked(null, false); 8786 } 8787 } finally { 8788 Binder.restoreCallingIdentity(ident); 8789 } 8790 } 8791 8792 @Override 8793 public void stopLockTaskModeOnCurrent() throws RemoteException { 8794 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8795 "stopLockTaskModeOnCurrent"); 8796 long ident = Binder.clearCallingIdentity(); 8797 try { 8798 stopLockTaskMode(); 8799 } finally { 8800 Binder.restoreCallingIdentity(ident); 8801 } 8802 } 8803 8804 @Override 8805 public boolean isInLockTaskMode() { 8806 synchronized (this) { 8807 return mStackSupervisor.isInLockTaskMode(); 8808 } 8809 } 8810 8811 // ========================================================= 8812 // CONTENT PROVIDERS 8813 // ========================================================= 8814 8815 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8816 List<ProviderInfo> providers = null; 8817 try { 8818 providers = AppGlobals.getPackageManager(). 8819 queryContentProviders(app.processName, app.uid, 8820 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8821 } catch (RemoteException ex) { 8822 } 8823 if (DEBUG_MU) 8824 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8825 int userId = app.userId; 8826 if (providers != null) { 8827 int N = providers.size(); 8828 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8829 for (int i=0; i<N; i++) { 8830 ProviderInfo cpi = 8831 (ProviderInfo)providers.get(i); 8832 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8833 cpi.name, cpi.flags); 8834 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8835 // This is a singleton provider, but a user besides the 8836 // default user is asking to initialize a process it runs 8837 // in... well, no, it doesn't actually run in this process, 8838 // it runs in the process of the default user. Get rid of it. 8839 providers.remove(i); 8840 N--; 8841 i--; 8842 continue; 8843 } 8844 8845 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8846 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8847 if (cpr == null) { 8848 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8849 mProviderMap.putProviderByClass(comp, cpr); 8850 } 8851 if (DEBUG_MU) 8852 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8853 app.pubProviders.put(cpi.name, cpr); 8854 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8855 // Don't add this if it is a platform component that is marked 8856 // to run in multiple processes, because this is actually 8857 // part of the framework so doesn't make sense to track as a 8858 // separate apk in the process. 8859 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8860 mProcessStats); 8861 } 8862 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8863 } 8864 } 8865 return providers; 8866 } 8867 8868 /** 8869 * Check if {@link ProcessRecord} has a possible chance at accessing the 8870 * given {@link ProviderInfo}. Final permission checking is always done 8871 * in {@link ContentProvider}. 8872 */ 8873 private final String checkContentProviderPermissionLocked( 8874 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8875 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8876 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8877 boolean checkedGrants = false; 8878 if (checkUser) { 8879 // Looking for cross-user grants before enforcing the typical cross-users permissions 8880 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8881 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8882 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8883 return null; 8884 } 8885 checkedGrants = true; 8886 } 8887 userId = handleIncomingUser(callingPid, callingUid, userId, 8888 false, ALLOW_NON_FULL, 8889 "checkContentProviderPermissionLocked " + cpi.authority, null); 8890 if (userId != tmpTargetUserId) { 8891 // When we actually went to determine the final targer user ID, this ended 8892 // up different than our initial check for the authority. This is because 8893 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8894 // SELF. So we need to re-check the grants again. 8895 checkedGrants = false; 8896 } 8897 } 8898 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8899 cpi.applicationInfo.uid, cpi.exported) 8900 == PackageManager.PERMISSION_GRANTED) { 8901 return null; 8902 } 8903 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8904 cpi.applicationInfo.uid, cpi.exported) 8905 == PackageManager.PERMISSION_GRANTED) { 8906 return null; 8907 } 8908 8909 PathPermission[] pps = cpi.pathPermissions; 8910 if (pps != null) { 8911 int i = pps.length; 8912 while (i > 0) { 8913 i--; 8914 PathPermission pp = pps[i]; 8915 String pprperm = pp.getReadPermission(); 8916 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8917 cpi.applicationInfo.uid, cpi.exported) 8918 == PackageManager.PERMISSION_GRANTED) { 8919 return null; 8920 } 8921 String ppwperm = pp.getWritePermission(); 8922 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8923 cpi.applicationInfo.uid, cpi.exported) 8924 == PackageManager.PERMISSION_GRANTED) { 8925 return null; 8926 } 8927 } 8928 } 8929 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8930 return null; 8931 } 8932 8933 String msg; 8934 if (!cpi.exported) { 8935 msg = "Permission Denial: opening provider " + cpi.name 8936 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8937 + ", uid=" + callingUid + ") that is not exported from uid " 8938 + cpi.applicationInfo.uid; 8939 } else { 8940 msg = "Permission Denial: opening provider " + cpi.name 8941 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8942 + ", uid=" + callingUid + ") requires " 8943 + cpi.readPermission + " or " + cpi.writePermission; 8944 } 8945 Slog.w(TAG, msg); 8946 return msg; 8947 } 8948 8949 /** 8950 * Returns if the ContentProvider has granted a uri to callingUid 8951 */ 8952 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8953 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8954 if (perms != null) { 8955 for (int i=perms.size()-1; i>=0; i--) { 8956 GrantUri grantUri = perms.keyAt(i); 8957 if (grantUri.sourceUserId == userId || !checkUser) { 8958 if (matchesProvider(grantUri.uri, cpi)) { 8959 return true; 8960 } 8961 } 8962 } 8963 } 8964 return false; 8965 } 8966 8967 /** 8968 * Returns true if the uri authority is one of the authorities specified in the provider. 8969 */ 8970 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8971 String uriAuth = uri.getAuthority(); 8972 String cpiAuth = cpi.authority; 8973 if (cpiAuth.indexOf(';') == -1) { 8974 return cpiAuth.equals(uriAuth); 8975 } 8976 String[] cpiAuths = cpiAuth.split(";"); 8977 int length = cpiAuths.length; 8978 for (int i = 0; i < length; i++) { 8979 if (cpiAuths[i].equals(uriAuth)) return true; 8980 } 8981 return false; 8982 } 8983 8984 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8985 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8986 if (r != null) { 8987 for (int i=0; i<r.conProviders.size(); i++) { 8988 ContentProviderConnection conn = r.conProviders.get(i); 8989 if (conn.provider == cpr) { 8990 if (DEBUG_PROVIDER) Slog.v(TAG, 8991 "Adding provider requested by " 8992 + r.processName + " from process " 8993 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8994 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8995 if (stable) { 8996 conn.stableCount++; 8997 conn.numStableIncs++; 8998 } else { 8999 conn.unstableCount++; 9000 conn.numUnstableIncs++; 9001 } 9002 return conn; 9003 } 9004 } 9005 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9006 if (stable) { 9007 conn.stableCount = 1; 9008 conn.numStableIncs = 1; 9009 } else { 9010 conn.unstableCount = 1; 9011 conn.numUnstableIncs = 1; 9012 } 9013 cpr.connections.add(conn); 9014 r.conProviders.add(conn); 9015 return conn; 9016 } 9017 cpr.addExternalProcessHandleLocked(externalProcessToken); 9018 return null; 9019 } 9020 9021 boolean decProviderCountLocked(ContentProviderConnection conn, 9022 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9023 if (conn != null) { 9024 cpr = conn.provider; 9025 if (DEBUG_PROVIDER) Slog.v(TAG, 9026 "Removing provider requested by " 9027 + conn.client.processName + " from process " 9028 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9029 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9030 if (stable) { 9031 conn.stableCount--; 9032 } else { 9033 conn.unstableCount--; 9034 } 9035 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9036 cpr.connections.remove(conn); 9037 conn.client.conProviders.remove(conn); 9038 return true; 9039 } 9040 return false; 9041 } 9042 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9043 return false; 9044 } 9045 9046 private void checkTime(long startTime, String where) { 9047 long now = SystemClock.elapsedRealtime(); 9048 if ((now-startTime) > 1000) { 9049 // If we are taking more than a second, log about it. 9050 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9051 } 9052 } 9053 9054 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9055 String name, IBinder token, boolean stable, int userId) { 9056 ContentProviderRecord cpr; 9057 ContentProviderConnection conn = null; 9058 ProviderInfo cpi = null; 9059 9060 synchronized(this) { 9061 long startTime = SystemClock.elapsedRealtime(); 9062 9063 ProcessRecord r = null; 9064 if (caller != null) { 9065 r = getRecordForAppLocked(caller); 9066 if (r == null) { 9067 throw new SecurityException( 9068 "Unable to find app for caller " + caller 9069 + " (pid=" + Binder.getCallingPid() 9070 + ") when getting content provider " + name); 9071 } 9072 } 9073 9074 boolean checkCrossUser = true; 9075 9076 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9077 9078 // First check if this content provider has been published... 9079 cpr = mProviderMap.getProviderByName(name, userId); 9080 // If that didn't work, check if it exists for user 0 and then 9081 // verify that it's a singleton provider before using it. 9082 if (cpr == null && userId != UserHandle.USER_OWNER) { 9083 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9084 if (cpr != null) { 9085 cpi = cpr.info; 9086 if (isSingleton(cpi.processName, cpi.applicationInfo, 9087 cpi.name, cpi.flags) 9088 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9089 userId = UserHandle.USER_OWNER; 9090 checkCrossUser = false; 9091 } else { 9092 cpr = null; 9093 cpi = null; 9094 } 9095 } 9096 } 9097 9098 boolean providerRunning = cpr != null; 9099 if (providerRunning) { 9100 cpi = cpr.info; 9101 String msg; 9102 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9103 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9104 != null) { 9105 throw new SecurityException(msg); 9106 } 9107 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9108 9109 if (r != null && cpr.canRunHere(r)) { 9110 // This provider has been published or is in the process 9111 // of being published... but it is also allowed to run 9112 // in the caller's process, so don't make a connection 9113 // and just let the caller instantiate its own instance. 9114 ContentProviderHolder holder = cpr.newHolder(null); 9115 // don't give caller the provider object, it needs 9116 // to make its own. 9117 holder.provider = null; 9118 return holder; 9119 } 9120 9121 final long origId = Binder.clearCallingIdentity(); 9122 9123 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9124 9125 // In this case the provider instance already exists, so we can 9126 // return it right away. 9127 conn = incProviderCountLocked(r, cpr, token, stable); 9128 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9129 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9130 // If this is a perceptible app accessing the provider, 9131 // make sure to count it as being accessed and thus 9132 // back up on the LRU list. This is good because 9133 // content providers are often expensive to start. 9134 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9135 updateLruProcessLocked(cpr.proc, false, null); 9136 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9137 } 9138 } 9139 9140 if (cpr.proc != null) { 9141 if (false) { 9142 if (cpr.name.flattenToShortString().equals( 9143 "com.android.providers.calendar/.CalendarProvider2")) { 9144 Slog.v(TAG, "****************** KILLING " 9145 + cpr.name.flattenToShortString()); 9146 Process.killProcess(cpr.proc.pid); 9147 } 9148 } 9149 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9150 boolean success = updateOomAdjLocked(cpr.proc); 9151 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9152 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9153 // NOTE: there is still a race here where a signal could be 9154 // pending on the process even though we managed to update its 9155 // adj level. Not sure what to do about this, but at least 9156 // the race is now smaller. 9157 if (!success) { 9158 // Uh oh... it looks like the provider's process 9159 // has been killed on us. We need to wait for a new 9160 // process to be started, and make sure its death 9161 // doesn't kill our process. 9162 Slog.i(TAG, 9163 "Existing provider " + cpr.name.flattenToShortString() 9164 + " is crashing; detaching " + r); 9165 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9166 checkTime(startTime, "getContentProviderImpl: before appDied"); 9167 appDiedLocked(cpr.proc); 9168 checkTime(startTime, "getContentProviderImpl: after appDied"); 9169 if (!lastRef) { 9170 // This wasn't the last ref our process had on 9171 // the provider... we have now been killed, bail. 9172 return null; 9173 } 9174 providerRunning = false; 9175 conn = null; 9176 } 9177 } 9178 9179 Binder.restoreCallingIdentity(origId); 9180 } 9181 9182 boolean singleton; 9183 if (!providerRunning) { 9184 try { 9185 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9186 cpi = AppGlobals.getPackageManager(). 9187 resolveContentProvider(name, 9188 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9189 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9190 } catch (RemoteException ex) { 9191 } 9192 if (cpi == null) { 9193 return null; 9194 } 9195 // If the provider is a singleton AND 9196 // (it's a call within the same user || the provider is a 9197 // privileged app) 9198 // Then allow connecting to the singleton provider 9199 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9200 cpi.name, cpi.flags) 9201 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9202 if (singleton) { 9203 userId = UserHandle.USER_OWNER; 9204 } 9205 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9206 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9207 9208 String msg; 9209 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9210 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9211 != null) { 9212 throw new SecurityException(msg); 9213 } 9214 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9215 9216 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9217 && !cpi.processName.equals("system")) { 9218 // If this content provider does not run in the system 9219 // process, and the system is not yet ready to run other 9220 // processes, then fail fast instead of hanging. 9221 throw new IllegalArgumentException( 9222 "Attempt to launch content provider before system ready"); 9223 } 9224 9225 // Make sure that the user who owns this provider is started. If not, 9226 // we don't want to allow it to run. 9227 if (mStartedUsers.get(userId) == null) { 9228 Slog.w(TAG, "Unable to launch app " 9229 + cpi.applicationInfo.packageName + "/" 9230 + cpi.applicationInfo.uid + " for provider " 9231 + name + ": user " + userId + " is stopped"); 9232 return null; 9233 } 9234 9235 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9236 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9237 cpr = mProviderMap.getProviderByClass(comp, userId); 9238 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9239 final boolean firstClass = cpr == null; 9240 if (firstClass) { 9241 try { 9242 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9243 ApplicationInfo ai = 9244 AppGlobals.getPackageManager(). 9245 getApplicationInfo( 9246 cpi.applicationInfo.packageName, 9247 STOCK_PM_FLAGS, userId); 9248 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9249 if (ai == null) { 9250 Slog.w(TAG, "No package info for content provider " 9251 + cpi.name); 9252 return null; 9253 } 9254 ai = getAppInfoForUser(ai, userId); 9255 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9256 } catch (RemoteException ex) { 9257 // pm is in same process, this will never happen. 9258 } 9259 } 9260 9261 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9262 9263 if (r != null && cpr.canRunHere(r)) { 9264 // If this is a multiprocess provider, then just return its 9265 // info and allow the caller to instantiate it. Only do 9266 // this if the provider is the same user as the caller's 9267 // process, or can run as root (so can be in any process). 9268 return cpr.newHolder(null); 9269 } 9270 9271 if (DEBUG_PROVIDER) { 9272 RuntimeException e = new RuntimeException("here"); 9273 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9274 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9275 } 9276 9277 // This is single process, and our app is now connecting to it. 9278 // See if we are already in the process of launching this 9279 // provider. 9280 final int N = mLaunchingProviders.size(); 9281 int i; 9282 for (i=0; i<N; i++) { 9283 if (mLaunchingProviders.get(i) == cpr) { 9284 break; 9285 } 9286 } 9287 9288 // If the provider is not already being launched, then get it 9289 // started. 9290 if (i >= N) { 9291 final long origId = Binder.clearCallingIdentity(); 9292 9293 try { 9294 // Content provider is now in use, its package can't be stopped. 9295 try { 9296 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9297 AppGlobals.getPackageManager().setPackageStoppedState( 9298 cpr.appInfo.packageName, false, userId); 9299 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9300 } catch (RemoteException e) { 9301 } catch (IllegalArgumentException e) { 9302 Slog.w(TAG, "Failed trying to unstop package " 9303 + cpr.appInfo.packageName + ": " + e); 9304 } 9305 9306 // Use existing process if already started 9307 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9308 ProcessRecord proc = getProcessRecordLocked( 9309 cpi.processName, cpr.appInfo.uid, false); 9310 if (proc != null && proc.thread != null) { 9311 if (DEBUG_PROVIDER) { 9312 Slog.d(TAG, "Installing in existing process " + proc); 9313 } 9314 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9315 proc.pubProviders.put(cpi.name, cpr); 9316 try { 9317 proc.thread.scheduleInstallProvider(cpi); 9318 } catch (RemoteException e) { 9319 } 9320 } else { 9321 checkTime(startTime, "getContentProviderImpl: before start process"); 9322 proc = startProcessLocked(cpi.processName, 9323 cpr.appInfo, false, 0, "content provider", 9324 new ComponentName(cpi.applicationInfo.packageName, 9325 cpi.name), false, false, false); 9326 checkTime(startTime, "getContentProviderImpl: after start process"); 9327 if (proc == null) { 9328 Slog.w(TAG, "Unable to launch app " 9329 + cpi.applicationInfo.packageName + "/" 9330 + cpi.applicationInfo.uid + " for provider " 9331 + name + ": process is bad"); 9332 return null; 9333 } 9334 } 9335 cpr.launchingApp = proc; 9336 mLaunchingProviders.add(cpr); 9337 } finally { 9338 Binder.restoreCallingIdentity(origId); 9339 } 9340 } 9341 9342 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9343 9344 // Make sure the provider is published (the same provider class 9345 // may be published under multiple names). 9346 if (firstClass) { 9347 mProviderMap.putProviderByClass(comp, cpr); 9348 } 9349 9350 mProviderMap.putProviderByName(name, cpr); 9351 conn = incProviderCountLocked(r, cpr, token, stable); 9352 if (conn != null) { 9353 conn.waiting = true; 9354 } 9355 } 9356 checkTime(startTime, "getContentProviderImpl: done!"); 9357 } 9358 9359 // Wait for the provider to be published... 9360 synchronized (cpr) { 9361 while (cpr.provider == null) { 9362 if (cpr.launchingApp == null) { 9363 Slog.w(TAG, "Unable to launch app " 9364 + cpi.applicationInfo.packageName + "/" 9365 + cpi.applicationInfo.uid + " for provider " 9366 + name + ": launching app became null"); 9367 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9368 UserHandle.getUserId(cpi.applicationInfo.uid), 9369 cpi.applicationInfo.packageName, 9370 cpi.applicationInfo.uid, name); 9371 return null; 9372 } 9373 try { 9374 if (DEBUG_MU) { 9375 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9376 + cpr.launchingApp); 9377 } 9378 if (conn != null) { 9379 conn.waiting = true; 9380 } 9381 cpr.wait(); 9382 } catch (InterruptedException ex) { 9383 } finally { 9384 if (conn != null) { 9385 conn.waiting = false; 9386 } 9387 } 9388 } 9389 } 9390 return cpr != null ? cpr.newHolder(conn) : null; 9391 } 9392 9393 @Override 9394 public final ContentProviderHolder getContentProvider( 9395 IApplicationThread caller, String name, int userId, boolean stable) { 9396 enforceNotIsolatedCaller("getContentProvider"); 9397 if (caller == null) { 9398 String msg = "null IApplicationThread when getting content provider " 9399 + name; 9400 Slog.w(TAG, msg); 9401 throw new SecurityException(msg); 9402 } 9403 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9404 // with cross-user grant. 9405 return getContentProviderImpl(caller, name, null, stable, userId); 9406 } 9407 9408 public ContentProviderHolder getContentProviderExternal( 9409 String name, int userId, IBinder token) { 9410 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9411 "Do not have permission in call getContentProviderExternal()"); 9412 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9413 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9414 return getContentProviderExternalUnchecked(name, token, userId); 9415 } 9416 9417 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9418 IBinder token, int userId) { 9419 return getContentProviderImpl(null, name, token, true, userId); 9420 } 9421 9422 /** 9423 * Drop a content provider from a ProcessRecord's bookkeeping 9424 */ 9425 public void removeContentProvider(IBinder connection, boolean stable) { 9426 enforceNotIsolatedCaller("removeContentProvider"); 9427 long ident = Binder.clearCallingIdentity(); 9428 try { 9429 synchronized (this) { 9430 ContentProviderConnection conn; 9431 try { 9432 conn = (ContentProviderConnection)connection; 9433 } catch (ClassCastException e) { 9434 String msg ="removeContentProvider: " + connection 9435 + " not a ContentProviderConnection"; 9436 Slog.w(TAG, msg); 9437 throw new IllegalArgumentException(msg); 9438 } 9439 if (conn == null) { 9440 throw new NullPointerException("connection is null"); 9441 } 9442 if (decProviderCountLocked(conn, null, null, stable)) { 9443 updateOomAdjLocked(); 9444 } 9445 } 9446 } finally { 9447 Binder.restoreCallingIdentity(ident); 9448 } 9449 } 9450 9451 public void removeContentProviderExternal(String name, IBinder token) { 9452 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9453 "Do not have permission in call removeContentProviderExternal()"); 9454 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9455 } 9456 9457 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9458 synchronized (this) { 9459 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9460 if(cpr == null) { 9461 //remove from mProvidersByClass 9462 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9463 return; 9464 } 9465 9466 //update content provider record entry info 9467 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9468 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9469 if (localCpr.hasExternalProcessHandles()) { 9470 if (localCpr.removeExternalProcessHandleLocked(token)) { 9471 updateOomAdjLocked(); 9472 } else { 9473 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9474 + " with no external reference for token: " 9475 + token + "."); 9476 } 9477 } else { 9478 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9479 + " with no external references."); 9480 } 9481 } 9482 } 9483 9484 public final void publishContentProviders(IApplicationThread caller, 9485 List<ContentProviderHolder> providers) { 9486 if (providers == null) { 9487 return; 9488 } 9489 9490 enforceNotIsolatedCaller("publishContentProviders"); 9491 synchronized (this) { 9492 final ProcessRecord r = getRecordForAppLocked(caller); 9493 if (DEBUG_MU) 9494 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9495 if (r == null) { 9496 throw new SecurityException( 9497 "Unable to find app for caller " + caller 9498 + " (pid=" + Binder.getCallingPid() 9499 + ") when publishing content providers"); 9500 } 9501 9502 final long origId = Binder.clearCallingIdentity(); 9503 9504 final int N = providers.size(); 9505 for (int i=0; i<N; i++) { 9506 ContentProviderHolder src = providers.get(i); 9507 if (src == null || src.info == null || src.provider == null) { 9508 continue; 9509 } 9510 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9511 if (DEBUG_MU) 9512 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9513 if (dst != null) { 9514 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9515 mProviderMap.putProviderByClass(comp, dst); 9516 String names[] = dst.info.authority.split(";"); 9517 for (int j = 0; j < names.length; j++) { 9518 mProviderMap.putProviderByName(names[j], dst); 9519 } 9520 9521 int NL = mLaunchingProviders.size(); 9522 int j; 9523 for (j=0; j<NL; j++) { 9524 if (mLaunchingProviders.get(j) == dst) { 9525 mLaunchingProviders.remove(j); 9526 j--; 9527 NL--; 9528 } 9529 } 9530 synchronized (dst) { 9531 dst.provider = src.provider; 9532 dst.proc = r; 9533 dst.notifyAll(); 9534 } 9535 updateOomAdjLocked(r); 9536 } 9537 } 9538 9539 Binder.restoreCallingIdentity(origId); 9540 } 9541 } 9542 9543 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9544 ContentProviderConnection conn; 9545 try { 9546 conn = (ContentProviderConnection)connection; 9547 } catch (ClassCastException e) { 9548 String msg ="refContentProvider: " + connection 9549 + " not a ContentProviderConnection"; 9550 Slog.w(TAG, msg); 9551 throw new IllegalArgumentException(msg); 9552 } 9553 if (conn == null) { 9554 throw new NullPointerException("connection is null"); 9555 } 9556 9557 synchronized (this) { 9558 if (stable > 0) { 9559 conn.numStableIncs += stable; 9560 } 9561 stable = conn.stableCount + stable; 9562 if (stable < 0) { 9563 throw new IllegalStateException("stableCount < 0: " + stable); 9564 } 9565 9566 if (unstable > 0) { 9567 conn.numUnstableIncs += unstable; 9568 } 9569 unstable = conn.unstableCount + unstable; 9570 if (unstable < 0) { 9571 throw new IllegalStateException("unstableCount < 0: " + unstable); 9572 } 9573 9574 if ((stable+unstable) <= 0) { 9575 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9576 + stable + " unstable=" + unstable); 9577 } 9578 conn.stableCount = stable; 9579 conn.unstableCount = unstable; 9580 return !conn.dead; 9581 } 9582 } 9583 9584 public void unstableProviderDied(IBinder connection) { 9585 ContentProviderConnection conn; 9586 try { 9587 conn = (ContentProviderConnection)connection; 9588 } catch (ClassCastException e) { 9589 String msg ="refContentProvider: " + connection 9590 + " not a ContentProviderConnection"; 9591 Slog.w(TAG, msg); 9592 throw new IllegalArgumentException(msg); 9593 } 9594 if (conn == null) { 9595 throw new NullPointerException("connection is null"); 9596 } 9597 9598 // Safely retrieve the content provider associated with the connection. 9599 IContentProvider provider; 9600 synchronized (this) { 9601 provider = conn.provider.provider; 9602 } 9603 9604 if (provider == null) { 9605 // Um, yeah, we're way ahead of you. 9606 return; 9607 } 9608 9609 // Make sure the caller is being honest with us. 9610 if (provider.asBinder().pingBinder()) { 9611 // Er, no, still looks good to us. 9612 synchronized (this) { 9613 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9614 + " says " + conn + " died, but we don't agree"); 9615 return; 9616 } 9617 } 9618 9619 // Well look at that! It's dead! 9620 synchronized (this) { 9621 if (conn.provider.provider != provider) { 9622 // But something changed... good enough. 9623 return; 9624 } 9625 9626 ProcessRecord proc = conn.provider.proc; 9627 if (proc == null || proc.thread == null) { 9628 // Seems like the process is already cleaned up. 9629 return; 9630 } 9631 9632 // As far as we're concerned, this is just like receiving a 9633 // death notification... just a bit prematurely. 9634 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9635 + ") early provider death"); 9636 final long ident = Binder.clearCallingIdentity(); 9637 try { 9638 appDiedLocked(proc); 9639 } finally { 9640 Binder.restoreCallingIdentity(ident); 9641 } 9642 } 9643 } 9644 9645 @Override 9646 public void appNotRespondingViaProvider(IBinder connection) { 9647 enforceCallingPermission( 9648 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9649 9650 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9651 if (conn == null) { 9652 Slog.w(TAG, "ContentProviderConnection is null"); 9653 return; 9654 } 9655 9656 final ProcessRecord host = conn.provider.proc; 9657 if (host == null) { 9658 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9659 return; 9660 } 9661 9662 final long token = Binder.clearCallingIdentity(); 9663 try { 9664 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9665 } finally { 9666 Binder.restoreCallingIdentity(token); 9667 } 9668 } 9669 9670 public final void installSystemProviders() { 9671 List<ProviderInfo> providers; 9672 synchronized (this) { 9673 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9674 providers = generateApplicationProvidersLocked(app); 9675 if (providers != null) { 9676 for (int i=providers.size()-1; i>=0; i--) { 9677 ProviderInfo pi = (ProviderInfo)providers.get(i); 9678 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9679 Slog.w(TAG, "Not installing system proc provider " + pi.name 9680 + ": not system .apk"); 9681 providers.remove(i); 9682 } 9683 } 9684 } 9685 } 9686 if (providers != null) { 9687 mSystemThread.installSystemProviders(providers); 9688 } 9689 9690 mCoreSettingsObserver = new CoreSettingsObserver(this); 9691 9692 //mUsageStatsService.monitorPackages(); 9693 } 9694 9695 /** 9696 * Allows apps to retrieve the MIME type of a URI. 9697 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9698 * users, then it does not need permission to access the ContentProvider. 9699 * Either, it needs cross-user uri grants. 9700 * 9701 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9702 * 9703 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9704 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9705 */ 9706 public String getProviderMimeType(Uri uri, int userId) { 9707 enforceNotIsolatedCaller("getProviderMimeType"); 9708 final String name = uri.getAuthority(); 9709 int callingUid = Binder.getCallingUid(); 9710 int callingPid = Binder.getCallingPid(); 9711 long ident = 0; 9712 boolean clearedIdentity = false; 9713 userId = unsafeConvertIncomingUser(userId); 9714 if (UserHandle.getUserId(callingUid) != userId) { 9715 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9716 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9717 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9718 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9719 clearedIdentity = true; 9720 ident = Binder.clearCallingIdentity(); 9721 } 9722 } 9723 ContentProviderHolder holder = null; 9724 try { 9725 holder = getContentProviderExternalUnchecked(name, null, userId); 9726 if (holder != null) { 9727 return holder.provider.getType(uri); 9728 } 9729 } catch (RemoteException e) { 9730 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9731 return null; 9732 } finally { 9733 // We need to clear the identity to call removeContentProviderExternalUnchecked 9734 if (!clearedIdentity) { 9735 ident = Binder.clearCallingIdentity(); 9736 } 9737 try { 9738 if (holder != null) { 9739 removeContentProviderExternalUnchecked(name, null, userId); 9740 } 9741 } finally { 9742 Binder.restoreCallingIdentity(ident); 9743 } 9744 } 9745 9746 return null; 9747 } 9748 9749 // ========================================================= 9750 // GLOBAL MANAGEMENT 9751 // ========================================================= 9752 9753 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9754 boolean isolated, int isolatedUid) { 9755 String proc = customProcess != null ? customProcess : info.processName; 9756 BatteryStatsImpl.Uid.Proc ps = null; 9757 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9758 int uid = info.uid; 9759 if (isolated) { 9760 if (isolatedUid == 0) { 9761 int userId = UserHandle.getUserId(uid); 9762 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9763 while (true) { 9764 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9765 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9766 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9767 } 9768 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9769 mNextIsolatedProcessUid++; 9770 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9771 // No process for this uid, use it. 9772 break; 9773 } 9774 stepsLeft--; 9775 if (stepsLeft <= 0) { 9776 return null; 9777 } 9778 } 9779 } else { 9780 // Special case for startIsolatedProcess (internal only), where 9781 // the uid of the isolated process is specified by the caller. 9782 uid = isolatedUid; 9783 } 9784 } 9785 return new ProcessRecord(stats, info, proc, uid); 9786 } 9787 9788 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9789 String abiOverride) { 9790 ProcessRecord app; 9791 if (!isolated) { 9792 app = getProcessRecordLocked(info.processName, info.uid, true); 9793 } else { 9794 app = null; 9795 } 9796 9797 if (app == null) { 9798 app = newProcessRecordLocked(info, null, isolated, 0); 9799 mProcessNames.put(info.processName, app.uid, app); 9800 if (isolated) { 9801 mIsolatedProcesses.put(app.uid, app); 9802 } 9803 updateLruProcessLocked(app, false, null); 9804 updateOomAdjLocked(); 9805 } 9806 9807 // This package really, really can not be stopped. 9808 try { 9809 AppGlobals.getPackageManager().setPackageStoppedState( 9810 info.packageName, false, UserHandle.getUserId(app.uid)); 9811 } catch (RemoteException e) { 9812 } catch (IllegalArgumentException e) { 9813 Slog.w(TAG, "Failed trying to unstop package " 9814 + info.packageName + ": " + e); 9815 } 9816 9817 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9818 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9819 app.persistent = true; 9820 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9821 } 9822 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9823 mPersistentStartingProcesses.add(app); 9824 startProcessLocked(app, "added application", app.processName, abiOverride, 9825 null /* entryPoint */, null /* entryPointArgs */); 9826 } 9827 9828 return app; 9829 } 9830 9831 public void unhandledBack() { 9832 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9833 "unhandledBack()"); 9834 9835 synchronized(this) { 9836 final long origId = Binder.clearCallingIdentity(); 9837 try { 9838 getFocusedStack().unhandledBackLocked(); 9839 } finally { 9840 Binder.restoreCallingIdentity(origId); 9841 } 9842 } 9843 } 9844 9845 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9846 enforceNotIsolatedCaller("openContentUri"); 9847 final int userId = UserHandle.getCallingUserId(); 9848 String name = uri.getAuthority(); 9849 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9850 ParcelFileDescriptor pfd = null; 9851 if (cph != null) { 9852 // We record the binder invoker's uid in thread-local storage before 9853 // going to the content provider to open the file. Later, in the code 9854 // that handles all permissions checks, we look for this uid and use 9855 // that rather than the Activity Manager's own uid. The effect is that 9856 // we do the check against the caller's permissions even though it looks 9857 // to the content provider like the Activity Manager itself is making 9858 // the request. 9859 sCallerIdentity.set(new Identity( 9860 Binder.getCallingPid(), Binder.getCallingUid())); 9861 try { 9862 pfd = cph.provider.openFile(null, uri, "r", null); 9863 } catch (FileNotFoundException e) { 9864 // do nothing; pfd will be returned null 9865 } finally { 9866 // Ensure that whatever happens, we clean up the identity state 9867 sCallerIdentity.remove(); 9868 } 9869 9870 // We've got the fd now, so we're done with the provider. 9871 removeContentProviderExternalUnchecked(name, null, userId); 9872 } else { 9873 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9874 } 9875 return pfd; 9876 } 9877 9878 // Actually is sleeping or shutting down or whatever else in the future 9879 // is an inactive state. 9880 public boolean isSleepingOrShuttingDown() { 9881 return mSleeping || mShuttingDown; 9882 } 9883 9884 public boolean isSleeping() { 9885 return mSleeping; 9886 } 9887 9888 void goingToSleep() { 9889 synchronized(this) { 9890 mWentToSleep = true; 9891 updateEventDispatchingLocked(); 9892 goToSleepIfNeededLocked(); 9893 } 9894 } 9895 9896 void finishRunningVoiceLocked() { 9897 if (mRunningVoice) { 9898 mRunningVoice = false; 9899 goToSleepIfNeededLocked(); 9900 } 9901 } 9902 9903 void goToSleepIfNeededLocked() { 9904 if (mWentToSleep && !mRunningVoice) { 9905 if (!mSleeping) { 9906 mSleeping = true; 9907 mStackSupervisor.goingToSleepLocked(); 9908 9909 // Initialize the wake times of all processes. 9910 checkExcessivePowerUsageLocked(false); 9911 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9912 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9913 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9914 } 9915 } 9916 } 9917 9918 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9919 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9920 // Never persist the home stack. 9921 return; 9922 } 9923 mTaskPersister.wakeup(task, flush); 9924 } 9925 9926 @Override 9927 public boolean shutdown(int timeout) { 9928 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9929 != PackageManager.PERMISSION_GRANTED) { 9930 throw new SecurityException("Requires permission " 9931 + android.Manifest.permission.SHUTDOWN); 9932 } 9933 9934 boolean timedout = false; 9935 9936 synchronized(this) { 9937 mShuttingDown = true; 9938 updateEventDispatchingLocked(); 9939 timedout = mStackSupervisor.shutdownLocked(timeout); 9940 } 9941 9942 mAppOpsService.shutdown(); 9943 if (mUsageStatsService != null) { 9944 mUsageStatsService.prepareShutdown(); 9945 } 9946 mBatteryStatsService.shutdown(); 9947 synchronized (this) { 9948 mProcessStats.shutdownLocked(); 9949 } 9950 notifyTaskPersisterLocked(null, true); 9951 9952 return timedout; 9953 } 9954 9955 public final void activitySlept(IBinder token) { 9956 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9957 9958 final long origId = Binder.clearCallingIdentity(); 9959 9960 synchronized (this) { 9961 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9962 if (r != null) { 9963 mStackSupervisor.activitySleptLocked(r); 9964 } 9965 } 9966 9967 Binder.restoreCallingIdentity(origId); 9968 } 9969 9970 void logLockScreen(String msg) { 9971 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9972 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9973 mWentToSleep + " mSleeping=" + mSleeping); 9974 } 9975 9976 private void comeOutOfSleepIfNeededLocked() { 9977 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9978 if (mSleeping) { 9979 mSleeping = false; 9980 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9981 } 9982 } 9983 } 9984 9985 void wakingUp() { 9986 synchronized(this) { 9987 mWentToSleep = false; 9988 updateEventDispatchingLocked(); 9989 comeOutOfSleepIfNeededLocked(); 9990 } 9991 } 9992 9993 void startRunningVoiceLocked() { 9994 if (!mRunningVoice) { 9995 mRunningVoice = true; 9996 comeOutOfSleepIfNeededLocked(); 9997 } 9998 } 9999 10000 private void updateEventDispatchingLocked() { 10001 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10002 } 10003 10004 public void setLockScreenShown(boolean shown) { 10005 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10006 != PackageManager.PERMISSION_GRANTED) { 10007 throw new SecurityException("Requires permission " 10008 + android.Manifest.permission.DEVICE_POWER); 10009 } 10010 10011 synchronized(this) { 10012 long ident = Binder.clearCallingIdentity(); 10013 try { 10014 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10015 mLockScreenShown = shown; 10016 comeOutOfSleepIfNeededLocked(); 10017 } finally { 10018 Binder.restoreCallingIdentity(ident); 10019 } 10020 } 10021 } 10022 10023 @Override 10024 public void stopAppSwitches() { 10025 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10026 != PackageManager.PERMISSION_GRANTED) { 10027 throw new SecurityException("Requires permission " 10028 + android.Manifest.permission.STOP_APP_SWITCHES); 10029 } 10030 10031 synchronized(this) { 10032 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10033 + APP_SWITCH_DELAY_TIME; 10034 mDidAppSwitch = false; 10035 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10036 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10037 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10038 } 10039 } 10040 10041 public void resumeAppSwitches() { 10042 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10043 != PackageManager.PERMISSION_GRANTED) { 10044 throw new SecurityException("Requires permission " 10045 + android.Manifest.permission.STOP_APP_SWITCHES); 10046 } 10047 10048 synchronized(this) { 10049 // Note that we don't execute any pending app switches... we will 10050 // let those wait until either the timeout, or the next start 10051 // activity request. 10052 mAppSwitchesAllowedTime = 0; 10053 } 10054 } 10055 10056 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10057 String name) { 10058 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10059 return true; 10060 } 10061 10062 final int perm = checkComponentPermission( 10063 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10064 callingUid, -1, true); 10065 if (perm == PackageManager.PERMISSION_GRANTED) { 10066 return true; 10067 } 10068 10069 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10070 return false; 10071 } 10072 10073 public void setDebugApp(String packageName, boolean waitForDebugger, 10074 boolean persistent) { 10075 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10076 "setDebugApp()"); 10077 10078 long ident = Binder.clearCallingIdentity(); 10079 try { 10080 // Note that this is not really thread safe if there are multiple 10081 // callers into it at the same time, but that's not a situation we 10082 // care about. 10083 if (persistent) { 10084 final ContentResolver resolver = mContext.getContentResolver(); 10085 Settings.Global.putString( 10086 resolver, Settings.Global.DEBUG_APP, 10087 packageName); 10088 Settings.Global.putInt( 10089 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10090 waitForDebugger ? 1 : 0); 10091 } 10092 10093 synchronized (this) { 10094 if (!persistent) { 10095 mOrigDebugApp = mDebugApp; 10096 mOrigWaitForDebugger = mWaitForDebugger; 10097 } 10098 mDebugApp = packageName; 10099 mWaitForDebugger = waitForDebugger; 10100 mDebugTransient = !persistent; 10101 if (packageName != null) { 10102 forceStopPackageLocked(packageName, -1, false, false, true, true, 10103 false, UserHandle.USER_ALL, "set debug app"); 10104 } 10105 } 10106 } finally { 10107 Binder.restoreCallingIdentity(ident); 10108 } 10109 } 10110 10111 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10112 synchronized (this) { 10113 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10114 if (!isDebuggable) { 10115 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10116 throw new SecurityException("Process not debuggable: " + app.packageName); 10117 } 10118 } 10119 10120 mOpenGlTraceApp = processName; 10121 } 10122 } 10123 10124 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10125 synchronized (this) { 10126 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10127 if (!isDebuggable) { 10128 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10129 throw new SecurityException("Process not debuggable: " + app.packageName); 10130 } 10131 } 10132 mProfileApp = processName; 10133 mProfileFile = profilerInfo.profileFile; 10134 if (mProfileFd != null) { 10135 try { 10136 mProfileFd.close(); 10137 } catch (IOException e) { 10138 } 10139 mProfileFd = null; 10140 } 10141 mProfileFd = profilerInfo.profileFd; 10142 mSamplingInterval = profilerInfo.samplingInterval; 10143 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10144 mProfileType = 0; 10145 } 10146 } 10147 10148 @Override 10149 public void setAlwaysFinish(boolean enabled) { 10150 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10151 "setAlwaysFinish()"); 10152 10153 Settings.Global.putInt( 10154 mContext.getContentResolver(), 10155 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10156 10157 synchronized (this) { 10158 mAlwaysFinishActivities = enabled; 10159 } 10160 } 10161 10162 @Override 10163 public void setActivityController(IActivityController controller) { 10164 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10165 "setActivityController()"); 10166 synchronized (this) { 10167 mController = controller; 10168 Watchdog.getInstance().setActivityController(controller); 10169 } 10170 } 10171 10172 @Override 10173 public void setUserIsMonkey(boolean userIsMonkey) { 10174 synchronized (this) { 10175 synchronized (mPidsSelfLocked) { 10176 final int callingPid = Binder.getCallingPid(); 10177 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10178 if (precessRecord == null) { 10179 throw new SecurityException("Unknown process: " + callingPid); 10180 } 10181 if (precessRecord.instrumentationUiAutomationConnection == null) { 10182 throw new SecurityException("Only an instrumentation process " 10183 + "with a UiAutomation can call setUserIsMonkey"); 10184 } 10185 } 10186 mUserIsMonkey = userIsMonkey; 10187 } 10188 } 10189 10190 @Override 10191 public boolean isUserAMonkey() { 10192 synchronized (this) { 10193 // If there is a controller also implies the user is a monkey. 10194 return (mUserIsMonkey || mController != null); 10195 } 10196 } 10197 10198 public void requestBugReport() { 10199 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10200 SystemProperties.set("ctl.start", "bugreport"); 10201 } 10202 10203 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10204 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10205 } 10206 10207 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10208 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10209 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10210 } 10211 return KEY_DISPATCHING_TIMEOUT; 10212 } 10213 10214 @Override 10215 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10216 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10217 != PackageManager.PERMISSION_GRANTED) { 10218 throw new SecurityException("Requires permission " 10219 + android.Manifest.permission.FILTER_EVENTS); 10220 } 10221 ProcessRecord proc; 10222 long timeout; 10223 synchronized (this) { 10224 synchronized (mPidsSelfLocked) { 10225 proc = mPidsSelfLocked.get(pid); 10226 } 10227 timeout = getInputDispatchingTimeoutLocked(proc); 10228 } 10229 10230 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10231 return -1; 10232 } 10233 10234 return timeout; 10235 } 10236 10237 /** 10238 * Handle input dispatching timeouts. 10239 * Returns whether input dispatching should be aborted or not. 10240 */ 10241 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10242 final ActivityRecord activity, final ActivityRecord parent, 10243 final boolean aboveSystem, String reason) { 10244 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10245 != PackageManager.PERMISSION_GRANTED) { 10246 throw new SecurityException("Requires permission " 10247 + android.Manifest.permission.FILTER_EVENTS); 10248 } 10249 10250 final String annotation; 10251 if (reason == null) { 10252 annotation = "Input dispatching timed out"; 10253 } else { 10254 annotation = "Input dispatching timed out (" + reason + ")"; 10255 } 10256 10257 if (proc != null) { 10258 synchronized (this) { 10259 if (proc.debugging) { 10260 return false; 10261 } 10262 10263 if (mDidDexOpt) { 10264 // Give more time since we were dexopting. 10265 mDidDexOpt = false; 10266 return false; 10267 } 10268 10269 if (proc.instrumentationClass != null) { 10270 Bundle info = new Bundle(); 10271 info.putString("shortMsg", "keyDispatchingTimedOut"); 10272 info.putString("longMsg", annotation); 10273 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10274 return true; 10275 } 10276 } 10277 mHandler.post(new Runnable() { 10278 @Override 10279 public void run() { 10280 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10281 } 10282 }); 10283 } 10284 10285 return true; 10286 } 10287 10288 public Bundle getAssistContextExtras(int requestType) { 10289 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10290 "getAssistContextExtras()"); 10291 PendingAssistExtras pae; 10292 Bundle extras = new Bundle(); 10293 synchronized (this) { 10294 ActivityRecord activity = getFocusedStack().mResumedActivity; 10295 if (activity == null) { 10296 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10297 return null; 10298 } 10299 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10300 if (activity.app == null || activity.app.thread == null) { 10301 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10302 return extras; 10303 } 10304 if (activity.app.pid == Binder.getCallingPid()) { 10305 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10306 return extras; 10307 } 10308 pae = new PendingAssistExtras(activity); 10309 try { 10310 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10311 requestType); 10312 mPendingAssistExtras.add(pae); 10313 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10314 } catch (RemoteException e) { 10315 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10316 return extras; 10317 } 10318 } 10319 synchronized (pae) { 10320 while (!pae.haveResult) { 10321 try { 10322 pae.wait(); 10323 } catch (InterruptedException e) { 10324 } 10325 } 10326 if (pae.result != null) { 10327 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10328 } 10329 } 10330 synchronized (this) { 10331 mPendingAssistExtras.remove(pae); 10332 mHandler.removeCallbacks(pae); 10333 } 10334 return extras; 10335 } 10336 10337 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10338 PendingAssistExtras pae = (PendingAssistExtras)token; 10339 synchronized (pae) { 10340 pae.result = extras; 10341 pae.haveResult = true; 10342 pae.notifyAll(); 10343 } 10344 } 10345 10346 public void registerProcessObserver(IProcessObserver observer) { 10347 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10348 "registerProcessObserver()"); 10349 synchronized (this) { 10350 mProcessObservers.register(observer); 10351 } 10352 } 10353 10354 @Override 10355 public void unregisterProcessObserver(IProcessObserver observer) { 10356 synchronized (this) { 10357 mProcessObservers.unregister(observer); 10358 } 10359 } 10360 10361 @Override 10362 public boolean convertFromTranslucent(IBinder token) { 10363 final long origId = Binder.clearCallingIdentity(); 10364 try { 10365 synchronized (this) { 10366 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10367 if (r == null) { 10368 return false; 10369 } 10370 final boolean translucentChanged = r.changeWindowTranslucency(true); 10371 if (translucentChanged) { 10372 r.task.stack.releaseBackgroundResources(); 10373 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10374 } 10375 mWindowManager.setAppFullscreen(token, true); 10376 return translucentChanged; 10377 } 10378 } finally { 10379 Binder.restoreCallingIdentity(origId); 10380 } 10381 } 10382 10383 @Override 10384 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10385 final long origId = Binder.clearCallingIdentity(); 10386 try { 10387 synchronized (this) { 10388 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10389 if (r == null) { 10390 return false; 10391 } 10392 int index = r.task.mActivities.lastIndexOf(r); 10393 if (index > 0) { 10394 ActivityRecord under = r.task.mActivities.get(index - 1); 10395 under.returningOptions = options; 10396 } 10397 final boolean translucentChanged = r.changeWindowTranslucency(false); 10398 if (translucentChanged) { 10399 r.task.stack.convertToTranslucent(r); 10400 } 10401 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10402 mWindowManager.setAppFullscreen(token, false); 10403 return translucentChanged; 10404 } 10405 } finally { 10406 Binder.restoreCallingIdentity(origId); 10407 } 10408 } 10409 10410 @Override 10411 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10412 final long origId = Binder.clearCallingIdentity(); 10413 try { 10414 synchronized (this) { 10415 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10416 if (r != null) { 10417 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10418 } 10419 } 10420 return false; 10421 } finally { 10422 Binder.restoreCallingIdentity(origId); 10423 } 10424 } 10425 10426 @Override 10427 public boolean isBackgroundVisibleBehind(IBinder token) { 10428 final long origId = Binder.clearCallingIdentity(); 10429 try { 10430 synchronized (this) { 10431 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10432 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10433 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10434 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10435 return visible; 10436 } 10437 } finally { 10438 Binder.restoreCallingIdentity(origId); 10439 } 10440 } 10441 10442 @Override 10443 public ActivityOptions getActivityOptions(IBinder token) { 10444 final long origId = Binder.clearCallingIdentity(); 10445 try { 10446 synchronized (this) { 10447 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10448 if (r != null) { 10449 final ActivityOptions activityOptions = r.pendingOptions; 10450 r.pendingOptions = null; 10451 return activityOptions; 10452 } 10453 return null; 10454 } 10455 } finally { 10456 Binder.restoreCallingIdentity(origId); 10457 } 10458 } 10459 10460 @Override 10461 public void setImmersive(IBinder token, boolean immersive) { 10462 synchronized(this) { 10463 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10464 if (r == null) { 10465 throw new IllegalArgumentException(); 10466 } 10467 r.immersive = immersive; 10468 10469 // update associated state if we're frontmost 10470 if (r == mFocusedActivity) { 10471 if (DEBUG_IMMERSIVE) { 10472 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10473 } 10474 applyUpdateLockStateLocked(r); 10475 } 10476 } 10477 } 10478 10479 @Override 10480 public boolean isImmersive(IBinder token) { 10481 synchronized (this) { 10482 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10483 if (r == null) { 10484 throw new IllegalArgumentException(); 10485 } 10486 return r.immersive; 10487 } 10488 } 10489 10490 public boolean isTopActivityImmersive() { 10491 enforceNotIsolatedCaller("startActivity"); 10492 synchronized (this) { 10493 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10494 return (r != null) ? r.immersive : false; 10495 } 10496 } 10497 10498 @Override 10499 public boolean isTopOfTask(IBinder token) { 10500 synchronized (this) { 10501 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10502 if (r == null) { 10503 throw new IllegalArgumentException(); 10504 } 10505 return r.task.getTopActivity() == r; 10506 } 10507 } 10508 10509 public final void enterSafeMode() { 10510 synchronized(this) { 10511 // It only makes sense to do this before the system is ready 10512 // and started launching other packages. 10513 if (!mSystemReady) { 10514 try { 10515 AppGlobals.getPackageManager().enterSafeMode(); 10516 } catch (RemoteException e) { 10517 } 10518 } 10519 10520 mSafeMode = true; 10521 } 10522 } 10523 10524 public final void showSafeModeOverlay() { 10525 View v = LayoutInflater.from(mContext).inflate( 10526 com.android.internal.R.layout.safe_mode, null); 10527 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10528 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10529 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10530 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10531 lp.gravity = Gravity.BOTTOM | Gravity.START; 10532 lp.format = v.getBackground().getOpacity(); 10533 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10534 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10535 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10536 ((WindowManager)mContext.getSystemService( 10537 Context.WINDOW_SERVICE)).addView(v, lp); 10538 } 10539 10540 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10541 if (!(sender instanceof PendingIntentRecord)) { 10542 return; 10543 } 10544 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10545 synchronized (stats) { 10546 if (mBatteryStatsService.isOnBattery()) { 10547 mBatteryStatsService.enforceCallingPermission(); 10548 PendingIntentRecord rec = (PendingIntentRecord)sender; 10549 int MY_UID = Binder.getCallingUid(); 10550 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10551 BatteryStatsImpl.Uid.Pkg pkg = 10552 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10553 sourcePkg != null ? sourcePkg : rec.key.packageName); 10554 pkg.incWakeupsLocked(); 10555 } 10556 } 10557 } 10558 10559 public boolean killPids(int[] pids, String pReason, boolean secure) { 10560 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10561 throw new SecurityException("killPids only available to the system"); 10562 } 10563 String reason = (pReason == null) ? "Unknown" : pReason; 10564 // XXX Note: don't acquire main activity lock here, because the window 10565 // manager calls in with its locks held. 10566 10567 boolean killed = false; 10568 synchronized (mPidsSelfLocked) { 10569 int[] types = new int[pids.length]; 10570 int worstType = 0; 10571 for (int i=0; i<pids.length; i++) { 10572 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10573 if (proc != null) { 10574 int type = proc.setAdj; 10575 types[i] = type; 10576 if (type > worstType) { 10577 worstType = type; 10578 } 10579 } 10580 } 10581 10582 // If the worst oom_adj is somewhere in the cached proc LRU range, 10583 // then constrain it so we will kill all cached procs. 10584 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10585 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10586 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10587 } 10588 10589 // If this is not a secure call, don't let it kill processes that 10590 // are important. 10591 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10592 worstType = ProcessList.SERVICE_ADJ; 10593 } 10594 10595 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10596 for (int i=0; i<pids.length; i++) { 10597 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10598 if (proc == null) { 10599 continue; 10600 } 10601 int adj = proc.setAdj; 10602 if (adj >= worstType && !proc.killedByAm) { 10603 proc.kill(reason, true); 10604 killed = true; 10605 } 10606 } 10607 } 10608 return killed; 10609 } 10610 10611 @Override 10612 public void killUid(int uid, String reason) { 10613 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10614 throw new SecurityException("killUid only available to the system"); 10615 } 10616 synchronized (this) { 10617 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10618 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10619 reason != null ? reason : "kill uid"); 10620 } 10621 } 10622 10623 @Override 10624 public boolean killProcessesBelowForeground(String reason) { 10625 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10626 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10627 } 10628 10629 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10630 } 10631 10632 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10633 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10634 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10635 } 10636 10637 boolean killed = false; 10638 synchronized (mPidsSelfLocked) { 10639 final int size = mPidsSelfLocked.size(); 10640 for (int i = 0; i < size; i++) { 10641 final int pid = mPidsSelfLocked.keyAt(i); 10642 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10643 if (proc == null) continue; 10644 10645 final int adj = proc.setAdj; 10646 if (adj > belowAdj && !proc.killedByAm) { 10647 proc.kill(reason, true); 10648 killed = true; 10649 } 10650 } 10651 } 10652 return killed; 10653 } 10654 10655 @Override 10656 public void hang(final IBinder who, boolean allowRestart) { 10657 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10658 != PackageManager.PERMISSION_GRANTED) { 10659 throw new SecurityException("Requires permission " 10660 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10661 } 10662 10663 final IBinder.DeathRecipient death = new DeathRecipient() { 10664 @Override 10665 public void binderDied() { 10666 synchronized (this) { 10667 notifyAll(); 10668 } 10669 } 10670 }; 10671 10672 try { 10673 who.linkToDeath(death, 0); 10674 } catch (RemoteException e) { 10675 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10676 return; 10677 } 10678 10679 synchronized (this) { 10680 Watchdog.getInstance().setAllowRestart(allowRestart); 10681 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10682 synchronized (death) { 10683 while (who.isBinderAlive()) { 10684 try { 10685 death.wait(); 10686 } catch (InterruptedException e) { 10687 } 10688 } 10689 } 10690 Watchdog.getInstance().setAllowRestart(true); 10691 } 10692 } 10693 10694 @Override 10695 public void restart() { 10696 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10697 != PackageManager.PERMISSION_GRANTED) { 10698 throw new SecurityException("Requires permission " 10699 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10700 } 10701 10702 Log.i(TAG, "Sending shutdown broadcast..."); 10703 10704 BroadcastReceiver br = new BroadcastReceiver() { 10705 @Override public void onReceive(Context context, Intent intent) { 10706 // Now the broadcast is done, finish up the low-level shutdown. 10707 Log.i(TAG, "Shutting down activity manager..."); 10708 shutdown(10000); 10709 Log.i(TAG, "Shutdown complete, restarting!"); 10710 Process.killProcess(Process.myPid()); 10711 System.exit(10); 10712 } 10713 }; 10714 10715 // First send the high-level shut down broadcast. 10716 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10717 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10718 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10719 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10720 mContext.sendOrderedBroadcastAsUser(intent, 10721 UserHandle.ALL, null, br, mHandler, 0, null, null); 10722 */ 10723 br.onReceive(mContext, intent); 10724 } 10725 10726 private long getLowRamTimeSinceIdle(long now) { 10727 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10728 } 10729 10730 @Override 10731 public void performIdleMaintenance() { 10732 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10733 != PackageManager.PERMISSION_GRANTED) { 10734 throw new SecurityException("Requires permission " 10735 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10736 } 10737 10738 synchronized (this) { 10739 final long now = SystemClock.uptimeMillis(); 10740 final long timeSinceLastIdle = now - mLastIdleTime; 10741 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10742 mLastIdleTime = now; 10743 mLowRamTimeSinceLastIdle = 0; 10744 if (mLowRamStartTime != 0) { 10745 mLowRamStartTime = now; 10746 } 10747 10748 StringBuilder sb = new StringBuilder(128); 10749 sb.append("Idle maintenance over "); 10750 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10751 sb.append(" low RAM for "); 10752 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10753 Slog.i(TAG, sb.toString()); 10754 10755 // If at least 1/3 of our time since the last idle period has been spent 10756 // with RAM low, then we want to kill processes. 10757 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10758 10759 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10760 ProcessRecord proc = mLruProcesses.get(i); 10761 if (proc.notCachedSinceIdle) { 10762 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10763 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10764 if (doKilling && proc.initialIdlePss != 0 10765 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10766 proc.kill("idle maint (pss " + proc.lastPss 10767 + " from " + proc.initialIdlePss + ")", true); 10768 } 10769 } 10770 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10771 proc.notCachedSinceIdle = true; 10772 proc.initialIdlePss = 0; 10773 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10774 isSleeping(), now); 10775 } 10776 } 10777 10778 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10779 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10780 } 10781 } 10782 10783 private void retrieveSettings() { 10784 final ContentResolver resolver = mContext.getContentResolver(); 10785 String debugApp = Settings.Global.getString( 10786 resolver, Settings.Global.DEBUG_APP); 10787 boolean waitForDebugger = Settings.Global.getInt( 10788 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10789 boolean alwaysFinishActivities = Settings.Global.getInt( 10790 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10791 boolean forceRtl = Settings.Global.getInt( 10792 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10793 // Transfer any global setting for forcing RTL layout, into a System Property 10794 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10795 10796 Configuration configuration = new Configuration(); 10797 Settings.System.getConfiguration(resolver, configuration); 10798 if (forceRtl) { 10799 // This will take care of setting the correct layout direction flags 10800 configuration.setLayoutDirection(configuration.locale); 10801 } 10802 10803 synchronized (this) { 10804 mDebugApp = mOrigDebugApp = debugApp; 10805 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10806 mAlwaysFinishActivities = alwaysFinishActivities; 10807 // This happens before any activities are started, so we can 10808 // change mConfiguration in-place. 10809 updateConfigurationLocked(configuration, null, false, true); 10810 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10811 } 10812 } 10813 10814 /** Loads resources after the current configuration has been set. */ 10815 private void loadResourcesOnSystemReady() { 10816 final Resources res = mContext.getResources(); 10817 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10818 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10819 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10820 } 10821 10822 public boolean testIsSystemReady() { 10823 // no need to synchronize(this) just to read & return the value 10824 return mSystemReady; 10825 } 10826 10827 private static File getCalledPreBootReceiversFile() { 10828 File dataDir = Environment.getDataDirectory(); 10829 File systemDir = new File(dataDir, "system"); 10830 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10831 return fname; 10832 } 10833 10834 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10835 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10836 File file = getCalledPreBootReceiversFile(); 10837 FileInputStream fis = null; 10838 try { 10839 fis = new FileInputStream(file); 10840 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10841 int fvers = dis.readInt(); 10842 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10843 String vers = dis.readUTF(); 10844 String codename = dis.readUTF(); 10845 String build = dis.readUTF(); 10846 if (android.os.Build.VERSION.RELEASE.equals(vers) 10847 && android.os.Build.VERSION.CODENAME.equals(codename) 10848 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10849 int num = dis.readInt(); 10850 while (num > 0) { 10851 num--; 10852 String pkg = dis.readUTF(); 10853 String cls = dis.readUTF(); 10854 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10855 } 10856 } 10857 } 10858 } catch (FileNotFoundException e) { 10859 } catch (IOException e) { 10860 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10861 } finally { 10862 if (fis != null) { 10863 try { 10864 fis.close(); 10865 } catch (IOException e) { 10866 } 10867 } 10868 } 10869 return lastDoneReceivers; 10870 } 10871 10872 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10873 File file = getCalledPreBootReceiversFile(); 10874 FileOutputStream fos = null; 10875 DataOutputStream dos = null; 10876 try { 10877 fos = new FileOutputStream(file); 10878 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10879 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10880 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10881 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10882 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10883 dos.writeInt(list.size()); 10884 for (int i=0; i<list.size(); i++) { 10885 dos.writeUTF(list.get(i).getPackageName()); 10886 dos.writeUTF(list.get(i).getClassName()); 10887 } 10888 } catch (IOException e) { 10889 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10890 file.delete(); 10891 } finally { 10892 FileUtils.sync(fos); 10893 if (dos != null) { 10894 try { 10895 dos.close(); 10896 } catch (IOException e) { 10897 // TODO Auto-generated catch block 10898 e.printStackTrace(); 10899 } 10900 } 10901 } 10902 } 10903 10904 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10905 ArrayList<ComponentName> doneReceivers, int userId) { 10906 boolean waitingUpdate = false; 10907 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10908 List<ResolveInfo> ris = null; 10909 try { 10910 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10911 intent, null, 0, userId); 10912 } catch (RemoteException e) { 10913 } 10914 if (ris != null) { 10915 for (int i=ris.size()-1; i>=0; i--) { 10916 if ((ris.get(i).activityInfo.applicationInfo.flags 10917 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10918 ris.remove(i); 10919 } 10920 } 10921 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10922 10923 // For User 0, load the version number. When delivering to a new user, deliver 10924 // to all receivers. 10925 if (userId == UserHandle.USER_OWNER) { 10926 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10927 for (int i=0; i<ris.size(); i++) { 10928 ActivityInfo ai = ris.get(i).activityInfo; 10929 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10930 if (lastDoneReceivers.contains(comp)) { 10931 // We already did the pre boot receiver for this app with the current 10932 // platform version, so don't do it again... 10933 ris.remove(i); 10934 i--; 10935 // ...however, do keep it as one that has been done, so we don't 10936 // forget about it when rewriting the file of last done receivers. 10937 doneReceivers.add(comp); 10938 } 10939 } 10940 } 10941 10942 // If primary user, send broadcast to all available users, else just to userId 10943 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10944 : new int[] { userId }; 10945 for (int i = 0; i < ris.size(); i++) { 10946 ActivityInfo ai = ris.get(i).activityInfo; 10947 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10948 doneReceivers.add(comp); 10949 intent.setComponent(comp); 10950 for (int j=0; j<users.length; j++) { 10951 IIntentReceiver finisher = null; 10952 // On last receiver and user, set up a completion callback 10953 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10954 finisher = new IIntentReceiver.Stub() { 10955 public void performReceive(Intent intent, int resultCode, 10956 String data, Bundle extras, boolean ordered, 10957 boolean sticky, int sendingUser) { 10958 // The raw IIntentReceiver interface is called 10959 // with the AM lock held, so redispatch to 10960 // execute our code without the lock. 10961 mHandler.post(onFinishCallback); 10962 } 10963 }; 10964 } 10965 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10966 + " for user " + users[j]); 10967 broadcastIntentLocked(null, null, intent, null, finisher, 10968 0, null, null, null, AppOpsManager.OP_NONE, 10969 true, false, MY_PID, Process.SYSTEM_UID, 10970 users[j]); 10971 if (finisher != null) { 10972 waitingUpdate = true; 10973 } 10974 } 10975 } 10976 } 10977 10978 return waitingUpdate; 10979 } 10980 10981 public void systemReady(final Runnable goingCallback) { 10982 synchronized(this) { 10983 if (mSystemReady) { 10984 // If we're done calling all the receivers, run the next "boot phase" passed in 10985 // by the SystemServer 10986 if (goingCallback != null) { 10987 goingCallback.run(); 10988 } 10989 return; 10990 } 10991 10992 // Make sure we have the current profile info, since it is needed for 10993 // security checks. 10994 updateCurrentProfileIdsLocked(); 10995 10996 if (mRecentTasks == null) { 10997 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10998 if (!mRecentTasks.isEmpty()) { 10999 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11000 } 11001 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11002 mTaskPersister.startPersisting(); 11003 } 11004 11005 // Check to see if there are any update receivers to run. 11006 if (!mDidUpdate) { 11007 if (mWaitingUpdate) { 11008 return; 11009 } 11010 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11011 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11012 public void run() { 11013 synchronized (ActivityManagerService.this) { 11014 mDidUpdate = true; 11015 } 11016 writeLastDonePreBootReceivers(doneReceivers); 11017 showBootMessage(mContext.getText( 11018 R.string.android_upgrading_complete), 11019 false); 11020 systemReady(goingCallback); 11021 } 11022 }, doneReceivers, UserHandle.USER_OWNER); 11023 11024 if (mWaitingUpdate) { 11025 return; 11026 } 11027 mDidUpdate = true; 11028 } 11029 11030 mAppOpsService.systemReady(); 11031 mSystemReady = true; 11032 } 11033 11034 ArrayList<ProcessRecord> procsToKill = null; 11035 synchronized(mPidsSelfLocked) { 11036 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11037 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11038 if (!isAllowedWhileBooting(proc.info)){ 11039 if (procsToKill == null) { 11040 procsToKill = new ArrayList<ProcessRecord>(); 11041 } 11042 procsToKill.add(proc); 11043 } 11044 } 11045 } 11046 11047 synchronized(this) { 11048 if (procsToKill != null) { 11049 for (int i=procsToKill.size()-1; i>=0; i--) { 11050 ProcessRecord proc = procsToKill.get(i); 11051 Slog.i(TAG, "Removing system update proc: " + proc); 11052 removeProcessLocked(proc, true, false, "system update done"); 11053 } 11054 } 11055 11056 // Now that we have cleaned up any update processes, we 11057 // are ready to start launching real processes and know that 11058 // we won't trample on them any more. 11059 mProcessesReady = true; 11060 } 11061 11062 Slog.i(TAG, "System now ready"); 11063 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11064 SystemClock.uptimeMillis()); 11065 11066 synchronized(this) { 11067 // Make sure we have no pre-ready processes sitting around. 11068 11069 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11070 ResolveInfo ri = mContext.getPackageManager() 11071 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11072 STOCK_PM_FLAGS); 11073 CharSequence errorMsg = null; 11074 if (ri != null) { 11075 ActivityInfo ai = ri.activityInfo; 11076 ApplicationInfo app = ai.applicationInfo; 11077 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11078 mTopAction = Intent.ACTION_FACTORY_TEST; 11079 mTopData = null; 11080 mTopComponent = new ComponentName(app.packageName, 11081 ai.name); 11082 } else { 11083 errorMsg = mContext.getResources().getText( 11084 com.android.internal.R.string.factorytest_not_system); 11085 } 11086 } else { 11087 errorMsg = mContext.getResources().getText( 11088 com.android.internal.R.string.factorytest_no_action); 11089 } 11090 if (errorMsg != null) { 11091 mTopAction = null; 11092 mTopData = null; 11093 mTopComponent = null; 11094 Message msg = Message.obtain(); 11095 msg.what = SHOW_FACTORY_ERROR_MSG; 11096 msg.getData().putCharSequence("msg", errorMsg); 11097 mHandler.sendMessage(msg); 11098 } 11099 } 11100 } 11101 11102 retrieveSettings(); 11103 loadResourcesOnSystemReady(); 11104 11105 synchronized (this) { 11106 readGrantedUriPermissionsLocked(); 11107 } 11108 11109 if (goingCallback != null) goingCallback.run(); 11110 11111 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11112 Integer.toString(mCurrentUserId), mCurrentUserId); 11113 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11114 Integer.toString(mCurrentUserId), mCurrentUserId); 11115 mSystemServiceManager.startUser(mCurrentUserId); 11116 11117 synchronized (this) { 11118 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11119 try { 11120 List apps = AppGlobals.getPackageManager(). 11121 getPersistentApplications(STOCK_PM_FLAGS); 11122 if (apps != null) { 11123 int N = apps.size(); 11124 int i; 11125 for (i=0; i<N; i++) { 11126 ApplicationInfo info 11127 = (ApplicationInfo)apps.get(i); 11128 if (info != null && 11129 !info.packageName.equals("android")) { 11130 addAppLocked(info, false, null /* ABI override */); 11131 } 11132 } 11133 } 11134 } catch (RemoteException ex) { 11135 // pm is in same process, this will never happen. 11136 } 11137 } 11138 11139 // Start up initial activity. 11140 mBooting = true; 11141 11142 try { 11143 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11144 Message msg = Message.obtain(); 11145 msg.what = SHOW_UID_ERROR_MSG; 11146 mHandler.sendMessage(msg); 11147 } 11148 } catch (RemoteException e) { 11149 } 11150 11151 long ident = Binder.clearCallingIdentity(); 11152 try { 11153 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11154 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11155 | Intent.FLAG_RECEIVER_FOREGROUND); 11156 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11157 broadcastIntentLocked(null, null, intent, 11158 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11159 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11160 intent = new Intent(Intent.ACTION_USER_STARTING); 11161 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11162 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11163 broadcastIntentLocked(null, null, intent, 11164 null, new IIntentReceiver.Stub() { 11165 @Override 11166 public void performReceive(Intent intent, int resultCode, String data, 11167 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11168 throws RemoteException { 11169 } 11170 }, 0, null, null, 11171 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11172 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11173 } catch (Throwable t) { 11174 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11175 } finally { 11176 Binder.restoreCallingIdentity(ident); 11177 } 11178 mStackSupervisor.resumeTopActivitiesLocked(); 11179 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11180 } 11181 } 11182 11183 private boolean makeAppCrashingLocked(ProcessRecord app, 11184 String shortMsg, String longMsg, String stackTrace) { 11185 app.crashing = true; 11186 app.crashingReport = generateProcessError(app, 11187 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11188 startAppProblemLocked(app); 11189 app.stopFreezingAllLocked(); 11190 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11191 } 11192 11193 private void makeAppNotRespondingLocked(ProcessRecord app, 11194 String activity, String shortMsg, String longMsg) { 11195 app.notResponding = true; 11196 app.notRespondingReport = generateProcessError(app, 11197 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11198 activity, shortMsg, longMsg, null); 11199 startAppProblemLocked(app); 11200 app.stopFreezingAllLocked(); 11201 } 11202 11203 /** 11204 * Generate a process error record, suitable for attachment to a ProcessRecord. 11205 * 11206 * @param app The ProcessRecord in which the error occurred. 11207 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11208 * ActivityManager.AppErrorStateInfo 11209 * @param activity The activity associated with the crash, if known. 11210 * @param shortMsg Short message describing the crash. 11211 * @param longMsg Long message describing the crash. 11212 * @param stackTrace Full crash stack trace, may be null. 11213 * 11214 * @return Returns a fully-formed AppErrorStateInfo record. 11215 */ 11216 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11217 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11218 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11219 11220 report.condition = condition; 11221 report.processName = app.processName; 11222 report.pid = app.pid; 11223 report.uid = app.info.uid; 11224 report.tag = activity; 11225 report.shortMsg = shortMsg; 11226 report.longMsg = longMsg; 11227 report.stackTrace = stackTrace; 11228 11229 return report; 11230 } 11231 11232 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11233 synchronized (this) { 11234 app.crashing = false; 11235 app.crashingReport = null; 11236 app.notResponding = false; 11237 app.notRespondingReport = null; 11238 if (app.anrDialog == fromDialog) { 11239 app.anrDialog = null; 11240 } 11241 if (app.waitDialog == fromDialog) { 11242 app.waitDialog = null; 11243 } 11244 if (app.pid > 0 && app.pid != MY_PID) { 11245 handleAppCrashLocked(app, null, null, null); 11246 app.kill("user request after error", true); 11247 } 11248 } 11249 } 11250 11251 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11252 String stackTrace) { 11253 long now = SystemClock.uptimeMillis(); 11254 11255 Long crashTime; 11256 if (!app.isolated) { 11257 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11258 } else { 11259 crashTime = null; 11260 } 11261 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11262 // This process loses! 11263 Slog.w(TAG, "Process " + app.info.processName 11264 + " has crashed too many times: killing!"); 11265 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11266 app.userId, app.info.processName, app.uid); 11267 mStackSupervisor.handleAppCrashLocked(app); 11268 if (!app.persistent) { 11269 // We don't want to start this process again until the user 11270 // explicitly does so... but for persistent process, we really 11271 // need to keep it running. If a persistent process is actually 11272 // repeatedly crashing, then badness for everyone. 11273 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11274 app.info.processName); 11275 if (!app.isolated) { 11276 // XXX We don't have a way to mark isolated processes 11277 // as bad, since they don't have a peristent identity. 11278 mBadProcesses.put(app.info.processName, app.uid, 11279 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11280 mProcessCrashTimes.remove(app.info.processName, app.uid); 11281 } 11282 app.bad = true; 11283 app.removed = true; 11284 // Don't let services in this process be restarted and potentially 11285 // annoy the user repeatedly. Unless it is persistent, since those 11286 // processes run critical code. 11287 removeProcessLocked(app, false, false, "crash"); 11288 mStackSupervisor.resumeTopActivitiesLocked(); 11289 return false; 11290 } 11291 mStackSupervisor.resumeTopActivitiesLocked(); 11292 } else { 11293 mStackSupervisor.finishTopRunningActivityLocked(app); 11294 } 11295 11296 // Bump up the crash count of any services currently running in the proc. 11297 for (int i=app.services.size()-1; i>=0; i--) { 11298 // Any services running in the application need to be placed 11299 // back in the pending list. 11300 ServiceRecord sr = app.services.valueAt(i); 11301 sr.crashCount++; 11302 } 11303 11304 // If the crashing process is what we consider to be the "home process" and it has been 11305 // replaced by a third-party app, clear the package preferred activities from packages 11306 // with a home activity running in the process to prevent a repeatedly crashing app 11307 // from blocking the user to manually clear the list. 11308 final ArrayList<ActivityRecord> activities = app.activities; 11309 if (app == mHomeProcess && activities.size() > 0 11310 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11311 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11312 final ActivityRecord r = activities.get(activityNdx); 11313 if (r.isHomeActivity()) { 11314 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11315 try { 11316 ActivityThread.getPackageManager() 11317 .clearPackagePreferredActivities(r.packageName); 11318 } catch (RemoteException c) { 11319 // pm is in same process, this will never happen. 11320 } 11321 } 11322 } 11323 } 11324 11325 if (!app.isolated) { 11326 // XXX Can't keep track of crash times for isolated processes, 11327 // because they don't have a perisistent identity. 11328 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11329 } 11330 11331 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11332 return true; 11333 } 11334 11335 void startAppProblemLocked(ProcessRecord app) { 11336 // If this app is not running under the current user, then we 11337 // can't give it a report button because that would require 11338 // launching the report UI under a different user. 11339 app.errorReportReceiver = null; 11340 11341 for (int userId : mCurrentProfileIds) { 11342 if (app.userId == userId) { 11343 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11344 mContext, app.info.packageName, app.info.flags); 11345 } 11346 } 11347 skipCurrentReceiverLocked(app); 11348 } 11349 11350 void skipCurrentReceiverLocked(ProcessRecord app) { 11351 for (BroadcastQueue queue : mBroadcastQueues) { 11352 queue.skipCurrentReceiverLocked(app); 11353 } 11354 } 11355 11356 /** 11357 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11358 * The application process will exit immediately after this call returns. 11359 * @param app object of the crashing app, null for the system server 11360 * @param crashInfo describing the exception 11361 */ 11362 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11363 ProcessRecord r = findAppProcess(app, "Crash"); 11364 final String processName = app == null ? "system_server" 11365 : (r == null ? "unknown" : r.processName); 11366 11367 handleApplicationCrashInner("crash", r, processName, crashInfo); 11368 } 11369 11370 /* Native crash reporting uses this inner version because it needs to be somewhat 11371 * decoupled from the AM-managed cleanup lifecycle 11372 */ 11373 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11374 ApplicationErrorReport.CrashInfo crashInfo) { 11375 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11376 UserHandle.getUserId(Binder.getCallingUid()), processName, 11377 r == null ? -1 : r.info.flags, 11378 crashInfo.exceptionClassName, 11379 crashInfo.exceptionMessage, 11380 crashInfo.throwFileName, 11381 crashInfo.throwLineNumber); 11382 11383 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11384 11385 crashApplication(r, crashInfo); 11386 } 11387 11388 public void handleApplicationStrictModeViolation( 11389 IBinder app, 11390 int violationMask, 11391 StrictMode.ViolationInfo info) { 11392 ProcessRecord r = findAppProcess(app, "StrictMode"); 11393 if (r == null) { 11394 return; 11395 } 11396 11397 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11398 Integer stackFingerprint = info.hashCode(); 11399 boolean logIt = true; 11400 synchronized (mAlreadyLoggedViolatedStacks) { 11401 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11402 logIt = false; 11403 // TODO: sub-sample into EventLog for these, with 11404 // the info.durationMillis? Then we'd get 11405 // the relative pain numbers, without logging all 11406 // the stack traces repeatedly. We'd want to do 11407 // likewise in the client code, which also does 11408 // dup suppression, before the Binder call. 11409 } else { 11410 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11411 mAlreadyLoggedViolatedStacks.clear(); 11412 } 11413 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11414 } 11415 } 11416 if (logIt) { 11417 logStrictModeViolationToDropBox(r, info); 11418 } 11419 } 11420 11421 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11422 AppErrorResult result = new AppErrorResult(); 11423 synchronized (this) { 11424 final long origId = Binder.clearCallingIdentity(); 11425 11426 Message msg = Message.obtain(); 11427 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11428 HashMap<String, Object> data = new HashMap<String, Object>(); 11429 data.put("result", result); 11430 data.put("app", r); 11431 data.put("violationMask", violationMask); 11432 data.put("info", info); 11433 msg.obj = data; 11434 mHandler.sendMessage(msg); 11435 11436 Binder.restoreCallingIdentity(origId); 11437 } 11438 int res = result.get(); 11439 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11440 } 11441 } 11442 11443 // Depending on the policy in effect, there could be a bunch of 11444 // these in quick succession so we try to batch these together to 11445 // minimize disk writes, number of dropbox entries, and maximize 11446 // compression, by having more fewer, larger records. 11447 private void logStrictModeViolationToDropBox( 11448 ProcessRecord process, 11449 StrictMode.ViolationInfo info) { 11450 if (info == null) { 11451 return; 11452 } 11453 final boolean isSystemApp = process == null || 11454 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11455 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11456 final String processName = process == null ? "unknown" : process.processName; 11457 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11458 final DropBoxManager dbox = (DropBoxManager) 11459 mContext.getSystemService(Context.DROPBOX_SERVICE); 11460 11461 // Exit early if the dropbox isn't configured to accept this report type. 11462 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11463 11464 boolean bufferWasEmpty; 11465 boolean needsFlush; 11466 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11467 synchronized (sb) { 11468 bufferWasEmpty = sb.length() == 0; 11469 appendDropBoxProcessHeaders(process, processName, sb); 11470 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11471 sb.append("System-App: ").append(isSystemApp).append("\n"); 11472 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11473 if (info.violationNumThisLoop != 0) { 11474 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11475 } 11476 if (info.numAnimationsRunning != 0) { 11477 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11478 } 11479 if (info.broadcastIntentAction != null) { 11480 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11481 } 11482 if (info.durationMillis != -1) { 11483 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11484 } 11485 if (info.numInstances != -1) { 11486 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11487 } 11488 if (info.tags != null) { 11489 for (String tag : info.tags) { 11490 sb.append("Span-Tag: ").append(tag).append("\n"); 11491 } 11492 } 11493 sb.append("\n"); 11494 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11495 sb.append(info.crashInfo.stackTrace); 11496 } 11497 sb.append("\n"); 11498 11499 // Only buffer up to ~64k. Various logging bits truncate 11500 // things at 128k. 11501 needsFlush = (sb.length() > 64 * 1024); 11502 } 11503 11504 // Flush immediately if the buffer's grown too large, or this 11505 // is a non-system app. Non-system apps are isolated with a 11506 // different tag & policy and not batched. 11507 // 11508 // Batching is useful during internal testing with 11509 // StrictMode settings turned up high. Without batching, 11510 // thousands of separate files could be created on boot. 11511 if (!isSystemApp || needsFlush) { 11512 new Thread("Error dump: " + dropboxTag) { 11513 @Override 11514 public void run() { 11515 String report; 11516 synchronized (sb) { 11517 report = sb.toString(); 11518 sb.delete(0, sb.length()); 11519 sb.trimToSize(); 11520 } 11521 if (report.length() != 0) { 11522 dbox.addText(dropboxTag, report); 11523 } 11524 } 11525 }.start(); 11526 return; 11527 } 11528 11529 // System app batching: 11530 if (!bufferWasEmpty) { 11531 // An existing dropbox-writing thread is outstanding, so 11532 // we don't need to start it up. The existing thread will 11533 // catch the buffer appends we just did. 11534 return; 11535 } 11536 11537 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11538 // (After this point, we shouldn't access AMS internal data structures.) 11539 new Thread("Error dump: " + dropboxTag) { 11540 @Override 11541 public void run() { 11542 // 5 second sleep to let stacks arrive and be batched together 11543 try { 11544 Thread.sleep(5000); // 5 seconds 11545 } catch (InterruptedException e) {} 11546 11547 String errorReport; 11548 synchronized (mStrictModeBuffer) { 11549 errorReport = mStrictModeBuffer.toString(); 11550 if (errorReport.length() == 0) { 11551 return; 11552 } 11553 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11554 mStrictModeBuffer.trimToSize(); 11555 } 11556 dbox.addText(dropboxTag, errorReport); 11557 } 11558 }.start(); 11559 } 11560 11561 /** 11562 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11563 * @param app object of the crashing app, null for the system server 11564 * @param tag reported by the caller 11565 * @param system whether this wtf is coming from the system 11566 * @param crashInfo describing the context of the error 11567 * @return true if the process should exit immediately (WTF is fatal) 11568 */ 11569 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11570 final ApplicationErrorReport.CrashInfo crashInfo) { 11571 final ProcessRecord r = findAppProcess(app, "WTF"); 11572 final String processName = app == null ? "system_server" 11573 : (r == null ? "unknown" : r.processName); 11574 11575 EventLog.writeEvent(EventLogTags.AM_WTF, 11576 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11577 processName, 11578 r == null ? -1 : r.info.flags, 11579 tag, crashInfo.exceptionMessage); 11580 11581 if (system) { 11582 // If this is coming from the system, we could very well have low-level 11583 // system locks held, so we want to do this all asynchronously. And we 11584 // never want this to become fatal, so there is that too. 11585 mHandler.post(new Runnable() { 11586 @Override public void run() { 11587 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11588 crashInfo); 11589 } 11590 }); 11591 return false; 11592 } 11593 11594 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11595 11596 if (r != null && r.pid != Process.myPid() && 11597 Settings.Global.getInt(mContext.getContentResolver(), 11598 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11599 crashApplication(r, crashInfo); 11600 return true; 11601 } else { 11602 return false; 11603 } 11604 } 11605 11606 /** 11607 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11608 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11609 */ 11610 private ProcessRecord findAppProcess(IBinder app, String reason) { 11611 if (app == null) { 11612 return null; 11613 } 11614 11615 synchronized (this) { 11616 final int NP = mProcessNames.getMap().size(); 11617 for (int ip=0; ip<NP; ip++) { 11618 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11619 final int NA = apps.size(); 11620 for (int ia=0; ia<NA; ia++) { 11621 ProcessRecord p = apps.valueAt(ia); 11622 if (p.thread != null && p.thread.asBinder() == app) { 11623 return p; 11624 } 11625 } 11626 } 11627 11628 Slog.w(TAG, "Can't find mystery application for " + reason 11629 + " from pid=" + Binder.getCallingPid() 11630 + " uid=" + Binder.getCallingUid() + ": " + app); 11631 return null; 11632 } 11633 } 11634 11635 /** 11636 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11637 * to append various headers to the dropbox log text. 11638 */ 11639 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11640 StringBuilder sb) { 11641 // Watchdog thread ends up invoking this function (with 11642 // a null ProcessRecord) to add the stack file to dropbox. 11643 // Do not acquire a lock on this (am) in such cases, as it 11644 // could cause a potential deadlock, if and when watchdog 11645 // is invoked due to unavailability of lock on am and it 11646 // would prevent watchdog from killing system_server. 11647 if (process == null) { 11648 sb.append("Process: ").append(processName).append("\n"); 11649 return; 11650 } 11651 // Note: ProcessRecord 'process' is guarded by the service 11652 // instance. (notably process.pkgList, which could otherwise change 11653 // concurrently during execution of this method) 11654 synchronized (this) { 11655 sb.append("Process: ").append(processName).append("\n"); 11656 int flags = process.info.flags; 11657 IPackageManager pm = AppGlobals.getPackageManager(); 11658 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11659 for (int ip=0; ip<process.pkgList.size(); ip++) { 11660 String pkg = process.pkgList.keyAt(ip); 11661 sb.append("Package: ").append(pkg); 11662 try { 11663 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11664 if (pi != null) { 11665 sb.append(" v").append(pi.versionCode); 11666 if (pi.versionName != null) { 11667 sb.append(" (").append(pi.versionName).append(")"); 11668 } 11669 } 11670 } catch (RemoteException e) { 11671 Slog.e(TAG, "Error getting package info: " + pkg, e); 11672 } 11673 sb.append("\n"); 11674 } 11675 } 11676 } 11677 11678 private static String processClass(ProcessRecord process) { 11679 if (process == null || process.pid == MY_PID) { 11680 return "system_server"; 11681 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11682 return "system_app"; 11683 } else { 11684 return "data_app"; 11685 } 11686 } 11687 11688 /** 11689 * Write a description of an error (crash, WTF, ANR) to the drop box. 11690 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11691 * @param process which caused the error, null means the system server 11692 * @param activity which triggered the error, null if unknown 11693 * @param parent activity related to the error, null if unknown 11694 * @param subject line related to the error, null if absent 11695 * @param report in long form describing the error, null if absent 11696 * @param logFile to include in the report, null if none 11697 * @param crashInfo giving an application stack trace, null if absent 11698 */ 11699 public void addErrorToDropBox(String eventType, 11700 ProcessRecord process, String processName, ActivityRecord activity, 11701 ActivityRecord parent, String subject, 11702 final String report, final File logFile, 11703 final ApplicationErrorReport.CrashInfo crashInfo) { 11704 // NOTE -- this must never acquire the ActivityManagerService lock, 11705 // otherwise the watchdog may be prevented from resetting the system. 11706 11707 final String dropboxTag = processClass(process) + "_" + eventType; 11708 final DropBoxManager dbox = (DropBoxManager) 11709 mContext.getSystemService(Context.DROPBOX_SERVICE); 11710 11711 // Exit early if the dropbox isn't configured to accept this report type. 11712 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11713 11714 final StringBuilder sb = new StringBuilder(1024); 11715 appendDropBoxProcessHeaders(process, processName, sb); 11716 if (activity != null) { 11717 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11718 } 11719 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11720 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11721 } 11722 if (parent != null && parent != activity) { 11723 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11724 } 11725 if (subject != null) { 11726 sb.append("Subject: ").append(subject).append("\n"); 11727 } 11728 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11729 if (Debug.isDebuggerConnected()) { 11730 sb.append("Debugger: Connected\n"); 11731 } 11732 sb.append("\n"); 11733 11734 // Do the rest in a worker thread to avoid blocking the caller on I/O 11735 // (After this point, we shouldn't access AMS internal data structures.) 11736 Thread worker = new Thread("Error dump: " + dropboxTag) { 11737 @Override 11738 public void run() { 11739 if (report != null) { 11740 sb.append(report); 11741 } 11742 if (logFile != null) { 11743 try { 11744 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11745 "\n\n[[TRUNCATED]]")); 11746 } catch (IOException e) { 11747 Slog.e(TAG, "Error reading " + logFile, e); 11748 } 11749 } 11750 if (crashInfo != null && crashInfo.stackTrace != null) { 11751 sb.append(crashInfo.stackTrace); 11752 } 11753 11754 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11755 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11756 if (lines > 0) { 11757 sb.append("\n"); 11758 11759 // Merge several logcat streams, and take the last N lines 11760 InputStreamReader input = null; 11761 try { 11762 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11763 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11764 "-b", "crash", 11765 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11766 11767 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11768 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11769 input = new InputStreamReader(logcat.getInputStream()); 11770 11771 int num; 11772 char[] buf = new char[8192]; 11773 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11774 } catch (IOException e) { 11775 Slog.e(TAG, "Error running logcat", e); 11776 } finally { 11777 if (input != null) try { input.close(); } catch (IOException e) {} 11778 } 11779 } 11780 11781 dbox.addText(dropboxTag, sb.toString()); 11782 } 11783 }; 11784 11785 if (process == null) { 11786 // If process is null, we are being called from some internal code 11787 // and may be about to die -- run this synchronously. 11788 worker.run(); 11789 } else { 11790 worker.start(); 11791 } 11792 } 11793 11794 /** 11795 * Bring up the "unexpected error" dialog box for a crashing app. 11796 * Deal with edge cases (intercepts from instrumented applications, 11797 * ActivityController, error intent receivers, that sort of thing). 11798 * @param r the application crashing 11799 * @param crashInfo describing the failure 11800 */ 11801 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11802 long timeMillis = System.currentTimeMillis(); 11803 String shortMsg = crashInfo.exceptionClassName; 11804 String longMsg = crashInfo.exceptionMessage; 11805 String stackTrace = crashInfo.stackTrace; 11806 if (shortMsg != null && longMsg != null) { 11807 longMsg = shortMsg + ": " + longMsg; 11808 } else if (shortMsg != null) { 11809 longMsg = shortMsg; 11810 } 11811 11812 AppErrorResult result = new AppErrorResult(); 11813 synchronized (this) { 11814 if (mController != null) { 11815 try { 11816 String name = r != null ? r.processName : null; 11817 int pid = r != null ? r.pid : Binder.getCallingPid(); 11818 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11819 if (!mController.appCrashed(name, pid, 11820 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11821 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11822 && "Native crash".equals(crashInfo.exceptionClassName)) { 11823 Slog.w(TAG, "Skip killing native crashed app " + name 11824 + "(" + pid + ") during testing"); 11825 } else { 11826 Slog.w(TAG, "Force-killing crashed app " + name 11827 + " at watcher's request"); 11828 if (r != null) { 11829 r.kill("crash", true); 11830 } else { 11831 // Huh. 11832 Process.killProcess(pid); 11833 Process.killProcessGroup(uid, pid); 11834 } 11835 } 11836 return; 11837 } 11838 } catch (RemoteException e) { 11839 mController = null; 11840 Watchdog.getInstance().setActivityController(null); 11841 } 11842 } 11843 11844 final long origId = Binder.clearCallingIdentity(); 11845 11846 // If this process is running instrumentation, finish it. 11847 if (r != null && r.instrumentationClass != null) { 11848 Slog.w(TAG, "Error in app " + r.processName 11849 + " running instrumentation " + r.instrumentationClass + ":"); 11850 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11851 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11852 Bundle info = new Bundle(); 11853 info.putString("shortMsg", shortMsg); 11854 info.putString("longMsg", longMsg); 11855 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11856 Binder.restoreCallingIdentity(origId); 11857 return; 11858 } 11859 11860 // If we can't identify the process or it's already exceeded its crash quota, 11861 // quit right away without showing a crash dialog. 11862 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11863 Binder.restoreCallingIdentity(origId); 11864 return; 11865 } 11866 11867 Message msg = Message.obtain(); 11868 msg.what = SHOW_ERROR_MSG; 11869 HashMap data = new HashMap(); 11870 data.put("result", result); 11871 data.put("app", r); 11872 msg.obj = data; 11873 mHandler.sendMessage(msg); 11874 11875 Binder.restoreCallingIdentity(origId); 11876 } 11877 11878 int res = result.get(); 11879 11880 Intent appErrorIntent = null; 11881 synchronized (this) { 11882 if (r != null && !r.isolated) { 11883 // XXX Can't keep track of crash time for isolated processes, 11884 // since they don't have a persistent identity. 11885 mProcessCrashTimes.put(r.info.processName, r.uid, 11886 SystemClock.uptimeMillis()); 11887 } 11888 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11889 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11890 } 11891 } 11892 11893 if (appErrorIntent != null) { 11894 try { 11895 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11896 } catch (ActivityNotFoundException e) { 11897 Slog.w(TAG, "bug report receiver dissappeared", e); 11898 } 11899 } 11900 } 11901 11902 Intent createAppErrorIntentLocked(ProcessRecord r, 11903 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11904 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11905 if (report == null) { 11906 return null; 11907 } 11908 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11909 result.setComponent(r.errorReportReceiver); 11910 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11911 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11912 return result; 11913 } 11914 11915 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11916 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11917 if (r.errorReportReceiver == null) { 11918 return null; 11919 } 11920 11921 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11922 return null; 11923 } 11924 11925 ApplicationErrorReport report = new ApplicationErrorReport(); 11926 report.packageName = r.info.packageName; 11927 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11928 report.processName = r.processName; 11929 report.time = timeMillis; 11930 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11931 11932 if (r.crashing || r.forceCrashReport) { 11933 report.type = ApplicationErrorReport.TYPE_CRASH; 11934 report.crashInfo = crashInfo; 11935 } else if (r.notResponding) { 11936 report.type = ApplicationErrorReport.TYPE_ANR; 11937 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11938 11939 report.anrInfo.activity = r.notRespondingReport.tag; 11940 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11941 report.anrInfo.info = r.notRespondingReport.longMsg; 11942 } 11943 11944 return report; 11945 } 11946 11947 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11948 enforceNotIsolatedCaller("getProcessesInErrorState"); 11949 // assume our apps are happy - lazy create the list 11950 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11951 11952 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11953 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11954 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11955 11956 synchronized (this) { 11957 11958 // iterate across all processes 11959 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11960 ProcessRecord app = mLruProcesses.get(i); 11961 if (!allUsers && app.userId != userId) { 11962 continue; 11963 } 11964 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11965 // This one's in trouble, so we'll generate a report for it 11966 // crashes are higher priority (in case there's a crash *and* an anr) 11967 ActivityManager.ProcessErrorStateInfo report = null; 11968 if (app.crashing) { 11969 report = app.crashingReport; 11970 } else if (app.notResponding) { 11971 report = app.notRespondingReport; 11972 } 11973 11974 if (report != null) { 11975 if (errList == null) { 11976 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11977 } 11978 errList.add(report); 11979 } else { 11980 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11981 " crashing = " + app.crashing + 11982 " notResponding = " + app.notResponding); 11983 } 11984 } 11985 } 11986 } 11987 11988 return errList; 11989 } 11990 11991 static int procStateToImportance(int procState, int memAdj, 11992 ActivityManager.RunningAppProcessInfo currApp) { 11993 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11994 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11995 currApp.lru = memAdj; 11996 } else { 11997 currApp.lru = 0; 11998 } 11999 return imp; 12000 } 12001 12002 private void fillInProcMemInfo(ProcessRecord app, 12003 ActivityManager.RunningAppProcessInfo outInfo) { 12004 outInfo.pid = app.pid; 12005 outInfo.uid = app.info.uid; 12006 if (mHeavyWeightProcess == app) { 12007 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12008 } 12009 if (app.persistent) { 12010 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12011 } 12012 if (app.activities.size() > 0) { 12013 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12014 } 12015 outInfo.lastTrimLevel = app.trimMemoryLevel; 12016 int adj = app.curAdj; 12017 int procState = app.curProcState; 12018 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12019 outInfo.importanceReasonCode = app.adjTypeCode; 12020 outInfo.processState = app.curProcState; 12021 } 12022 12023 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12024 enforceNotIsolatedCaller("getRunningAppProcesses"); 12025 // Lazy instantiation of list 12026 List<ActivityManager.RunningAppProcessInfo> runList = null; 12027 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12028 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12029 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12030 synchronized (this) { 12031 // Iterate across all processes 12032 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12033 ProcessRecord app = mLruProcesses.get(i); 12034 if (!allUsers && app.userId != userId) { 12035 continue; 12036 } 12037 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12038 // Generate process state info for running application 12039 ActivityManager.RunningAppProcessInfo currApp = 12040 new ActivityManager.RunningAppProcessInfo(app.processName, 12041 app.pid, app.getPackageList()); 12042 fillInProcMemInfo(app, currApp); 12043 if (app.adjSource instanceof ProcessRecord) { 12044 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12045 currApp.importanceReasonImportance = 12046 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12047 app.adjSourceProcState); 12048 } else if (app.adjSource instanceof ActivityRecord) { 12049 ActivityRecord r = (ActivityRecord)app.adjSource; 12050 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12051 } 12052 if (app.adjTarget instanceof ComponentName) { 12053 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12054 } 12055 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12056 // + " lru=" + currApp.lru); 12057 if (runList == null) { 12058 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12059 } 12060 runList.add(currApp); 12061 } 12062 } 12063 } 12064 return runList; 12065 } 12066 12067 public List<ApplicationInfo> getRunningExternalApplications() { 12068 enforceNotIsolatedCaller("getRunningExternalApplications"); 12069 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12070 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12071 if (runningApps != null && runningApps.size() > 0) { 12072 Set<String> extList = new HashSet<String>(); 12073 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12074 if (app.pkgList != null) { 12075 for (String pkg : app.pkgList) { 12076 extList.add(pkg); 12077 } 12078 } 12079 } 12080 IPackageManager pm = AppGlobals.getPackageManager(); 12081 for (String pkg : extList) { 12082 try { 12083 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12084 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12085 retList.add(info); 12086 } 12087 } catch (RemoteException e) { 12088 } 12089 } 12090 } 12091 return retList; 12092 } 12093 12094 @Override 12095 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12096 enforceNotIsolatedCaller("getMyMemoryState"); 12097 synchronized (this) { 12098 ProcessRecord proc; 12099 synchronized (mPidsSelfLocked) { 12100 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12101 } 12102 fillInProcMemInfo(proc, outInfo); 12103 } 12104 } 12105 12106 @Override 12107 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12108 if (checkCallingPermission(android.Manifest.permission.DUMP) 12109 != PackageManager.PERMISSION_GRANTED) { 12110 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12111 + Binder.getCallingPid() 12112 + ", uid=" + Binder.getCallingUid() 12113 + " without permission " 12114 + android.Manifest.permission.DUMP); 12115 return; 12116 } 12117 12118 boolean dumpAll = false; 12119 boolean dumpClient = false; 12120 String dumpPackage = null; 12121 12122 int opti = 0; 12123 while (opti < args.length) { 12124 String opt = args[opti]; 12125 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12126 break; 12127 } 12128 opti++; 12129 if ("-a".equals(opt)) { 12130 dumpAll = true; 12131 } else if ("-c".equals(opt)) { 12132 dumpClient = true; 12133 } else if ("-h".equals(opt)) { 12134 pw.println("Activity manager dump options:"); 12135 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12136 pw.println(" cmd may be one of:"); 12137 pw.println(" a[ctivities]: activity stack state"); 12138 pw.println(" r[recents]: recent activities state"); 12139 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12140 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12141 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12142 pw.println(" o[om]: out of memory management"); 12143 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12144 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12145 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12146 pw.println(" service [COMP_SPEC]: service client-side state"); 12147 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12148 pw.println(" all: dump all activities"); 12149 pw.println(" top: dump the top activity"); 12150 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12151 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12152 pw.println(" a partial substring in a component name, a"); 12153 pw.println(" hex object identifier."); 12154 pw.println(" -a: include all available server state."); 12155 pw.println(" -c: include client state."); 12156 return; 12157 } else { 12158 pw.println("Unknown argument: " + opt + "; use -h for help"); 12159 } 12160 } 12161 12162 long origId = Binder.clearCallingIdentity(); 12163 boolean more = false; 12164 // Is the caller requesting to dump a particular piece of data? 12165 if (opti < args.length) { 12166 String cmd = args[opti]; 12167 opti++; 12168 if ("activities".equals(cmd) || "a".equals(cmd)) { 12169 synchronized (this) { 12170 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12171 } 12172 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12173 synchronized (this) { 12174 dumpRecentsLocked(fd, pw, args, opti, true, null); 12175 } 12176 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12177 String[] newArgs; 12178 String name; 12179 if (opti >= args.length) { 12180 name = null; 12181 newArgs = EMPTY_STRING_ARRAY; 12182 } else { 12183 name = args[opti]; 12184 opti++; 12185 newArgs = new String[args.length - opti]; 12186 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12187 args.length - opti); 12188 } 12189 synchronized (this) { 12190 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12191 } 12192 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12193 String[] newArgs; 12194 String name; 12195 if (opti >= args.length) { 12196 name = null; 12197 newArgs = EMPTY_STRING_ARRAY; 12198 } else { 12199 name = args[opti]; 12200 opti++; 12201 newArgs = new String[args.length - opti]; 12202 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12203 args.length - opti); 12204 } 12205 synchronized (this) { 12206 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12207 } 12208 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12209 String[] newArgs; 12210 String name; 12211 if (opti >= args.length) { 12212 name = null; 12213 newArgs = EMPTY_STRING_ARRAY; 12214 } else { 12215 name = args[opti]; 12216 opti++; 12217 newArgs = new String[args.length - opti]; 12218 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12219 args.length - opti); 12220 } 12221 synchronized (this) { 12222 dumpProcessesLocked(fd, pw, args, opti, true, name); 12223 } 12224 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12225 synchronized (this) { 12226 dumpOomLocked(fd, pw, args, opti, true); 12227 } 12228 } else if ("provider".equals(cmd)) { 12229 String[] newArgs; 12230 String name; 12231 if (opti >= args.length) { 12232 name = null; 12233 newArgs = EMPTY_STRING_ARRAY; 12234 } else { 12235 name = args[opti]; 12236 opti++; 12237 newArgs = new String[args.length - opti]; 12238 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12239 } 12240 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12241 pw.println("No providers match: " + name); 12242 pw.println("Use -h for help."); 12243 } 12244 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12245 synchronized (this) { 12246 dumpProvidersLocked(fd, pw, args, opti, true, null); 12247 } 12248 } else if ("service".equals(cmd)) { 12249 String[] newArgs; 12250 String name; 12251 if (opti >= args.length) { 12252 name = null; 12253 newArgs = EMPTY_STRING_ARRAY; 12254 } else { 12255 name = args[opti]; 12256 opti++; 12257 newArgs = new String[args.length - opti]; 12258 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12259 args.length - opti); 12260 } 12261 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12262 pw.println("No services match: " + name); 12263 pw.println("Use -h for help."); 12264 } 12265 } else if ("package".equals(cmd)) { 12266 String[] newArgs; 12267 if (opti >= args.length) { 12268 pw.println("package: no package name specified"); 12269 pw.println("Use -h for help."); 12270 } else { 12271 dumpPackage = args[opti]; 12272 opti++; 12273 newArgs = new String[args.length - opti]; 12274 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12275 args.length - opti); 12276 args = newArgs; 12277 opti = 0; 12278 more = true; 12279 } 12280 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12281 synchronized (this) { 12282 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12283 } 12284 } else { 12285 // Dumping a single activity? 12286 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12287 pw.println("Bad activity command, or no activities match: " + cmd); 12288 pw.println("Use -h for help."); 12289 } 12290 } 12291 if (!more) { 12292 Binder.restoreCallingIdentity(origId); 12293 return; 12294 } 12295 } 12296 12297 // No piece of data specified, dump everything. 12298 synchronized (this) { 12299 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12300 pw.println(); 12301 if (dumpAll) { 12302 pw.println("-------------------------------------------------------------------------------"); 12303 } 12304 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12305 pw.println(); 12306 if (dumpAll) { 12307 pw.println("-------------------------------------------------------------------------------"); 12308 } 12309 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12310 pw.println(); 12311 if (dumpAll) { 12312 pw.println("-------------------------------------------------------------------------------"); 12313 } 12314 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12315 pw.println(); 12316 if (dumpAll) { 12317 pw.println("-------------------------------------------------------------------------------"); 12318 } 12319 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12320 pw.println(); 12321 if (dumpAll) { 12322 pw.println("-------------------------------------------------------------------------------"); 12323 } 12324 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12325 pw.println(); 12326 if (dumpAll) { 12327 pw.println("-------------------------------------------------------------------------------"); 12328 } 12329 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12330 } 12331 Binder.restoreCallingIdentity(origId); 12332 } 12333 12334 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12335 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12336 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12337 12338 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12339 dumpPackage); 12340 boolean needSep = printedAnything; 12341 12342 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12343 dumpPackage, needSep, " mFocusedActivity: "); 12344 if (printed) { 12345 printedAnything = true; 12346 needSep = false; 12347 } 12348 12349 if (dumpPackage == null) { 12350 if (needSep) { 12351 pw.println(); 12352 } 12353 needSep = true; 12354 printedAnything = true; 12355 mStackSupervisor.dump(pw, " "); 12356 } 12357 12358 if (!printedAnything) { 12359 pw.println(" (nothing)"); 12360 } 12361 } 12362 12363 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12364 int opti, boolean dumpAll, String dumpPackage) { 12365 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12366 12367 boolean printedAnything = false; 12368 12369 if (mRecentTasks.size() > 0) { 12370 boolean printedHeader = false; 12371 12372 final int N = mRecentTasks.size(); 12373 for (int i=0; i<N; i++) { 12374 TaskRecord tr = mRecentTasks.get(i); 12375 if (dumpPackage != null) { 12376 if (tr.realActivity == null || 12377 !dumpPackage.equals(tr.realActivity)) { 12378 continue; 12379 } 12380 } 12381 if (!printedHeader) { 12382 pw.println(" Recent tasks:"); 12383 printedHeader = true; 12384 printedAnything = true; 12385 } 12386 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12387 pw.println(tr); 12388 if (dumpAll) { 12389 mRecentTasks.get(i).dump(pw, " "); 12390 } 12391 } 12392 } 12393 12394 if (!printedAnything) { 12395 pw.println(" (nothing)"); 12396 } 12397 } 12398 12399 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12400 int opti, boolean dumpAll, String dumpPackage) { 12401 boolean needSep = false; 12402 boolean printedAnything = false; 12403 int numPers = 0; 12404 12405 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12406 12407 if (dumpAll) { 12408 final int NP = mProcessNames.getMap().size(); 12409 for (int ip=0; ip<NP; ip++) { 12410 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12411 final int NA = procs.size(); 12412 for (int ia=0; ia<NA; ia++) { 12413 ProcessRecord r = procs.valueAt(ia); 12414 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12415 continue; 12416 } 12417 if (!needSep) { 12418 pw.println(" All known processes:"); 12419 needSep = true; 12420 printedAnything = true; 12421 } 12422 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12423 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12424 pw.print(" "); pw.println(r); 12425 r.dump(pw, " "); 12426 if (r.persistent) { 12427 numPers++; 12428 } 12429 } 12430 } 12431 } 12432 12433 if (mIsolatedProcesses.size() > 0) { 12434 boolean printed = false; 12435 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12436 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12437 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12438 continue; 12439 } 12440 if (!printed) { 12441 if (needSep) { 12442 pw.println(); 12443 } 12444 pw.println(" Isolated process list (sorted by uid):"); 12445 printedAnything = true; 12446 printed = true; 12447 needSep = true; 12448 } 12449 pw.println(String.format("%sIsolated #%2d: %s", 12450 " ", i, r.toString())); 12451 } 12452 } 12453 12454 if (mLruProcesses.size() > 0) { 12455 if (needSep) { 12456 pw.println(); 12457 } 12458 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12459 pw.print(" total, non-act at "); 12460 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12461 pw.print(", non-svc at "); 12462 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12463 pw.println("):"); 12464 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12465 needSep = true; 12466 printedAnything = true; 12467 } 12468 12469 if (dumpAll || dumpPackage != null) { 12470 synchronized (mPidsSelfLocked) { 12471 boolean printed = false; 12472 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12473 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12474 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12475 continue; 12476 } 12477 if (!printed) { 12478 if (needSep) pw.println(); 12479 needSep = true; 12480 pw.println(" PID mappings:"); 12481 printed = true; 12482 printedAnything = true; 12483 } 12484 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12485 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12486 } 12487 } 12488 } 12489 12490 if (mForegroundProcesses.size() > 0) { 12491 synchronized (mPidsSelfLocked) { 12492 boolean printed = false; 12493 for (int i=0; i<mForegroundProcesses.size(); i++) { 12494 ProcessRecord r = mPidsSelfLocked.get( 12495 mForegroundProcesses.valueAt(i).pid); 12496 if (dumpPackage != null && (r == null 12497 || !r.pkgList.containsKey(dumpPackage))) { 12498 continue; 12499 } 12500 if (!printed) { 12501 if (needSep) pw.println(); 12502 needSep = true; 12503 pw.println(" Foreground Processes:"); 12504 printed = true; 12505 printedAnything = true; 12506 } 12507 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12508 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12509 } 12510 } 12511 } 12512 12513 if (mPersistentStartingProcesses.size() > 0) { 12514 if (needSep) pw.println(); 12515 needSep = true; 12516 printedAnything = true; 12517 pw.println(" Persisent processes that are starting:"); 12518 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12519 "Starting Norm", "Restarting PERS", dumpPackage); 12520 } 12521 12522 if (mRemovedProcesses.size() > 0) { 12523 if (needSep) pw.println(); 12524 needSep = true; 12525 printedAnything = true; 12526 pw.println(" Processes that are being removed:"); 12527 dumpProcessList(pw, this, mRemovedProcesses, " ", 12528 "Removed Norm", "Removed PERS", dumpPackage); 12529 } 12530 12531 if (mProcessesOnHold.size() > 0) { 12532 if (needSep) pw.println(); 12533 needSep = true; 12534 printedAnything = true; 12535 pw.println(" Processes that are on old until the system is ready:"); 12536 dumpProcessList(pw, this, mProcessesOnHold, " ", 12537 "OnHold Norm", "OnHold PERS", dumpPackage); 12538 } 12539 12540 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12541 12542 if (mProcessCrashTimes.getMap().size() > 0) { 12543 boolean printed = false; 12544 long now = SystemClock.uptimeMillis(); 12545 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12546 final int NP = pmap.size(); 12547 for (int ip=0; ip<NP; ip++) { 12548 String pname = pmap.keyAt(ip); 12549 SparseArray<Long> uids = pmap.valueAt(ip); 12550 final int N = uids.size(); 12551 for (int i=0; i<N; i++) { 12552 int puid = uids.keyAt(i); 12553 ProcessRecord r = mProcessNames.get(pname, puid); 12554 if (dumpPackage != null && (r == null 12555 || !r.pkgList.containsKey(dumpPackage))) { 12556 continue; 12557 } 12558 if (!printed) { 12559 if (needSep) pw.println(); 12560 needSep = true; 12561 pw.println(" Time since processes crashed:"); 12562 printed = true; 12563 printedAnything = true; 12564 } 12565 pw.print(" Process "); pw.print(pname); 12566 pw.print(" uid "); pw.print(puid); 12567 pw.print(": last crashed "); 12568 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12569 pw.println(" ago"); 12570 } 12571 } 12572 } 12573 12574 if (mBadProcesses.getMap().size() > 0) { 12575 boolean printed = false; 12576 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12577 final int NP = pmap.size(); 12578 for (int ip=0; ip<NP; ip++) { 12579 String pname = pmap.keyAt(ip); 12580 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12581 final int N = uids.size(); 12582 for (int i=0; i<N; i++) { 12583 int puid = uids.keyAt(i); 12584 ProcessRecord r = mProcessNames.get(pname, puid); 12585 if (dumpPackage != null && (r == null 12586 || !r.pkgList.containsKey(dumpPackage))) { 12587 continue; 12588 } 12589 if (!printed) { 12590 if (needSep) pw.println(); 12591 needSep = true; 12592 pw.println(" Bad processes:"); 12593 printedAnything = true; 12594 } 12595 BadProcessInfo info = uids.valueAt(i); 12596 pw.print(" Bad process "); pw.print(pname); 12597 pw.print(" uid "); pw.print(puid); 12598 pw.print(": crashed at time "); pw.println(info.time); 12599 if (info.shortMsg != null) { 12600 pw.print(" Short msg: "); pw.println(info.shortMsg); 12601 } 12602 if (info.longMsg != null) { 12603 pw.print(" Long msg: "); pw.println(info.longMsg); 12604 } 12605 if (info.stack != null) { 12606 pw.println(" Stack:"); 12607 int lastPos = 0; 12608 for (int pos=0; pos<info.stack.length(); pos++) { 12609 if (info.stack.charAt(pos) == '\n') { 12610 pw.print(" "); 12611 pw.write(info.stack, lastPos, pos-lastPos); 12612 pw.println(); 12613 lastPos = pos+1; 12614 } 12615 } 12616 if (lastPos < info.stack.length()) { 12617 pw.print(" "); 12618 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12619 pw.println(); 12620 } 12621 } 12622 } 12623 } 12624 } 12625 12626 if (dumpPackage == null) { 12627 pw.println(); 12628 needSep = false; 12629 pw.println(" mStartedUsers:"); 12630 for (int i=0; i<mStartedUsers.size(); i++) { 12631 UserStartedState uss = mStartedUsers.valueAt(i); 12632 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12633 pw.print(": "); uss.dump("", pw); 12634 } 12635 pw.print(" mStartedUserArray: ["); 12636 for (int i=0; i<mStartedUserArray.length; i++) { 12637 if (i > 0) pw.print(", "); 12638 pw.print(mStartedUserArray[i]); 12639 } 12640 pw.println("]"); 12641 pw.print(" mUserLru: ["); 12642 for (int i=0; i<mUserLru.size(); i++) { 12643 if (i > 0) pw.print(", "); 12644 pw.print(mUserLru.get(i)); 12645 } 12646 pw.println("]"); 12647 if (dumpAll) { 12648 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12649 } 12650 synchronized (mUserProfileGroupIdsSelfLocked) { 12651 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12652 pw.println(" mUserProfileGroupIds:"); 12653 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12654 pw.print(" User #"); 12655 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12656 pw.print(" -> profile #"); 12657 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12658 } 12659 } 12660 } 12661 } 12662 if (mHomeProcess != null && (dumpPackage == null 12663 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12664 if (needSep) { 12665 pw.println(); 12666 needSep = false; 12667 } 12668 pw.println(" mHomeProcess: " + mHomeProcess); 12669 } 12670 if (mPreviousProcess != null && (dumpPackage == null 12671 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12672 if (needSep) { 12673 pw.println(); 12674 needSep = false; 12675 } 12676 pw.println(" mPreviousProcess: " + mPreviousProcess); 12677 } 12678 if (dumpAll) { 12679 StringBuilder sb = new StringBuilder(128); 12680 sb.append(" mPreviousProcessVisibleTime: "); 12681 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12682 pw.println(sb); 12683 } 12684 if (mHeavyWeightProcess != null && (dumpPackage == null 12685 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12686 if (needSep) { 12687 pw.println(); 12688 needSep = false; 12689 } 12690 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12691 } 12692 if (dumpPackage == null) { 12693 pw.println(" mConfiguration: " + mConfiguration); 12694 } 12695 if (dumpAll) { 12696 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12697 if (mCompatModePackages.getPackages().size() > 0) { 12698 boolean printed = false; 12699 for (Map.Entry<String, Integer> entry 12700 : mCompatModePackages.getPackages().entrySet()) { 12701 String pkg = entry.getKey(); 12702 int mode = entry.getValue(); 12703 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12704 continue; 12705 } 12706 if (!printed) { 12707 pw.println(" mScreenCompatPackages:"); 12708 printed = true; 12709 } 12710 pw.print(" "); pw.print(pkg); pw.print(": "); 12711 pw.print(mode); pw.println(); 12712 } 12713 } 12714 } 12715 if (dumpPackage == null) { 12716 if (mSleeping || mWentToSleep || mLockScreenShown) { 12717 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12718 + " mLockScreenShown " + mLockScreenShown); 12719 } 12720 if (mShuttingDown || mRunningVoice) { 12721 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12722 } 12723 } 12724 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12725 || mOrigWaitForDebugger) { 12726 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12727 || dumpPackage.equals(mOrigDebugApp)) { 12728 if (needSep) { 12729 pw.println(); 12730 needSep = false; 12731 } 12732 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12733 + " mDebugTransient=" + mDebugTransient 12734 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12735 } 12736 } 12737 if (mOpenGlTraceApp != null) { 12738 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12739 if (needSep) { 12740 pw.println(); 12741 needSep = false; 12742 } 12743 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12744 } 12745 } 12746 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12747 || mProfileFd != null) { 12748 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12749 if (needSep) { 12750 pw.println(); 12751 needSep = false; 12752 } 12753 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12754 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12755 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12756 + mAutoStopProfiler); 12757 pw.println(" mProfileType=" + mProfileType); 12758 } 12759 } 12760 if (dumpPackage == null) { 12761 if (mAlwaysFinishActivities || mController != null) { 12762 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12763 + " mController=" + mController); 12764 } 12765 if (dumpAll) { 12766 pw.println(" Total persistent processes: " + numPers); 12767 pw.println(" mProcessesReady=" + mProcessesReady 12768 + " mSystemReady=" + mSystemReady); 12769 pw.println(" mBooting=" + mBooting 12770 + " mBooted=" + mBooted 12771 + " mFactoryTest=" + mFactoryTest); 12772 pw.print(" mLastPowerCheckRealtime="); 12773 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12774 pw.println(""); 12775 pw.print(" mLastPowerCheckUptime="); 12776 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12777 pw.println(""); 12778 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12779 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12780 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12781 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12782 + " (" + mLruProcesses.size() + " total)" 12783 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12784 + " mNumServiceProcs=" + mNumServiceProcs 12785 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12786 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12787 + " mLastMemoryLevel" + mLastMemoryLevel 12788 + " mLastNumProcesses" + mLastNumProcesses); 12789 long now = SystemClock.uptimeMillis(); 12790 pw.print(" mLastIdleTime="); 12791 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12792 pw.print(" mLowRamSinceLastIdle="); 12793 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12794 pw.println(); 12795 } 12796 } 12797 12798 if (!printedAnything) { 12799 pw.println(" (nothing)"); 12800 } 12801 } 12802 12803 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12804 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12805 if (mProcessesToGc.size() > 0) { 12806 boolean printed = false; 12807 long now = SystemClock.uptimeMillis(); 12808 for (int i=0; i<mProcessesToGc.size(); i++) { 12809 ProcessRecord proc = mProcessesToGc.get(i); 12810 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12811 continue; 12812 } 12813 if (!printed) { 12814 if (needSep) pw.println(); 12815 needSep = true; 12816 pw.println(" Processes that are waiting to GC:"); 12817 printed = true; 12818 } 12819 pw.print(" Process "); pw.println(proc); 12820 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12821 pw.print(", last gced="); 12822 pw.print(now-proc.lastRequestedGc); 12823 pw.print(" ms ago, last lowMem="); 12824 pw.print(now-proc.lastLowMemory); 12825 pw.println(" ms ago"); 12826 12827 } 12828 } 12829 return needSep; 12830 } 12831 12832 void printOomLevel(PrintWriter pw, String name, int adj) { 12833 pw.print(" "); 12834 if (adj >= 0) { 12835 pw.print(' '); 12836 if (adj < 10) pw.print(' '); 12837 } else { 12838 if (adj > -10) pw.print(' '); 12839 } 12840 pw.print(adj); 12841 pw.print(": "); 12842 pw.print(name); 12843 pw.print(" ("); 12844 pw.print(mProcessList.getMemLevel(adj)/1024); 12845 pw.println(" kB)"); 12846 } 12847 12848 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12849 int opti, boolean dumpAll) { 12850 boolean needSep = false; 12851 12852 if (mLruProcesses.size() > 0) { 12853 if (needSep) pw.println(); 12854 needSep = true; 12855 pw.println(" OOM levels:"); 12856 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12857 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12858 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12859 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12860 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12861 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12862 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12863 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12864 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12865 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12866 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12867 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12868 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12869 12870 if (needSep) pw.println(); 12871 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12872 pw.print(" total, non-act at "); 12873 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12874 pw.print(", non-svc at "); 12875 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12876 pw.println("):"); 12877 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12878 needSep = true; 12879 } 12880 12881 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12882 12883 pw.println(); 12884 pw.println(" mHomeProcess: " + mHomeProcess); 12885 pw.println(" mPreviousProcess: " + mPreviousProcess); 12886 if (mHeavyWeightProcess != null) { 12887 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12888 } 12889 12890 return true; 12891 } 12892 12893 /** 12894 * There are three ways to call this: 12895 * - no provider specified: dump all the providers 12896 * - a flattened component name that matched an existing provider was specified as the 12897 * first arg: dump that one provider 12898 * - the first arg isn't the flattened component name of an existing provider: 12899 * dump all providers whose component contains the first arg as a substring 12900 */ 12901 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12902 int opti, boolean dumpAll) { 12903 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12904 } 12905 12906 static class ItemMatcher { 12907 ArrayList<ComponentName> components; 12908 ArrayList<String> strings; 12909 ArrayList<Integer> objects; 12910 boolean all; 12911 12912 ItemMatcher() { 12913 all = true; 12914 } 12915 12916 void build(String name) { 12917 ComponentName componentName = ComponentName.unflattenFromString(name); 12918 if (componentName != null) { 12919 if (components == null) { 12920 components = new ArrayList<ComponentName>(); 12921 } 12922 components.add(componentName); 12923 all = false; 12924 } else { 12925 int objectId = 0; 12926 // Not a '/' separated full component name; maybe an object ID? 12927 try { 12928 objectId = Integer.parseInt(name, 16); 12929 if (objects == null) { 12930 objects = new ArrayList<Integer>(); 12931 } 12932 objects.add(objectId); 12933 all = false; 12934 } catch (RuntimeException e) { 12935 // Not an integer; just do string match. 12936 if (strings == null) { 12937 strings = new ArrayList<String>(); 12938 } 12939 strings.add(name); 12940 all = false; 12941 } 12942 } 12943 } 12944 12945 int build(String[] args, int opti) { 12946 for (; opti<args.length; opti++) { 12947 String name = args[opti]; 12948 if ("--".equals(name)) { 12949 return opti+1; 12950 } 12951 build(name); 12952 } 12953 return opti; 12954 } 12955 12956 boolean match(Object object, ComponentName comp) { 12957 if (all) { 12958 return true; 12959 } 12960 if (components != null) { 12961 for (int i=0; i<components.size(); i++) { 12962 if (components.get(i).equals(comp)) { 12963 return true; 12964 } 12965 } 12966 } 12967 if (objects != null) { 12968 for (int i=0; i<objects.size(); i++) { 12969 if (System.identityHashCode(object) == objects.get(i)) { 12970 return true; 12971 } 12972 } 12973 } 12974 if (strings != null) { 12975 String flat = comp.flattenToString(); 12976 for (int i=0; i<strings.size(); i++) { 12977 if (flat.contains(strings.get(i))) { 12978 return true; 12979 } 12980 } 12981 } 12982 return false; 12983 } 12984 } 12985 12986 /** 12987 * There are three things that cmd can be: 12988 * - a flattened component name that matches an existing activity 12989 * - the cmd arg isn't the flattened component name of an existing activity: 12990 * dump all activity whose component contains the cmd as a substring 12991 * - A hex number of the ActivityRecord object instance. 12992 */ 12993 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12994 int opti, boolean dumpAll) { 12995 ArrayList<ActivityRecord> activities; 12996 12997 synchronized (this) { 12998 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12999 } 13000 13001 if (activities.size() <= 0) { 13002 return false; 13003 } 13004 13005 String[] newArgs = new String[args.length - opti]; 13006 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13007 13008 TaskRecord lastTask = null; 13009 boolean needSep = false; 13010 for (int i=activities.size()-1; i>=0; i--) { 13011 ActivityRecord r = activities.get(i); 13012 if (needSep) { 13013 pw.println(); 13014 } 13015 needSep = true; 13016 synchronized (this) { 13017 if (lastTask != r.task) { 13018 lastTask = r.task; 13019 pw.print("TASK "); pw.print(lastTask.affinity); 13020 pw.print(" id="); pw.println(lastTask.taskId); 13021 if (dumpAll) { 13022 lastTask.dump(pw, " "); 13023 } 13024 } 13025 } 13026 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13027 } 13028 return true; 13029 } 13030 13031 /** 13032 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13033 * there is a thread associated with the activity. 13034 */ 13035 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13036 final ActivityRecord r, String[] args, boolean dumpAll) { 13037 String innerPrefix = prefix + " "; 13038 synchronized (this) { 13039 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13040 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13041 pw.print(" pid="); 13042 if (r.app != null) pw.println(r.app.pid); 13043 else pw.println("(not running)"); 13044 if (dumpAll) { 13045 r.dump(pw, innerPrefix); 13046 } 13047 } 13048 if (r.app != null && r.app.thread != null) { 13049 // flush anything that is already in the PrintWriter since the thread is going 13050 // to write to the file descriptor directly 13051 pw.flush(); 13052 try { 13053 TransferPipe tp = new TransferPipe(); 13054 try { 13055 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13056 r.appToken, innerPrefix, args); 13057 tp.go(fd); 13058 } finally { 13059 tp.kill(); 13060 } 13061 } catch (IOException e) { 13062 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13063 } catch (RemoteException e) { 13064 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13065 } 13066 } 13067 } 13068 13069 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13070 int opti, boolean dumpAll, String dumpPackage) { 13071 boolean needSep = false; 13072 boolean onlyHistory = false; 13073 boolean printedAnything = false; 13074 13075 if ("history".equals(dumpPackage)) { 13076 if (opti < args.length && "-s".equals(args[opti])) { 13077 dumpAll = false; 13078 } 13079 onlyHistory = true; 13080 dumpPackage = null; 13081 } 13082 13083 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13084 if (!onlyHistory && dumpAll) { 13085 if (mRegisteredReceivers.size() > 0) { 13086 boolean printed = false; 13087 Iterator it = mRegisteredReceivers.values().iterator(); 13088 while (it.hasNext()) { 13089 ReceiverList r = (ReceiverList)it.next(); 13090 if (dumpPackage != null && (r.app == null || 13091 !dumpPackage.equals(r.app.info.packageName))) { 13092 continue; 13093 } 13094 if (!printed) { 13095 pw.println(" Registered Receivers:"); 13096 needSep = true; 13097 printed = true; 13098 printedAnything = true; 13099 } 13100 pw.print(" * "); pw.println(r); 13101 r.dump(pw, " "); 13102 } 13103 } 13104 13105 if (mReceiverResolver.dump(pw, needSep ? 13106 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13107 " ", dumpPackage, false)) { 13108 needSep = true; 13109 printedAnything = true; 13110 } 13111 } 13112 13113 for (BroadcastQueue q : mBroadcastQueues) { 13114 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13115 printedAnything |= needSep; 13116 } 13117 13118 needSep = true; 13119 13120 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13121 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13122 if (needSep) { 13123 pw.println(); 13124 } 13125 needSep = true; 13126 printedAnything = true; 13127 pw.print(" Sticky broadcasts for user "); 13128 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13129 StringBuilder sb = new StringBuilder(128); 13130 for (Map.Entry<String, ArrayList<Intent>> ent 13131 : mStickyBroadcasts.valueAt(user).entrySet()) { 13132 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13133 if (dumpAll) { 13134 pw.println(":"); 13135 ArrayList<Intent> intents = ent.getValue(); 13136 final int N = intents.size(); 13137 for (int i=0; i<N; i++) { 13138 sb.setLength(0); 13139 sb.append(" Intent: "); 13140 intents.get(i).toShortString(sb, false, true, false, false); 13141 pw.println(sb.toString()); 13142 Bundle bundle = intents.get(i).getExtras(); 13143 if (bundle != null) { 13144 pw.print(" "); 13145 pw.println(bundle.toString()); 13146 } 13147 } 13148 } else { 13149 pw.println(""); 13150 } 13151 } 13152 } 13153 } 13154 13155 if (!onlyHistory && dumpAll) { 13156 pw.println(); 13157 for (BroadcastQueue queue : mBroadcastQueues) { 13158 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13159 + queue.mBroadcastsScheduled); 13160 } 13161 pw.println(" mHandler:"); 13162 mHandler.dump(new PrintWriterPrinter(pw), " "); 13163 needSep = true; 13164 printedAnything = true; 13165 } 13166 13167 if (!printedAnything) { 13168 pw.println(" (nothing)"); 13169 } 13170 } 13171 13172 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13173 int opti, boolean dumpAll, String dumpPackage) { 13174 boolean needSep; 13175 boolean printedAnything = false; 13176 13177 ItemMatcher matcher = new ItemMatcher(); 13178 matcher.build(args, opti); 13179 13180 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13181 13182 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13183 printedAnything |= needSep; 13184 13185 if (mLaunchingProviders.size() > 0) { 13186 boolean printed = false; 13187 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13188 ContentProviderRecord r = mLaunchingProviders.get(i); 13189 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13190 continue; 13191 } 13192 if (!printed) { 13193 if (needSep) pw.println(); 13194 needSep = true; 13195 pw.println(" Launching content providers:"); 13196 printed = true; 13197 printedAnything = true; 13198 } 13199 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13200 pw.println(r); 13201 } 13202 } 13203 13204 if (mGrantedUriPermissions.size() > 0) { 13205 boolean printed = false; 13206 int dumpUid = -2; 13207 if (dumpPackage != null) { 13208 try { 13209 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13210 } catch (NameNotFoundException e) { 13211 dumpUid = -1; 13212 } 13213 } 13214 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13215 int uid = mGrantedUriPermissions.keyAt(i); 13216 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13217 continue; 13218 } 13219 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13220 if (!printed) { 13221 if (needSep) pw.println(); 13222 needSep = true; 13223 pw.println(" Granted Uri Permissions:"); 13224 printed = true; 13225 printedAnything = true; 13226 } 13227 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13228 for (UriPermission perm : perms.values()) { 13229 pw.print(" "); pw.println(perm); 13230 if (dumpAll) { 13231 perm.dump(pw, " "); 13232 } 13233 } 13234 } 13235 } 13236 13237 if (!printedAnything) { 13238 pw.println(" (nothing)"); 13239 } 13240 } 13241 13242 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13243 int opti, boolean dumpAll, String dumpPackage) { 13244 boolean printed = false; 13245 13246 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13247 13248 if (mIntentSenderRecords.size() > 0) { 13249 Iterator<WeakReference<PendingIntentRecord>> it 13250 = mIntentSenderRecords.values().iterator(); 13251 while (it.hasNext()) { 13252 WeakReference<PendingIntentRecord> ref = it.next(); 13253 PendingIntentRecord rec = ref != null ? ref.get(): null; 13254 if (dumpPackage != null && (rec == null 13255 || !dumpPackage.equals(rec.key.packageName))) { 13256 continue; 13257 } 13258 printed = true; 13259 if (rec != null) { 13260 pw.print(" * "); pw.println(rec); 13261 if (dumpAll) { 13262 rec.dump(pw, " "); 13263 } 13264 } else { 13265 pw.print(" * "); pw.println(ref); 13266 } 13267 } 13268 } 13269 13270 if (!printed) { 13271 pw.println(" (nothing)"); 13272 } 13273 } 13274 13275 private static final int dumpProcessList(PrintWriter pw, 13276 ActivityManagerService service, List list, 13277 String prefix, String normalLabel, String persistentLabel, 13278 String dumpPackage) { 13279 int numPers = 0; 13280 final int N = list.size()-1; 13281 for (int i=N; i>=0; i--) { 13282 ProcessRecord r = (ProcessRecord)list.get(i); 13283 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13284 continue; 13285 } 13286 pw.println(String.format("%s%s #%2d: %s", 13287 prefix, (r.persistent ? persistentLabel : normalLabel), 13288 i, r.toString())); 13289 if (r.persistent) { 13290 numPers++; 13291 } 13292 } 13293 return numPers; 13294 } 13295 13296 private static final boolean dumpProcessOomList(PrintWriter pw, 13297 ActivityManagerService service, List<ProcessRecord> origList, 13298 String prefix, String normalLabel, String persistentLabel, 13299 boolean inclDetails, String dumpPackage) { 13300 13301 ArrayList<Pair<ProcessRecord, Integer>> list 13302 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13303 for (int i=0; i<origList.size(); i++) { 13304 ProcessRecord r = origList.get(i); 13305 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13306 continue; 13307 } 13308 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13309 } 13310 13311 if (list.size() <= 0) { 13312 return false; 13313 } 13314 13315 Comparator<Pair<ProcessRecord, Integer>> comparator 13316 = new Comparator<Pair<ProcessRecord, Integer>>() { 13317 @Override 13318 public int compare(Pair<ProcessRecord, Integer> object1, 13319 Pair<ProcessRecord, Integer> object2) { 13320 if (object1.first.setAdj != object2.first.setAdj) { 13321 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13322 } 13323 if (object1.second.intValue() != object2.second.intValue()) { 13324 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13325 } 13326 return 0; 13327 } 13328 }; 13329 13330 Collections.sort(list, comparator); 13331 13332 final long curRealtime = SystemClock.elapsedRealtime(); 13333 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13334 final long curUptime = SystemClock.uptimeMillis(); 13335 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13336 13337 for (int i=list.size()-1; i>=0; i--) { 13338 ProcessRecord r = list.get(i).first; 13339 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13340 char schedGroup; 13341 switch (r.setSchedGroup) { 13342 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13343 schedGroup = 'B'; 13344 break; 13345 case Process.THREAD_GROUP_DEFAULT: 13346 schedGroup = 'F'; 13347 break; 13348 default: 13349 schedGroup = '?'; 13350 break; 13351 } 13352 char foreground; 13353 if (r.foregroundActivities) { 13354 foreground = 'A'; 13355 } else if (r.foregroundServices) { 13356 foreground = 'S'; 13357 } else { 13358 foreground = ' '; 13359 } 13360 String procState = ProcessList.makeProcStateString(r.curProcState); 13361 pw.print(prefix); 13362 pw.print(r.persistent ? persistentLabel : normalLabel); 13363 pw.print(" #"); 13364 int num = (origList.size()-1)-list.get(i).second; 13365 if (num < 10) pw.print(' '); 13366 pw.print(num); 13367 pw.print(": "); 13368 pw.print(oomAdj); 13369 pw.print(' '); 13370 pw.print(schedGroup); 13371 pw.print('/'); 13372 pw.print(foreground); 13373 pw.print('/'); 13374 pw.print(procState); 13375 pw.print(" trm:"); 13376 if (r.trimMemoryLevel < 10) pw.print(' '); 13377 pw.print(r.trimMemoryLevel); 13378 pw.print(' '); 13379 pw.print(r.toShortString()); 13380 pw.print(" ("); 13381 pw.print(r.adjType); 13382 pw.println(')'); 13383 if (r.adjSource != null || r.adjTarget != null) { 13384 pw.print(prefix); 13385 pw.print(" "); 13386 if (r.adjTarget instanceof ComponentName) { 13387 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13388 } else if (r.adjTarget != null) { 13389 pw.print(r.adjTarget.toString()); 13390 } else { 13391 pw.print("{null}"); 13392 } 13393 pw.print("<="); 13394 if (r.adjSource instanceof ProcessRecord) { 13395 pw.print("Proc{"); 13396 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13397 pw.println("}"); 13398 } else if (r.adjSource != null) { 13399 pw.println(r.adjSource.toString()); 13400 } else { 13401 pw.println("{null}"); 13402 } 13403 } 13404 if (inclDetails) { 13405 pw.print(prefix); 13406 pw.print(" "); 13407 pw.print("oom: max="); pw.print(r.maxAdj); 13408 pw.print(" curRaw="); pw.print(r.curRawAdj); 13409 pw.print(" setRaw="); pw.print(r.setRawAdj); 13410 pw.print(" cur="); pw.print(r.curAdj); 13411 pw.print(" set="); pw.println(r.setAdj); 13412 pw.print(prefix); 13413 pw.print(" "); 13414 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13415 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13416 pw.print(" lastPss="); pw.print(r.lastPss); 13417 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13418 pw.print(prefix); 13419 pw.print(" "); 13420 pw.print("cached="); pw.print(r.cached); 13421 pw.print(" empty="); pw.print(r.empty); 13422 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13423 13424 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13425 if (r.lastWakeTime != 0) { 13426 long wtime; 13427 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13428 synchronized (stats) { 13429 wtime = stats.getProcessWakeTime(r.info.uid, 13430 r.pid, curRealtime); 13431 } 13432 long timeUsed = wtime - r.lastWakeTime; 13433 pw.print(prefix); 13434 pw.print(" "); 13435 pw.print("keep awake over "); 13436 TimeUtils.formatDuration(realtimeSince, pw); 13437 pw.print(" used "); 13438 TimeUtils.formatDuration(timeUsed, pw); 13439 pw.print(" ("); 13440 pw.print((timeUsed*100)/realtimeSince); 13441 pw.println("%)"); 13442 } 13443 if (r.lastCpuTime != 0) { 13444 long timeUsed = r.curCpuTime - r.lastCpuTime; 13445 pw.print(prefix); 13446 pw.print(" "); 13447 pw.print("run cpu over "); 13448 TimeUtils.formatDuration(uptimeSince, pw); 13449 pw.print(" used "); 13450 TimeUtils.formatDuration(timeUsed, pw); 13451 pw.print(" ("); 13452 pw.print((timeUsed*100)/uptimeSince); 13453 pw.println("%)"); 13454 } 13455 } 13456 } 13457 } 13458 return true; 13459 } 13460 13461 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13462 ArrayList<ProcessRecord> procs; 13463 synchronized (this) { 13464 if (args != null && args.length > start 13465 && args[start].charAt(0) != '-') { 13466 procs = new ArrayList<ProcessRecord>(); 13467 int pid = -1; 13468 try { 13469 pid = Integer.parseInt(args[start]); 13470 } catch (NumberFormatException e) { 13471 } 13472 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13473 ProcessRecord proc = mLruProcesses.get(i); 13474 if (proc.pid == pid) { 13475 procs.add(proc); 13476 } else if (proc.processName.equals(args[start])) { 13477 procs.add(proc); 13478 } 13479 } 13480 if (procs.size() <= 0) { 13481 return null; 13482 } 13483 } else { 13484 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13485 } 13486 } 13487 return procs; 13488 } 13489 13490 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13491 PrintWriter pw, String[] args) { 13492 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13493 if (procs == null) { 13494 pw.println("No process found for: " + args[0]); 13495 return; 13496 } 13497 13498 long uptime = SystemClock.uptimeMillis(); 13499 long realtime = SystemClock.elapsedRealtime(); 13500 pw.println("Applications Graphics Acceleration Info:"); 13501 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13502 13503 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13504 ProcessRecord r = procs.get(i); 13505 if (r.thread != null) { 13506 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13507 pw.flush(); 13508 try { 13509 TransferPipe tp = new TransferPipe(); 13510 try { 13511 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13512 tp.go(fd); 13513 } finally { 13514 tp.kill(); 13515 } 13516 } catch (IOException e) { 13517 pw.println("Failure while dumping the app: " + r); 13518 pw.flush(); 13519 } catch (RemoteException e) { 13520 pw.println("Got a RemoteException while dumping the app " + r); 13521 pw.flush(); 13522 } 13523 } 13524 } 13525 } 13526 13527 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13528 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13529 if (procs == null) { 13530 pw.println("No process found for: " + args[0]); 13531 return; 13532 } 13533 13534 pw.println("Applications Database Info:"); 13535 13536 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13537 ProcessRecord r = procs.get(i); 13538 if (r.thread != null) { 13539 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13540 pw.flush(); 13541 try { 13542 TransferPipe tp = new TransferPipe(); 13543 try { 13544 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13545 tp.go(fd); 13546 } finally { 13547 tp.kill(); 13548 } 13549 } catch (IOException e) { 13550 pw.println("Failure while dumping the app: " + r); 13551 pw.flush(); 13552 } catch (RemoteException e) { 13553 pw.println("Got a RemoteException while dumping the app " + r); 13554 pw.flush(); 13555 } 13556 } 13557 } 13558 } 13559 13560 final static class MemItem { 13561 final boolean isProc; 13562 final String label; 13563 final String shortLabel; 13564 final long pss; 13565 final int id; 13566 final boolean hasActivities; 13567 ArrayList<MemItem> subitems; 13568 13569 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13570 boolean _hasActivities) { 13571 isProc = true; 13572 label = _label; 13573 shortLabel = _shortLabel; 13574 pss = _pss; 13575 id = _id; 13576 hasActivities = _hasActivities; 13577 } 13578 13579 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13580 isProc = false; 13581 label = _label; 13582 shortLabel = _shortLabel; 13583 pss = _pss; 13584 id = _id; 13585 hasActivities = false; 13586 } 13587 } 13588 13589 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13590 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13591 if (sort && !isCompact) { 13592 Collections.sort(items, new Comparator<MemItem>() { 13593 @Override 13594 public int compare(MemItem lhs, MemItem rhs) { 13595 if (lhs.pss < rhs.pss) { 13596 return 1; 13597 } else if (lhs.pss > rhs.pss) { 13598 return -1; 13599 } 13600 return 0; 13601 } 13602 }); 13603 } 13604 13605 for (int i=0; i<items.size(); i++) { 13606 MemItem mi = items.get(i); 13607 if (!isCompact) { 13608 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13609 } else if (mi.isProc) { 13610 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13611 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13612 pw.println(mi.hasActivities ? ",a" : ",e"); 13613 } else { 13614 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13615 pw.println(mi.pss); 13616 } 13617 if (mi.subitems != null) { 13618 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13619 true, isCompact); 13620 } 13621 } 13622 } 13623 13624 // These are in KB. 13625 static final long[] DUMP_MEM_BUCKETS = new long[] { 13626 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13627 120*1024, 160*1024, 200*1024, 13628 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13629 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13630 }; 13631 13632 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13633 boolean stackLike) { 13634 int start = label.lastIndexOf('.'); 13635 if (start >= 0) start++; 13636 else start = 0; 13637 int end = label.length(); 13638 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13639 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13640 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13641 out.append(bucket); 13642 out.append(stackLike ? "MB." : "MB "); 13643 out.append(label, start, end); 13644 return; 13645 } 13646 } 13647 out.append(memKB/1024); 13648 out.append(stackLike ? "MB." : "MB "); 13649 out.append(label, start, end); 13650 } 13651 13652 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13653 ProcessList.NATIVE_ADJ, 13654 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13655 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13656 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13657 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13658 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13659 }; 13660 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13661 "Native", 13662 "System", "Persistent", "Foreground", 13663 "Visible", "Perceptible", 13664 "Heavy Weight", "Backup", 13665 "A Services", "Home", 13666 "Previous", "B Services", "Cached" 13667 }; 13668 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13669 "native", 13670 "sys", "pers", "fore", 13671 "vis", "percept", 13672 "heavy", "backup", 13673 "servicea", "home", 13674 "prev", "serviceb", "cached" 13675 }; 13676 13677 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13678 long realtime, boolean isCheckinRequest, boolean isCompact) { 13679 if (isCheckinRequest || isCompact) { 13680 // short checkin version 13681 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13682 } else { 13683 pw.println("Applications Memory Usage (kB):"); 13684 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13685 } 13686 } 13687 13688 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13689 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13690 boolean dumpDetails = false; 13691 boolean dumpFullDetails = false; 13692 boolean dumpDalvik = false; 13693 boolean oomOnly = false; 13694 boolean isCompact = false; 13695 boolean localOnly = false; 13696 13697 int opti = 0; 13698 while (opti < args.length) { 13699 String opt = args[opti]; 13700 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13701 break; 13702 } 13703 opti++; 13704 if ("-a".equals(opt)) { 13705 dumpDetails = true; 13706 dumpFullDetails = true; 13707 dumpDalvik = true; 13708 } else if ("-d".equals(opt)) { 13709 dumpDalvik = true; 13710 } else if ("-c".equals(opt)) { 13711 isCompact = true; 13712 } else if ("--oom".equals(opt)) { 13713 oomOnly = true; 13714 } else if ("--local".equals(opt)) { 13715 localOnly = true; 13716 } else if ("-h".equals(opt)) { 13717 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13718 pw.println(" -a: include all available information for each process."); 13719 pw.println(" -d: include dalvik details when dumping process details."); 13720 pw.println(" -c: dump in a compact machine-parseable representation."); 13721 pw.println(" --oom: only show processes organized by oom adj."); 13722 pw.println(" --local: only collect details locally, don't call process."); 13723 pw.println("If [process] is specified it can be the name or "); 13724 pw.println("pid of a specific process to dump."); 13725 return; 13726 } else { 13727 pw.println("Unknown argument: " + opt + "; use -h for help"); 13728 } 13729 } 13730 13731 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13732 long uptime = SystemClock.uptimeMillis(); 13733 long realtime = SystemClock.elapsedRealtime(); 13734 final long[] tmpLong = new long[1]; 13735 13736 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13737 if (procs == null) { 13738 // No Java processes. Maybe they want to print a native process. 13739 if (args != null && args.length > opti 13740 && args[opti].charAt(0) != '-') { 13741 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13742 = new ArrayList<ProcessCpuTracker.Stats>(); 13743 updateCpuStatsNow(); 13744 int findPid = -1; 13745 try { 13746 findPid = Integer.parseInt(args[opti]); 13747 } catch (NumberFormatException e) { 13748 } 13749 synchronized (mProcessCpuTracker) { 13750 final int N = mProcessCpuTracker.countStats(); 13751 for (int i=0; i<N; i++) { 13752 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13753 if (st.pid == findPid || (st.baseName != null 13754 && st.baseName.equals(args[opti]))) { 13755 nativeProcs.add(st); 13756 } 13757 } 13758 } 13759 if (nativeProcs.size() > 0) { 13760 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13761 isCompact); 13762 Debug.MemoryInfo mi = null; 13763 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13764 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13765 final int pid = r.pid; 13766 if (!isCheckinRequest && dumpDetails) { 13767 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13768 } 13769 if (mi == null) { 13770 mi = new Debug.MemoryInfo(); 13771 } 13772 if (dumpDetails || (!brief && !oomOnly)) { 13773 Debug.getMemoryInfo(pid, mi); 13774 } else { 13775 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13776 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13777 } 13778 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13779 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13780 if (isCheckinRequest) { 13781 pw.println(); 13782 } 13783 } 13784 return; 13785 } 13786 } 13787 pw.println("No process found for: " + args[opti]); 13788 return; 13789 } 13790 13791 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13792 dumpDetails = true; 13793 } 13794 13795 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13796 13797 String[] innerArgs = new String[args.length-opti]; 13798 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13799 13800 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13801 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13802 long nativePss=0, dalvikPss=0, otherPss=0; 13803 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13804 13805 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13806 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13807 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13808 13809 long totalPss = 0; 13810 long cachedPss = 0; 13811 13812 Debug.MemoryInfo mi = null; 13813 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13814 final ProcessRecord r = procs.get(i); 13815 final IApplicationThread thread; 13816 final int pid; 13817 final int oomAdj; 13818 final boolean hasActivities; 13819 synchronized (this) { 13820 thread = r.thread; 13821 pid = r.pid; 13822 oomAdj = r.getSetAdjWithServices(); 13823 hasActivities = r.activities.size() > 0; 13824 } 13825 if (thread != null) { 13826 if (!isCheckinRequest && dumpDetails) { 13827 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13828 } 13829 if (mi == null) { 13830 mi = new Debug.MemoryInfo(); 13831 } 13832 if (dumpDetails || (!brief && !oomOnly)) { 13833 Debug.getMemoryInfo(pid, mi); 13834 } else { 13835 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13836 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13837 } 13838 if (dumpDetails) { 13839 if (localOnly) { 13840 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13841 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13842 if (isCheckinRequest) { 13843 pw.println(); 13844 } 13845 } else { 13846 try { 13847 pw.flush(); 13848 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13849 dumpDalvik, innerArgs); 13850 } catch (RemoteException e) { 13851 if (!isCheckinRequest) { 13852 pw.println("Got RemoteException!"); 13853 pw.flush(); 13854 } 13855 } 13856 } 13857 } 13858 13859 final long myTotalPss = mi.getTotalPss(); 13860 final long myTotalUss = mi.getTotalUss(); 13861 13862 synchronized (this) { 13863 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13864 // Record this for posterity if the process has been stable. 13865 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13866 } 13867 } 13868 13869 if (!isCheckinRequest && mi != null) { 13870 totalPss += myTotalPss; 13871 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13872 (hasActivities ? " / activities)" : ")"), 13873 r.processName, myTotalPss, pid, hasActivities); 13874 procMems.add(pssItem); 13875 procMemsMap.put(pid, pssItem); 13876 13877 nativePss += mi.nativePss; 13878 dalvikPss += mi.dalvikPss; 13879 otherPss += mi.otherPss; 13880 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13881 long mem = mi.getOtherPss(j); 13882 miscPss[j] += mem; 13883 otherPss -= mem; 13884 } 13885 13886 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13887 cachedPss += myTotalPss; 13888 } 13889 13890 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13891 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13892 || oomIndex == (oomPss.length-1)) { 13893 oomPss[oomIndex] += myTotalPss; 13894 if (oomProcs[oomIndex] == null) { 13895 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13896 } 13897 oomProcs[oomIndex].add(pssItem); 13898 break; 13899 } 13900 } 13901 } 13902 } 13903 } 13904 13905 long nativeProcTotalPss = 0; 13906 13907 if (!isCheckinRequest && procs.size() > 1) { 13908 // If we are showing aggregations, also look for native processes to 13909 // include so that our aggregations are more accurate. 13910 updateCpuStatsNow(); 13911 synchronized (mProcessCpuTracker) { 13912 final int N = mProcessCpuTracker.countStats(); 13913 for (int i=0; i<N; i++) { 13914 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13915 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13916 if (mi == null) { 13917 mi = new Debug.MemoryInfo(); 13918 } 13919 if (!brief && !oomOnly) { 13920 Debug.getMemoryInfo(st.pid, mi); 13921 } else { 13922 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13923 mi.nativePrivateDirty = (int)tmpLong[0]; 13924 } 13925 13926 final long myTotalPss = mi.getTotalPss(); 13927 totalPss += myTotalPss; 13928 nativeProcTotalPss += myTotalPss; 13929 13930 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13931 st.name, myTotalPss, st.pid, false); 13932 procMems.add(pssItem); 13933 13934 nativePss += mi.nativePss; 13935 dalvikPss += mi.dalvikPss; 13936 otherPss += mi.otherPss; 13937 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13938 long mem = mi.getOtherPss(j); 13939 miscPss[j] += mem; 13940 otherPss -= mem; 13941 } 13942 oomPss[0] += myTotalPss; 13943 if (oomProcs[0] == null) { 13944 oomProcs[0] = new ArrayList<MemItem>(); 13945 } 13946 oomProcs[0].add(pssItem); 13947 } 13948 } 13949 } 13950 13951 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13952 13953 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13954 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13955 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13956 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13957 String label = Debug.MemoryInfo.getOtherLabel(j); 13958 catMems.add(new MemItem(label, label, miscPss[j], j)); 13959 } 13960 13961 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13962 for (int j=0; j<oomPss.length; j++) { 13963 if (oomPss[j] != 0) { 13964 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13965 : DUMP_MEM_OOM_LABEL[j]; 13966 MemItem item = new MemItem(label, label, oomPss[j], 13967 DUMP_MEM_OOM_ADJ[j]); 13968 item.subitems = oomProcs[j]; 13969 oomMems.add(item); 13970 } 13971 } 13972 13973 if (!brief && !oomOnly && !isCompact) { 13974 pw.println(); 13975 pw.println("Total PSS by process:"); 13976 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13977 pw.println(); 13978 } 13979 if (!isCompact) { 13980 pw.println("Total PSS by OOM adjustment:"); 13981 } 13982 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13983 if (!brief && !oomOnly) { 13984 PrintWriter out = categoryPw != null ? categoryPw : pw; 13985 if (!isCompact) { 13986 out.println(); 13987 out.println("Total PSS by category:"); 13988 } 13989 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13990 } 13991 if (!isCompact) { 13992 pw.println(); 13993 } 13994 MemInfoReader memInfo = new MemInfoReader(); 13995 memInfo.readMemInfo(); 13996 if (nativeProcTotalPss > 0) { 13997 synchronized (this) { 13998 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13999 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14000 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14001 nativeProcTotalPss); 14002 } 14003 } 14004 if (!brief) { 14005 if (!isCompact) { 14006 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14007 pw.print(" kB (status "); 14008 switch (mLastMemoryLevel) { 14009 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14010 pw.println("normal)"); 14011 break; 14012 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14013 pw.println("moderate)"); 14014 break; 14015 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14016 pw.println("low)"); 14017 break; 14018 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14019 pw.println("critical)"); 14020 break; 14021 default: 14022 pw.print(mLastMemoryLevel); 14023 pw.println(")"); 14024 break; 14025 } 14026 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14027 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14028 pw.print(cachedPss); pw.print(" cached pss + "); 14029 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14030 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14031 } else { 14032 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14033 pw.print(cachedPss + memInfo.getCachedSizeKb() 14034 + memInfo.getFreeSizeKb()); pw.print(","); 14035 pw.println(totalPss - cachedPss); 14036 } 14037 } 14038 if (!isCompact) { 14039 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14040 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14041 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14042 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14043 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14044 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14045 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14046 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14047 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14048 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14049 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14050 } 14051 if (!brief) { 14052 if (memInfo.getZramTotalSizeKb() != 0) { 14053 if (!isCompact) { 14054 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14055 pw.print(" kB physical used for "); 14056 pw.print(memInfo.getSwapTotalSizeKb() 14057 - memInfo.getSwapFreeSizeKb()); 14058 pw.print(" kB in swap ("); 14059 pw.print(memInfo.getSwapTotalSizeKb()); 14060 pw.println(" kB total swap)"); 14061 } else { 14062 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14063 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14064 pw.println(memInfo.getSwapFreeSizeKb()); 14065 } 14066 } 14067 final int[] SINGLE_LONG_FORMAT = new int[] { 14068 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14069 }; 14070 long[] longOut = new long[1]; 14071 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14072 SINGLE_LONG_FORMAT, null, longOut, null); 14073 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14074 longOut[0] = 0; 14075 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14076 SINGLE_LONG_FORMAT, null, longOut, null); 14077 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14078 longOut[0] = 0; 14079 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14080 SINGLE_LONG_FORMAT, null, longOut, null); 14081 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14082 longOut[0] = 0; 14083 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14084 SINGLE_LONG_FORMAT, null, longOut, null); 14085 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14086 if (!isCompact) { 14087 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14088 pw.print(" KSM: "); pw.print(sharing); 14089 pw.print(" kB saved from shared "); 14090 pw.print(shared); pw.println(" kB"); 14091 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14092 pw.print(voltile); pw.println(" kB volatile"); 14093 } 14094 pw.print(" Tuning: "); 14095 pw.print(ActivityManager.staticGetMemoryClass()); 14096 pw.print(" (large "); 14097 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14098 pw.print("), oom "); 14099 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14100 pw.print(" kB"); 14101 pw.print(", restore limit "); 14102 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14103 pw.print(" kB"); 14104 if (ActivityManager.isLowRamDeviceStatic()) { 14105 pw.print(" (low-ram)"); 14106 } 14107 if (ActivityManager.isHighEndGfx()) { 14108 pw.print(" (high-end-gfx)"); 14109 } 14110 pw.println(); 14111 } else { 14112 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14113 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14114 pw.println(voltile); 14115 pw.print("tuning,"); 14116 pw.print(ActivityManager.staticGetMemoryClass()); 14117 pw.print(','); 14118 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14119 pw.print(','); 14120 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14121 if (ActivityManager.isLowRamDeviceStatic()) { 14122 pw.print(",low-ram"); 14123 } 14124 if (ActivityManager.isHighEndGfx()) { 14125 pw.print(",high-end-gfx"); 14126 } 14127 pw.println(); 14128 } 14129 } 14130 } 14131 } 14132 14133 /** 14134 * Searches array of arguments for the specified string 14135 * @param args array of argument strings 14136 * @param value value to search for 14137 * @return true if the value is contained in the array 14138 */ 14139 private static boolean scanArgs(String[] args, String value) { 14140 if (args != null) { 14141 for (String arg : args) { 14142 if (value.equals(arg)) { 14143 return true; 14144 } 14145 } 14146 } 14147 return false; 14148 } 14149 14150 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14151 ContentProviderRecord cpr, boolean always) { 14152 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14153 14154 if (!inLaunching || always) { 14155 synchronized (cpr) { 14156 cpr.launchingApp = null; 14157 cpr.notifyAll(); 14158 } 14159 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14160 String names[] = cpr.info.authority.split(";"); 14161 for (int j = 0; j < names.length; j++) { 14162 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14163 } 14164 } 14165 14166 for (int i=0; i<cpr.connections.size(); i++) { 14167 ContentProviderConnection conn = cpr.connections.get(i); 14168 if (conn.waiting) { 14169 // If this connection is waiting for the provider, then we don't 14170 // need to mess with its process unless we are always removing 14171 // or for some reason the provider is not currently launching. 14172 if (inLaunching && !always) { 14173 continue; 14174 } 14175 } 14176 ProcessRecord capp = conn.client; 14177 conn.dead = true; 14178 if (conn.stableCount > 0) { 14179 if (!capp.persistent && capp.thread != null 14180 && capp.pid != 0 14181 && capp.pid != MY_PID) { 14182 capp.kill("depends on provider " 14183 + cpr.name.flattenToShortString() 14184 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14185 } 14186 } else if (capp.thread != null && conn.provider.provider != null) { 14187 try { 14188 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14189 } catch (RemoteException e) { 14190 } 14191 // In the protocol here, we don't expect the client to correctly 14192 // clean up this connection, we'll just remove it. 14193 cpr.connections.remove(i); 14194 conn.client.conProviders.remove(conn); 14195 } 14196 } 14197 14198 if (inLaunching && always) { 14199 mLaunchingProviders.remove(cpr); 14200 } 14201 return inLaunching; 14202 } 14203 14204 /** 14205 * Main code for cleaning up a process when it has gone away. This is 14206 * called both as a result of the process dying, or directly when stopping 14207 * a process when running in single process mode. 14208 */ 14209 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14210 boolean restarting, boolean allowRestart, int index) { 14211 if (index >= 0) { 14212 removeLruProcessLocked(app); 14213 ProcessList.remove(app.pid); 14214 } 14215 14216 mProcessesToGc.remove(app); 14217 mPendingPssProcesses.remove(app); 14218 14219 // Dismiss any open dialogs. 14220 if (app.crashDialog != null && !app.forceCrashReport) { 14221 app.crashDialog.dismiss(); 14222 app.crashDialog = null; 14223 } 14224 if (app.anrDialog != null) { 14225 app.anrDialog.dismiss(); 14226 app.anrDialog = null; 14227 } 14228 if (app.waitDialog != null) { 14229 app.waitDialog.dismiss(); 14230 app.waitDialog = null; 14231 } 14232 14233 app.crashing = false; 14234 app.notResponding = false; 14235 14236 app.resetPackageList(mProcessStats); 14237 app.unlinkDeathRecipient(); 14238 app.makeInactive(mProcessStats); 14239 app.waitingToKill = null; 14240 app.forcingToForeground = null; 14241 updateProcessForegroundLocked(app, false, false); 14242 app.foregroundActivities = false; 14243 app.hasShownUi = false; 14244 app.treatLikeActivity = false; 14245 app.hasAboveClient = false; 14246 app.hasClientActivities = false; 14247 14248 mServices.killServicesLocked(app, allowRestart); 14249 14250 boolean restart = false; 14251 14252 // Remove published content providers. 14253 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14254 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14255 final boolean always = app.bad || !allowRestart; 14256 if (removeDyingProviderLocked(app, cpr, always) || always) { 14257 // We left the provider in the launching list, need to 14258 // restart it. 14259 restart = true; 14260 } 14261 14262 cpr.provider = null; 14263 cpr.proc = null; 14264 } 14265 app.pubProviders.clear(); 14266 14267 // Take care of any launching providers waiting for this process. 14268 if (checkAppInLaunchingProvidersLocked(app, false)) { 14269 restart = true; 14270 } 14271 14272 // Unregister from connected content providers. 14273 if (!app.conProviders.isEmpty()) { 14274 for (int i=0; i<app.conProviders.size(); i++) { 14275 ContentProviderConnection conn = app.conProviders.get(i); 14276 conn.provider.connections.remove(conn); 14277 } 14278 app.conProviders.clear(); 14279 } 14280 14281 // At this point there may be remaining entries in mLaunchingProviders 14282 // where we were the only one waiting, so they are no longer of use. 14283 // Look for these and clean up if found. 14284 // XXX Commented out for now. Trying to figure out a way to reproduce 14285 // the actual situation to identify what is actually going on. 14286 if (false) { 14287 for (int i=0; i<mLaunchingProviders.size(); i++) { 14288 ContentProviderRecord cpr = (ContentProviderRecord) 14289 mLaunchingProviders.get(i); 14290 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14291 synchronized (cpr) { 14292 cpr.launchingApp = null; 14293 cpr.notifyAll(); 14294 } 14295 } 14296 } 14297 } 14298 14299 skipCurrentReceiverLocked(app); 14300 14301 // Unregister any receivers. 14302 for (int i=app.receivers.size()-1; i>=0; i--) { 14303 removeReceiverLocked(app.receivers.valueAt(i)); 14304 } 14305 app.receivers.clear(); 14306 14307 // If the app is undergoing backup, tell the backup manager about it 14308 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14309 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14310 + mBackupTarget.appInfo + " died during backup"); 14311 try { 14312 IBackupManager bm = IBackupManager.Stub.asInterface( 14313 ServiceManager.getService(Context.BACKUP_SERVICE)); 14314 bm.agentDisconnected(app.info.packageName); 14315 } catch (RemoteException e) { 14316 // can't happen; backup manager is local 14317 } 14318 } 14319 14320 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14321 ProcessChangeItem item = mPendingProcessChanges.get(i); 14322 if (item.pid == app.pid) { 14323 mPendingProcessChanges.remove(i); 14324 mAvailProcessChanges.add(item); 14325 } 14326 } 14327 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14328 14329 // If the caller is restarting this app, then leave it in its 14330 // current lists and let the caller take care of it. 14331 if (restarting) { 14332 return; 14333 } 14334 14335 if (!app.persistent || app.isolated) { 14336 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14337 "Removing non-persistent process during cleanup: " + app); 14338 mProcessNames.remove(app.processName, app.uid); 14339 mIsolatedProcesses.remove(app.uid); 14340 if (mHeavyWeightProcess == app) { 14341 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14342 mHeavyWeightProcess.userId, 0)); 14343 mHeavyWeightProcess = null; 14344 } 14345 } else if (!app.removed) { 14346 // This app is persistent, so we need to keep its record around. 14347 // If it is not already on the pending app list, add it there 14348 // and start a new process for it. 14349 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14350 mPersistentStartingProcesses.add(app); 14351 restart = true; 14352 } 14353 } 14354 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14355 "Clean-up removing on hold: " + app); 14356 mProcessesOnHold.remove(app); 14357 14358 if (app == mHomeProcess) { 14359 mHomeProcess = null; 14360 } 14361 if (app == mPreviousProcess) { 14362 mPreviousProcess = null; 14363 } 14364 14365 if (restart && !app.isolated) { 14366 // We have components that still need to be running in the 14367 // process, so re-launch it. 14368 mProcessNames.put(app.processName, app.uid, app); 14369 startProcessLocked(app, "restart", app.processName); 14370 } else if (app.pid > 0 && app.pid != MY_PID) { 14371 // Goodbye! 14372 boolean removed; 14373 synchronized (mPidsSelfLocked) { 14374 mPidsSelfLocked.remove(app.pid); 14375 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14376 } 14377 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14378 if (app.isolated) { 14379 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14380 } 14381 app.setPid(0); 14382 } 14383 } 14384 14385 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14386 // Look through the content providers we are waiting to have launched, 14387 // and if any run in this process then either schedule a restart of 14388 // the process or kill the client waiting for it if this process has 14389 // gone bad. 14390 int NL = mLaunchingProviders.size(); 14391 boolean restart = false; 14392 for (int i=0; i<NL; i++) { 14393 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14394 if (cpr.launchingApp == app) { 14395 if (!alwaysBad && !app.bad) { 14396 restart = true; 14397 } else { 14398 removeDyingProviderLocked(app, cpr, true); 14399 // cpr should have been removed from mLaunchingProviders 14400 NL = mLaunchingProviders.size(); 14401 i--; 14402 } 14403 } 14404 } 14405 return restart; 14406 } 14407 14408 // ========================================================= 14409 // SERVICES 14410 // ========================================================= 14411 14412 @Override 14413 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14414 int flags) { 14415 enforceNotIsolatedCaller("getServices"); 14416 synchronized (this) { 14417 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14418 } 14419 } 14420 14421 @Override 14422 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14423 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14424 synchronized (this) { 14425 return mServices.getRunningServiceControlPanelLocked(name); 14426 } 14427 } 14428 14429 @Override 14430 public ComponentName startService(IApplicationThread caller, Intent service, 14431 String resolvedType, int userId) { 14432 enforceNotIsolatedCaller("startService"); 14433 // Refuse possible leaked file descriptors 14434 if (service != null && service.hasFileDescriptors() == true) { 14435 throw new IllegalArgumentException("File descriptors passed in Intent"); 14436 } 14437 14438 if (DEBUG_SERVICE) 14439 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14440 synchronized(this) { 14441 final int callingPid = Binder.getCallingPid(); 14442 final int callingUid = Binder.getCallingUid(); 14443 final long origId = Binder.clearCallingIdentity(); 14444 ComponentName res = mServices.startServiceLocked(caller, service, 14445 resolvedType, callingPid, callingUid, userId); 14446 Binder.restoreCallingIdentity(origId); 14447 return res; 14448 } 14449 } 14450 14451 ComponentName startServiceInPackage(int uid, 14452 Intent service, String resolvedType, int userId) { 14453 synchronized(this) { 14454 if (DEBUG_SERVICE) 14455 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14456 final long origId = Binder.clearCallingIdentity(); 14457 ComponentName res = mServices.startServiceLocked(null, service, 14458 resolvedType, -1, uid, userId); 14459 Binder.restoreCallingIdentity(origId); 14460 return res; 14461 } 14462 } 14463 14464 @Override 14465 public int stopService(IApplicationThread caller, Intent service, 14466 String resolvedType, int userId) { 14467 enforceNotIsolatedCaller("stopService"); 14468 // Refuse possible leaked file descriptors 14469 if (service != null && service.hasFileDescriptors() == true) { 14470 throw new IllegalArgumentException("File descriptors passed in Intent"); 14471 } 14472 14473 synchronized(this) { 14474 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14475 } 14476 } 14477 14478 @Override 14479 public IBinder peekService(Intent service, String resolvedType) { 14480 enforceNotIsolatedCaller("peekService"); 14481 // Refuse possible leaked file descriptors 14482 if (service != null && service.hasFileDescriptors() == true) { 14483 throw new IllegalArgumentException("File descriptors passed in Intent"); 14484 } 14485 synchronized(this) { 14486 return mServices.peekServiceLocked(service, resolvedType); 14487 } 14488 } 14489 14490 @Override 14491 public boolean stopServiceToken(ComponentName className, IBinder token, 14492 int startId) { 14493 synchronized(this) { 14494 return mServices.stopServiceTokenLocked(className, token, startId); 14495 } 14496 } 14497 14498 @Override 14499 public void setServiceForeground(ComponentName className, IBinder token, 14500 int id, Notification notification, boolean removeNotification) { 14501 synchronized(this) { 14502 mServices.setServiceForegroundLocked(className, token, id, notification, 14503 removeNotification); 14504 } 14505 } 14506 14507 @Override 14508 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14509 boolean requireFull, String name, String callerPackage) { 14510 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14511 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14512 } 14513 14514 int unsafeConvertIncomingUser(int userId) { 14515 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14516 ? mCurrentUserId : userId; 14517 } 14518 14519 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14520 int allowMode, String name, String callerPackage) { 14521 final int callingUserId = UserHandle.getUserId(callingUid); 14522 if (callingUserId == userId) { 14523 return userId; 14524 } 14525 14526 // Note that we may be accessing mCurrentUserId outside of a lock... 14527 // shouldn't be a big deal, if this is being called outside 14528 // of a locked context there is intrinsically a race with 14529 // the value the caller will receive and someone else changing it. 14530 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14531 // we will switch to the calling user if access to the current user fails. 14532 int targetUserId = unsafeConvertIncomingUser(userId); 14533 14534 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14535 final boolean allow; 14536 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14537 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14538 // If the caller has this permission, they always pass go. And collect $200. 14539 allow = true; 14540 } else if (allowMode == ALLOW_FULL_ONLY) { 14541 // We require full access, sucks to be you. 14542 allow = false; 14543 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14544 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14545 // If the caller does not have either permission, they are always doomed. 14546 allow = false; 14547 } else if (allowMode == ALLOW_NON_FULL) { 14548 // We are blanket allowing non-full access, you lucky caller! 14549 allow = true; 14550 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14551 // We may or may not allow this depending on whether the two users are 14552 // in the same profile. 14553 synchronized (mUserProfileGroupIdsSelfLocked) { 14554 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14555 UserInfo.NO_PROFILE_GROUP_ID); 14556 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14557 UserInfo.NO_PROFILE_GROUP_ID); 14558 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14559 && callingProfile == targetProfile; 14560 } 14561 } else { 14562 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14563 } 14564 if (!allow) { 14565 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14566 // In this case, they would like to just execute as their 14567 // owner user instead of failing. 14568 targetUserId = callingUserId; 14569 } else { 14570 StringBuilder builder = new StringBuilder(128); 14571 builder.append("Permission Denial: "); 14572 builder.append(name); 14573 if (callerPackage != null) { 14574 builder.append(" from "); 14575 builder.append(callerPackage); 14576 } 14577 builder.append(" asks to run as user "); 14578 builder.append(userId); 14579 builder.append(" but is calling from user "); 14580 builder.append(UserHandle.getUserId(callingUid)); 14581 builder.append("; this requires "); 14582 builder.append(INTERACT_ACROSS_USERS_FULL); 14583 if (allowMode != ALLOW_FULL_ONLY) { 14584 builder.append(" or "); 14585 builder.append(INTERACT_ACROSS_USERS); 14586 } 14587 String msg = builder.toString(); 14588 Slog.w(TAG, msg); 14589 throw new SecurityException(msg); 14590 } 14591 } 14592 } 14593 if (!allowAll && targetUserId < 0) { 14594 throw new IllegalArgumentException( 14595 "Call does not support special user #" + targetUserId); 14596 } 14597 return targetUserId; 14598 } 14599 14600 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14601 String className, int flags) { 14602 boolean result = false; 14603 // For apps that don't have pre-defined UIDs, check for permission 14604 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14605 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14606 if (ActivityManager.checkUidPermission( 14607 INTERACT_ACROSS_USERS, 14608 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14609 ComponentName comp = new ComponentName(aInfo.packageName, className); 14610 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14611 + " requests FLAG_SINGLE_USER, but app does not hold " 14612 + INTERACT_ACROSS_USERS; 14613 Slog.w(TAG, msg); 14614 throw new SecurityException(msg); 14615 } 14616 // Permission passed 14617 result = true; 14618 } 14619 } else if ("system".equals(componentProcessName)) { 14620 result = true; 14621 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14622 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14623 // Phone app is allowed to export singleuser providers. 14624 result = true; 14625 } else { 14626 // App with pre-defined UID, check if it's a persistent app 14627 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14628 } 14629 if (DEBUG_MU) { 14630 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14631 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14632 } 14633 return result; 14634 } 14635 14636 /** 14637 * Checks to see if the caller is in the same app as the singleton 14638 * component, or the component is in a special app. It allows special apps 14639 * to export singleton components but prevents exporting singleton 14640 * components for regular apps. 14641 */ 14642 boolean isValidSingletonCall(int callingUid, int componentUid) { 14643 int componentAppId = UserHandle.getAppId(componentUid); 14644 return UserHandle.isSameApp(callingUid, componentUid) 14645 || componentAppId == Process.SYSTEM_UID 14646 || componentAppId == Process.PHONE_UID 14647 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14648 == PackageManager.PERMISSION_GRANTED; 14649 } 14650 14651 public int bindService(IApplicationThread caller, IBinder token, 14652 Intent service, String resolvedType, 14653 IServiceConnection connection, int flags, int userId) { 14654 enforceNotIsolatedCaller("bindService"); 14655 // Refuse possible leaked file descriptors 14656 if (service != null && service.hasFileDescriptors() == true) { 14657 throw new IllegalArgumentException("File descriptors passed in Intent"); 14658 } 14659 14660 synchronized(this) { 14661 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14662 connection, flags, userId); 14663 } 14664 } 14665 14666 public boolean unbindService(IServiceConnection connection) { 14667 synchronized (this) { 14668 return mServices.unbindServiceLocked(connection); 14669 } 14670 } 14671 14672 public void publishService(IBinder token, Intent intent, IBinder service) { 14673 // Refuse possible leaked file descriptors 14674 if (intent != null && intent.hasFileDescriptors() == true) { 14675 throw new IllegalArgumentException("File descriptors passed in Intent"); 14676 } 14677 14678 synchronized(this) { 14679 if (!(token instanceof ServiceRecord)) { 14680 throw new IllegalArgumentException("Invalid service token"); 14681 } 14682 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14683 } 14684 } 14685 14686 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14687 // Refuse possible leaked file descriptors 14688 if (intent != null && intent.hasFileDescriptors() == true) { 14689 throw new IllegalArgumentException("File descriptors passed in Intent"); 14690 } 14691 14692 synchronized(this) { 14693 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14694 } 14695 } 14696 14697 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14698 synchronized(this) { 14699 if (!(token instanceof ServiceRecord)) { 14700 throw new IllegalArgumentException("Invalid service token"); 14701 } 14702 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14703 } 14704 } 14705 14706 // ========================================================= 14707 // BACKUP AND RESTORE 14708 // ========================================================= 14709 14710 // Cause the target app to be launched if necessary and its backup agent 14711 // instantiated. The backup agent will invoke backupAgentCreated() on the 14712 // activity manager to announce its creation. 14713 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14714 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14715 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14716 14717 synchronized(this) { 14718 // !!! TODO: currently no check here that we're already bound 14719 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14720 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14721 synchronized (stats) { 14722 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14723 } 14724 14725 // Backup agent is now in use, its package can't be stopped. 14726 try { 14727 AppGlobals.getPackageManager().setPackageStoppedState( 14728 app.packageName, false, UserHandle.getUserId(app.uid)); 14729 } catch (RemoteException e) { 14730 } catch (IllegalArgumentException e) { 14731 Slog.w(TAG, "Failed trying to unstop package " 14732 + app.packageName + ": " + e); 14733 } 14734 14735 BackupRecord r = new BackupRecord(ss, app, backupMode); 14736 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14737 ? new ComponentName(app.packageName, app.backupAgentName) 14738 : new ComponentName("android", "FullBackupAgent"); 14739 // startProcessLocked() returns existing proc's record if it's already running 14740 ProcessRecord proc = startProcessLocked(app.processName, app, 14741 false, 0, "backup", hostingName, false, false, false); 14742 if (proc == null) { 14743 Slog.e(TAG, "Unable to start backup agent process " + r); 14744 return false; 14745 } 14746 14747 r.app = proc; 14748 mBackupTarget = r; 14749 mBackupAppName = app.packageName; 14750 14751 // Try not to kill the process during backup 14752 updateOomAdjLocked(proc); 14753 14754 // If the process is already attached, schedule the creation of the backup agent now. 14755 // If it is not yet live, this will be done when it attaches to the framework. 14756 if (proc.thread != null) { 14757 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14758 try { 14759 proc.thread.scheduleCreateBackupAgent(app, 14760 compatibilityInfoForPackageLocked(app), backupMode); 14761 } catch (RemoteException e) { 14762 // Will time out on the backup manager side 14763 } 14764 } else { 14765 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14766 } 14767 // Invariants: at this point, the target app process exists and the application 14768 // is either already running or in the process of coming up. mBackupTarget and 14769 // mBackupAppName describe the app, so that when it binds back to the AM we 14770 // know that it's scheduled for a backup-agent operation. 14771 } 14772 14773 return true; 14774 } 14775 14776 @Override 14777 public void clearPendingBackup() { 14778 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14779 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14780 14781 synchronized (this) { 14782 mBackupTarget = null; 14783 mBackupAppName = null; 14784 } 14785 } 14786 14787 // A backup agent has just come up 14788 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14789 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14790 + " = " + agent); 14791 14792 synchronized(this) { 14793 if (!agentPackageName.equals(mBackupAppName)) { 14794 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14795 return; 14796 } 14797 } 14798 14799 long oldIdent = Binder.clearCallingIdentity(); 14800 try { 14801 IBackupManager bm = IBackupManager.Stub.asInterface( 14802 ServiceManager.getService(Context.BACKUP_SERVICE)); 14803 bm.agentConnected(agentPackageName, agent); 14804 } catch (RemoteException e) { 14805 // can't happen; the backup manager service is local 14806 } catch (Exception e) { 14807 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14808 e.printStackTrace(); 14809 } finally { 14810 Binder.restoreCallingIdentity(oldIdent); 14811 } 14812 } 14813 14814 // done with this agent 14815 public void unbindBackupAgent(ApplicationInfo appInfo) { 14816 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14817 if (appInfo == null) { 14818 Slog.w(TAG, "unbind backup agent for null app"); 14819 return; 14820 } 14821 14822 synchronized(this) { 14823 try { 14824 if (mBackupAppName == null) { 14825 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14826 return; 14827 } 14828 14829 if (!mBackupAppName.equals(appInfo.packageName)) { 14830 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14831 return; 14832 } 14833 14834 // Not backing this app up any more; reset its OOM adjustment 14835 final ProcessRecord proc = mBackupTarget.app; 14836 updateOomAdjLocked(proc); 14837 14838 // If the app crashed during backup, 'thread' will be null here 14839 if (proc.thread != null) { 14840 try { 14841 proc.thread.scheduleDestroyBackupAgent(appInfo, 14842 compatibilityInfoForPackageLocked(appInfo)); 14843 } catch (Exception e) { 14844 Slog.e(TAG, "Exception when unbinding backup agent:"); 14845 e.printStackTrace(); 14846 } 14847 } 14848 } finally { 14849 mBackupTarget = null; 14850 mBackupAppName = null; 14851 } 14852 } 14853 } 14854 // ========================================================= 14855 // BROADCASTS 14856 // ========================================================= 14857 14858 private final List getStickiesLocked(String action, IntentFilter filter, 14859 List cur, int userId) { 14860 final ContentResolver resolver = mContext.getContentResolver(); 14861 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14862 if (stickies == null) { 14863 return cur; 14864 } 14865 final ArrayList<Intent> list = stickies.get(action); 14866 if (list == null) { 14867 return cur; 14868 } 14869 int N = list.size(); 14870 for (int i=0; i<N; i++) { 14871 Intent intent = list.get(i); 14872 if (filter.match(resolver, intent, true, TAG) >= 0) { 14873 if (cur == null) { 14874 cur = new ArrayList<Intent>(); 14875 } 14876 cur.add(intent); 14877 } 14878 } 14879 return cur; 14880 } 14881 14882 boolean isPendingBroadcastProcessLocked(int pid) { 14883 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14884 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14885 } 14886 14887 void skipPendingBroadcastLocked(int pid) { 14888 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14889 for (BroadcastQueue queue : mBroadcastQueues) { 14890 queue.skipPendingBroadcastLocked(pid); 14891 } 14892 } 14893 14894 // The app just attached; send any pending broadcasts that it should receive 14895 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14896 boolean didSomething = false; 14897 for (BroadcastQueue queue : mBroadcastQueues) { 14898 didSomething |= queue.sendPendingBroadcastsLocked(app); 14899 } 14900 return didSomething; 14901 } 14902 14903 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14904 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14905 enforceNotIsolatedCaller("registerReceiver"); 14906 int callingUid; 14907 int callingPid; 14908 synchronized(this) { 14909 ProcessRecord callerApp = null; 14910 if (caller != null) { 14911 callerApp = getRecordForAppLocked(caller); 14912 if (callerApp == null) { 14913 throw new SecurityException( 14914 "Unable to find app for caller " + caller 14915 + " (pid=" + Binder.getCallingPid() 14916 + ") when registering receiver " + receiver); 14917 } 14918 if (callerApp.info.uid != Process.SYSTEM_UID && 14919 !callerApp.pkgList.containsKey(callerPackage) && 14920 !"android".equals(callerPackage)) { 14921 throw new SecurityException("Given caller package " + callerPackage 14922 + " is not running in process " + callerApp); 14923 } 14924 callingUid = callerApp.info.uid; 14925 callingPid = callerApp.pid; 14926 } else { 14927 callerPackage = null; 14928 callingUid = Binder.getCallingUid(); 14929 callingPid = Binder.getCallingPid(); 14930 } 14931 14932 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14933 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14934 14935 List allSticky = null; 14936 14937 // Look for any matching sticky broadcasts... 14938 Iterator actions = filter.actionsIterator(); 14939 if (actions != null) { 14940 while (actions.hasNext()) { 14941 String action = (String)actions.next(); 14942 allSticky = getStickiesLocked(action, filter, allSticky, 14943 UserHandle.USER_ALL); 14944 allSticky = getStickiesLocked(action, filter, allSticky, 14945 UserHandle.getUserId(callingUid)); 14946 } 14947 } else { 14948 allSticky = getStickiesLocked(null, filter, allSticky, 14949 UserHandle.USER_ALL); 14950 allSticky = getStickiesLocked(null, filter, allSticky, 14951 UserHandle.getUserId(callingUid)); 14952 } 14953 14954 // The first sticky in the list is returned directly back to 14955 // the client. 14956 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14957 14958 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14959 + ": " + sticky); 14960 14961 if (receiver == null) { 14962 return sticky; 14963 } 14964 14965 ReceiverList rl 14966 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14967 if (rl == null) { 14968 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14969 userId, receiver); 14970 if (rl.app != null) { 14971 rl.app.receivers.add(rl); 14972 } else { 14973 try { 14974 receiver.asBinder().linkToDeath(rl, 0); 14975 } catch (RemoteException e) { 14976 return sticky; 14977 } 14978 rl.linkedToDeath = true; 14979 } 14980 mRegisteredReceivers.put(receiver.asBinder(), rl); 14981 } else if (rl.uid != callingUid) { 14982 throw new IllegalArgumentException( 14983 "Receiver requested to register for uid " + callingUid 14984 + " was previously registered for uid " + rl.uid); 14985 } else if (rl.pid != callingPid) { 14986 throw new IllegalArgumentException( 14987 "Receiver requested to register for pid " + callingPid 14988 + " was previously registered for pid " + rl.pid); 14989 } else if (rl.userId != userId) { 14990 throw new IllegalArgumentException( 14991 "Receiver requested to register for user " + userId 14992 + " was previously registered for user " + rl.userId); 14993 } 14994 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14995 permission, callingUid, userId); 14996 rl.add(bf); 14997 if (!bf.debugCheck()) { 14998 Slog.w(TAG, "==> For Dynamic broadast"); 14999 } 15000 mReceiverResolver.addFilter(bf); 15001 15002 // Enqueue broadcasts for all existing stickies that match 15003 // this filter. 15004 if (allSticky != null) { 15005 ArrayList receivers = new ArrayList(); 15006 receivers.add(bf); 15007 15008 int N = allSticky.size(); 15009 for (int i=0; i<N; i++) { 15010 Intent intent = (Intent)allSticky.get(i); 15011 BroadcastQueue queue = broadcastQueueForIntent(intent); 15012 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15013 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15014 null, null, false, true, true, -1); 15015 queue.enqueueParallelBroadcastLocked(r); 15016 queue.scheduleBroadcastsLocked(); 15017 } 15018 } 15019 15020 return sticky; 15021 } 15022 } 15023 15024 public void unregisterReceiver(IIntentReceiver receiver) { 15025 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15026 15027 final long origId = Binder.clearCallingIdentity(); 15028 try { 15029 boolean doTrim = false; 15030 15031 synchronized(this) { 15032 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15033 if (rl != null) { 15034 if (rl.curBroadcast != null) { 15035 BroadcastRecord r = rl.curBroadcast; 15036 final boolean doNext = finishReceiverLocked( 15037 receiver.asBinder(), r.resultCode, r.resultData, 15038 r.resultExtras, r.resultAbort); 15039 if (doNext) { 15040 doTrim = true; 15041 r.queue.processNextBroadcast(false); 15042 } 15043 } 15044 15045 if (rl.app != null) { 15046 rl.app.receivers.remove(rl); 15047 } 15048 removeReceiverLocked(rl); 15049 if (rl.linkedToDeath) { 15050 rl.linkedToDeath = false; 15051 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15052 } 15053 } 15054 } 15055 15056 // If we actually concluded any broadcasts, we might now be able 15057 // to trim the recipients' apps from our working set 15058 if (doTrim) { 15059 trimApplications(); 15060 return; 15061 } 15062 15063 } finally { 15064 Binder.restoreCallingIdentity(origId); 15065 } 15066 } 15067 15068 void removeReceiverLocked(ReceiverList rl) { 15069 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15070 int N = rl.size(); 15071 for (int i=0; i<N; i++) { 15072 mReceiverResolver.removeFilter(rl.get(i)); 15073 } 15074 } 15075 15076 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15077 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15078 ProcessRecord r = mLruProcesses.get(i); 15079 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15080 try { 15081 r.thread.dispatchPackageBroadcast(cmd, packages); 15082 } catch (RemoteException ex) { 15083 } 15084 } 15085 } 15086 } 15087 15088 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15089 int[] users) { 15090 List<ResolveInfo> receivers = null; 15091 try { 15092 HashSet<ComponentName> singleUserReceivers = null; 15093 boolean scannedFirstReceivers = false; 15094 for (int user : users) { 15095 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15096 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15097 if (user != 0 && newReceivers != null) { 15098 // If this is not the primary user, we need to check for 15099 // any receivers that should be filtered out. 15100 for (int i=0; i<newReceivers.size(); i++) { 15101 ResolveInfo ri = newReceivers.get(i); 15102 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15103 newReceivers.remove(i); 15104 i--; 15105 } 15106 } 15107 } 15108 if (newReceivers != null && newReceivers.size() == 0) { 15109 newReceivers = null; 15110 } 15111 if (receivers == null) { 15112 receivers = newReceivers; 15113 } else if (newReceivers != null) { 15114 // We need to concatenate the additional receivers 15115 // found with what we have do far. This would be easy, 15116 // but we also need to de-dup any receivers that are 15117 // singleUser. 15118 if (!scannedFirstReceivers) { 15119 // Collect any single user receivers we had already retrieved. 15120 scannedFirstReceivers = true; 15121 for (int i=0; i<receivers.size(); i++) { 15122 ResolveInfo ri = receivers.get(i); 15123 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15124 ComponentName cn = new ComponentName( 15125 ri.activityInfo.packageName, ri.activityInfo.name); 15126 if (singleUserReceivers == null) { 15127 singleUserReceivers = new HashSet<ComponentName>(); 15128 } 15129 singleUserReceivers.add(cn); 15130 } 15131 } 15132 } 15133 // Add the new results to the existing results, tracking 15134 // and de-dupping single user receivers. 15135 for (int i=0; i<newReceivers.size(); i++) { 15136 ResolveInfo ri = newReceivers.get(i); 15137 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15138 ComponentName cn = new ComponentName( 15139 ri.activityInfo.packageName, ri.activityInfo.name); 15140 if (singleUserReceivers == null) { 15141 singleUserReceivers = new HashSet<ComponentName>(); 15142 } 15143 if (!singleUserReceivers.contains(cn)) { 15144 singleUserReceivers.add(cn); 15145 receivers.add(ri); 15146 } 15147 } else { 15148 receivers.add(ri); 15149 } 15150 } 15151 } 15152 } 15153 } catch (RemoteException ex) { 15154 // pm is in same process, this will never happen. 15155 } 15156 return receivers; 15157 } 15158 15159 private final int broadcastIntentLocked(ProcessRecord callerApp, 15160 String callerPackage, Intent intent, String resolvedType, 15161 IIntentReceiver resultTo, int resultCode, String resultData, 15162 Bundle map, String requiredPermission, int appOp, 15163 boolean ordered, boolean sticky, int callingPid, int callingUid, 15164 int userId) { 15165 intent = new Intent(intent); 15166 15167 // By default broadcasts do not go to stopped apps. 15168 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15169 15170 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15171 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15172 + " ordered=" + ordered + " userid=" + userId); 15173 if ((resultTo != null) && !ordered) { 15174 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15175 } 15176 15177 userId = handleIncomingUser(callingPid, callingUid, userId, 15178 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15179 15180 // Make sure that the user who is receiving this broadcast is started. 15181 // If not, we will just skip it. 15182 15183 15184 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15185 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15186 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15187 Slog.w(TAG, "Skipping broadcast of " + intent 15188 + ": user " + userId + " is stopped"); 15189 return ActivityManager.BROADCAST_SUCCESS; 15190 } 15191 } 15192 15193 /* 15194 * Prevent non-system code (defined here to be non-persistent 15195 * processes) from sending protected broadcasts. 15196 */ 15197 int callingAppId = UserHandle.getAppId(callingUid); 15198 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15199 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15200 || callingAppId == Process.NFC_UID || callingUid == 0) { 15201 // Always okay. 15202 } else if (callerApp == null || !callerApp.persistent) { 15203 try { 15204 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15205 intent.getAction())) { 15206 String msg = "Permission Denial: not allowed to send broadcast " 15207 + intent.getAction() + " from pid=" 15208 + callingPid + ", uid=" + callingUid; 15209 Slog.w(TAG, msg); 15210 throw new SecurityException(msg); 15211 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15212 // Special case for compatibility: we don't want apps to send this, 15213 // but historically it has not been protected and apps may be using it 15214 // to poke their own app widget. So, instead of making it protected, 15215 // just limit it to the caller. 15216 if (callerApp == null) { 15217 String msg = "Permission Denial: not allowed to send broadcast " 15218 + intent.getAction() + " from unknown caller."; 15219 Slog.w(TAG, msg); 15220 throw new SecurityException(msg); 15221 } else if (intent.getComponent() != null) { 15222 // They are good enough to send to an explicit component... verify 15223 // it is being sent to the calling app. 15224 if (!intent.getComponent().getPackageName().equals( 15225 callerApp.info.packageName)) { 15226 String msg = "Permission Denial: not allowed to send broadcast " 15227 + intent.getAction() + " to " 15228 + intent.getComponent().getPackageName() + " from " 15229 + callerApp.info.packageName; 15230 Slog.w(TAG, msg); 15231 throw new SecurityException(msg); 15232 } 15233 } else { 15234 // Limit broadcast to their own package. 15235 intent.setPackage(callerApp.info.packageName); 15236 } 15237 } 15238 } catch (RemoteException e) { 15239 Slog.w(TAG, "Remote exception", e); 15240 return ActivityManager.BROADCAST_SUCCESS; 15241 } 15242 } 15243 15244 // Handle special intents: if this broadcast is from the package 15245 // manager about a package being removed, we need to remove all of 15246 // its activities from the history stack. 15247 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15248 intent.getAction()); 15249 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15250 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15251 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15252 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15253 || uidRemoved) { 15254 if (checkComponentPermission( 15255 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15256 callingPid, callingUid, -1, true) 15257 == PackageManager.PERMISSION_GRANTED) { 15258 if (uidRemoved) { 15259 final Bundle intentExtras = intent.getExtras(); 15260 final int uid = intentExtras != null 15261 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15262 if (uid >= 0) { 15263 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15264 synchronized (bs) { 15265 bs.removeUidStatsLocked(uid); 15266 } 15267 mAppOpsService.uidRemoved(uid); 15268 } 15269 } else { 15270 // If resources are unavailable just force stop all 15271 // those packages and flush the attribute cache as well. 15272 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15273 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15274 if (list != null && (list.length > 0)) { 15275 for (String pkg : list) { 15276 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15277 "storage unmount"); 15278 } 15279 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15280 sendPackageBroadcastLocked( 15281 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15282 } 15283 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15284 intent.getAction())) { 15285 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15286 } else { 15287 Uri data = intent.getData(); 15288 String ssp; 15289 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15290 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15291 intent.getAction()); 15292 boolean fullUninstall = removed && 15293 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15294 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15295 forceStopPackageLocked(ssp, UserHandle.getAppId( 15296 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15297 false, fullUninstall, userId, 15298 removed ? "pkg removed" : "pkg changed"); 15299 } 15300 if (removed) { 15301 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15302 new String[] {ssp}, userId); 15303 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15304 mAppOpsService.packageRemoved( 15305 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15306 15307 // Remove all permissions granted from/to this package 15308 removeUriPermissionsForPackageLocked(ssp, userId, true); 15309 } 15310 } 15311 } 15312 } 15313 } 15314 } else { 15315 String msg = "Permission Denial: " + intent.getAction() 15316 + " broadcast from " + callerPackage + " (pid=" + callingPid 15317 + ", uid=" + callingUid + ")" 15318 + " requires " 15319 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15320 Slog.w(TAG, msg); 15321 throw new SecurityException(msg); 15322 } 15323 15324 // Special case for adding a package: by default turn on compatibility 15325 // mode. 15326 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15327 Uri data = intent.getData(); 15328 String ssp; 15329 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15330 mCompatModePackages.handlePackageAddedLocked(ssp, 15331 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15332 } 15333 } 15334 15335 /* 15336 * If this is the time zone changed action, queue up a message that will reset the timezone 15337 * of all currently running processes. This message will get queued up before the broadcast 15338 * happens. 15339 */ 15340 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15341 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15342 } 15343 15344 /* 15345 * If the user set the time, let all running processes know. 15346 */ 15347 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15348 final int is24Hour = intent.getBooleanExtra( 15349 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15350 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15351 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15352 synchronized (stats) { 15353 stats.noteCurrentTimeChangedLocked(); 15354 } 15355 } 15356 15357 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15358 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15359 } 15360 15361 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15362 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15363 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15364 } 15365 15366 // Add to the sticky list if requested. 15367 if (sticky) { 15368 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15369 callingPid, callingUid) 15370 != PackageManager.PERMISSION_GRANTED) { 15371 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15372 + callingPid + ", uid=" + callingUid 15373 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15374 Slog.w(TAG, msg); 15375 throw new SecurityException(msg); 15376 } 15377 if (requiredPermission != null) { 15378 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15379 + " and enforce permission " + requiredPermission); 15380 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15381 } 15382 if (intent.getComponent() != null) { 15383 throw new SecurityException( 15384 "Sticky broadcasts can't target a specific component"); 15385 } 15386 // We use userId directly here, since the "all" target is maintained 15387 // as a separate set of sticky broadcasts. 15388 if (userId != UserHandle.USER_ALL) { 15389 // But first, if this is not a broadcast to all users, then 15390 // make sure it doesn't conflict with an existing broadcast to 15391 // all users. 15392 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15393 UserHandle.USER_ALL); 15394 if (stickies != null) { 15395 ArrayList<Intent> list = stickies.get(intent.getAction()); 15396 if (list != null) { 15397 int N = list.size(); 15398 int i; 15399 for (i=0; i<N; i++) { 15400 if (intent.filterEquals(list.get(i))) { 15401 throw new IllegalArgumentException( 15402 "Sticky broadcast " + intent + " for user " 15403 + userId + " conflicts with existing global broadcast"); 15404 } 15405 } 15406 } 15407 } 15408 } 15409 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15410 if (stickies == null) { 15411 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15412 mStickyBroadcasts.put(userId, stickies); 15413 } 15414 ArrayList<Intent> list = stickies.get(intent.getAction()); 15415 if (list == null) { 15416 list = new ArrayList<Intent>(); 15417 stickies.put(intent.getAction(), list); 15418 } 15419 int N = list.size(); 15420 int i; 15421 for (i=0; i<N; i++) { 15422 if (intent.filterEquals(list.get(i))) { 15423 // This sticky already exists, replace it. 15424 list.set(i, new Intent(intent)); 15425 break; 15426 } 15427 } 15428 if (i >= N) { 15429 list.add(new Intent(intent)); 15430 } 15431 } 15432 15433 int[] users; 15434 if (userId == UserHandle.USER_ALL) { 15435 // Caller wants broadcast to go to all started users. 15436 users = mStartedUserArray; 15437 } else { 15438 // Caller wants broadcast to go to one specific user. 15439 users = new int[] {userId}; 15440 } 15441 15442 // Figure out who all will receive this broadcast. 15443 List receivers = null; 15444 List<BroadcastFilter> registeredReceivers = null; 15445 // Need to resolve the intent to interested receivers... 15446 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15447 == 0) { 15448 receivers = collectReceiverComponents(intent, resolvedType, users); 15449 } 15450 if (intent.getComponent() == null) { 15451 registeredReceivers = mReceiverResolver.queryIntent(intent, 15452 resolvedType, false, userId); 15453 } 15454 15455 final boolean replacePending = 15456 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15457 15458 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15459 + " replacePending=" + replacePending); 15460 15461 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15462 if (!ordered && NR > 0) { 15463 // If we are not serializing this broadcast, then send the 15464 // registered receivers separately so they don't wait for the 15465 // components to be launched. 15466 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15467 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15468 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15469 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15470 ordered, sticky, false, userId); 15471 if (DEBUG_BROADCAST) Slog.v( 15472 TAG, "Enqueueing parallel broadcast " + r); 15473 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15474 if (!replaced) { 15475 queue.enqueueParallelBroadcastLocked(r); 15476 queue.scheduleBroadcastsLocked(); 15477 } 15478 registeredReceivers = null; 15479 NR = 0; 15480 } 15481 15482 // Merge into one list. 15483 int ir = 0; 15484 if (receivers != null) { 15485 // A special case for PACKAGE_ADDED: do not allow the package 15486 // being added to see this broadcast. This prevents them from 15487 // using this as a back door to get run as soon as they are 15488 // installed. Maybe in the future we want to have a special install 15489 // broadcast or such for apps, but we'd like to deliberately make 15490 // this decision. 15491 String skipPackages[] = null; 15492 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15493 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15494 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15495 Uri data = intent.getData(); 15496 if (data != null) { 15497 String pkgName = data.getSchemeSpecificPart(); 15498 if (pkgName != null) { 15499 skipPackages = new String[] { pkgName }; 15500 } 15501 } 15502 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15503 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15504 } 15505 if (skipPackages != null && (skipPackages.length > 0)) { 15506 for (String skipPackage : skipPackages) { 15507 if (skipPackage != null) { 15508 int NT = receivers.size(); 15509 for (int it=0; it<NT; it++) { 15510 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15511 if (curt.activityInfo.packageName.equals(skipPackage)) { 15512 receivers.remove(it); 15513 it--; 15514 NT--; 15515 } 15516 } 15517 } 15518 } 15519 } 15520 15521 int NT = receivers != null ? receivers.size() : 0; 15522 int it = 0; 15523 ResolveInfo curt = null; 15524 BroadcastFilter curr = null; 15525 while (it < NT && ir < NR) { 15526 if (curt == null) { 15527 curt = (ResolveInfo)receivers.get(it); 15528 } 15529 if (curr == null) { 15530 curr = registeredReceivers.get(ir); 15531 } 15532 if (curr.getPriority() >= curt.priority) { 15533 // Insert this broadcast record into the final list. 15534 receivers.add(it, curr); 15535 ir++; 15536 curr = null; 15537 it++; 15538 NT++; 15539 } else { 15540 // Skip to the next ResolveInfo in the final list. 15541 it++; 15542 curt = null; 15543 } 15544 } 15545 } 15546 while (ir < NR) { 15547 if (receivers == null) { 15548 receivers = new ArrayList(); 15549 } 15550 receivers.add(registeredReceivers.get(ir)); 15551 ir++; 15552 } 15553 15554 if ((receivers != null && receivers.size() > 0) 15555 || resultTo != null) { 15556 BroadcastQueue queue = broadcastQueueForIntent(intent); 15557 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15558 callerPackage, callingPid, callingUid, resolvedType, 15559 requiredPermission, appOp, receivers, resultTo, resultCode, 15560 resultData, map, ordered, sticky, false, userId); 15561 if (DEBUG_BROADCAST) Slog.v( 15562 TAG, "Enqueueing ordered broadcast " + r 15563 + ": prev had " + queue.mOrderedBroadcasts.size()); 15564 if (DEBUG_BROADCAST) { 15565 int seq = r.intent.getIntExtra("seq", -1); 15566 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15567 } 15568 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15569 if (!replaced) { 15570 queue.enqueueOrderedBroadcastLocked(r); 15571 queue.scheduleBroadcastsLocked(); 15572 } 15573 } 15574 15575 return ActivityManager.BROADCAST_SUCCESS; 15576 } 15577 15578 final Intent verifyBroadcastLocked(Intent intent) { 15579 // Refuse possible leaked file descriptors 15580 if (intent != null && intent.hasFileDescriptors() == true) { 15581 throw new IllegalArgumentException("File descriptors passed in Intent"); 15582 } 15583 15584 int flags = intent.getFlags(); 15585 15586 if (!mProcessesReady) { 15587 // if the caller really truly claims to know what they're doing, go 15588 // ahead and allow the broadcast without launching any receivers 15589 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15590 intent = new Intent(intent); 15591 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15592 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15593 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15594 + " before boot completion"); 15595 throw new IllegalStateException("Cannot broadcast before boot completed"); 15596 } 15597 } 15598 15599 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15600 throw new IllegalArgumentException( 15601 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15602 } 15603 15604 return intent; 15605 } 15606 15607 public final int broadcastIntent(IApplicationThread caller, 15608 Intent intent, String resolvedType, IIntentReceiver resultTo, 15609 int resultCode, String resultData, Bundle map, 15610 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15611 enforceNotIsolatedCaller("broadcastIntent"); 15612 synchronized(this) { 15613 intent = verifyBroadcastLocked(intent); 15614 15615 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15616 final int callingPid = Binder.getCallingPid(); 15617 final int callingUid = Binder.getCallingUid(); 15618 final long origId = Binder.clearCallingIdentity(); 15619 int res = broadcastIntentLocked(callerApp, 15620 callerApp != null ? callerApp.info.packageName : null, 15621 intent, resolvedType, resultTo, 15622 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15623 callingPid, callingUid, userId); 15624 Binder.restoreCallingIdentity(origId); 15625 return res; 15626 } 15627 } 15628 15629 int broadcastIntentInPackage(String packageName, int uid, 15630 Intent intent, String resolvedType, IIntentReceiver resultTo, 15631 int resultCode, String resultData, Bundle map, 15632 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15633 synchronized(this) { 15634 intent = verifyBroadcastLocked(intent); 15635 15636 final long origId = Binder.clearCallingIdentity(); 15637 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15638 resultTo, resultCode, resultData, map, requiredPermission, 15639 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15640 Binder.restoreCallingIdentity(origId); 15641 return res; 15642 } 15643 } 15644 15645 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15646 // Refuse possible leaked file descriptors 15647 if (intent != null && intent.hasFileDescriptors() == true) { 15648 throw new IllegalArgumentException("File descriptors passed in Intent"); 15649 } 15650 15651 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15652 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15653 15654 synchronized(this) { 15655 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15656 != PackageManager.PERMISSION_GRANTED) { 15657 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15658 + Binder.getCallingPid() 15659 + ", uid=" + Binder.getCallingUid() 15660 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15661 Slog.w(TAG, msg); 15662 throw new SecurityException(msg); 15663 } 15664 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15665 if (stickies != null) { 15666 ArrayList<Intent> list = stickies.get(intent.getAction()); 15667 if (list != null) { 15668 int N = list.size(); 15669 int i; 15670 for (i=0; i<N; i++) { 15671 if (intent.filterEquals(list.get(i))) { 15672 list.remove(i); 15673 break; 15674 } 15675 } 15676 if (list.size() <= 0) { 15677 stickies.remove(intent.getAction()); 15678 } 15679 } 15680 if (stickies.size() <= 0) { 15681 mStickyBroadcasts.remove(userId); 15682 } 15683 } 15684 } 15685 } 15686 15687 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15688 String resultData, Bundle resultExtras, boolean resultAbort) { 15689 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15690 if (r == null) { 15691 Slog.w(TAG, "finishReceiver called but not found on queue"); 15692 return false; 15693 } 15694 15695 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15696 } 15697 15698 void backgroundServicesFinishedLocked(int userId) { 15699 for (BroadcastQueue queue : mBroadcastQueues) { 15700 queue.backgroundServicesFinishedLocked(userId); 15701 } 15702 } 15703 15704 public void finishReceiver(IBinder who, int resultCode, String resultData, 15705 Bundle resultExtras, boolean resultAbort) { 15706 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15707 15708 // Refuse possible leaked file descriptors 15709 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15710 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15711 } 15712 15713 final long origId = Binder.clearCallingIdentity(); 15714 try { 15715 boolean doNext = false; 15716 BroadcastRecord r; 15717 15718 synchronized(this) { 15719 r = broadcastRecordForReceiverLocked(who); 15720 if (r != null) { 15721 doNext = r.queue.finishReceiverLocked(r, resultCode, 15722 resultData, resultExtras, resultAbort, true); 15723 } 15724 } 15725 15726 if (doNext) { 15727 r.queue.processNextBroadcast(false); 15728 } 15729 trimApplications(); 15730 } finally { 15731 Binder.restoreCallingIdentity(origId); 15732 } 15733 } 15734 15735 // ========================================================= 15736 // INSTRUMENTATION 15737 // ========================================================= 15738 15739 public boolean startInstrumentation(ComponentName className, 15740 String profileFile, int flags, Bundle arguments, 15741 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15742 int userId, String abiOverride) { 15743 enforceNotIsolatedCaller("startInstrumentation"); 15744 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15745 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15746 // Refuse possible leaked file descriptors 15747 if (arguments != null && arguments.hasFileDescriptors()) { 15748 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15749 } 15750 15751 synchronized(this) { 15752 InstrumentationInfo ii = null; 15753 ApplicationInfo ai = null; 15754 try { 15755 ii = mContext.getPackageManager().getInstrumentationInfo( 15756 className, STOCK_PM_FLAGS); 15757 ai = AppGlobals.getPackageManager().getApplicationInfo( 15758 ii.targetPackage, STOCK_PM_FLAGS, userId); 15759 } catch (PackageManager.NameNotFoundException e) { 15760 } catch (RemoteException e) { 15761 } 15762 if (ii == null) { 15763 reportStartInstrumentationFailure(watcher, className, 15764 "Unable to find instrumentation info for: " + className); 15765 return false; 15766 } 15767 if (ai == null) { 15768 reportStartInstrumentationFailure(watcher, className, 15769 "Unable to find instrumentation target package: " + ii.targetPackage); 15770 return false; 15771 } 15772 15773 int match = mContext.getPackageManager().checkSignatures( 15774 ii.targetPackage, ii.packageName); 15775 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15776 String msg = "Permission Denial: starting instrumentation " 15777 + className + " from pid=" 15778 + Binder.getCallingPid() 15779 + ", uid=" + Binder.getCallingPid() 15780 + " not allowed because package " + ii.packageName 15781 + " does not have a signature matching the target " 15782 + ii.targetPackage; 15783 reportStartInstrumentationFailure(watcher, className, msg); 15784 throw new SecurityException(msg); 15785 } 15786 15787 final long origId = Binder.clearCallingIdentity(); 15788 // Instrumentation can kill and relaunch even persistent processes 15789 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15790 "start instr"); 15791 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15792 app.instrumentationClass = className; 15793 app.instrumentationInfo = ai; 15794 app.instrumentationProfileFile = profileFile; 15795 app.instrumentationArguments = arguments; 15796 app.instrumentationWatcher = watcher; 15797 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15798 app.instrumentationResultClass = className; 15799 Binder.restoreCallingIdentity(origId); 15800 } 15801 15802 return true; 15803 } 15804 15805 /** 15806 * Report errors that occur while attempting to start Instrumentation. Always writes the 15807 * error to the logs, but if somebody is watching, send the report there too. This enables 15808 * the "am" command to report errors with more information. 15809 * 15810 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15811 * @param cn The component name of the instrumentation. 15812 * @param report The error report. 15813 */ 15814 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15815 ComponentName cn, String report) { 15816 Slog.w(TAG, report); 15817 try { 15818 if (watcher != null) { 15819 Bundle results = new Bundle(); 15820 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15821 results.putString("Error", report); 15822 watcher.instrumentationStatus(cn, -1, results); 15823 } 15824 } catch (RemoteException e) { 15825 Slog.w(TAG, e); 15826 } 15827 } 15828 15829 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15830 if (app.instrumentationWatcher != null) { 15831 try { 15832 // NOTE: IInstrumentationWatcher *must* be oneway here 15833 app.instrumentationWatcher.instrumentationFinished( 15834 app.instrumentationClass, 15835 resultCode, 15836 results); 15837 } catch (RemoteException e) { 15838 } 15839 } 15840 if (app.instrumentationUiAutomationConnection != null) { 15841 try { 15842 app.instrumentationUiAutomationConnection.shutdown(); 15843 } catch (RemoteException re) { 15844 /* ignore */ 15845 } 15846 // Only a UiAutomation can set this flag and now that 15847 // it is finished we make sure it is reset to its default. 15848 mUserIsMonkey = false; 15849 } 15850 app.instrumentationWatcher = null; 15851 app.instrumentationUiAutomationConnection = null; 15852 app.instrumentationClass = null; 15853 app.instrumentationInfo = null; 15854 app.instrumentationProfileFile = null; 15855 app.instrumentationArguments = null; 15856 15857 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15858 "finished inst"); 15859 } 15860 15861 public void finishInstrumentation(IApplicationThread target, 15862 int resultCode, Bundle results) { 15863 int userId = UserHandle.getCallingUserId(); 15864 // Refuse possible leaked file descriptors 15865 if (results != null && results.hasFileDescriptors()) { 15866 throw new IllegalArgumentException("File descriptors passed in Intent"); 15867 } 15868 15869 synchronized(this) { 15870 ProcessRecord app = getRecordForAppLocked(target); 15871 if (app == null) { 15872 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15873 return; 15874 } 15875 final long origId = Binder.clearCallingIdentity(); 15876 finishInstrumentationLocked(app, resultCode, results); 15877 Binder.restoreCallingIdentity(origId); 15878 } 15879 } 15880 15881 // ========================================================= 15882 // CONFIGURATION 15883 // ========================================================= 15884 15885 public ConfigurationInfo getDeviceConfigurationInfo() { 15886 ConfigurationInfo config = new ConfigurationInfo(); 15887 synchronized (this) { 15888 config.reqTouchScreen = mConfiguration.touchscreen; 15889 config.reqKeyboardType = mConfiguration.keyboard; 15890 config.reqNavigation = mConfiguration.navigation; 15891 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15892 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15893 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15894 } 15895 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15896 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15897 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15898 } 15899 config.reqGlEsVersion = GL_ES_VERSION; 15900 } 15901 return config; 15902 } 15903 15904 ActivityStack getFocusedStack() { 15905 return mStackSupervisor.getFocusedStack(); 15906 } 15907 15908 public Configuration getConfiguration() { 15909 Configuration ci; 15910 synchronized(this) { 15911 ci = new Configuration(mConfiguration); 15912 } 15913 return ci; 15914 } 15915 15916 public void updatePersistentConfiguration(Configuration values) { 15917 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15918 "updateConfiguration()"); 15919 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15920 "updateConfiguration()"); 15921 if (values == null) { 15922 throw new NullPointerException("Configuration must not be null"); 15923 } 15924 15925 synchronized(this) { 15926 final long origId = Binder.clearCallingIdentity(); 15927 updateConfigurationLocked(values, null, true, false); 15928 Binder.restoreCallingIdentity(origId); 15929 } 15930 } 15931 15932 public void updateConfiguration(Configuration values) { 15933 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15934 "updateConfiguration()"); 15935 15936 synchronized(this) { 15937 if (values == null && mWindowManager != null) { 15938 // sentinel: fetch the current configuration from the window manager 15939 values = mWindowManager.computeNewConfiguration(); 15940 } 15941 15942 if (mWindowManager != null) { 15943 mProcessList.applyDisplaySize(mWindowManager); 15944 } 15945 15946 final long origId = Binder.clearCallingIdentity(); 15947 if (values != null) { 15948 Settings.System.clearConfiguration(values); 15949 } 15950 updateConfigurationLocked(values, null, false, false); 15951 Binder.restoreCallingIdentity(origId); 15952 } 15953 } 15954 15955 /** 15956 * Do either or both things: (1) change the current configuration, and (2) 15957 * make sure the given activity is running with the (now) current 15958 * configuration. Returns true if the activity has been left running, or 15959 * false if <var>starting</var> is being destroyed to match the new 15960 * configuration. 15961 * @param persistent TODO 15962 */ 15963 boolean updateConfigurationLocked(Configuration values, 15964 ActivityRecord starting, boolean persistent, boolean initLocale) { 15965 int changes = 0; 15966 15967 if (values != null) { 15968 Configuration newConfig = new Configuration(mConfiguration); 15969 changes = newConfig.updateFrom(values); 15970 if (changes != 0) { 15971 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15972 Slog.i(TAG, "Updating configuration to: " + values); 15973 } 15974 15975 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15976 15977 if (values.locale != null && !initLocale) { 15978 saveLocaleLocked(values.locale, 15979 !values.locale.equals(mConfiguration.locale), 15980 values.userSetLocale); 15981 } 15982 15983 mConfigurationSeq++; 15984 if (mConfigurationSeq <= 0) { 15985 mConfigurationSeq = 1; 15986 } 15987 newConfig.seq = mConfigurationSeq; 15988 mConfiguration = newConfig; 15989 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15990 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15991 //mUsageStatsService.noteStartConfig(newConfig); 15992 15993 final Configuration configCopy = new Configuration(mConfiguration); 15994 15995 // TODO: If our config changes, should we auto dismiss any currently 15996 // showing dialogs? 15997 mShowDialogs = shouldShowDialogs(newConfig); 15998 15999 AttributeCache ac = AttributeCache.instance(); 16000 if (ac != null) { 16001 ac.updateConfiguration(configCopy); 16002 } 16003 16004 // Make sure all resources in our process are updated 16005 // right now, so that anyone who is going to retrieve 16006 // resource values after we return will be sure to get 16007 // the new ones. This is especially important during 16008 // boot, where the first config change needs to guarantee 16009 // all resources have that config before following boot 16010 // code is executed. 16011 mSystemThread.applyConfigurationToResources(configCopy); 16012 16013 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16014 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16015 msg.obj = new Configuration(configCopy); 16016 mHandler.sendMessage(msg); 16017 } 16018 16019 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16020 ProcessRecord app = mLruProcesses.get(i); 16021 try { 16022 if (app.thread != null) { 16023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16024 + app.processName + " new config " + mConfiguration); 16025 app.thread.scheduleConfigurationChanged(configCopy); 16026 } 16027 } catch (Exception e) { 16028 } 16029 } 16030 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16031 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16032 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16033 | Intent.FLAG_RECEIVER_FOREGROUND); 16034 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16035 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16036 Process.SYSTEM_UID, UserHandle.USER_ALL); 16037 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16038 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16039 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16040 broadcastIntentLocked(null, null, intent, 16041 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16042 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16043 } 16044 } 16045 } 16046 16047 boolean kept = true; 16048 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16049 // mainStack is null during startup. 16050 if (mainStack != null) { 16051 if (changes != 0 && starting == null) { 16052 // If the configuration changed, and the caller is not already 16053 // in the process of starting an activity, then find the top 16054 // activity to check if its configuration needs to change. 16055 starting = mainStack.topRunningActivityLocked(null); 16056 } 16057 16058 if (starting != null) { 16059 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16060 // And we need to make sure at this point that all other activities 16061 // are made visible with the correct configuration. 16062 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16063 } 16064 } 16065 16066 if (values != null && mWindowManager != null) { 16067 mWindowManager.setNewConfiguration(mConfiguration); 16068 } 16069 16070 return kept; 16071 } 16072 16073 /** 16074 * Decide based on the configuration whether we should shouw the ANR, 16075 * crash, etc dialogs. The idea is that if there is no affordnace to 16076 * press the on-screen buttons, we shouldn't show the dialog. 16077 * 16078 * A thought: SystemUI might also want to get told about this, the Power 16079 * dialog / global actions also might want different behaviors. 16080 */ 16081 private static final boolean shouldShowDialogs(Configuration config) { 16082 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16083 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16084 } 16085 16086 /** 16087 * Save the locale. You must be inside a synchronized (this) block. 16088 */ 16089 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16090 if(isDiff) { 16091 SystemProperties.set("user.language", l.getLanguage()); 16092 SystemProperties.set("user.region", l.getCountry()); 16093 } 16094 16095 if(isPersist) { 16096 SystemProperties.set("persist.sys.language", l.getLanguage()); 16097 SystemProperties.set("persist.sys.country", l.getCountry()); 16098 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16099 } 16100 } 16101 16102 @Override 16103 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16104 synchronized (this) { 16105 ActivityRecord srec = ActivityRecord.forToken(token); 16106 if (srec.task != null && srec.task.stack != null) { 16107 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16108 } 16109 } 16110 return false; 16111 } 16112 16113 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16114 Intent resultData) { 16115 16116 synchronized (this) { 16117 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16118 if (stack != null) { 16119 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16120 } 16121 return false; 16122 } 16123 } 16124 16125 public int getLaunchedFromUid(IBinder activityToken) { 16126 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16127 if (srec == null) { 16128 return -1; 16129 } 16130 return srec.launchedFromUid; 16131 } 16132 16133 public String getLaunchedFromPackage(IBinder activityToken) { 16134 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16135 if (srec == null) { 16136 return null; 16137 } 16138 return srec.launchedFromPackage; 16139 } 16140 16141 // ========================================================= 16142 // LIFETIME MANAGEMENT 16143 // ========================================================= 16144 16145 // Returns which broadcast queue the app is the current [or imminent] receiver 16146 // on, or 'null' if the app is not an active broadcast recipient. 16147 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16148 BroadcastRecord r = app.curReceiver; 16149 if (r != null) { 16150 return r.queue; 16151 } 16152 16153 // It's not the current receiver, but it might be starting up to become one 16154 synchronized (this) { 16155 for (BroadcastQueue queue : mBroadcastQueues) { 16156 r = queue.mPendingBroadcast; 16157 if (r != null && r.curApp == app) { 16158 // found it; report which queue it's in 16159 return queue; 16160 } 16161 } 16162 } 16163 16164 return null; 16165 } 16166 16167 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16168 boolean doingAll, long now) { 16169 if (mAdjSeq == app.adjSeq) { 16170 // This adjustment has already been computed. 16171 return app.curRawAdj; 16172 } 16173 16174 if (app.thread == null) { 16175 app.adjSeq = mAdjSeq; 16176 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16177 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16178 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16179 } 16180 16181 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16182 app.adjSource = null; 16183 app.adjTarget = null; 16184 app.empty = false; 16185 app.cached = false; 16186 16187 final int activitiesSize = app.activities.size(); 16188 16189 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16190 // The max adjustment doesn't allow this app to be anything 16191 // below foreground, so it is not worth doing work for it. 16192 app.adjType = "fixed"; 16193 app.adjSeq = mAdjSeq; 16194 app.curRawAdj = app.maxAdj; 16195 app.foregroundActivities = false; 16196 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16197 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16198 // System processes can do UI, and when they do we want to have 16199 // them trim their memory after the user leaves the UI. To 16200 // facilitate this, here we need to determine whether or not it 16201 // is currently showing UI. 16202 app.systemNoUi = true; 16203 if (app == TOP_APP) { 16204 app.systemNoUi = false; 16205 } else if (activitiesSize > 0) { 16206 for (int j = 0; j < activitiesSize; j++) { 16207 final ActivityRecord r = app.activities.get(j); 16208 if (r.visible) { 16209 app.systemNoUi = false; 16210 } 16211 } 16212 } 16213 if (!app.systemNoUi) { 16214 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16215 } 16216 return (app.curAdj=app.maxAdj); 16217 } 16218 16219 app.systemNoUi = false; 16220 16221 // Determine the importance of the process, starting with most 16222 // important to least, and assign an appropriate OOM adjustment. 16223 int adj; 16224 int schedGroup; 16225 int procState; 16226 boolean foregroundActivities = false; 16227 BroadcastQueue queue; 16228 if (app == TOP_APP) { 16229 // The last app on the list is the foreground app. 16230 adj = ProcessList.FOREGROUND_APP_ADJ; 16231 schedGroup = Process.THREAD_GROUP_DEFAULT; 16232 app.adjType = "top-activity"; 16233 foregroundActivities = true; 16234 procState = ActivityManager.PROCESS_STATE_TOP; 16235 } else if (app.instrumentationClass != null) { 16236 // Don't want to kill running instrumentation. 16237 adj = ProcessList.FOREGROUND_APP_ADJ; 16238 schedGroup = Process.THREAD_GROUP_DEFAULT; 16239 app.adjType = "instrumentation"; 16240 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16241 } else if ((queue = isReceivingBroadcast(app)) != null) { 16242 // An app that is currently receiving a broadcast also 16243 // counts as being in the foreground for OOM killer purposes. 16244 // It's placed in a sched group based on the nature of the 16245 // broadcast as reflected by which queue it's active in. 16246 adj = ProcessList.FOREGROUND_APP_ADJ; 16247 schedGroup = (queue == mFgBroadcastQueue) 16248 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16249 app.adjType = "broadcast"; 16250 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16251 } else if (app.executingServices.size() > 0) { 16252 // An app that is currently executing a service callback also 16253 // counts as being in the foreground. 16254 adj = ProcessList.FOREGROUND_APP_ADJ; 16255 schedGroup = app.execServicesFg ? 16256 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16257 app.adjType = "exec-service"; 16258 procState = ActivityManager.PROCESS_STATE_SERVICE; 16259 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16260 } else { 16261 // As far as we know the process is empty. We may change our mind later. 16262 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16263 // At this point we don't actually know the adjustment. Use the cached adj 16264 // value that the caller wants us to. 16265 adj = cachedAdj; 16266 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16267 app.cached = true; 16268 app.empty = true; 16269 app.adjType = "cch-empty"; 16270 } 16271 16272 // Examine all activities if not already foreground. 16273 if (!foregroundActivities && activitiesSize > 0) { 16274 for (int j = 0; j < activitiesSize; j++) { 16275 final ActivityRecord r = app.activities.get(j); 16276 if (r.app != app) { 16277 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16278 + app + "?!?"); 16279 continue; 16280 } 16281 if (r.visible) { 16282 // App has a visible activity; only upgrade adjustment. 16283 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16284 adj = ProcessList.VISIBLE_APP_ADJ; 16285 app.adjType = "visible"; 16286 } 16287 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16288 procState = ActivityManager.PROCESS_STATE_TOP; 16289 } 16290 schedGroup = Process.THREAD_GROUP_DEFAULT; 16291 app.cached = false; 16292 app.empty = false; 16293 foregroundActivities = true; 16294 break; 16295 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16296 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16297 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16298 app.adjType = "pausing"; 16299 } 16300 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16301 procState = ActivityManager.PROCESS_STATE_TOP; 16302 } 16303 schedGroup = Process.THREAD_GROUP_DEFAULT; 16304 app.cached = false; 16305 app.empty = false; 16306 foregroundActivities = true; 16307 } else if (r.state == ActivityState.STOPPING) { 16308 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16309 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16310 app.adjType = "stopping"; 16311 } 16312 // For the process state, we will at this point consider the 16313 // process to be cached. It will be cached either as an activity 16314 // or empty depending on whether the activity is finishing. We do 16315 // this so that we can treat the process as cached for purposes of 16316 // memory trimming (determing current memory level, trim command to 16317 // send to process) since there can be an arbitrary number of stopping 16318 // processes and they should soon all go into the cached state. 16319 if (!r.finishing) { 16320 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16321 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16322 } 16323 } 16324 app.cached = false; 16325 app.empty = false; 16326 foregroundActivities = true; 16327 } else { 16328 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16329 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16330 app.adjType = "cch-act"; 16331 } 16332 } 16333 } 16334 } 16335 16336 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16337 if (app.foregroundServices) { 16338 // The user is aware of this app, so make it visible. 16339 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16340 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16341 app.cached = false; 16342 app.adjType = "fg-service"; 16343 schedGroup = Process.THREAD_GROUP_DEFAULT; 16344 } else if (app.forcingToForeground != null) { 16345 // The user is aware of this app, so make it visible. 16346 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16347 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16348 app.cached = false; 16349 app.adjType = "force-fg"; 16350 app.adjSource = app.forcingToForeground; 16351 schedGroup = Process.THREAD_GROUP_DEFAULT; 16352 } 16353 } 16354 16355 if (app == mHeavyWeightProcess) { 16356 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16357 // We don't want to kill the current heavy-weight process. 16358 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16359 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16360 app.cached = false; 16361 app.adjType = "heavy"; 16362 } 16363 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16364 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16365 } 16366 } 16367 16368 if (app == mHomeProcess) { 16369 if (adj > ProcessList.HOME_APP_ADJ) { 16370 // This process is hosting what we currently consider to be the 16371 // home app, so we don't want to let it go into the background. 16372 adj = ProcessList.HOME_APP_ADJ; 16373 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16374 app.cached = false; 16375 app.adjType = "home"; 16376 } 16377 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16378 procState = ActivityManager.PROCESS_STATE_HOME; 16379 } 16380 } 16381 16382 if (app == mPreviousProcess && app.activities.size() > 0) { 16383 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16384 // This was the previous process that showed UI to the user. 16385 // We want to try to keep it around more aggressively, to give 16386 // a good experience around switching between two apps. 16387 adj = ProcessList.PREVIOUS_APP_ADJ; 16388 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16389 app.cached = false; 16390 app.adjType = "previous"; 16391 } 16392 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16393 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16394 } 16395 } 16396 16397 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16398 + " reason=" + app.adjType); 16399 16400 // By default, we use the computed adjustment. It may be changed if 16401 // there are applications dependent on our services or providers, but 16402 // this gives us a baseline and makes sure we don't get into an 16403 // infinite recursion. 16404 app.adjSeq = mAdjSeq; 16405 app.curRawAdj = adj; 16406 app.hasStartedServices = false; 16407 16408 if (mBackupTarget != null && app == mBackupTarget.app) { 16409 // If possible we want to avoid killing apps while they're being backed up 16410 if (adj > ProcessList.BACKUP_APP_ADJ) { 16411 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16412 adj = ProcessList.BACKUP_APP_ADJ; 16413 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16414 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16415 } 16416 app.adjType = "backup"; 16417 app.cached = false; 16418 } 16419 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16420 procState = ActivityManager.PROCESS_STATE_BACKUP; 16421 } 16422 } 16423 16424 boolean mayBeTop = false; 16425 16426 for (int is = app.services.size()-1; 16427 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16428 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16429 || procState > ActivityManager.PROCESS_STATE_TOP); 16430 is--) { 16431 ServiceRecord s = app.services.valueAt(is); 16432 if (s.startRequested) { 16433 app.hasStartedServices = true; 16434 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16435 procState = ActivityManager.PROCESS_STATE_SERVICE; 16436 } 16437 if (app.hasShownUi && app != mHomeProcess) { 16438 // If this process has shown some UI, let it immediately 16439 // go to the LRU list because it may be pretty heavy with 16440 // UI stuff. We'll tag it with a label just to help 16441 // debug and understand what is going on. 16442 if (adj > ProcessList.SERVICE_ADJ) { 16443 app.adjType = "cch-started-ui-services"; 16444 } 16445 } else { 16446 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16447 // This service has seen some activity within 16448 // recent memory, so we will keep its process ahead 16449 // of the background processes. 16450 if (adj > ProcessList.SERVICE_ADJ) { 16451 adj = ProcessList.SERVICE_ADJ; 16452 app.adjType = "started-services"; 16453 app.cached = false; 16454 } 16455 } 16456 // If we have let the service slide into the background 16457 // state, still have some text describing what it is doing 16458 // even though the service no longer has an impact. 16459 if (adj > ProcessList.SERVICE_ADJ) { 16460 app.adjType = "cch-started-services"; 16461 } 16462 } 16463 } 16464 for (int conni = s.connections.size()-1; 16465 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16466 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16467 || procState > ActivityManager.PROCESS_STATE_TOP); 16468 conni--) { 16469 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16470 for (int i = 0; 16471 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16472 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16473 || procState > ActivityManager.PROCESS_STATE_TOP); 16474 i++) { 16475 // XXX should compute this based on the max of 16476 // all connected clients. 16477 ConnectionRecord cr = clist.get(i); 16478 if (cr.binding.client == app) { 16479 // Binding to ourself is not interesting. 16480 continue; 16481 } 16482 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16483 ProcessRecord client = cr.binding.client; 16484 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16485 TOP_APP, doingAll, now); 16486 int clientProcState = client.curProcState; 16487 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16488 // If the other app is cached for any reason, for purposes here 16489 // we are going to consider it empty. The specific cached state 16490 // doesn't propagate except under certain conditions. 16491 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16492 } 16493 String adjType = null; 16494 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16495 // Not doing bind OOM management, so treat 16496 // this guy more like a started service. 16497 if (app.hasShownUi && app != mHomeProcess) { 16498 // If this process has shown some UI, let it immediately 16499 // go to the LRU list because it may be pretty heavy with 16500 // UI stuff. We'll tag it with a label just to help 16501 // debug and understand what is going on. 16502 if (adj > clientAdj) { 16503 adjType = "cch-bound-ui-services"; 16504 } 16505 app.cached = false; 16506 clientAdj = adj; 16507 clientProcState = procState; 16508 } else { 16509 if (now >= (s.lastActivity 16510 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16511 // This service has not seen activity within 16512 // recent memory, so allow it to drop to the 16513 // LRU list if there is no other reason to keep 16514 // it around. We'll also tag it with a label just 16515 // to help debug and undertand what is going on. 16516 if (adj > clientAdj) { 16517 adjType = "cch-bound-services"; 16518 } 16519 clientAdj = adj; 16520 } 16521 } 16522 } 16523 if (adj > clientAdj) { 16524 // If this process has recently shown UI, and 16525 // the process that is binding to it is less 16526 // important than being visible, then we don't 16527 // care about the binding as much as we care 16528 // about letting this process get into the LRU 16529 // list to be killed and restarted if needed for 16530 // memory. 16531 if (app.hasShownUi && app != mHomeProcess 16532 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16533 adjType = "cch-bound-ui-services"; 16534 } else { 16535 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16536 |Context.BIND_IMPORTANT)) != 0) { 16537 adj = clientAdj; 16538 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16539 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16540 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16541 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16542 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16543 adj = clientAdj; 16544 } else { 16545 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16546 adj = ProcessList.VISIBLE_APP_ADJ; 16547 } 16548 } 16549 if (!client.cached) { 16550 app.cached = false; 16551 } 16552 adjType = "service"; 16553 } 16554 } 16555 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16556 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16557 schedGroup = Process.THREAD_GROUP_DEFAULT; 16558 } 16559 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16560 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16561 // Special handling of clients who are in the top state. 16562 // We *may* want to consider this process to be in the 16563 // top state as well, but only if there is not another 16564 // reason for it to be running. Being on the top is a 16565 // special state, meaning you are specifically running 16566 // for the current top app. If the process is already 16567 // running in the background for some other reason, it 16568 // is more important to continue considering it to be 16569 // in the background state. 16570 mayBeTop = true; 16571 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16572 } else { 16573 // Special handling for above-top states (persistent 16574 // processes). These should not bring the current process 16575 // into the top state, since they are not on top. Instead 16576 // give them the best state after that. 16577 clientProcState = 16578 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16579 } 16580 } 16581 } else { 16582 if (clientProcState < 16583 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16584 clientProcState = 16585 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16586 } 16587 } 16588 if (procState > clientProcState) { 16589 procState = clientProcState; 16590 } 16591 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16592 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16593 app.pendingUiClean = true; 16594 } 16595 if (adjType != null) { 16596 app.adjType = adjType; 16597 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16598 .REASON_SERVICE_IN_USE; 16599 app.adjSource = cr.binding.client; 16600 app.adjSourceProcState = clientProcState; 16601 app.adjTarget = s.name; 16602 } 16603 } 16604 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16605 app.treatLikeActivity = true; 16606 } 16607 final ActivityRecord a = cr.activity; 16608 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16609 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16610 (a.visible || a.state == ActivityState.RESUMED 16611 || a.state == ActivityState.PAUSING)) { 16612 adj = ProcessList.FOREGROUND_APP_ADJ; 16613 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16614 schedGroup = Process.THREAD_GROUP_DEFAULT; 16615 } 16616 app.cached = false; 16617 app.adjType = "service"; 16618 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16619 .REASON_SERVICE_IN_USE; 16620 app.adjSource = a; 16621 app.adjSourceProcState = procState; 16622 app.adjTarget = s.name; 16623 } 16624 } 16625 } 16626 } 16627 } 16628 16629 for (int provi = app.pubProviders.size()-1; 16630 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16631 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16632 || procState > ActivityManager.PROCESS_STATE_TOP); 16633 provi--) { 16634 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16635 for (int i = cpr.connections.size()-1; 16636 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16637 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16638 || procState > ActivityManager.PROCESS_STATE_TOP); 16639 i--) { 16640 ContentProviderConnection conn = cpr.connections.get(i); 16641 ProcessRecord client = conn.client; 16642 if (client == app) { 16643 // Being our own client is not interesting. 16644 continue; 16645 } 16646 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16647 int clientProcState = client.curProcState; 16648 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16649 // If the other app is cached for any reason, for purposes here 16650 // we are going to consider it empty. 16651 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16652 } 16653 if (adj > clientAdj) { 16654 if (app.hasShownUi && app != mHomeProcess 16655 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16656 app.adjType = "cch-ui-provider"; 16657 } else { 16658 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16659 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16660 app.adjType = "provider"; 16661 } 16662 app.cached &= client.cached; 16663 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16664 .REASON_PROVIDER_IN_USE; 16665 app.adjSource = client; 16666 app.adjSourceProcState = clientProcState; 16667 app.adjTarget = cpr.name; 16668 } 16669 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16670 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16671 // Special handling of clients who are in the top state. 16672 // We *may* want to consider this process to be in the 16673 // top state as well, but only if there is not another 16674 // reason for it to be running. Being on the top is a 16675 // special state, meaning you are specifically running 16676 // for the current top app. If the process is already 16677 // running in the background for some other reason, it 16678 // is more important to continue considering it to be 16679 // in the background state. 16680 mayBeTop = true; 16681 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16682 } else { 16683 // Special handling for above-top states (persistent 16684 // processes). These should not bring the current process 16685 // into the top state, since they are not on top. Instead 16686 // give them the best state after that. 16687 clientProcState = 16688 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16689 } 16690 } 16691 if (procState > clientProcState) { 16692 procState = clientProcState; 16693 } 16694 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16695 schedGroup = Process.THREAD_GROUP_DEFAULT; 16696 } 16697 } 16698 // If the provider has external (non-framework) process 16699 // dependencies, ensure that its adjustment is at least 16700 // FOREGROUND_APP_ADJ. 16701 if (cpr.hasExternalProcessHandles()) { 16702 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16703 adj = ProcessList.FOREGROUND_APP_ADJ; 16704 schedGroup = Process.THREAD_GROUP_DEFAULT; 16705 app.cached = false; 16706 app.adjType = "provider"; 16707 app.adjTarget = cpr.name; 16708 } 16709 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16710 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16711 } 16712 } 16713 } 16714 16715 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16716 // A client of one of our services or providers is in the top state. We 16717 // *may* want to be in the top state, but not if we are already running in 16718 // the background for some other reason. For the decision here, we are going 16719 // to pick out a few specific states that we want to remain in when a client 16720 // is top (states that tend to be longer-term) and otherwise allow it to go 16721 // to the top state. 16722 switch (procState) { 16723 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16724 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16725 case ActivityManager.PROCESS_STATE_SERVICE: 16726 // These all are longer-term states, so pull them up to the top 16727 // of the background states, but not all the way to the top state. 16728 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16729 break; 16730 default: 16731 // Otherwise, top is a better choice, so take it. 16732 procState = ActivityManager.PROCESS_STATE_TOP; 16733 break; 16734 } 16735 } 16736 16737 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16738 if (app.hasClientActivities) { 16739 // This is a cached process, but with client activities. Mark it so. 16740 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16741 app.adjType = "cch-client-act"; 16742 } else if (app.treatLikeActivity) { 16743 // This is a cached process, but somebody wants us to treat it like it has 16744 // an activity, okay! 16745 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16746 app.adjType = "cch-as-act"; 16747 } 16748 } 16749 16750 if (adj == ProcessList.SERVICE_ADJ) { 16751 if (doingAll) { 16752 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16753 mNewNumServiceProcs++; 16754 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16755 if (!app.serviceb) { 16756 // This service isn't far enough down on the LRU list to 16757 // normally be a B service, but if we are low on RAM and it 16758 // is large we want to force it down since we would prefer to 16759 // keep launcher over it. 16760 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16761 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16762 app.serviceHighRam = true; 16763 app.serviceb = true; 16764 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16765 } else { 16766 mNewNumAServiceProcs++; 16767 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16768 } 16769 } else { 16770 app.serviceHighRam = false; 16771 } 16772 } 16773 if (app.serviceb) { 16774 adj = ProcessList.SERVICE_B_ADJ; 16775 } 16776 } 16777 16778 app.curRawAdj = adj; 16779 16780 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16781 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16782 if (adj > app.maxAdj) { 16783 adj = app.maxAdj; 16784 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16785 schedGroup = Process.THREAD_GROUP_DEFAULT; 16786 } 16787 } 16788 16789 // Do final modification to adj. Everything we do between here and applying 16790 // the final setAdj must be done in this function, because we will also use 16791 // it when computing the final cached adj later. Note that we don't need to 16792 // worry about this for max adj above, since max adj will always be used to 16793 // keep it out of the cached vaues. 16794 app.curAdj = app.modifyRawOomAdj(adj); 16795 app.curSchedGroup = schedGroup; 16796 app.curProcState = procState; 16797 app.foregroundActivities = foregroundActivities; 16798 16799 return app.curRawAdj; 16800 } 16801 16802 /** 16803 * Schedule PSS collection of a process. 16804 */ 16805 void requestPssLocked(ProcessRecord proc, int procState) { 16806 if (mPendingPssProcesses.contains(proc)) { 16807 return; 16808 } 16809 if (mPendingPssProcesses.size() == 0) { 16810 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16811 } 16812 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16813 proc.pssProcState = procState; 16814 mPendingPssProcesses.add(proc); 16815 } 16816 16817 /** 16818 * Schedule PSS collection of all processes. 16819 */ 16820 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16821 if (!always) { 16822 if (now < (mLastFullPssTime + 16823 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16824 return; 16825 } 16826 } 16827 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16828 mLastFullPssTime = now; 16829 mFullPssPending = true; 16830 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16831 mPendingPssProcesses.clear(); 16832 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16833 ProcessRecord app = mLruProcesses.get(i); 16834 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16835 app.pssProcState = app.setProcState; 16836 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16837 isSleeping(), now); 16838 mPendingPssProcesses.add(app); 16839 } 16840 } 16841 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16842 } 16843 16844 /** 16845 * Ask a given process to GC right now. 16846 */ 16847 final void performAppGcLocked(ProcessRecord app) { 16848 try { 16849 app.lastRequestedGc = SystemClock.uptimeMillis(); 16850 if (app.thread != null) { 16851 if (app.reportLowMemory) { 16852 app.reportLowMemory = false; 16853 app.thread.scheduleLowMemory(); 16854 } else { 16855 app.thread.processInBackground(); 16856 } 16857 } 16858 } catch (Exception e) { 16859 // whatever. 16860 } 16861 } 16862 16863 /** 16864 * Returns true if things are idle enough to perform GCs. 16865 */ 16866 private final boolean canGcNowLocked() { 16867 boolean processingBroadcasts = false; 16868 for (BroadcastQueue q : mBroadcastQueues) { 16869 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16870 processingBroadcasts = true; 16871 } 16872 } 16873 return !processingBroadcasts 16874 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16875 } 16876 16877 /** 16878 * Perform GCs on all processes that are waiting for it, but only 16879 * if things are idle. 16880 */ 16881 final void performAppGcsLocked() { 16882 final int N = mProcessesToGc.size(); 16883 if (N <= 0) { 16884 return; 16885 } 16886 if (canGcNowLocked()) { 16887 while (mProcessesToGc.size() > 0) { 16888 ProcessRecord proc = mProcessesToGc.remove(0); 16889 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16890 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16891 <= SystemClock.uptimeMillis()) { 16892 // To avoid spamming the system, we will GC processes one 16893 // at a time, waiting a few seconds between each. 16894 performAppGcLocked(proc); 16895 scheduleAppGcsLocked(); 16896 return; 16897 } else { 16898 // It hasn't been long enough since we last GCed this 16899 // process... put it in the list to wait for its time. 16900 addProcessToGcListLocked(proc); 16901 break; 16902 } 16903 } 16904 } 16905 16906 scheduleAppGcsLocked(); 16907 } 16908 } 16909 16910 /** 16911 * If all looks good, perform GCs on all processes waiting for them. 16912 */ 16913 final void performAppGcsIfAppropriateLocked() { 16914 if (canGcNowLocked()) { 16915 performAppGcsLocked(); 16916 return; 16917 } 16918 // Still not idle, wait some more. 16919 scheduleAppGcsLocked(); 16920 } 16921 16922 /** 16923 * Schedule the execution of all pending app GCs. 16924 */ 16925 final void scheduleAppGcsLocked() { 16926 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16927 16928 if (mProcessesToGc.size() > 0) { 16929 // Schedule a GC for the time to the next process. 16930 ProcessRecord proc = mProcessesToGc.get(0); 16931 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16932 16933 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16934 long now = SystemClock.uptimeMillis(); 16935 if (when < (now+GC_TIMEOUT)) { 16936 when = now + GC_TIMEOUT; 16937 } 16938 mHandler.sendMessageAtTime(msg, when); 16939 } 16940 } 16941 16942 /** 16943 * Add a process to the array of processes waiting to be GCed. Keeps the 16944 * list in sorted order by the last GC time. The process can't already be 16945 * on the list. 16946 */ 16947 final void addProcessToGcListLocked(ProcessRecord proc) { 16948 boolean added = false; 16949 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16950 if (mProcessesToGc.get(i).lastRequestedGc < 16951 proc.lastRequestedGc) { 16952 added = true; 16953 mProcessesToGc.add(i+1, proc); 16954 break; 16955 } 16956 } 16957 if (!added) { 16958 mProcessesToGc.add(0, proc); 16959 } 16960 } 16961 16962 /** 16963 * Set up to ask a process to GC itself. This will either do it 16964 * immediately, or put it on the list of processes to gc the next 16965 * time things are idle. 16966 */ 16967 final void scheduleAppGcLocked(ProcessRecord app) { 16968 long now = SystemClock.uptimeMillis(); 16969 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16970 return; 16971 } 16972 if (!mProcessesToGc.contains(app)) { 16973 addProcessToGcListLocked(app); 16974 scheduleAppGcsLocked(); 16975 } 16976 } 16977 16978 final void checkExcessivePowerUsageLocked(boolean doKills) { 16979 updateCpuStatsNow(); 16980 16981 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16982 boolean doWakeKills = doKills; 16983 boolean doCpuKills = doKills; 16984 if (mLastPowerCheckRealtime == 0) { 16985 doWakeKills = false; 16986 } 16987 if (mLastPowerCheckUptime == 0) { 16988 doCpuKills = false; 16989 } 16990 if (stats.isScreenOn()) { 16991 doWakeKills = false; 16992 } 16993 final long curRealtime = SystemClock.elapsedRealtime(); 16994 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16995 final long curUptime = SystemClock.uptimeMillis(); 16996 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16997 mLastPowerCheckRealtime = curRealtime; 16998 mLastPowerCheckUptime = curUptime; 16999 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17000 doWakeKills = false; 17001 } 17002 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17003 doCpuKills = false; 17004 } 17005 int i = mLruProcesses.size(); 17006 while (i > 0) { 17007 i--; 17008 ProcessRecord app = mLruProcesses.get(i); 17009 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17010 long wtime; 17011 synchronized (stats) { 17012 wtime = stats.getProcessWakeTime(app.info.uid, 17013 app.pid, curRealtime); 17014 } 17015 long wtimeUsed = wtime - app.lastWakeTime; 17016 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17017 if (DEBUG_POWER) { 17018 StringBuilder sb = new StringBuilder(128); 17019 sb.append("Wake for "); 17020 app.toShortString(sb); 17021 sb.append(": over "); 17022 TimeUtils.formatDuration(realtimeSince, sb); 17023 sb.append(" used "); 17024 TimeUtils.formatDuration(wtimeUsed, sb); 17025 sb.append(" ("); 17026 sb.append((wtimeUsed*100)/realtimeSince); 17027 sb.append("%)"); 17028 Slog.i(TAG, sb.toString()); 17029 sb.setLength(0); 17030 sb.append("CPU for "); 17031 app.toShortString(sb); 17032 sb.append(": over "); 17033 TimeUtils.formatDuration(uptimeSince, sb); 17034 sb.append(" used "); 17035 TimeUtils.formatDuration(cputimeUsed, sb); 17036 sb.append(" ("); 17037 sb.append((cputimeUsed*100)/uptimeSince); 17038 sb.append("%)"); 17039 Slog.i(TAG, sb.toString()); 17040 } 17041 // If a process has held a wake lock for more 17042 // than 50% of the time during this period, 17043 // that sounds bad. Kill! 17044 if (doWakeKills && realtimeSince > 0 17045 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17046 synchronized (stats) { 17047 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17048 realtimeSince, wtimeUsed); 17049 } 17050 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17051 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17052 } else if (doCpuKills && uptimeSince > 0 17053 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17054 synchronized (stats) { 17055 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17056 uptimeSince, cputimeUsed); 17057 } 17058 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17059 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17060 } else { 17061 app.lastWakeTime = wtime; 17062 app.lastCpuTime = app.curCpuTime; 17063 } 17064 } 17065 } 17066 } 17067 17068 private final boolean applyOomAdjLocked(ProcessRecord app, 17069 ProcessRecord TOP_APP, boolean doingAll, long now) { 17070 boolean success = true; 17071 17072 if (app.curRawAdj != app.setRawAdj) { 17073 app.setRawAdj = app.curRawAdj; 17074 } 17075 17076 int changes = 0; 17077 17078 if (app.curAdj != app.setAdj) { 17079 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17081 TAG, "Set " + app.pid + " " + app.processName + 17082 " adj " + app.curAdj + ": " + app.adjType); 17083 app.setAdj = app.curAdj; 17084 } 17085 17086 if (app.setSchedGroup != app.curSchedGroup) { 17087 app.setSchedGroup = app.curSchedGroup; 17088 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17089 "Setting process group of " + app.processName 17090 + " to " + app.curSchedGroup); 17091 if (app.waitingToKill != null && 17092 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17093 app.kill(app.waitingToKill, true); 17094 success = false; 17095 } else { 17096 if (true) { 17097 long oldId = Binder.clearCallingIdentity(); 17098 try { 17099 Process.setProcessGroup(app.pid, app.curSchedGroup); 17100 } catch (Exception e) { 17101 Slog.w(TAG, "Failed setting process group of " + app.pid 17102 + " to " + app.curSchedGroup); 17103 e.printStackTrace(); 17104 } finally { 17105 Binder.restoreCallingIdentity(oldId); 17106 } 17107 } else { 17108 if (app.thread != null) { 17109 try { 17110 app.thread.setSchedulingGroup(app.curSchedGroup); 17111 } catch (RemoteException e) { 17112 } 17113 } 17114 } 17115 Process.setSwappiness(app.pid, 17116 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17117 } 17118 } 17119 if (app.repForegroundActivities != app.foregroundActivities) { 17120 app.repForegroundActivities = app.foregroundActivities; 17121 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17122 } 17123 if (app.repProcState != app.curProcState) { 17124 app.repProcState = app.curProcState; 17125 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17126 if (app.thread != null) { 17127 try { 17128 if (false) { 17129 //RuntimeException h = new RuntimeException("here"); 17130 Slog.i(TAG, "Sending new process state " + app.repProcState 17131 + " to " + app /*, h*/); 17132 } 17133 app.thread.setProcessState(app.repProcState); 17134 } catch (RemoteException e) { 17135 } 17136 } 17137 } 17138 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17139 app.setProcState)) { 17140 app.lastStateTime = now; 17141 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17142 isSleeping(), now); 17143 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17144 + ProcessList.makeProcStateString(app.setProcState) + " to " 17145 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17146 + (app.nextPssTime-now) + ": " + app); 17147 } else { 17148 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17149 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17150 requestPssLocked(app, app.setProcState); 17151 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17152 isSleeping(), now); 17153 } else if (false && DEBUG_PSS) { 17154 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17155 } 17156 } 17157 if (app.setProcState != app.curProcState) { 17158 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17159 "Proc state change of " + app.processName 17160 + " to " + app.curProcState); 17161 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17162 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17163 if (setImportant && !curImportant) { 17164 // This app is no longer something we consider important enough to allow to 17165 // use arbitrary amounts of battery power. Note 17166 // its current wake lock time to later know to kill it if 17167 // it is not behaving well. 17168 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17169 synchronized (stats) { 17170 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17171 app.pid, SystemClock.elapsedRealtime()); 17172 } 17173 app.lastCpuTime = app.curCpuTime; 17174 17175 } 17176 app.setProcState = app.curProcState; 17177 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17178 app.notCachedSinceIdle = false; 17179 } 17180 if (!doingAll) { 17181 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17182 } else { 17183 app.procStateChanged = true; 17184 } 17185 } 17186 17187 if (changes != 0) { 17188 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17189 int i = mPendingProcessChanges.size()-1; 17190 ProcessChangeItem item = null; 17191 while (i >= 0) { 17192 item = mPendingProcessChanges.get(i); 17193 if (item.pid == app.pid) { 17194 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17195 break; 17196 } 17197 i--; 17198 } 17199 if (i < 0) { 17200 // No existing item in pending changes; need a new one. 17201 final int NA = mAvailProcessChanges.size(); 17202 if (NA > 0) { 17203 item = mAvailProcessChanges.remove(NA-1); 17204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17205 } else { 17206 item = new ProcessChangeItem(); 17207 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17208 } 17209 item.changes = 0; 17210 item.pid = app.pid; 17211 item.uid = app.info.uid; 17212 if (mPendingProcessChanges.size() == 0) { 17213 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17214 "*** Enqueueing dispatch processes changed!"); 17215 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17216 } 17217 mPendingProcessChanges.add(item); 17218 } 17219 item.changes |= changes; 17220 item.processState = app.repProcState; 17221 item.foregroundActivities = app.repForegroundActivities; 17222 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17223 + Integer.toHexString(System.identityHashCode(item)) 17224 + " " + app.toShortString() + ": changes=" + item.changes 17225 + " procState=" + item.processState 17226 + " foreground=" + item.foregroundActivities 17227 + " type=" + app.adjType + " source=" + app.adjSource 17228 + " target=" + app.adjTarget); 17229 } 17230 17231 return success; 17232 } 17233 17234 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17235 if (proc.thread != null) { 17236 if (proc.baseProcessTracker != null) { 17237 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17238 } 17239 if (proc.repProcState >= 0) { 17240 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17241 proc.repProcState); 17242 } 17243 } 17244 } 17245 17246 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17247 ProcessRecord TOP_APP, boolean doingAll, long now) { 17248 if (app.thread == null) { 17249 return false; 17250 } 17251 17252 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17253 17254 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17255 } 17256 17257 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17258 boolean oomAdj) { 17259 if (isForeground != proc.foregroundServices) { 17260 proc.foregroundServices = isForeground; 17261 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17262 proc.info.uid); 17263 if (isForeground) { 17264 if (curProcs == null) { 17265 curProcs = new ArrayList<ProcessRecord>(); 17266 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17267 } 17268 if (!curProcs.contains(proc)) { 17269 curProcs.add(proc); 17270 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17271 proc.info.packageName, proc.info.uid); 17272 } 17273 } else { 17274 if (curProcs != null) { 17275 if (curProcs.remove(proc)) { 17276 mBatteryStatsService.noteEvent( 17277 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17278 proc.info.packageName, proc.info.uid); 17279 if (curProcs.size() <= 0) { 17280 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17281 } 17282 } 17283 } 17284 } 17285 if (oomAdj) { 17286 updateOomAdjLocked(); 17287 } 17288 } 17289 } 17290 17291 private final ActivityRecord resumedAppLocked() { 17292 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17293 String pkg; 17294 int uid; 17295 if (act != null) { 17296 pkg = act.packageName; 17297 uid = act.info.applicationInfo.uid; 17298 } else { 17299 pkg = null; 17300 uid = -1; 17301 } 17302 // Has the UID or resumed package name changed? 17303 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17304 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17305 if (mCurResumedPackage != null) { 17306 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17307 mCurResumedPackage, mCurResumedUid); 17308 } 17309 mCurResumedPackage = pkg; 17310 mCurResumedUid = uid; 17311 if (mCurResumedPackage != null) { 17312 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17313 mCurResumedPackage, mCurResumedUid); 17314 } 17315 } 17316 return act; 17317 } 17318 17319 final boolean updateOomAdjLocked(ProcessRecord app) { 17320 final ActivityRecord TOP_ACT = resumedAppLocked(); 17321 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17322 final boolean wasCached = app.cached; 17323 17324 mAdjSeq++; 17325 17326 // This is the desired cached adjusment we want to tell it to use. 17327 // If our app is currently cached, we know it, and that is it. Otherwise, 17328 // we don't know it yet, and it needs to now be cached we will then 17329 // need to do a complete oom adj. 17330 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17331 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17332 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17333 SystemClock.uptimeMillis()); 17334 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17335 // Changed to/from cached state, so apps after it in the LRU 17336 // list may also be changed. 17337 updateOomAdjLocked(); 17338 } 17339 return success; 17340 } 17341 17342 final void updateOomAdjLocked() { 17343 final ActivityRecord TOP_ACT = resumedAppLocked(); 17344 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17345 final long now = SystemClock.uptimeMillis(); 17346 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17347 final int N = mLruProcesses.size(); 17348 17349 if (false) { 17350 RuntimeException e = new RuntimeException(); 17351 e.fillInStackTrace(); 17352 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17353 } 17354 17355 mAdjSeq++; 17356 mNewNumServiceProcs = 0; 17357 mNewNumAServiceProcs = 0; 17358 17359 final int emptyProcessLimit; 17360 final int cachedProcessLimit; 17361 if (mProcessLimit <= 0) { 17362 emptyProcessLimit = cachedProcessLimit = 0; 17363 } else if (mProcessLimit == 1) { 17364 emptyProcessLimit = 1; 17365 cachedProcessLimit = 0; 17366 } else { 17367 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17368 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17369 } 17370 17371 // Let's determine how many processes we have running vs. 17372 // how many slots we have for background processes; we may want 17373 // to put multiple processes in a slot of there are enough of 17374 // them. 17375 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17376 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17377 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17378 if (numEmptyProcs > cachedProcessLimit) { 17379 // If there are more empty processes than our limit on cached 17380 // processes, then use the cached process limit for the factor. 17381 // This ensures that the really old empty processes get pushed 17382 // down to the bottom, so if we are running low on memory we will 17383 // have a better chance at keeping around more cached processes 17384 // instead of a gazillion empty processes. 17385 numEmptyProcs = cachedProcessLimit; 17386 } 17387 int emptyFactor = numEmptyProcs/numSlots; 17388 if (emptyFactor < 1) emptyFactor = 1; 17389 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17390 if (cachedFactor < 1) cachedFactor = 1; 17391 int stepCached = 0; 17392 int stepEmpty = 0; 17393 int numCached = 0; 17394 int numEmpty = 0; 17395 int numTrimming = 0; 17396 17397 mNumNonCachedProcs = 0; 17398 mNumCachedHiddenProcs = 0; 17399 17400 // First update the OOM adjustment for each of the 17401 // application processes based on their current state. 17402 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17403 int nextCachedAdj = curCachedAdj+1; 17404 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17405 int nextEmptyAdj = curEmptyAdj+2; 17406 for (int i=N-1; i>=0; i--) { 17407 ProcessRecord app = mLruProcesses.get(i); 17408 if (!app.killedByAm && app.thread != null) { 17409 app.procStateChanged = false; 17410 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17411 17412 // If we haven't yet assigned the final cached adj 17413 // to the process, do that now. 17414 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17415 switch (app.curProcState) { 17416 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17417 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17418 // This process is a cached process holding activities... 17419 // assign it the next cached value for that type, and then 17420 // step that cached level. 17421 app.curRawAdj = curCachedAdj; 17422 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17423 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17424 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17425 + ")"); 17426 if (curCachedAdj != nextCachedAdj) { 17427 stepCached++; 17428 if (stepCached >= cachedFactor) { 17429 stepCached = 0; 17430 curCachedAdj = nextCachedAdj; 17431 nextCachedAdj += 2; 17432 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17433 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17434 } 17435 } 17436 } 17437 break; 17438 default: 17439 // For everything else, assign next empty cached process 17440 // level and bump that up. Note that this means that 17441 // long-running services that have dropped down to the 17442 // cached level will be treated as empty (since their process 17443 // state is still as a service), which is what we want. 17444 app.curRawAdj = curEmptyAdj; 17445 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17446 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17447 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17448 + ")"); 17449 if (curEmptyAdj != nextEmptyAdj) { 17450 stepEmpty++; 17451 if (stepEmpty >= emptyFactor) { 17452 stepEmpty = 0; 17453 curEmptyAdj = nextEmptyAdj; 17454 nextEmptyAdj += 2; 17455 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17456 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17457 } 17458 } 17459 } 17460 break; 17461 } 17462 } 17463 17464 applyOomAdjLocked(app, TOP_APP, true, now); 17465 17466 // Count the number of process types. 17467 switch (app.curProcState) { 17468 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17469 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17470 mNumCachedHiddenProcs++; 17471 numCached++; 17472 if (numCached > cachedProcessLimit) { 17473 app.kill("cached #" + numCached, true); 17474 } 17475 break; 17476 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17477 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17478 && app.lastActivityTime < oldTime) { 17479 app.kill("empty for " 17480 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17481 / 1000) + "s", true); 17482 } else { 17483 numEmpty++; 17484 if (numEmpty > emptyProcessLimit) { 17485 app.kill("empty #" + numEmpty, true); 17486 } 17487 } 17488 break; 17489 default: 17490 mNumNonCachedProcs++; 17491 break; 17492 } 17493 17494 if (app.isolated && app.services.size() <= 0) { 17495 // If this is an isolated process, and there are no 17496 // services running in it, then the process is no longer 17497 // needed. We agressively kill these because we can by 17498 // definition not re-use the same process again, and it is 17499 // good to avoid having whatever code was running in them 17500 // left sitting around after no longer needed. 17501 app.kill("isolated not needed", true); 17502 } 17503 17504 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17505 && !app.killedByAm) { 17506 numTrimming++; 17507 } 17508 } 17509 } 17510 17511 mNumServiceProcs = mNewNumServiceProcs; 17512 17513 // Now determine the memory trimming level of background processes. 17514 // Unfortunately we need to start at the back of the list to do this 17515 // properly. We only do this if the number of background apps we 17516 // are managing to keep around is less than half the maximum we desire; 17517 // if we are keeping a good number around, we'll let them use whatever 17518 // memory they want. 17519 final int numCachedAndEmpty = numCached + numEmpty; 17520 int memFactor; 17521 if (numCached <= ProcessList.TRIM_CACHED_APPS 17522 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17523 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17524 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17525 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17526 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17527 } else { 17528 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17529 } 17530 } else { 17531 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17532 } 17533 // We always allow the memory level to go up (better). We only allow it to go 17534 // down if we are in a state where that is allowed, *and* the total number of processes 17535 // has gone down since last time. 17536 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17537 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17538 + " last=" + mLastNumProcesses); 17539 if (memFactor > mLastMemoryLevel) { 17540 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17541 memFactor = mLastMemoryLevel; 17542 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17543 } 17544 } 17545 mLastMemoryLevel = memFactor; 17546 mLastNumProcesses = mLruProcesses.size(); 17547 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17548 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17549 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17550 if (mLowRamStartTime == 0) { 17551 mLowRamStartTime = now; 17552 } 17553 int step = 0; 17554 int fgTrimLevel; 17555 switch (memFactor) { 17556 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17557 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17558 break; 17559 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17560 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17561 break; 17562 default: 17563 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17564 break; 17565 } 17566 int factor = numTrimming/3; 17567 int minFactor = 2; 17568 if (mHomeProcess != null) minFactor++; 17569 if (mPreviousProcess != null) minFactor++; 17570 if (factor < minFactor) factor = minFactor; 17571 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17572 for (int i=N-1; i>=0; i--) { 17573 ProcessRecord app = mLruProcesses.get(i); 17574 if (allChanged || app.procStateChanged) { 17575 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17576 app.procStateChanged = false; 17577 } 17578 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17579 && !app.killedByAm) { 17580 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17581 try { 17582 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17583 "Trimming memory of " + app.processName 17584 + " to " + curLevel); 17585 app.thread.scheduleTrimMemory(curLevel); 17586 } catch (RemoteException e) { 17587 } 17588 if (false) { 17589 // For now we won't do this; our memory trimming seems 17590 // to be good enough at this point that destroying 17591 // activities causes more harm than good. 17592 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17593 && app != mHomeProcess && app != mPreviousProcess) { 17594 // Need to do this on its own message because the stack may not 17595 // be in a consistent state at this point. 17596 // For these apps we will also finish their activities 17597 // to help them free memory. 17598 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17599 } 17600 } 17601 } 17602 app.trimMemoryLevel = curLevel; 17603 step++; 17604 if (step >= factor) { 17605 step = 0; 17606 switch (curLevel) { 17607 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17608 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17609 break; 17610 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17611 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17612 break; 17613 } 17614 } 17615 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17616 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17617 && app.thread != null) { 17618 try { 17619 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17620 "Trimming memory of heavy-weight " + app.processName 17621 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17622 app.thread.scheduleTrimMemory( 17623 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17624 } catch (RemoteException e) { 17625 } 17626 } 17627 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17628 } else { 17629 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17630 || app.systemNoUi) && app.pendingUiClean) { 17631 // If this application is now in the background and it 17632 // had done UI, then give it the special trim level to 17633 // have it free UI resources. 17634 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17635 if (app.trimMemoryLevel < level && app.thread != null) { 17636 try { 17637 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17638 "Trimming memory of bg-ui " + app.processName 17639 + " to " + level); 17640 app.thread.scheduleTrimMemory(level); 17641 } catch (RemoteException e) { 17642 } 17643 } 17644 app.pendingUiClean = false; 17645 } 17646 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17647 try { 17648 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17649 "Trimming memory of fg " + app.processName 17650 + " to " + fgTrimLevel); 17651 app.thread.scheduleTrimMemory(fgTrimLevel); 17652 } catch (RemoteException e) { 17653 } 17654 } 17655 app.trimMemoryLevel = fgTrimLevel; 17656 } 17657 } 17658 } else { 17659 if (mLowRamStartTime != 0) { 17660 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17661 mLowRamStartTime = 0; 17662 } 17663 for (int i=N-1; i>=0; i--) { 17664 ProcessRecord app = mLruProcesses.get(i); 17665 if (allChanged || app.procStateChanged) { 17666 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17667 app.procStateChanged = false; 17668 } 17669 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17670 || app.systemNoUi) && app.pendingUiClean) { 17671 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17672 && app.thread != null) { 17673 try { 17674 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17675 "Trimming memory of ui hidden " + app.processName 17676 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17677 app.thread.scheduleTrimMemory( 17678 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17679 } catch (RemoteException e) { 17680 } 17681 } 17682 app.pendingUiClean = false; 17683 } 17684 app.trimMemoryLevel = 0; 17685 } 17686 } 17687 17688 if (mAlwaysFinishActivities) { 17689 // Need to do this on its own message because the stack may not 17690 // be in a consistent state at this point. 17691 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17692 } 17693 17694 if (allChanged) { 17695 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17696 } 17697 17698 if (mProcessStats.shouldWriteNowLocked(now)) { 17699 mHandler.post(new Runnable() { 17700 @Override public void run() { 17701 synchronized (ActivityManagerService.this) { 17702 mProcessStats.writeStateAsyncLocked(); 17703 } 17704 } 17705 }); 17706 } 17707 17708 if (DEBUG_OOM_ADJ) { 17709 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17710 } 17711 } 17712 17713 final void trimApplications() { 17714 synchronized (this) { 17715 int i; 17716 17717 // First remove any unused application processes whose package 17718 // has been removed. 17719 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17720 final ProcessRecord app = mRemovedProcesses.get(i); 17721 if (app.activities.size() == 0 17722 && app.curReceiver == null && app.services.size() == 0) { 17723 Slog.i( 17724 TAG, "Exiting empty application process " 17725 + app.processName + " (" 17726 + (app.thread != null ? app.thread.asBinder() : null) 17727 + ")\n"); 17728 if (app.pid > 0 && app.pid != MY_PID) { 17729 app.kill("empty", false); 17730 } else { 17731 try { 17732 app.thread.scheduleExit(); 17733 } catch (Exception e) { 17734 // Ignore exceptions. 17735 } 17736 } 17737 cleanUpApplicationRecordLocked(app, false, true, -1); 17738 mRemovedProcesses.remove(i); 17739 17740 if (app.persistent) { 17741 addAppLocked(app.info, false, null /* ABI override */); 17742 } 17743 } 17744 } 17745 17746 // Now update the oom adj for all processes. 17747 updateOomAdjLocked(); 17748 } 17749 } 17750 17751 /** This method sends the specified signal to each of the persistent apps */ 17752 public void signalPersistentProcesses(int sig) throws RemoteException { 17753 if (sig != Process.SIGNAL_USR1) { 17754 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17755 } 17756 17757 synchronized (this) { 17758 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17759 != PackageManager.PERMISSION_GRANTED) { 17760 throw new SecurityException("Requires permission " 17761 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17762 } 17763 17764 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17765 ProcessRecord r = mLruProcesses.get(i); 17766 if (r.thread != null && r.persistent) { 17767 Process.sendSignal(r.pid, sig); 17768 } 17769 } 17770 } 17771 } 17772 17773 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17774 if (proc == null || proc == mProfileProc) { 17775 proc = mProfileProc; 17776 profileType = mProfileType; 17777 clearProfilerLocked(); 17778 } 17779 if (proc == null) { 17780 return; 17781 } 17782 try { 17783 proc.thread.profilerControl(false, null, profileType); 17784 } catch (RemoteException e) { 17785 throw new IllegalStateException("Process disappeared"); 17786 } 17787 } 17788 17789 private void clearProfilerLocked() { 17790 if (mProfileFd != null) { 17791 try { 17792 mProfileFd.close(); 17793 } catch (IOException e) { 17794 } 17795 } 17796 mProfileApp = null; 17797 mProfileProc = null; 17798 mProfileFile = null; 17799 mProfileType = 0; 17800 mAutoStopProfiler = false; 17801 mSamplingInterval = 0; 17802 } 17803 17804 public boolean profileControl(String process, int userId, boolean start, 17805 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17806 17807 try { 17808 synchronized (this) { 17809 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17810 // its own permission. 17811 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17812 != PackageManager.PERMISSION_GRANTED) { 17813 throw new SecurityException("Requires permission " 17814 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17815 } 17816 17817 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17818 throw new IllegalArgumentException("null profile info or fd"); 17819 } 17820 17821 ProcessRecord proc = null; 17822 if (process != null) { 17823 proc = findProcessLocked(process, userId, "profileControl"); 17824 } 17825 17826 if (start && (proc == null || proc.thread == null)) { 17827 throw new IllegalArgumentException("Unknown process: " + process); 17828 } 17829 17830 if (start) { 17831 stopProfilerLocked(null, 0); 17832 setProfileApp(proc.info, proc.processName, profilerInfo); 17833 mProfileProc = proc; 17834 mProfileType = profileType; 17835 ParcelFileDescriptor fd = profilerInfo.profileFd; 17836 try { 17837 fd = fd.dup(); 17838 } catch (IOException e) { 17839 fd = null; 17840 } 17841 profilerInfo.profileFd = fd; 17842 proc.thread.profilerControl(start, profilerInfo, profileType); 17843 fd = null; 17844 mProfileFd = null; 17845 } else { 17846 stopProfilerLocked(proc, profileType); 17847 if (profilerInfo != null && profilerInfo.profileFd != null) { 17848 try { 17849 profilerInfo.profileFd.close(); 17850 } catch (IOException e) { 17851 } 17852 } 17853 } 17854 17855 return true; 17856 } 17857 } catch (RemoteException e) { 17858 throw new IllegalStateException("Process disappeared"); 17859 } finally { 17860 if (profilerInfo != null && profilerInfo.profileFd != null) { 17861 try { 17862 profilerInfo.profileFd.close(); 17863 } catch (IOException e) { 17864 } 17865 } 17866 } 17867 } 17868 17869 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17870 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17871 userId, true, ALLOW_FULL_ONLY, callName, null); 17872 ProcessRecord proc = null; 17873 try { 17874 int pid = Integer.parseInt(process); 17875 synchronized (mPidsSelfLocked) { 17876 proc = mPidsSelfLocked.get(pid); 17877 } 17878 } catch (NumberFormatException e) { 17879 } 17880 17881 if (proc == null) { 17882 ArrayMap<String, SparseArray<ProcessRecord>> all 17883 = mProcessNames.getMap(); 17884 SparseArray<ProcessRecord> procs = all.get(process); 17885 if (procs != null && procs.size() > 0) { 17886 proc = procs.valueAt(0); 17887 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17888 for (int i=1; i<procs.size(); i++) { 17889 ProcessRecord thisProc = procs.valueAt(i); 17890 if (thisProc.userId == userId) { 17891 proc = thisProc; 17892 break; 17893 } 17894 } 17895 } 17896 } 17897 } 17898 17899 return proc; 17900 } 17901 17902 public boolean dumpHeap(String process, int userId, boolean managed, 17903 String path, ParcelFileDescriptor fd) throws RemoteException { 17904 17905 try { 17906 synchronized (this) { 17907 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17908 // its own permission (same as profileControl). 17909 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17910 != PackageManager.PERMISSION_GRANTED) { 17911 throw new SecurityException("Requires permission " 17912 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17913 } 17914 17915 if (fd == null) { 17916 throw new IllegalArgumentException("null fd"); 17917 } 17918 17919 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17920 if (proc == null || proc.thread == null) { 17921 throw new IllegalArgumentException("Unknown process: " + process); 17922 } 17923 17924 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17925 if (!isDebuggable) { 17926 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17927 throw new SecurityException("Process not debuggable: " + proc); 17928 } 17929 } 17930 17931 proc.thread.dumpHeap(managed, path, fd); 17932 fd = null; 17933 return true; 17934 } 17935 } catch (RemoteException e) { 17936 throw new IllegalStateException("Process disappeared"); 17937 } finally { 17938 if (fd != null) { 17939 try { 17940 fd.close(); 17941 } catch (IOException e) { 17942 } 17943 } 17944 } 17945 } 17946 17947 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17948 public void monitor() { 17949 synchronized (this) { } 17950 } 17951 17952 void onCoreSettingsChange(Bundle settings) { 17953 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17954 ProcessRecord processRecord = mLruProcesses.get(i); 17955 try { 17956 if (processRecord.thread != null) { 17957 processRecord.thread.setCoreSettings(settings); 17958 } 17959 } catch (RemoteException re) { 17960 /* ignore */ 17961 } 17962 } 17963 } 17964 17965 // Multi-user methods 17966 17967 /** 17968 * Start user, if its not already running, but don't bring it to foreground. 17969 */ 17970 @Override 17971 public boolean startUserInBackground(final int userId) { 17972 return startUser(userId, /* foreground */ false); 17973 } 17974 17975 /** 17976 * Start user, if its not already running, and bring it to foreground. 17977 */ 17978 boolean startUserInForeground(final int userId, Dialog dlg) { 17979 boolean result = startUser(userId, /* foreground */ true); 17980 dlg.dismiss(); 17981 return result; 17982 } 17983 17984 /** 17985 * Refreshes the list of users related to the current user when either a 17986 * user switch happens or when a new related user is started in the 17987 * background. 17988 */ 17989 private void updateCurrentProfileIdsLocked() { 17990 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17991 mCurrentUserId, false /* enabledOnly */); 17992 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17993 for (int i = 0; i < currentProfileIds.length; i++) { 17994 currentProfileIds[i] = profiles.get(i).id; 17995 } 17996 mCurrentProfileIds = currentProfileIds; 17997 17998 synchronized (mUserProfileGroupIdsSelfLocked) { 17999 mUserProfileGroupIdsSelfLocked.clear(); 18000 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18001 for (int i = 0; i < users.size(); i++) { 18002 UserInfo user = users.get(i); 18003 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18004 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18005 } 18006 } 18007 } 18008 } 18009 18010 private Set getProfileIdsLocked(int userId) { 18011 Set userIds = new HashSet<Integer>(); 18012 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18013 userId, false /* enabledOnly */); 18014 for (UserInfo user : profiles) { 18015 userIds.add(Integer.valueOf(user.id)); 18016 } 18017 return userIds; 18018 } 18019 18020 @Override 18021 public boolean switchUser(final int userId) { 18022 String userName; 18023 synchronized (this) { 18024 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18025 if (userInfo == null) { 18026 Slog.w(TAG, "No user info for user #" + userId); 18027 return false; 18028 } 18029 if (userInfo.isManagedProfile()) { 18030 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18031 return false; 18032 } 18033 userName = userInfo.name; 18034 mTargetUserId = userId; 18035 } 18036 mHandler.removeMessages(START_USER_SWITCH_MSG); 18037 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18038 return true; 18039 } 18040 18041 private void showUserSwitchDialog(int userId, String userName) { 18042 // The dialog will show and then initiate the user switch by calling startUserInForeground 18043 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18044 true /* above system */); 18045 d.show(); 18046 } 18047 18048 private boolean startUser(final int userId, final boolean foreground) { 18049 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18050 != PackageManager.PERMISSION_GRANTED) { 18051 String msg = "Permission Denial: switchUser() from pid=" 18052 + Binder.getCallingPid() 18053 + ", uid=" + Binder.getCallingUid() 18054 + " requires " + INTERACT_ACROSS_USERS_FULL; 18055 Slog.w(TAG, msg); 18056 throw new SecurityException(msg); 18057 } 18058 18059 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18060 18061 final long ident = Binder.clearCallingIdentity(); 18062 try { 18063 synchronized (this) { 18064 final int oldUserId = mCurrentUserId; 18065 if (oldUserId == userId) { 18066 return true; 18067 } 18068 18069 mStackSupervisor.setLockTaskModeLocked(null, false); 18070 18071 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18072 if (userInfo == null) { 18073 Slog.w(TAG, "No user info for user #" + userId); 18074 return false; 18075 } 18076 if (foreground && userInfo.isManagedProfile()) { 18077 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18078 return false; 18079 } 18080 18081 if (foreground) { 18082 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18083 R.anim.screen_user_enter); 18084 } 18085 18086 boolean needStart = false; 18087 18088 // If the user we are switching to is not currently started, then 18089 // we need to start it now. 18090 if (mStartedUsers.get(userId) == null) { 18091 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18092 updateStartedUserArrayLocked(); 18093 needStart = true; 18094 } 18095 18096 final Integer userIdInt = Integer.valueOf(userId); 18097 mUserLru.remove(userIdInt); 18098 mUserLru.add(userIdInt); 18099 18100 if (foreground) { 18101 mCurrentUserId = userId; 18102 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18103 updateCurrentProfileIdsLocked(); 18104 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18105 // Once the internal notion of the active user has switched, we lock the device 18106 // with the option to show the user switcher on the keyguard. 18107 mWindowManager.lockNow(null); 18108 } else { 18109 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18110 updateCurrentProfileIdsLocked(); 18111 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18112 mUserLru.remove(currentUserIdInt); 18113 mUserLru.add(currentUserIdInt); 18114 } 18115 18116 final UserStartedState uss = mStartedUsers.get(userId); 18117 18118 // Make sure user is in the started state. If it is currently 18119 // stopping, we need to knock that off. 18120 if (uss.mState == UserStartedState.STATE_STOPPING) { 18121 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18122 // so we can just fairly silently bring the user back from 18123 // the almost-dead. 18124 uss.mState = UserStartedState.STATE_RUNNING; 18125 updateStartedUserArrayLocked(); 18126 needStart = true; 18127 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18128 // This means ACTION_SHUTDOWN has been sent, so we will 18129 // need to treat this as a new boot of the user. 18130 uss.mState = UserStartedState.STATE_BOOTING; 18131 updateStartedUserArrayLocked(); 18132 needStart = true; 18133 } 18134 18135 if (uss.mState == UserStartedState.STATE_BOOTING) { 18136 // Booting up a new user, need to tell system services about it. 18137 // Note that this is on the same handler as scheduling of broadcasts, 18138 // which is important because it needs to go first. 18139 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18140 } 18141 18142 if (foreground) { 18143 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18144 oldUserId)); 18145 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18146 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18147 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18148 oldUserId, userId, uss)); 18149 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18150 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18151 } 18152 18153 if (needStart) { 18154 // Send USER_STARTED broadcast 18155 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18157 | Intent.FLAG_RECEIVER_FOREGROUND); 18158 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18159 broadcastIntentLocked(null, null, intent, 18160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18161 false, false, MY_PID, Process.SYSTEM_UID, userId); 18162 } 18163 18164 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18165 if (userId != UserHandle.USER_OWNER) { 18166 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18167 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18168 broadcastIntentLocked(null, null, intent, null, 18169 new IIntentReceiver.Stub() { 18170 public void performReceive(Intent intent, int resultCode, 18171 String data, Bundle extras, boolean ordered, 18172 boolean sticky, int sendingUser) { 18173 onUserInitialized(uss, foreground, oldUserId, userId); 18174 } 18175 }, 0, null, null, null, AppOpsManager.OP_NONE, 18176 true, false, MY_PID, Process.SYSTEM_UID, 18177 userId); 18178 uss.initializing = true; 18179 } else { 18180 getUserManagerLocked().makeInitialized(userInfo.id); 18181 } 18182 } 18183 18184 if (foreground) { 18185 if (!uss.initializing) { 18186 moveUserToForeground(uss, oldUserId, userId); 18187 } 18188 } else { 18189 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18190 } 18191 18192 if (needStart) { 18193 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18196 broadcastIntentLocked(null, null, intent, 18197 null, new IIntentReceiver.Stub() { 18198 @Override 18199 public void performReceive(Intent intent, int resultCode, String data, 18200 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18201 throws RemoteException { 18202 } 18203 }, 0, null, null, 18204 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18205 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18206 } 18207 } 18208 } finally { 18209 Binder.restoreCallingIdentity(ident); 18210 } 18211 18212 return true; 18213 } 18214 18215 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18216 long ident = Binder.clearCallingIdentity(); 18217 try { 18218 Intent intent; 18219 if (oldUserId >= 0) { 18220 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18221 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18222 int count = profiles.size(); 18223 for (int i = 0; i < count; i++) { 18224 int profileUserId = profiles.get(i).id; 18225 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18226 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18227 | Intent.FLAG_RECEIVER_FOREGROUND); 18228 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18229 broadcastIntentLocked(null, null, intent, 18230 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18231 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18232 } 18233 } 18234 if (newUserId >= 0) { 18235 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18236 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18237 int count = profiles.size(); 18238 for (int i = 0; i < count; i++) { 18239 int profileUserId = profiles.get(i).id; 18240 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18241 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18242 | Intent.FLAG_RECEIVER_FOREGROUND); 18243 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18244 broadcastIntentLocked(null, null, intent, 18245 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18246 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18247 } 18248 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18249 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18250 | Intent.FLAG_RECEIVER_FOREGROUND); 18251 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18252 broadcastIntentLocked(null, null, intent, 18253 null, null, 0, null, null, 18254 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18255 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18256 } 18257 } finally { 18258 Binder.restoreCallingIdentity(ident); 18259 } 18260 } 18261 18262 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18263 final int newUserId) { 18264 final int N = mUserSwitchObservers.beginBroadcast(); 18265 if (N > 0) { 18266 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18267 int mCount = 0; 18268 @Override 18269 public void sendResult(Bundle data) throws RemoteException { 18270 synchronized (ActivityManagerService.this) { 18271 if (mCurUserSwitchCallback == this) { 18272 mCount++; 18273 if (mCount == N) { 18274 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18275 } 18276 } 18277 } 18278 } 18279 }; 18280 synchronized (this) { 18281 uss.switching = true; 18282 mCurUserSwitchCallback = callback; 18283 } 18284 for (int i=0; i<N; i++) { 18285 try { 18286 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18287 newUserId, callback); 18288 } catch (RemoteException e) { 18289 } 18290 } 18291 } else { 18292 synchronized (this) { 18293 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18294 } 18295 } 18296 mUserSwitchObservers.finishBroadcast(); 18297 } 18298 18299 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18300 synchronized (this) { 18301 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18302 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18303 } 18304 } 18305 18306 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18307 mCurUserSwitchCallback = null; 18308 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18309 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18310 oldUserId, newUserId, uss)); 18311 } 18312 18313 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18314 synchronized (this) { 18315 if (foreground) { 18316 moveUserToForeground(uss, oldUserId, newUserId); 18317 } 18318 } 18319 18320 completeSwitchAndInitalize(uss, newUserId, true, false); 18321 } 18322 18323 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18324 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18325 if (homeInFront) { 18326 startHomeActivityLocked(newUserId); 18327 } else { 18328 mStackSupervisor.resumeTopActivitiesLocked(); 18329 } 18330 EventLogTags.writeAmSwitchUser(newUserId); 18331 getUserManagerLocked().userForeground(newUserId); 18332 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18333 } 18334 18335 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18336 completeSwitchAndInitalize(uss, newUserId, false, true); 18337 } 18338 18339 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18340 boolean clearInitializing, boolean clearSwitching) { 18341 boolean unfrozen = false; 18342 synchronized (this) { 18343 if (clearInitializing) { 18344 uss.initializing = false; 18345 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18346 } 18347 if (clearSwitching) { 18348 uss.switching = false; 18349 } 18350 if (!uss.switching && !uss.initializing) { 18351 mWindowManager.stopFreezingScreen(); 18352 unfrozen = true; 18353 } 18354 } 18355 if (unfrozen) { 18356 final int N = mUserSwitchObservers.beginBroadcast(); 18357 for (int i=0; i<N; i++) { 18358 try { 18359 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18360 } catch (RemoteException e) { 18361 } 18362 } 18363 mUserSwitchObservers.finishBroadcast(); 18364 } 18365 } 18366 18367 void scheduleStartProfilesLocked() { 18368 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18369 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18370 DateUtils.SECOND_IN_MILLIS); 18371 } 18372 } 18373 18374 void startProfilesLocked() { 18375 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18376 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18377 mCurrentUserId, false /* enabledOnly */); 18378 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18379 for (UserInfo user : profiles) { 18380 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18381 && user.id != mCurrentUserId) { 18382 toStart.add(user); 18383 } 18384 } 18385 final int n = toStart.size(); 18386 int i = 0; 18387 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18388 startUserInBackground(toStart.get(i).id); 18389 } 18390 if (i < n) { 18391 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18392 } 18393 } 18394 18395 void finishUserBoot(UserStartedState uss) { 18396 synchronized (this) { 18397 if (uss.mState == UserStartedState.STATE_BOOTING 18398 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18399 uss.mState = UserStartedState.STATE_RUNNING; 18400 final int userId = uss.mHandle.getIdentifier(); 18401 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18402 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18403 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18404 broadcastIntentLocked(null, null, intent, 18405 null, null, 0, null, null, 18406 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18407 true, false, MY_PID, Process.SYSTEM_UID, userId); 18408 } 18409 } 18410 } 18411 18412 void finishUserSwitch(UserStartedState uss) { 18413 synchronized (this) { 18414 finishUserBoot(uss); 18415 18416 startProfilesLocked(); 18417 18418 int num = mUserLru.size(); 18419 int i = 0; 18420 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18421 Integer oldUserId = mUserLru.get(i); 18422 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18423 if (oldUss == null) { 18424 // Shouldn't happen, but be sane if it does. 18425 mUserLru.remove(i); 18426 num--; 18427 continue; 18428 } 18429 if (oldUss.mState == UserStartedState.STATE_STOPPING 18430 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18431 // This user is already stopping, doesn't count. 18432 num--; 18433 i++; 18434 continue; 18435 } 18436 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18437 // Owner and current can't be stopped, but count as running. 18438 i++; 18439 continue; 18440 } 18441 // This is a user to be stopped. 18442 stopUserLocked(oldUserId, null); 18443 num--; 18444 i++; 18445 } 18446 } 18447 } 18448 18449 @Override 18450 public int stopUser(final int userId, final IStopUserCallback callback) { 18451 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18452 != PackageManager.PERMISSION_GRANTED) { 18453 String msg = "Permission Denial: switchUser() from pid=" 18454 + Binder.getCallingPid() 18455 + ", uid=" + Binder.getCallingUid() 18456 + " requires " + INTERACT_ACROSS_USERS_FULL; 18457 Slog.w(TAG, msg); 18458 throw new SecurityException(msg); 18459 } 18460 if (userId <= 0) { 18461 throw new IllegalArgumentException("Can't stop primary user " + userId); 18462 } 18463 synchronized (this) { 18464 return stopUserLocked(userId, callback); 18465 } 18466 } 18467 18468 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18469 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18470 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18471 return ActivityManager.USER_OP_IS_CURRENT; 18472 } 18473 18474 final UserStartedState uss = mStartedUsers.get(userId); 18475 if (uss == null) { 18476 // User is not started, nothing to do... but we do need to 18477 // callback if requested. 18478 if (callback != null) { 18479 mHandler.post(new Runnable() { 18480 @Override 18481 public void run() { 18482 try { 18483 callback.userStopped(userId); 18484 } catch (RemoteException e) { 18485 } 18486 } 18487 }); 18488 } 18489 return ActivityManager.USER_OP_SUCCESS; 18490 } 18491 18492 if (callback != null) { 18493 uss.mStopCallbacks.add(callback); 18494 } 18495 18496 if (uss.mState != UserStartedState.STATE_STOPPING 18497 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18498 uss.mState = UserStartedState.STATE_STOPPING; 18499 updateStartedUserArrayLocked(); 18500 18501 long ident = Binder.clearCallingIdentity(); 18502 try { 18503 // We are going to broadcast ACTION_USER_STOPPING and then 18504 // once that is done send a final ACTION_SHUTDOWN and then 18505 // stop the user. 18506 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18507 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18508 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18509 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18510 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18511 // This is the result receiver for the final shutdown broadcast. 18512 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18513 @Override 18514 public void performReceive(Intent intent, int resultCode, String data, 18515 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18516 finishUserStop(uss); 18517 } 18518 }; 18519 // This is the result receiver for the initial stopping broadcast. 18520 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18521 @Override 18522 public void performReceive(Intent intent, int resultCode, String data, 18523 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18524 // On to the next. 18525 synchronized (ActivityManagerService.this) { 18526 if (uss.mState != UserStartedState.STATE_STOPPING) { 18527 // Whoops, we are being started back up. Abort, abort! 18528 return; 18529 } 18530 uss.mState = UserStartedState.STATE_SHUTDOWN; 18531 } 18532 mBatteryStatsService.noteEvent( 18533 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18534 Integer.toString(userId), userId); 18535 mSystemServiceManager.stopUser(userId); 18536 broadcastIntentLocked(null, null, shutdownIntent, 18537 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18538 true, false, MY_PID, Process.SYSTEM_UID, userId); 18539 } 18540 }; 18541 // Kick things off. 18542 broadcastIntentLocked(null, null, stoppingIntent, 18543 null, stoppingReceiver, 0, null, null, 18544 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18545 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18546 } finally { 18547 Binder.restoreCallingIdentity(ident); 18548 } 18549 } 18550 18551 return ActivityManager.USER_OP_SUCCESS; 18552 } 18553 18554 void finishUserStop(UserStartedState uss) { 18555 final int userId = uss.mHandle.getIdentifier(); 18556 boolean stopped; 18557 ArrayList<IStopUserCallback> callbacks; 18558 synchronized (this) { 18559 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18560 if (mStartedUsers.get(userId) != uss) { 18561 stopped = false; 18562 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18563 stopped = false; 18564 } else { 18565 stopped = true; 18566 // User can no longer run. 18567 mStartedUsers.remove(userId); 18568 mUserLru.remove(Integer.valueOf(userId)); 18569 updateStartedUserArrayLocked(); 18570 18571 // Clean up all state and processes associated with the user. 18572 // Kill all the processes for the user. 18573 forceStopUserLocked(userId, "finish user"); 18574 } 18575 18576 // Explicitly remove the old information in mRecentTasks. 18577 removeRecentTasksForUserLocked(userId); 18578 } 18579 18580 for (int i=0; i<callbacks.size(); i++) { 18581 try { 18582 if (stopped) callbacks.get(i).userStopped(userId); 18583 else callbacks.get(i).userStopAborted(userId); 18584 } catch (RemoteException e) { 18585 } 18586 } 18587 18588 if (stopped) { 18589 mSystemServiceManager.cleanupUser(userId); 18590 synchronized (this) { 18591 mStackSupervisor.removeUserLocked(userId); 18592 } 18593 } 18594 } 18595 18596 @Override 18597 public UserInfo getCurrentUser() { 18598 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18599 != PackageManager.PERMISSION_GRANTED) && ( 18600 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18601 != PackageManager.PERMISSION_GRANTED)) { 18602 String msg = "Permission Denial: getCurrentUser() from pid=" 18603 + Binder.getCallingPid() 18604 + ", uid=" + Binder.getCallingUid() 18605 + " requires " + INTERACT_ACROSS_USERS; 18606 Slog.w(TAG, msg); 18607 throw new SecurityException(msg); 18608 } 18609 synchronized (this) { 18610 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18611 return getUserManagerLocked().getUserInfo(userId); 18612 } 18613 } 18614 18615 int getCurrentUserIdLocked() { 18616 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18617 } 18618 18619 @Override 18620 public boolean isUserRunning(int userId, boolean orStopped) { 18621 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18622 != PackageManager.PERMISSION_GRANTED) { 18623 String msg = "Permission Denial: isUserRunning() from pid=" 18624 + Binder.getCallingPid() 18625 + ", uid=" + Binder.getCallingUid() 18626 + " requires " + INTERACT_ACROSS_USERS; 18627 Slog.w(TAG, msg); 18628 throw new SecurityException(msg); 18629 } 18630 synchronized (this) { 18631 return isUserRunningLocked(userId, orStopped); 18632 } 18633 } 18634 18635 boolean isUserRunningLocked(int userId, boolean orStopped) { 18636 UserStartedState state = mStartedUsers.get(userId); 18637 if (state == null) { 18638 return false; 18639 } 18640 if (orStopped) { 18641 return true; 18642 } 18643 return state.mState != UserStartedState.STATE_STOPPING 18644 && state.mState != UserStartedState.STATE_SHUTDOWN; 18645 } 18646 18647 @Override 18648 public int[] getRunningUserIds() { 18649 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18650 != PackageManager.PERMISSION_GRANTED) { 18651 String msg = "Permission Denial: isUserRunning() from pid=" 18652 + Binder.getCallingPid() 18653 + ", uid=" + Binder.getCallingUid() 18654 + " requires " + INTERACT_ACROSS_USERS; 18655 Slog.w(TAG, msg); 18656 throw new SecurityException(msg); 18657 } 18658 synchronized (this) { 18659 return mStartedUserArray; 18660 } 18661 } 18662 18663 private void updateStartedUserArrayLocked() { 18664 int num = 0; 18665 for (int i=0; i<mStartedUsers.size(); i++) { 18666 UserStartedState uss = mStartedUsers.valueAt(i); 18667 // This list does not include stopping users. 18668 if (uss.mState != UserStartedState.STATE_STOPPING 18669 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18670 num++; 18671 } 18672 } 18673 mStartedUserArray = new int[num]; 18674 num = 0; 18675 for (int i=0; i<mStartedUsers.size(); i++) { 18676 UserStartedState uss = mStartedUsers.valueAt(i); 18677 if (uss.mState != UserStartedState.STATE_STOPPING 18678 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18679 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18680 num++; 18681 } 18682 } 18683 } 18684 18685 @Override 18686 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18687 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18688 != PackageManager.PERMISSION_GRANTED) { 18689 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18690 + Binder.getCallingPid() 18691 + ", uid=" + Binder.getCallingUid() 18692 + " requires " + INTERACT_ACROSS_USERS_FULL; 18693 Slog.w(TAG, msg); 18694 throw new SecurityException(msg); 18695 } 18696 18697 mUserSwitchObservers.register(observer); 18698 } 18699 18700 @Override 18701 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18702 mUserSwitchObservers.unregister(observer); 18703 } 18704 18705 private boolean userExists(int userId) { 18706 if (userId == 0) { 18707 return true; 18708 } 18709 UserManagerService ums = getUserManagerLocked(); 18710 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18711 } 18712 18713 int[] getUsersLocked() { 18714 UserManagerService ums = getUserManagerLocked(); 18715 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18716 } 18717 18718 UserManagerService getUserManagerLocked() { 18719 if (mUserManager == null) { 18720 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18721 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18722 } 18723 return mUserManager; 18724 } 18725 18726 private int applyUserId(int uid, int userId) { 18727 return UserHandle.getUid(userId, uid); 18728 } 18729 18730 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18731 if (info == null) return null; 18732 ApplicationInfo newInfo = new ApplicationInfo(info); 18733 newInfo.uid = applyUserId(info.uid, userId); 18734 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18735 + info.packageName; 18736 return newInfo; 18737 } 18738 18739 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18740 if (aInfo == null 18741 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18742 return aInfo; 18743 } 18744 18745 ActivityInfo info = new ActivityInfo(aInfo); 18746 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18747 return info; 18748 } 18749 18750 private final class LocalService extends ActivityManagerInternal { 18751 @Override 18752 public void goingToSleep() { 18753 ActivityManagerService.this.goingToSleep(); 18754 } 18755 18756 @Override 18757 public void wakingUp() { 18758 ActivityManagerService.this.wakingUp(); 18759 } 18760 18761 @Override 18762 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18763 String processName, String abiOverride, int uid, Runnable crashHandler) { 18764 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18765 processName, abiOverride, uid, crashHandler); 18766 } 18767 } 18768 18769 /** 18770 * An implementation of IAppTask, that allows an app to manage its own tasks via 18771 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18772 * only the process that calls getAppTasks() can call the AppTask methods. 18773 */ 18774 class AppTaskImpl extends IAppTask.Stub { 18775 private int mTaskId; 18776 private int mCallingUid; 18777 18778 public AppTaskImpl(int taskId, int callingUid) { 18779 mTaskId = taskId; 18780 mCallingUid = callingUid; 18781 } 18782 18783 private void checkCaller() { 18784 if (mCallingUid != Binder.getCallingUid()) { 18785 throw new SecurityException("Caller " + mCallingUid 18786 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18787 } 18788 } 18789 18790 @Override 18791 public void finishAndRemoveTask() { 18792 checkCaller(); 18793 18794 synchronized (ActivityManagerService.this) { 18795 long origId = Binder.clearCallingIdentity(); 18796 try { 18797 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18798 if (tr == null) { 18799 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18800 } 18801 // Only kill the process if we are not a new document 18802 int flags = tr.getBaseIntent().getFlags(); 18803 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18804 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18805 removeTaskByIdLocked(mTaskId, 18806 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18807 } finally { 18808 Binder.restoreCallingIdentity(origId); 18809 } 18810 } 18811 } 18812 18813 @Override 18814 public ActivityManager.RecentTaskInfo getTaskInfo() { 18815 checkCaller(); 18816 18817 synchronized (ActivityManagerService.this) { 18818 long origId = Binder.clearCallingIdentity(); 18819 try { 18820 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18821 if (tr == null) { 18822 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18823 } 18824 return createRecentTaskInfoFromTaskRecord(tr); 18825 } finally { 18826 Binder.restoreCallingIdentity(origId); 18827 } 18828 } 18829 } 18830 18831 @Override 18832 public void moveToFront() { 18833 checkCaller(); 18834 18835 final TaskRecord tr; 18836 synchronized (ActivityManagerService.this) { 18837 tr = recentTaskForIdLocked(mTaskId); 18838 if (tr == null) { 18839 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18840 } 18841 if (tr.getRootActivity() != null) { 18842 long origId = Binder.clearCallingIdentity(); 18843 try { 18844 moveTaskToFrontLocked(tr.taskId, 0, null); 18845 return; 18846 } finally { 18847 Binder.restoreCallingIdentity(origId); 18848 } 18849 } 18850 } 18851 18852 startActivityFromRecentsInner(tr.taskId, null); 18853 } 18854 18855 @Override 18856 public int startActivity(IBinder whoThread, String callingPackage, 18857 Intent intent, String resolvedType, Bundle options) { 18858 checkCaller(); 18859 18860 int callingUser = UserHandle.getCallingUserId(); 18861 TaskRecord tr; 18862 IApplicationThread appThread; 18863 synchronized (ActivityManagerService.this) { 18864 tr = recentTaskForIdLocked(mTaskId); 18865 if (tr == null) { 18866 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18867 } 18868 appThread = ApplicationThreadNative.asInterface(whoThread); 18869 if (appThread == null) { 18870 throw new IllegalArgumentException("Bad app thread " + appThread); 18871 } 18872 } 18873 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18874 resolvedType, null, null, null, null, 0, 0, null, null, 18875 null, options, callingUser, null, tr); 18876 } 18877 18878 @Override 18879 public void setExcludeFromRecents(boolean exclude) { 18880 checkCaller(); 18881 18882 synchronized (ActivityManagerService.this) { 18883 long origId = Binder.clearCallingIdentity(); 18884 try { 18885 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18886 if (tr == null) { 18887 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18888 } 18889 Intent intent = tr.getBaseIntent(); 18890 if (exclude) { 18891 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18892 } else { 18893 intent.setFlags(intent.getFlags() 18894 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18895 } 18896 } finally { 18897 Binder.restoreCallingIdentity(origId); 18898 } 18899 } 18900 } 18901 } 18902} 18903