ActivityManagerService.java revision 192679a7d37d268854f4b17876c702625f9475eb
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199import dalvik.system.VMRuntime; 200 201import java.io.BufferedInputStream; 202import java.io.BufferedOutputStream; 203import java.io.DataInputStream; 204import java.io.DataOutputStream; 205import java.io.File; 206import java.io.FileDescriptor; 207import java.io.FileInputStream; 208import java.io.FileNotFoundException; 209import java.io.FileOutputStream; 210import java.io.IOException; 211import java.io.InputStreamReader; 212import java.io.PrintWriter; 213import java.io.StringWriter; 214import java.lang.ref.WeakReference; 215import java.util.ArrayList; 216import java.util.Arrays; 217import java.util.Collections; 218import java.util.Comparator; 219import java.util.HashMap; 220import java.util.HashSet; 221import java.util.Iterator; 222import java.util.List; 223import java.util.Locale; 224import java.util.Map; 225import java.util.Set; 226import java.util.concurrent.atomic.AtomicBoolean; 227import java.util.concurrent.atomic.AtomicLong; 228 229public final class ActivityManagerService extends ActivityManagerNative 230 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 231 232 private static final String USER_DATA_DIR = "/data/user/"; 233 // File that stores last updated system version and called preboot receivers 234 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 235 236 static final String TAG = "ActivityManager"; 237 static final String TAG_MU = "ActivityManagerServiceMU"; 238 static final boolean DEBUG = false; 239 static final boolean localLOGV = DEBUG; 240 static final boolean DEBUG_BACKUP = localLOGV || false; 241 static final boolean DEBUG_BROADCAST = localLOGV || false; 242 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_CLEANUP = localLOGV || false; 245 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 246 static final boolean DEBUG_FOCUS = false; 247 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 248 static final boolean DEBUG_MU = localLOGV || false; 249 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 250 static final boolean DEBUG_LRU = localLOGV || false; 251 static final boolean DEBUG_PAUSE = localLOGV || false; 252 static final boolean DEBUG_POWER = localLOGV || false; 253 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 254 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 255 static final boolean DEBUG_PROCESSES = localLOGV || false; 256 static final boolean DEBUG_PROVIDER = localLOGV || false; 257 static final boolean DEBUG_RESULTS = localLOGV || false; 258 static final boolean DEBUG_SERVICE = localLOGV || false; 259 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 260 static final boolean DEBUG_STACK = localLOGV || false; 261 static final boolean DEBUG_SWITCH = localLOGV || false; 262 static final boolean DEBUG_TASKS = localLOGV || false; 263 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 264 static final boolean DEBUG_TRANSITION = localLOGV || false; 265 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 266 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 267 static final boolean DEBUG_VISBILITY = localLOGV || false; 268 static final boolean DEBUG_PSS = localLOGV || false; 269 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 270 static final boolean DEBUG_RECENTS = localLOGV || false; 271 static final boolean VALIDATE_TOKENS = false; 272 static final boolean SHOW_ACTIVITY_START_TIME = true; 273 274 // Control over CPU and battery monitoring. 275 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 276 static final boolean MONITOR_CPU_USAGE = true; 277 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 278 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 279 static final boolean MONITOR_THREAD_CPU_USAGE = false; 280 281 // The flags that are set for all calls we make to the package manager. 282 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 283 284 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 285 286 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mWaitingUpdate = false; 892 boolean mDidUpdate = false; 893 boolean mOnBattery = false; 894 boolean mLaunchWarningShown = false; 895 896 Context mContext; 897 898 int mFactoryTest; 899 900 boolean mCheckedForSetup; 901 902 /** 903 * The time at which we will allow normal application switches again, 904 * after a call to {@link #stopAppSwitches()}. 905 */ 906 long mAppSwitchesAllowedTime; 907 908 /** 909 * This is set to true after the first switch after mAppSwitchesAllowedTime 910 * is set; any switches after that will clear the time. 911 */ 912 boolean mDidAppSwitch; 913 914 /** 915 * Last time (in realtime) at which we checked for power usage. 916 */ 917 long mLastPowerCheckRealtime; 918 919 /** 920 * Last time (in uptime) at which we checked for power usage. 921 */ 922 long mLastPowerCheckUptime; 923 924 /** 925 * Set while we are wanting to sleep, to prevent any 926 * activities from being started/resumed. 927 */ 928 private boolean mSleeping = false; 929 930 /** 931 * Set while we are running a voice interaction. This overrides 932 * sleeping while it is active. 933 */ 934 private boolean mRunningVoice = false; 935 936 /** 937 * State of external calls telling us if the device is asleep. 938 */ 939 private boolean mWentToSleep = false; 940 941 /** 942 * State of external call telling us if the lock screen is shown. 943 */ 944 private boolean mLockScreenShown = false; 945 946 /** 947 * Set if we are shutting down the system, similar to sleeping. 948 */ 949 boolean mShuttingDown = false; 950 951 /** 952 * Current sequence id for oom_adj computation traversal. 953 */ 954 int mAdjSeq = 0; 955 956 /** 957 * Current sequence id for process LRU updating. 958 */ 959 int mLruSeq = 0; 960 961 /** 962 * Keep track of the non-cached/empty process we last found, to help 963 * determine how to distribute cached/empty processes next time. 964 */ 965 int mNumNonCachedProcs = 0; 966 967 /** 968 * Keep track of the number of cached hidden procs, to balance oom adj 969 * distribution between those and empty procs. 970 */ 971 int mNumCachedHiddenProcs = 0; 972 973 /** 974 * Keep track of the number of service processes we last found, to 975 * determine on the next iteration which should be B services. 976 */ 977 int mNumServiceProcs = 0; 978 int mNewNumAServiceProcs = 0; 979 int mNewNumServiceProcs = 0; 980 981 /** 982 * Allow the current computed overall memory level of the system to go down? 983 * This is set to false when we are killing processes for reasons other than 984 * memory management, so that the now smaller process list will not be taken as 985 * an indication that memory is tighter. 986 */ 987 boolean mAllowLowerMemLevel = false; 988 989 /** 990 * The last computed memory level, for holding when we are in a state that 991 * processes are going away for other reasons. 992 */ 993 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 994 995 /** 996 * The last total number of process we have, to determine if changes actually look 997 * like a shrinking number of process due to lower RAM. 998 */ 999 int mLastNumProcesses; 1000 1001 /** 1002 * The uptime of the last time we performed idle maintenance. 1003 */ 1004 long mLastIdleTime = SystemClock.uptimeMillis(); 1005 1006 /** 1007 * Total time spent with RAM that has been added in the past since the last idle time. 1008 */ 1009 long mLowRamTimeSinceLastIdle = 0; 1010 1011 /** 1012 * If RAM is currently low, when that horrible situation started. 1013 */ 1014 long mLowRamStartTime = 0; 1015 1016 /** 1017 * For reporting to battery stats the current top application. 1018 */ 1019 private String mCurResumedPackage = null; 1020 private int mCurResumedUid = -1; 1021 1022 /** 1023 * For reporting to battery stats the apps currently running foreground 1024 * service. The ProcessMap is package/uid tuples; each of these contain 1025 * an array of the currently foreground processes. 1026 */ 1027 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1028 = new ProcessMap<ArrayList<ProcessRecord>>(); 1029 1030 /** 1031 * This is set if we had to do a delayed dexopt of an app before launching 1032 * it, to increase the ANR timeouts in that case. 1033 */ 1034 boolean mDidDexOpt; 1035 1036 /** 1037 * Set if the systemServer made a call to enterSafeMode. 1038 */ 1039 boolean mSafeMode; 1040 1041 String mDebugApp = null; 1042 boolean mWaitForDebugger = false; 1043 boolean mDebugTransient = false; 1044 String mOrigDebugApp = null; 1045 boolean mOrigWaitForDebugger = false; 1046 boolean mAlwaysFinishActivities = false; 1047 IActivityController mController = null; 1048 String mProfileApp = null; 1049 ProcessRecord mProfileProc = null; 1050 String mProfileFile; 1051 ParcelFileDescriptor mProfileFd; 1052 int mSamplingInterval = 0; 1053 boolean mAutoStopProfiler = false; 1054 int mProfileType = 0; 1055 String mOpenGlTraceApp = null; 1056 1057 static class ProcessChangeItem { 1058 static final int CHANGE_ACTIVITIES = 1<<0; 1059 static final int CHANGE_PROCESS_STATE = 1<<1; 1060 int changes; 1061 int uid; 1062 int pid; 1063 int processState; 1064 boolean foregroundActivities; 1065 } 1066 1067 final RemoteCallbackList<IProcessObserver> mProcessObservers 1068 = new RemoteCallbackList<IProcessObserver>(); 1069 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1070 1071 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1072 = new ArrayList<ProcessChangeItem>(); 1073 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1074 = new ArrayList<ProcessChangeItem>(); 1075 1076 /** 1077 * Runtime CPU use collection thread. This object's lock is used to 1078 * protect all related state. 1079 */ 1080 final Thread mProcessCpuThread; 1081 1082 /** 1083 * Used to collect process stats when showing not responding dialog. 1084 * Protected by mProcessCpuThread. 1085 */ 1086 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1087 MONITOR_THREAD_CPU_USAGE); 1088 final AtomicLong mLastCpuTime = new AtomicLong(0); 1089 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1090 1091 long mLastWriteTime = 0; 1092 1093 /** 1094 * Used to retain an update lock when the foreground activity is in 1095 * immersive mode. 1096 */ 1097 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1098 1099 /** 1100 * Set to true after the system has finished booting. 1101 */ 1102 boolean mBooted = false; 1103 1104 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1105 int mProcessLimitOverride = -1; 1106 1107 WindowManagerService mWindowManager; 1108 1109 final ActivityThread mSystemThread; 1110 1111 // Holds the current foreground user's id 1112 int mCurrentUserId = 0; 1113 // Holds the target user's id during a user switch 1114 int mTargetUserId = UserHandle.USER_NULL; 1115 // If there are multiple profiles for the current user, their ids are here 1116 // Currently only the primary user can have managed profiles 1117 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1118 1119 /** 1120 * Mapping from each known user ID to the profile group ID it is associated with. 1121 */ 1122 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1123 1124 private UserManagerService mUserManager; 1125 1126 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1127 final ProcessRecord mApp; 1128 final int mPid; 1129 final IApplicationThread mAppThread; 1130 1131 AppDeathRecipient(ProcessRecord app, int pid, 1132 IApplicationThread thread) { 1133 if (localLOGV) Slog.v( 1134 TAG, "New death recipient " + this 1135 + " for thread " + thread.asBinder()); 1136 mApp = app; 1137 mPid = pid; 1138 mAppThread = thread; 1139 } 1140 1141 @Override 1142 public void binderDied() { 1143 if (localLOGV) Slog.v( 1144 TAG, "Death received in " + this 1145 + " for thread " + mAppThread.asBinder()); 1146 synchronized(ActivityManagerService.this) { 1147 appDiedLocked(mApp, mPid, mAppThread); 1148 } 1149 } 1150 } 1151 1152 static final int SHOW_ERROR_MSG = 1; 1153 static final int SHOW_NOT_RESPONDING_MSG = 2; 1154 static final int SHOW_FACTORY_ERROR_MSG = 3; 1155 static final int UPDATE_CONFIGURATION_MSG = 4; 1156 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1157 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1158 static final int SERVICE_TIMEOUT_MSG = 12; 1159 static final int UPDATE_TIME_ZONE = 13; 1160 static final int SHOW_UID_ERROR_MSG = 14; 1161 static final int IM_FEELING_LUCKY_MSG = 15; 1162 static final int PROC_START_TIMEOUT_MSG = 20; 1163 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1164 static final int KILL_APPLICATION_MSG = 22; 1165 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1166 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1167 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1168 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1169 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1170 static final int CLEAR_DNS_CACHE_MSG = 28; 1171 static final int UPDATE_HTTP_PROXY_MSG = 29; 1172 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1173 static final int DISPATCH_PROCESSES_CHANGED = 31; 1174 static final int DISPATCH_PROCESS_DIED = 32; 1175 static final int REPORT_MEM_USAGE_MSG = 33; 1176 static final int REPORT_USER_SWITCH_MSG = 34; 1177 static final int CONTINUE_USER_SWITCH_MSG = 35; 1178 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1179 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1180 static final int PERSIST_URI_GRANTS_MSG = 38; 1181 static final int REQUEST_ALL_PSS_MSG = 39; 1182 static final int START_PROFILES_MSG = 40; 1183 static final int UPDATE_TIME = 41; 1184 static final int SYSTEM_USER_START_MSG = 42; 1185 static final int SYSTEM_USER_CURRENT_MSG = 43; 1186 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1187 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1188 static final int START_USER_SWITCH_MSG = 46; 1189 1190 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1191 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1192 static final int FIRST_COMPAT_MODE_MSG = 300; 1193 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1194 1195 AlertDialog mUidAlert; 1196 CompatModeDialog mCompatModeDialog; 1197 long mLastMemUsageReportTime = 0; 1198 1199 private LockToAppRequestDialog mLockToAppRequest; 1200 1201 /** 1202 * Flag whether the current user is a "monkey", i.e. whether 1203 * the UI is driven by a UI automation tool. 1204 */ 1205 private boolean mUserIsMonkey; 1206 1207 /** Flag whether the device has a Recents UI */ 1208 boolean mHasRecents; 1209 1210 /** The dimensions of the thumbnails in the Recents UI. */ 1211 int mThumbnailWidth; 1212 int mThumbnailHeight; 1213 1214 final ServiceThread mHandlerThread; 1215 final MainHandler mHandler; 1216 1217 final class MainHandler extends Handler { 1218 public MainHandler(Looper looper) { 1219 super(looper, null, true); 1220 } 1221 1222 @Override 1223 public void handleMessage(Message msg) { 1224 switch (msg.what) { 1225 case SHOW_ERROR_MSG: { 1226 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1227 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1228 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord)data.get("app"); 1231 AppErrorResult res = (AppErrorResult) data.get("result"); 1232 if (proc != null && proc.crashDialog != null) { 1233 Slog.e(TAG, "App already has crash dialog: " + proc); 1234 if (res != null) { 1235 res.set(0); 1236 } 1237 return; 1238 } 1239 boolean isBackground = (UserHandle.getAppId(proc.uid) 1240 >= Process.FIRST_APPLICATION_UID 1241 && proc.pid != MY_PID); 1242 for (int userId : mCurrentProfileIds) { 1243 isBackground &= (proc.userId != userId); 1244 } 1245 if (isBackground && !showBackground) { 1246 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1247 if (res != null) { 1248 res.set(0); 1249 } 1250 return; 1251 } 1252 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1253 Dialog d = new AppErrorDialog(mContext, 1254 ActivityManagerService.this, res, proc); 1255 d.show(); 1256 proc.crashDialog = d; 1257 } else { 1258 // The device is asleep, so just pretend that the user 1259 // saw a crash dialog and hit "force quit". 1260 if (res != null) { 1261 res.set(0); 1262 } 1263 } 1264 } 1265 1266 ensureBootCompleted(); 1267 } break; 1268 case SHOW_NOT_RESPONDING_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1271 ProcessRecord proc = (ProcessRecord)data.get("app"); 1272 if (proc != null && proc.anrDialog != null) { 1273 Slog.e(TAG, "App already has anr dialog: " + proc); 1274 return; 1275 } 1276 1277 Intent intent = new Intent("android.intent.action.ANR"); 1278 if (!mProcessesReady) { 1279 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1280 | Intent.FLAG_RECEIVER_FOREGROUND); 1281 } 1282 broadcastIntentLocked(null, null, intent, 1283 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1284 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1285 1286 if (mShowDialogs) { 1287 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1288 mContext, proc, (ActivityRecord)data.get("activity"), 1289 msg.arg1 != 0); 1290 d.show(); 1291 proc.anrDialog = d; 1292 } else { 1293 // Just kill the app if there is no dialog to be shown. 1294 killAppAtUsersRequest(proc, null); 1295 } 1296 } 1297 1298 ensureBootCompleted(); 1299 } break; 1300 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1301 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord proc = (ProcessRecord) data.get("app"); 1304 if (proc == null) { 1305 Slog.e(TAG, "App not found when showing strict mode dialog."); 1306 break; 1307 } 1308 if (proc.crashDialog != null) { 1309 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1310 return; 1311 } 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1314 Dialog d = new StrictModeViolationDialog(mContext, 1315 ActivityManagerService.this, res, proc); 1316 d.show(); 1317 proc.crashDialog = d; 1318 } else { 1319 // The device is asleep, so just pretend that the user 1320 // saw a crash dialog and hit "force quit". 1321 res.set(0); 1322 } 1323 } 1324 ensureBootCompleted(); 1325 } break; 1326 case SHOW_FACTORY_ERROR_MSG: { 1327 Dialog d = new FactoryErrorDialog( 1328 mContext, msg.getData().getCharSequence("msg")); 1329 d.show(); 1330 ensureBootCompleted(); 1331 } break; 1332 case UPDATE_CONFIGURATION_MSG: { 1333 final ContentResolver resolver = mContext.getContentResolver(); 1334 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1335 } break; 1336 case GC_BACKGROUND_PROCESSES_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 performAppGcsIfAppropriateLocked(); 1339 } 1340 } break; 1341 case WAIT_FOR_DEBUGGER_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 ProcessRecord app = (ProcessRecord)msg.obj; 1344 if (msg.arg1 != 0) { 1345 if (!app.waitedForDebugger) { 1346 Dialog d = new AppWaitingForDebuggerDialog( 1347 ActivityManagerService.this, 1348 mContext, app); 1349 app.waitDialog = d; 1350 app.waitedForDebugger = true; 1351 d.show(); 1352 } 1353 } else { 1354 if (app.waitDialog != null) { 1355 app.waitDialog.dismiss(); 1356 app.waitDialog = null; 1357 } 1358 } 1359 } 1360 } break; 1361 case SERVICE_TIMEOUT_MSG: { 1362 if (mDidDexOpt) { 1363 mDidDexOpt = false; 1364 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1365 nmsg.obj = msg.obj; 1366 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1367 return; 1368 } 1369 mServices.serviceTimeout((ProcessRecord)msg.obj); 1370 } break; 1371 case UPDATE_TIME_ZONE: { 1372 synchronized (ActivityManagerService.this) { 1373 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1374 ProcessRecord r = mLruProcesses.get(i); 1375 if (r.thread != null) { 1376 try { 1377 r.thread.updateTimeZone(); 1378 } catch (RemoteException ex) { 1379 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case CLEAR_DNS_CACHE_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1388 ProcessRecord r = mLruProcesses.get(i); 1389 if (r.thread != null) { 1390 try { 1391 r.thread.clearDnsCache(); 1392 } catch (RemoteException ex) { 1393 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1394 } 1395 } 1396 } 1397 } 1398 } break; 1399 case UPDATE_HTTP_PROXY_MSG: { 1400 ProxyInfo proxy = (ProxyInfo)msg.obj; 1401 String host = ""; 1402 String port = ""; 1403 String exclList = ""; 1404 Uri pacFileUrl = Uri.EMPTY; 1405 if (proxy != null) { 1406 host = proxy.getHost(); 1407 port = Integer.toString(proxy.getPort()); 1408 exclList = proxy.getExclusionListAsString(); 1409 pacFileUrl = proxy.getPacFileUrl(); 1410 } 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update http proxy for: " + 1419 r.info.processName); 1420 } 1421 } 1422 } 1423 } 1424 } break; 1425 case SHOW_UID_ERROR_MSG: { 1426 String title = "System UIDs Inconsistent"; 1427 String text = "UIDs on the system are inconsistent, you need to wipe your" 1428 + " data partition or your device will be unstable."; 1429 Log.e(TAG, title + ": " + text); 1430 if (mShowDialogs) { 1431 // XXX This is a temporary dialog, no need to localize. 1432 AlertDialog d = new BaseErrorDialog(mContext); 1433 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1434 d.setCancelable(false); 1435 d.setTitle(title); 1436 d.setMessage(text); 1437 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1438 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1439 mUidAlert = d; 1440 d.show(); 1441 } 1442 } break; 1443 case IM_FEELING_LUCKY_MSG: { 1444 if (mUidAlert != null) { 1445 mUidAlert.dismiss(); 1446 mUidAlert = null; 1447 } 1448 } break; 1449 case PROC_START_TIMEOUT_MSG: { 1450 if (mDidDexOpt) { 1451 mDidDexOpt = false; 1452 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1453 nmsg.obj = msg.obj; 1454 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1455 return; 1456 } 1457 ProcessRecord app = (ProcessRecord)msg.obj; 1458 synchronized (ActivityManagerService.this) { 1459 processStartTimedOutLocked(app); 1460 } 1461 } break; 1462 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1463 synchronized (ActivityManagerService.this) { 1464 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1465 } 1466 } break; 1467 case KILL_APPLICATION_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 int appid = msg.arg1; 1470 boolean restart = (msg.arg2 == 1); 1471 Bundle bundle = (Bundle)msg.obj; 1472 String pkg = bundle.getString("pkg"); 1473 String reason = bundle.getString("reason"); 1474 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1475 false, UserHandle.USER_ALL, reason); 1476 } 1477 } break; 1478 case FINALIZE_PENDING_INTENT_MSG: { 1479 ((PendingIntentRecord)msg.obj).completeFinalize(); 1480 } break; 1481 case POST_HEAVY_NOTIFICATION_MSG: { 1482 INotificationManager inm = NotificationManager.getService(); 1483 if (inm == null) { 1484 return; 1485 } 1486 1487 ActivityRecord root = (ActivityRecord)msg.obj; 1488 ProcessRecord process = root.app; 1489 if (process == null) { 1490 return; 1491 } 1492 1493 try { 1494 Context context = mContext.createPackageContext(process.info.packageName, 0); 1495 String text = mContext.getString(R.string.heavy_weight_notification, 1496 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1497 Notification notification = new Notification(); 1498 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1499 notification.when = 0; 1500 notification.flags = Notification.FLAG_ONGOING_EVENT; 1501 notification.tickerText = text; 1502 notification.defaults = 0; // please be quiet 1503 notification.sound = null; 1504 notification.vibrate = null; 1505 notification.color = mContext.getResources().getColor( 1506 com.android.internal.R.color.system_notification_accent_color); 1507 notification.setLatestEventInfo(context, text, 1508 mContext.getText(R.string.heavy_weight_notification_detail), 1509 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1510 PendingIntent.FLAG_CANCEL_CURRENT, null, 1511 new UserHandle(root.userId))); 1512 1513 try { 1514 int[] outId = new int[1]; 1515 inm.enqueueNotificationWithTag("android", "android", null, 1516 R.string.heavy_weight_notification, 1517 notification, outId, root.userId); 1518 } catch (RuntimeException e) { 1519 Slog.w(ActivityManagerService.TAG, 1520 "Error showing notification for heavy-weight app", e); 1521 } catch (RemoteException e) { 1522 } 1523 } catch (NameNotFoundException e) { 1524 Slog.w(TAG, "Unable to create context for heavy notification", e); 1525 } 1526 } break; 1527 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1528 INotificationManager inm = NotificationManager.getService(); 1529 if (inm == null) { 1530 return; 1531 } 1532 try { 1533 inm.cancelNotificationWithTag("android", null, 1534 R.string.heavy_weight_notification, msg.arg1); 1535 } catch (RuntimeException e) { 1536 Slog.w(ActivityManagerService.TAG, 1537 "Error canceling notification for service", e); 1538 } catch (RemoteException e) { 1539 } 1540 } break; 1541 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1542 synchronized (ActivityManagerService.this) { 1543 checkExcessivePowerUsageLocked(true); 1544 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1546 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1547 } 1548 } break; 1549 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1550 synchronized (ActivityManagerService.this) { 1551 ActivityRecord ar = (ActivityRecord)msg.obj; 1552 if (mCompatModeDialog != null) { 1553 if (mCompatModeDialog.mAppInfo.packageName.equals( 1554 ar.info.applicationInfo.packageName)) { 1555 return; 1556 } 1557 mCompatModeDialog.dismiss(); 1558 mCompatModeDialog = null; 1559 } 1560 if (ar != null && false) { 1561 if (mCompatModePackages.getPackageAskCompatModeLocked( 1562 ar.packageName)) { 1563 int mode = mCompatModePackages.computeCompatModeLocked( 1564 ar.info.applicationInfo); 1565 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1566 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1567 mCompatModeDialog = new CompatModeDialog( 1568 ActivityManagerService.this, mContext, 1569 ar.info.applicationInfo); 1570 mCompatModeDialog.show(); 1571 } 1572 } 1573 } 1574 } 1575 break; 1576 } 1577 case DISPATCH_PROCESSES_CHANGED: { 1578 dispatchProcessesChanged(); 1579 break; 1580 } 1581 case DISPATCH_PROCESS_DIED: { 1582 final int pid = msg.arg1; 1583 final int uid = msg.arg2; 1584 dispatchProcessDied(pid, uid); 1585 break; 1586 } 1587 case REPORT_MEM_USAGE_MSG: { 1588 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1589 Thread thread = new Thread() { 1590 @Override public void run() { 1591 final SparseArray<ProcessMemInfo> infoMap 1592 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 infoMap.put(mi.pid, mi); 1596 } 1597 updateCpuStatsNow(); 1598 synchronized (mProcessCpuThread) { 1599 final int N = mProcessCpuTracker.countStats(); 1600 for (int i=0; i<N; i++) { 1601 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1602 if (st.vsize > 0) { 1603 long pss = Debug.getPss(st.pid, null); 1604 if (pss > 0) { 1605 if (infoMap.indexOfKey(st.pid) < 0) { 1606 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1607 ProcessList.NATIVE_ADJ, -1, "native", null); 1608 mi.pss = pss; 1609 memInfos.add(mi); 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 long totalPss = 0; 1617 for (int i=0, N=memInfos.size(); i<N; i++) { 1618 ProcessMemInfo mi = memInfos.get(i); 1619 if (mi.pss == 0) { 1620 mi.pss = Debug.getPss(mi.pid, null); 1621 } 1622 totalPss += mi.pss; 1623 } 1624 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1625 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1626 if (lhs.oomAdj != rhs.oomAdj) { 1627 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1628 } 1629 if (lhs.pss != rhs.pss) { 1630 return lhs.pss < rhs.pss ? 1 : -1; 1631 } 1632 return 0; 1633 } 1634 }); 1635 1636 StringBuilder tag = new StringBuilder(128); 1637 StringBuilder stack = new StringBuilder(128); 1638 tag.append("Low on memory -- "); 1639 appendMemBucket(tag, totalPss, "total", false); 1640 appendMemBucket(stack, totalPss, "total", true); 1641 1642 StringBuilder logBuilder = new StringBuilder(1024); 1643 logBuilder.append("Low on memory:\n"); 1644 1645 boolean firstLine = true; 1646 int lastOomAdj = Integer.MIN_VALUE; 1647 for (int i=0, N=memInfos.size(); i<N; i++) { 1648 ProcessMemInfo mi = memInfos.get(i); 1649 1650 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1651 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1652 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1653 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1654 if (lastOomAdj != mi.oomAdj) { 1655 lastOomAdj = mi.oomAdj; 1656 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1657 tag.append(" / "); 1658 } 1659 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1660 if (firstLine) { 1661 stack.append(":"); 1662 firstLine = false; 1663 } 1664 stack.append("\n\t at "); 1665 } else { 1666 stack.append("$"); 1667 } 1668 } else { 1669 tag.append(" "); 1670 stack.append("$"); 1671 } 1672 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1673 appendMemBucket(tag, mi.pss, mi.name, false); 1674 } 1675 appendMemBucket(stack, mi.pss, mi.name, true); 1676 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1677 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1678 stack.append("("); 1679 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1680 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1681 stack.append(DUMP_MEM_OOM_LABEL[k]); 1682 stack.append(":"); 1683 stack.append(DUMP_MEM_OOM_ADJ[k]); 1684 } 1685 } 1686 stack.append(")"); 1687 } 1688 } 1689 1690 logBuilder.append(" "); 1691 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1692 logBuilder.append(' '); 1693 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1694 logBuilder.append(' '); 1695 ProcessList.appendRamKb(logBuilder, mi.pss); 1696 logBuilder.append(" kB: "); 1697 logBuilder.append(mi.name); 1698 logBuilder.append(" ("); 1699 logBuilder.append(mi.pid); 1700 logBuilder.append(") "); 1701 logBuilder.append(mi.adjType); 1702 logBuilder.append('\n'); 1703 if (mi.adjReason != null) { 1704 logBuilder.append(" "); 1705 logBuilder.append(mi.adjReason); 1706 logBuilder.append('\n'); 1707 } 1708 } 1709 1710 logBuilder.append(" "); 1711 ProcessList.appendRamKb(logBuilder, totalPss); 1712 logBuilder.append(" kB: TOTAL\n"); 1713 1714 long[] infos = new long[Debug.MEMINFO_COUNT]; 1715 Debug.getMemInfo(infos); 1716 logBuilder.append(" MemInfo: "); 1717 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1718 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1719 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1720 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1721 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1722 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1723 logBuilder.append(" ZRAM: "); 1724 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1725 logBuilder.append(" kB RAM, "); 1726 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1727 logBuilder.append(" kB swap total, "); 1728 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1729 logBuilder.append(" kB swap free\n"); 1730 } 1731 Slog.i(TAG, logBuilder.toString()); 1732 1733 StringBuilder dropBuilder = new StringBuilder(1024); 1734 /* 1735 StringWriter oomSw = new StringWriter(); 1736 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1737 StringWriter catSw = new StringWriter(); 1738 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1739 String[] emptyArgs = new String[] { }; 1740 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1741 oomPw.flush(); 1742 String oomString = oomSw.toString(); 1743 */ 1744 dropBuilder.append(stack); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append('\n'); 1747 dropBuilder.append(logBuilder); 1748 dropBuilder.append('\n'); 1749 /* 1750 dropBuilder.append(oomString); 1751 dropBuilder.append('\n'); 1752 */ 1753 StringWriter catSw = new StringWriter(); 1754 synchronized (ActivityManagerService.this) { 1755 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1756 String[] emptyArgs = new String[] { }; 1757 catPw.println(); 1758 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1759 catPw.println(); 1760 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1761 false, false, null); 1762 catPw.println(); 1763 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1764 catPw.flush(); 1765 } 1766 dropBuilder.append(catSw.toString()); 1767 addErrorToDropBox("lowmem", null, "system_server", null, 1768 null, tag.toString(), dropBuilder.toString(), null, null); 1769 //Slog.i(TAG, "Sent to dropbox:"); 1770 //Slog.i(TAG, dropBuilder.toString()); 1771 synchronized (ActivityManagerService.this) { 1772 long now = SystemClock.uptimeMillis(); 1773 if (mLastMemUsageReportTime < now) { 1774 mLastMemUsageReportTime = now; 1775 } 1776 } 1777 } 1778 }; 1779 thread.start(); 1780 break; 1781 } 1782 case START_USER_SWITCH_MSG: { 1783 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1784 break; 1785 } 1786 case REPORT_USER_SWITCH_MSG: { 1787 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1788 break; 1789 } 1790 case CONTINUE_USER_SWITCH_MSG: { 1791 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1792 break; 1793 } 1794 case USER_SWITCH_TIMEOUT_MSG: { 1795 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1796 break; 1797 } 1798 case IMMERSIVE_MODE_LOCK_MSG: { 1799 final boolean nextState = (msg.arg1 != 0); 1800 if (mUpdateLock.isHeld() != nextState) { 1801 if (DEBUG_IMMERSIVE) { 1802 final ActivityRecord r = (ActivityRecord) msg.obj; 1803 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1804 } 1805 if (nextState) { 1806 mUpdateLock.acquire(); 1807 } else { 1808 mUpdateLock.release(); 1809 } 1810 } 1811 break; 1812 } 1813 case PERSIST_URI_GRANTS_MSG: { 1814 writeGrantedUriPermissions(); 1815 break; 1816 } 1817 case REQUEST_ALL_PSS_MSG: { 1818 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1819 break; 1820 } 1821 case START_PROFILES_MSG: { 1822 synchronized (ActivityManagerService.this) { 1823 startProfilesLocked(); 1824 } 1825 break; 1826 } 1827 case UPDATE_TIME: { 1828 synchronized (ActivityManagerService.this) { 1829 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1830 ProcessRecord r = mLruProcesses.get(i); 1831 if (r.thread != null) { 1832 try { 1833 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1834 } catch (RemoteException ex) { 1835 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1836 } 1837 } 1838 } 1839 } 1840 break; 1841 } 1842 case SYSTEM_USER_START_MSG: { 1843 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1844 Integer.toString(msg.arg1), msg.arg1); 1845 mSystemServiceManager.startUser(msg.arg1); 1846 break; 1847 } 1848 case SYSTEM_USER_CURRENT_MSG: { 1849 mBatteryStatsService.noteEvent( 1850 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1851 Integer.toString(msg.arg2), msg.arg2); 1852 mBatteryStatsService.noteEvent( 1853 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1854 Integer.toString(msg.arg1), msg.arg1); 1855 mSystemServiceManager.switchUser(msg.arg1); 1856 mLockToAppRequest.clearPrompt(); 1857 break; 1858 } 1859 case ENTER_ANIMATION_COMPLETE_MSG: { 1860 synchronized (ActivityManagerService.this) { 1861 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1862 if (r != null && r.app != null && r.app.thread != null) { 1863 try { 1864 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1865 } catch (RemoteException e) { 1866 } 1867 } 1868 } 1869 break; 1870 } 1871 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1872 enableScreenAfterBoot(); 1873 break; 1874 } 1875 } 1876 } 1877 }; 1878 1879 static final int COLLECT_PSS_BG_MSG = 1; 1880 1881 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1882 @Override 1883 public void handleMessage(Message msg) { 1884 switch (msg.what) { 1885 case COLLECT_PSS_BG_MSG: { 1886 long start = SystemClock.uptimeMillis(); 1887 MemInfoReader memInfo = null; 1888 synchronized (ActivityManagerService.this) { 1889 if (mFullPssPending) { 1890 mFullPssPending = false; 1891 memInfo = new MemInfoReader(); 1892 } 1893 } 1894 if (memInfo != null) { 1895 updateCpuStatsNow(); 1896 long nativeTotalPss = 0; 1897 synchronized (mProcessCpuThread) { 1898 final int N = mProcessCpuTracker.countStats(); 1899 for (int j=0; j<N; j++) { 1900 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1901 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1902 // This is definitely an application process; skip it. 1903 continue; 1904 } 1905 synchronized (mPidsSelfLocked) { 1906 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1907 // This is one of our own processes; skip it. 1908 continue; 1909 } 1910 } 1911 nativeTotalPss += Debug.getPss(st.pid, null); 1912 } 1913 } 1914 memInfo.readMemInfo(); 1915 synchronized (this) { 1916 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1917 + (SystemClock.uptimeMillis()-start) + "ms"); 1918 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1919 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1920 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1921 +memInfo.getSlabSizeKb(), 1922 nativeTotalPss); 1923 } 1924 } 1925 1926 int i=0, num=0; 1927 long[] tmp = new long[1]; 1928 do { 1929 ProcessRecord proc; 1930 int procState; 1931 int pid; 1932 synchronized (ActivityManagerService.this) { 1933 if (i >= mPendingPssProcesses.size()) { 1934 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1935 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1936 mPendingPssProcesses.clear(); 1937 return; 1938 } 1939 proc = mPendingPssProcesses.get(i); 1940 procState = proc.pssProcState; 1941 if (proc.thread != null && procState == proc.setProcState) { 1942 pid = proc.pid; 1943 } else { 1944 proc = null; 1945 pid = 0; 1946 } 1947 i++; 1948 } 1949 if (proc != null) { 1950 long pss = Debug.getPss(pid, tmp); 1951 synchronized (ActivityManagerService.this) { 1952 if (proc.thread != null && proc.setProcState == procState 1953 && proc.pid == pid) { 1954 num++; 1955 proc.lastPssTime = SystemClock.uptimeMillis(); 1956 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1957 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1958 + ": " + pss + " lastPss=" + proc.lastPss 1959 + " state=" + ProcessList.makeProcStateString(procState)); 1960 if (proc.initialIdlePss == 0) { 1961 proc.initialIdlePss = pss; 1962 } 1963 proc.lastPss = pss; 1964 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1965 proc.lastCachedPss = pss; 1966 } 1967 } 1968 } 1969 } 1970 } while (true); 1971 } 1972 } 1973 } 1974 }; 1975 1976 /** 1977 * Monitor for package changes and update our internal state. 1978 */ 1979 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1980 @Override 1981 public void onPackageRemoved(String packageName, int uid) { 1982 // Remove all tasks with activities in the specified package from the list of recent tasks 1983 synchronized (ActivityManagerService.this) { 1984 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1985 TaskRecord tr = mRecentTasks.get(i); 1986 ComponentName cn = tr.intent.getComponent(); 1987 if (cn != null && cn.getPackageName().equals(packageName)) { 1988 // If the package name matches, remove the task and kill the process 1989 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1990 } 1991 } 1992 } 1993 } 1994 1995 @Override 1996 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1997 onPackageModified(packageName); 1998 return true; 1999 } 2000 2001 @Override 2002 public void onPackageModified(String packageName) { 2003 final PackageManager pm = mContext.getPackageManager(); 2004 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2005 new ArrayList<Pair<Intent, Integer>>(); 2006 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2007 // Copy the list of recent tasks so that we don't hold onto the lock on 2008 // ActivityManagerService for long periods while checking if components exist. 2009 synchronized (ActivityManagerService.this) { 2010 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2011 TaskRecord tr = mRecentTasks.get(i); 2012 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2013 } 2014 } 2015 // Check the recent tasks and filter out all tasks with components that no longer exist. 2016 Intent tmpI = new Intent(); 2017 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2018 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2019 ComponentName cn = p.first.getComponent(); 2020 if (cn != null && cn.getPackageName().equals(packageName)) { 2021 try { 2022 // Add the task to the list to remove if the component no longer exists 2023 tmpI.setComponent(cn); 2024 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2025 tasksToRemove.add(p.second); 2026 } 2027 } catch (Exception e) {} 2028 } 2029 } 2030 // Prune all the tasks with removed components from the list of recent tasks 2031 synchronized (ActivityManagerService.this) { 2032 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2033 // Remove the task but don't kill the process (since other components in that 2034 // package may still be running and in the background) 2035 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2036 } 2037 } 2038 } 2039 2040 @Override 2041 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2042 // Force stop the specified packages 2043 if (packages != null) { 2044 for (String pkg : packages) { 2045 synchronized (ActivityManagerService.this) { 2046 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2047 "finished booting")) { 2048 return true; 2049 } 2050 } 2051 } 2052 } 2053 return false; 2054 } 2055 }; 2056 2057 public void setSystemProcess() { 2058 try { 2059 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2060 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2061 ServiceManager.addService("meminfo", new MemBinder(this)); 2062 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2063 ServiceManager.addService("dbinfo", new DbBinder(this)); 2064 if (MONITOR_CPU_USAGE) { 2065 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2066 } 2067 ServiceManager.addService("permission", new PermissionController(this)); 2068 2069 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2070 "android", STOCK_PM_FLAGS); 2071 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2072 2073 synchronized (this) { 2074 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2075 app.persistent = true; 2076 app.pid = MY_PID; 2077 app.maxAdj = ProcessList.SYSTEM_ADJ; 2078 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2079 mProcessNames.put(app.processName, app.uid, app); 2080 synchronized (mPidsSelfLocked) { 2081 mPidsSelfLocked.put(app.pid, app); 2082 } 2083 updateLruProcessLocked(app, false, null); 2084 updateOomAdjLocked(); 2085 } 2086 } catch (PackageManager.NameNotFoundException e) { 2087 throw new RuntimeException( 2088 "Unable to find android system package", e); 2089 } 2090 } 2091 2092 public void setWindowManager(WindowManagerService wm) { 2093 mWindowManager = wm; 2094 mStackSupervisor.setWindowManager(wm); 2095 } 2096 2097 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2098 mUsageStatsService = usageStatsManager; 2099 } 2100 2101 public void startObservingNativeCrashes() { 2102 final NativeCrashListener ncl = new NativeCrashListener(this); 2103 ncl.start(); 2104 } 2105 2106 public IAppOpsService getAppOpsService() { 2107 return mAppOpsService; 2108 } 2109 2110 static class MemBinder extends Binder { 2111 ActivityManagerService mActivityManagerService; 2112 MemBinder(ActivityManagerService activityManagerService) { 2113 mActivityManagerService = activityManagerService; 2114 } 2115 2116 @Override 2117 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2118 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2119 != PackageManager.PERMISSION_GRANTED) { 2120 pw.println("Permission Denial: can't dump meminfo from from pid=" 2121 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2122 + " without permission " + android.Manifest.permission.DUMP); 2123 return; 2124 } 2125 2126 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2127 } 2128 } 2129 2130 static class GraphicsBinder extends Binder { 2131 ActivityManagerService mActivityManagerService; 2132 GraphicsBinder(ActivityManagerService activityManagerService) { 2133 mActivityManagerService = activityManagerService; 2134 } 2135 2136 @Override 2137 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2138 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2139 != PackageManager.PERMISSION_GRANTED) { 2140 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2141 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2142 + " without permission " + android.Manifest.permission.DUMP); 2143 return; 2144 } 2145 2146 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2147 } 2148 } 2149 2150 static class DbBinder extends Binder { 2151 ActivityManagerService mActivityManagerService; 2152 DbBinder(ActivityManagerService activityManagerService) { 2153 mActivityManagerService = activityManagerService; 2154 } 2155 2156 @Override 2157 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2158 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2159 != PackageManager.PERMISSION_GRANTED) { 2160 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2161 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2162 + " without permission " + android.Manifest.permission.DUMP); 2163 return; 2164 } 2165 2166 mActivityManagerService.dumpDbInfo(fd, pw, args); 2167 } 2168 } 2169 2170 static class CpuBinder extends Binder { 2171 ActivityManagerService mActivityManagerService; 2172 CpuBinder(ActivityManagerService activityManagerService) { 2173 mActivityManagerService = activityManagerService; 2174 } 2175 2176 @Override 2177 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2178 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2179 != PackageManager.PERMISSION_GRANTED) { 2180 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2181 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2182 + " without permission " + android.Manifest.permission.DUMP); 2183 return; 2184 } 2185 2186 synchronized (mActivityManagerService.mProcessCpuThread) { 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2188 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2189 SystemClock.uptimeMillis())); 2190 } 2191 } 2192 } 2193 2194 public static final class Lifecycle extends SystemService { 2195 private final ActivityManagerService mService; 2196 2197 public Lifecycle(Context context) { 2198 super(context); 2199 mService = new ActivityManagerService(context); 2200 } 2201 2202 @Override 2203 public void onStart() { 2204 mService.start(); 2205 } 2206 2207 public ActivityManagerService getService() { 2208 return mService; 2209 } 2210 } 2211 2212 // Note: This method is invoked on the main thread but may need to attach various 2213 // handlers to other threads. So take care to be explicit about the looper. 2214 public ActivityManagerService(Context systemContext) { 2215 mContext = systemContext; 2216 mFactoryTest = FactoryTest.getMode(); 2217 mSystemThread = ActivityThread.currentActivityThread(); 2218 2219 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2220 2221 mHandlerThread = new ServiceThread(TAG, 2222 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2223 mHandlerThread.start(); 2224 mHandler = new MainHandler(mHandlerThread.getLooper()); 2225 2226 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2227 "foreground", BROADCAST_FG_TIMEOUT, false); 2228 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2229 "background", BROADCAST_BG_TIMEOUT, true); 2230 mBroadcastQueues[0] = mFgBroadcastQueue; 2231 mBroadcastQueues[1] = mBgBroadcastQueue; 2232 2233 mServices = new ActiveServices(this); 2234 mProviderMap = new ProviderMap(this); 2235 2236 // TODO: Move creation of battery stats service outside of activity manager service. 2237 File dataDir = Environment.getDataDirectory(); 2238 File systemDir = new File(dataDir, "system"); 2239 systemDir.mkdirs(); 2240 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2241 mBatteryStatsService.getActiveStatistics().readLocked(); 2242 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2243 mOnBattery = DEBUG_POWER ? true 2244 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2245 mBatteryStatsService.getActiveStatistics().setCallback(this); 2246 2247 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2248 2249 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2250 2251 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2252 2253 // User 0 is the first and only user that runs at boot. 2254 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2255 mUserLru.add(Integer.valueOf(0)); 2256 updateStartedUserArrayLocked(); 2257 2258 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2259 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2260 2261 mConfiguration.setToDefaults(); 2262 mConfiguration.setLocale(Locale.getDefault()); 2263 2264 mConfigurationSeq = mConfiguration.seq = 1; 2265 mProcessCpuTracker.init(); 2266 2267 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2268 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2269 mStackSupervisor = new ActivityStackSupervisor(this); 2270 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2271 2272 mProcessCpuThread = new Thread("CpuTracker") { 2273 @Override 2274 public void run() { 2275 while (true) { 2276 try { 2277 try { 2278 synchronized(this) { 2279 final long now = SystemClock.uptimeMillis(); 2280 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2281 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2282 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2283 // + ", write delay=" + nextWriteDelay); 2284 if (nextWriteDelay < nextCpuDelay) { 2285 nextCpuDelay = nextWriteDelay; 2286 } 2287 if (nextCpuDelay > 0) { 2288 mProcessCpuMutexFree.set(true); 2289 this.wait(nextCpuDelay); 2290 } 2291 } 2292 } catch (InterruptedException e) { 2293 } 2294 updateCpuStatsNow(); 2295 } catch (Exception e) { 2296 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2297 } 2298 } 2299 } 2300 }; 2301 2302 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2303 2304 Watchdog.getInstance().addMonitor(this); 2305 Watchdog.getInstance().addThread(mHandler); 2306 } 2307 2308 public void setSystemServiceManager(SystemServiceManager mgr) { 2309 mSystemServiceManager = mgr; 2310 } 2311 2312 private void start() { 2313 Process.removeAllProcessGroups(); 2314 mProcessCpuThread.start(); 2315 2316 mBatteryStatsService.publish(mContext); 2317 mAppOpsService.publish(mContext); 2318 Slog.d("AppOps", "AppOpsService published"); 2319 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2320 } 2321 2322 public void initPowerManagement() { 2323 mStackSupervisor.initPowerManagement(); 2324 mBatteryStatsService.initPowerManagement(); 2325 } 2326 2327 @Override 2328 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2329 throws RemoteException { 2330 if (code == SYSPROPS_TRANSACTION) { 2331 // We need to tell all apps about the system property change. 2332 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2333 synchronized(this) { 2334 final int NP = mProcessNames.getMap().size(); 2335 for (int ip=0; ip<NP; ip++) { 2336 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2337 final int NA = apps.size(); 2338 for (int ia=0; ia<NA; ia++) { 2339 ProcessRecord app = apps.valueAt(ia); 2340 if (app.thread != null) { 2341 procs.add(app.thread.asBinder()); 2342 } 2343 } 2344 } 2345 } 2346 2347 int N = procs.size(); 2348 for (int i=0; i<N; i++) { 2349 Parcel data2 = Parcel.obtain(); 2350 try { 2351 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2352 } catch (RemoteException e) { 2353 } 2354 data2.recycle(); 2355 } 2356 } 2357 try { 2358 return super.onTransact(code, data, reply, flags); 2359 } catch (RuntimeException e) { 2360 // The activity manager only throws security exceptions, so let's 2361 // log all others. 2362 if (!(e instanceof SecurityException)) { 2363 Slog.wtf(TAG, "Activity Manager Crash", e); 2364 } 2365 throw e; 2366 } 2367 } 2368 2369 void updateCpuStats() { 2370 final long now = SystemClock.uptimeMillis(); 2371 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2372 return; 2373 } 2374 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2375 synchronized (mProcessCpuThread) { 2376 mProcessCpuThread.notify(); 2377 } 2378 } 2379 } 2380 2381 void updateCpuStatsNow() { 2382 synchronized (mProcessCpuThread) { 2383 mProcessCpuMutexFree.set(false); 2384 final long now = SystemClock.uptimeMillis(); 2385 boolean haveNewCpuStats = false; 2386 2387 if (MONITOR_CPU_USAGE && 2388 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2389 mLastCpuTime.set(now); 2390 haveNewCpuStats = true; 2391 mProcessCpuTracker.update(); 2392 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2393 //Slog.i(TAG, "Total CPU usage: " 2394 // + mProcessCpu.getTotalCpuPercent() + "%"); 2395 2396 // Slog the cpu usage if the property is set. 2397 if ("true".equals(SystemProperties.get("events.cpu"))) { 2398 int user = mProcessCpuTracker.getLastUserTime(); 2399 int system = mProcessCpuTracker.getLastSystemTime(); 2400 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2401 int irq = mProcessCpuTracker.getLastIrqTime(); 2402 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2403 int idle = mProcessCpuTracker.getLastIdleTime(); 2404 2405 int total = user + system + iowait + irq + softIrq + idle; 2406 if (total == 0) total = 1; 2407 2408 EventLog.writeEvent(EventLogTags.CPU, 2409 ((user+system+iowait+irq+softIrq) * 100) / total, 2410 (user * 100) / total, 2411 (system * 100) / total, 2412 (iowait * 100) / total, 2413 (irq * 100) / total, 2414 (softIrq * 100) / total); 2415 } 2416 } 2417 2418 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2419 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2420 synchronized(bstats) { 2421 synchronized(mPidsSelfLocked) { 2422 if (haveNewCpuStats) { 2423 if (mOnBattery) { 2424 int perc = bstats.startAddingCpuLocked(); 2425 int totalUTime = 0; 2426 int totalSTime = 0; 2427 final int N = mProcessCpuTracker.countStats(); 2428 for (int i=0; i<N; i++) { 2429 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2430 if (!st.working) { 2431 continue; 2432 } 2433 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2434 int otherUTime = (st.rel_utime*perc)/100; 2435 int otherSTime = (st.rel_stime*perc)/100; 2436 totalUTime += otherUTime; 2437 totalSTime += otherSTime; 2438 if (pr != null) { 2439 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2440 if (ps == null || !ps.isActive()) { 2441 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2442 pr.info.uid, pr.processName); 2443 } 2444 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2445 st.rel_stime-otherSTime); 2446 ps.addSpeedStepTimes(cpuSpeedTimes); 2447 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2448 } else { 2449 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2450 if (ps == null || !ps.isActive()) { 2451 st.batteryStats = ps = bstats.getProcessStatsLocked( 2452 bstats.mapUid(st.uid), st.name); 2453 } 2454 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2455 st.rel_stime-otherSTime); 2456 ps.addSpeedStepTimes(cpuSpeedTimes); 2457 } 2458 } 2459 bstats.finishAddingCpuLocked(perc, totalUTime, 2460 totalSTime, cpuSpeedTimes); 2461 } 2462 } 2463 } 2464 2465 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2466 mLastWriteTime = now; 2467 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2468 } 2469 } 2470 } 2471 } 2472 2473 @Override 2474 public void batteryNeedsCpuUpdate() { 2475 updateCpuStatsNow(); 2476 } 2477 2478 @Override 2479 public void batteryPowerChanged(boolean onBattery) { 2480 // When plugging in, update the CPU stats first before changing 2481 // the plug state. 2482 updateCpuStatsNow(); 2483 synchronized (this) { 2484 synchronized(mPidsSelfLocked) { 2485 mOnBattery = DEBUG_POWER ? true : onBattery; 2486 } 2487 } 2488 } 2489 2490 /** 2491 * Initialize the application bind args. These are passed to each 2492 * process when the bindApplication() IPC is sent to the process. They're 2493 * lazily setup to make sure the services are running when they're asked for. 2494 */ 2495 private HashMap<String, IBinder> getCommonServicesLocked() { 2496 if (mAppBindArgs == null) { 2497 mAppBindArgs = new HashMap<String, IBinder>(); 2498 2499 // Setup the application init args 2500 mAppBindArgs.put("package", ServiceManager.getService("package")); 2501 mAppBindArgs.put("window", ServiceManager.getService("window")); 2502 mAppBindArgs.put(Context.ALARM_SERVICE, 2503 ServiceManager.getService(Context.ALARM_SERVICE)); 2504 } 2505 return mAppBindArgs; 2506 } 2507 2508 final void setFocusedActivityLocked(ActivityRecord r) { 2509 if (mFocusedActivity != r) { 2510 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2511 mFocusedActivity = r; 2512 if (r.task != null && r.task.voiceInteractor != null) { 2513 startRunningVoiceLocked(); 2514 } else { 2515 finishRunningVoiceLocked(); 2516 } 2517 mStackSupervisor.setFocusedStack(r); 2518 if (r != null) { 2519 mWindowManager.setFocusedApp(r.appToken, true); 2520 } 2521 applyUpdateLockStateLocked(r); 2522 } 2523 } 2524 2525 final void clearFocusedActivity(ActivityRecord r) { 2526 if (mFocusedActivity == r) { 2527 mFocusedActivity = null; 2528 } 2529 } 2530 2531 @Override 2532 public void setFocusedStack(int stackId) { 2533 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2534 synchronized (ActivityManagerService.this) { 2535 ActivityStack stack = mStackSupervisor.getStack(stackId); 2536 if (stack != null) { 2537 ActivityRecord r = stack.topRunningActivityLocked(null); 2538 if (r != null) { 2539 setFocusedActivityLocked(r); 2540 } 2541 } 2542 } 2543 } 2544 2545 @Override 2546 public void notifyActivityDrawn(IBinder token) { 2547 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2548 synchronized (this) { 2549 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2550 if (r != null) { 2551 r.task.stack.notifyActivityDrawnLocked(r); 2552 } 2553 } 2554 } 2555 2556 final void applyUpdateLockStateLocked(ActivityRecord r) { 2557 // Modifications to the UpdateLock state are done on our handler, outside 2558 // the activity manager's locks. The new state is determined based on the 2559 // state *now* of the relevant activity record. The object is passed to 2560 // the handler solely for logging detail, not to be consulted/modified. 2561 final boolean nextState = r != null && r.immersive; 2562 mHandler.sendMessage( 2563 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2564 } 2565 2566 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2567 Message msg = Message.obtain(); 2568 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2569 msg.obj = r.task.askedCompatMode ? null : r; 2570 mHandler.sendMessage(msg); 2571 } 2572 2573 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2574 String what, Object obj, ProcessRecord srcApp) { 2575 app.lastActivityTime = now; 2576 2577 if (app.activities.size() > 0) { 2578 // Don't want to touch dependent processes that are hosting activities. 2579 return index; 2580 } 2581 2582 int lrui = mLruProcesses.lastIndexOf(app); 2583 if (lrui < 0) { 2584 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2585 + what + " " + obj + " from " + srcApp); 2586 return index; 2587 } 2588 2589 if (lrui >= index) { 2590 // Don't want to cause this to move dependent processes *back* in the 2591 // list as if they were less frequently used. 2592 return index; 2593 } 2594 2595 if (lrui >= mLruProcessActivityStart) { 2596 // Don't want to touch dependent processes that are hosting activities. 2597 return index; 2598 } 2599 2600 mLruProcesses.remove(lrui); 2601 if (index > 0) { 2602 index--; 2603 } 2604 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2605 + " in LRU list: " + app); 2606 mLruProcesses.add(index, app); 2607 return index; 2608 } 2609 2610 final void removeLruProcessLocked(ProcessRecord app) { 2611 int lrui = mLruProcesses.lastIndexOf(app); 2612 if (lrui >= 0) { 2613 if (lrui <= mLruProcessActivityStart) { 2614 mLruProcessActivityStart--; 2615 } 2616 if (lrui <= mLruProcessServiceStart) { 2617 mLruProcessServiceStart--; 2618 } 2619 mLruProcesses.remove(lrui); 2620 } 2621 } 2622 2623 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2624 ProcessRecord client) { 2625 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2626 || app.treatLikeActivity; 2627 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2628 if (!activityChange && hasActivity) { 2629 // The process has activities, so we are only allowing activity-based adjustments 2630 // to move it. It should be kept in the front of the list with other 2631 // processes that have activities, and we don't want those to change their 2632 // order except due to activity operations. 2633 return; 2634 } 2635 2636 mLruSeq++; 2637 final long now = SystemClock.uptimeMillis(); 2638 app.lastActivityTime = now; 2639 2640 // First a quick reject: if the app is already at the position we will 2641 // put it, then there is nothing to do. 2642 if (hasActivity) { 2643 final int N = mLruProcesses.size(); 2644 if (N > 0 && mLruProcesses.get(N-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2646 return; 2647 } 2648 } else { 2649 if (mLruProcessServiceStart > 0 2650 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2651 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2652 return; 2653 } 2654 } 2655 2656 int lrui = mLruProcesses.lastIndexOf(app); 2657 2658 if (app.persistent && lrui >= 0) { 2659 // We don't care about the position of persistent processes, as long as 2660 // they are in the list. 2661 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2662 return; 2663 } 2664 2665 /* In progress: compute new position first, so we can avoid doing work 2666 if the process is not actually going to move. Not yet working. 2667 int addIndex; 2668 int nextIndex; 2669 boolean inActivity = false, inService = false; 2670 if (hasActivity) { 2671 // Process has activities, put it at the very tipsy-top. 2672 addIndex = mLruProcesses.size(); 2673 nextIndex = mLruProcessServiceStart; 2674 inActivity = true; 2675 } else if (hasService) { 2676 // Process has services, put it at the top of the service list. 2677 addIndex = mLruProcessActivityStart; 2678 nextIndex = mLruProcessServiceStart; 2679 inActivity = true; 2680 inService = true; 2681 } else { 2682 // Process not otherwise of interest, it goes to the top of the non-service area. 2683 addIndex = mLruProcessServiceStart; 2684 if (client != null) { 2685 int clientIndex = mLruProcesses.lastIndexOf(client); 2686 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2687 + app); 2688 if (clientIndex >= 0 && addIndex > clientIndex) { 2689 addIndex = clientIndex; 2690 } 2691 } 2692 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2693 } 2694 2695 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2696 + mLruProcessActivityStart + "): " + app); 2697 */ 2698 2699 if (lrui >= 0) { 2700 if (lrui < mLruProcessActivityStart) { 2701 mLruProcessActivityStart--; 2702 } 2703 if (lrui < mLruProcessServiceStart) { 2704 mLruProcessServiceStart--; 2705 } 2706 /* 2707 if (addIndex > lrui) { 2708 addIndex--; 2709 } 2710 if (nextIndex > lrui) { 2711 nextIndex--; 2712 } 2713 */ 2714 mLruProcesses.remove(lrui); 2715 } 2716 2717 /* 2718 mLruProcesses.add(addIndex, app); 2719 if (inActivity) { 2720 mLruProcessActivityStart++; 2721 } 2722 if (inService) { 2723 mLruProcessActivityStart++; 2724 } 2725 */ 2726 2727 int nextIndex; 2728 if (hasActivity) { 2729 final int N = mLruProcesses.size(); 2730 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2731 // Process doesn't have activities, but has clients with 2732 // activities... move it up, but one below the top (the top 2733 // should always have a real activity). 2734 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2735 mLruProcesses.add(N-1, app); 2736 // To keep it from spamming the LRU list (by making a bunch of clients), 2737 // we will push down any other entries owned by the app. 2738 final int uid = app.info.uid; 2739 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2740 ProcessRecord subProc = mLruProcesses.get(i); 2741 if (subProc.info.uid == uid) { 2742 // We want to push this one down the list. If the process after 2743 // it is for the same uid, however, don't do so, because we don't 2744 // want them internally to be re-ordered. 2745 if (mLruProcesses.get(i-1).info.uid != uid) { 2746 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2747 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2748 ProcessRecord tmp = mLruProcesses.get(i); 2749 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2750 mLruProcesses.set(i-1, tmp); 2751 i--; 2752 } 2753 } else { 2754 // A gap, we can stop here. 2755 break; 2756 } 2757 } 2758 } else { 2759 // Process has activities, put it at the very tipsy-top. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2761 mLruProcesses.add(app); 2762 } 2763 nextIndex = mLruProcessServiceStart; 2764 } else if (hasService) { 2765 // Process has services, put it at the top of the service list. 2766 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2767 mLruProcesses.add(mLruProcessActivityStart, app); 2768 nextIndex = mLruProcessServiceStart; 2769 mLruProcessActivityStart++; 2770 } else { 2771 // Process not otherwise of interest, it goes to the top of the non-service area. 2772 int index = mLruProcessServiceStart; 2773 if (client != null) { 2774 // If there is a client, don't allow the process to be moved up higher 2775 // in the list than that client. 2776 int clientIndex = mLruProcesses.lastIndexOf(client); 2777 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2778 + " when updating " + app); 2779 if (clientIndex <= lrui) { 2780 // Don't allow the client index restriction to push it down farther in the 2781 // list than it already is. 2782 clientIndex = lrui; 2783 } 2784 if (clientIndex >= 0 && index > clientIndex) { 2785 index = clientIndex; 2786 } 2787 } 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2789 mLruProcesses.add(index, app); 2790 nextIndex = index-1; 2791 mLruProcessActivityStart++; 2792 mLruProcessServiceStart++; 2793 } 2794 2795 // If the app is currently using a content provider or service, 2796 // bump those processes as well. 2797 for (int j=app.connections.size()-1; j>=0; j--) { 2798 ConnectionRecord cr = app.connections.valueAt(j); 2799 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2800 && cr.binding.service.app != null 2801 && cr.binding.service.app.lruSeq != mLruSeq 2802 && !cr.binding.service.app.persistent) { 2803 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2804 "service connection", cr, app); 2805 } 2806 } 2807 for (int j=app.conProviders.size()-1; j>=0; j--) { 2808 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2809 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2810 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2811 "provider reference", cpr, app); 2812 } 2813 } 2814 } 2815 2816 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2817 if (uid == Process.SYSTEM_UID) { 2818 // The system gets to run in any process. If there are multiple 2819 // processes with the same uid, just pick the first (this 2820 // should never happen). 2821 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2822 if (procs == null) return null; 2823 final int N = procs.size(); 2824 for (int i = 0; i < N; i++) { 2825 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2826 } 2827 } 2828 ProcessRecord proc = mProcessNames.get(processName, uid); 2829 if (false && proc != null && !keepIfLarge 2830 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2831 && proc.lastCachedPss >= 4000) { 2832 // Turn this condition on to cause killing to happen regularly, for testing. 2833 if (proc.baseProcessTracker != null) { 2834 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2835 } 2836 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2837 } else if (proc != null && !keepIfLarge 2838 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2839 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2840 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2841 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2842 if (proc.baseProcessTracker != null) { 2843 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2844 } 2845 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2846 } 2847 } 2848 return proc; 2849 } 2850 2851 void ensurePackageDexOpt(String packageName) { 2852 IPackageManager pm = AppGlobals.getPackageManager(); 2853 try { 2854 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2855 mDidDexOpt = true; 2856 } 2857 } catch (RemoteException e) { 2858 } 2859 } 2860 2861 boolean isNextTransitionForward() { 2862 int transit = mWindowManager.getPendingAppTransition(); 2863 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_OPEN 2865 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2866 } 2867 2868 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2869 String processName, String abiOverride, int uid, Runnable crashHandler) { 2870 synchronized(this) { 2871 ApplicationInfo info = new ApplicationInfo(); 2872 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2873 // For isolated processes, the former contains the parent's uid and the latter the 2874 // actual uid of the isolated process. 2875 // In the special case introduced by this method (which is, starting an isolated 2876 // process directly from the SystemServer without an actual parent app process) the 2877 // closest thing to a parent's uid is SYSTEM_UID. 2878 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2879 // the |isolated| logic in the ProcessRecord constructor. 2880 info.uid = Process.SYSTEM_UID; 2881 info.processName = processName; 2882 info.className = entryPoint; 2883 info.packageName = "android"; 2884 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2885 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2886 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2887 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2888 crashHandler); 2889 return proc != null ? proc.pid : 0; 2890 } 2891 } 2892 2893 final ProcessRecord startProcessLocked(String processName, 2894 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2895 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2896 boolean isolated, boolean keepIfLarge) { 2897 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2898 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2899 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2900 null /* crashHandler */); 2901 } 2902 2903 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2904 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2905 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2906 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2907 long startTime = SystemClock.elapsedRealtime(); 2908 ProcessRecord app; 2909 if (!isolated) { 2910 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2911 checkTime(startTime, "startProcess: after getProcessRecord"); 2912 } else { 2913 // If this is an isolated process, it can't re-use an existing process. 2914 app = null; 2915 } 2916 // We don't have to do anything more if: 2917 // (1) There is an existing application record; and 2918 // (2) The caller doesn't think it is dead, OR there is no thread 2919 // object attached to it so we know it couldn't have crashed; and 2920 // (3) There is a pid assigned to it, so it is either starting or 2921 // already running. 2922 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2923 + " app=" + app + " knownToBeDead=" + knownToBeDead 2924 + " thread=" + (app != null ? app.thread : null) 2925 + " pid=" + (app != null ? app.pid : -1)); 2926 if (app != null && app.pid > 0) { 2927 if (!knownToBeDead || app.thread == null) { 2928 // We already have the app running, or are waiting for it to 2929 // come up (we have a pid but not yet its thread), so keep it. 2930 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2931 // If this is a new package in the process, add the package to the list 2932 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2933 checkTime(startTime, "startProcess: done, added package to proc"); 2934 return app; 2935 } 2936 2937 // An application record is attached to a previous process, 2938 // clean it up now. 2939 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2940 checkTime(startTime, "startProcess: bad proc running, killing"); 2941 Process.killProcessGroup(app.info.uid, app.pid); 2942 handleAppDiedLocked(app, true, true); 2943 checkTime(startTime, "startProcess: done killing old proc"); 2944 } 2945 2946 String hostingNameStr = hostingName != null 2947 ? hostingName.flattenToShortString() : null; 2948 2949 if (!isolated) { 2950 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2951 // If we are in the background, then check to see if this process 2952 // is bad. If so, we will just silently fail. 2953 if (mBadProcesses.get(info.processName, info.uid) != null) { 2954 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2955 + "/" + info.processName); 2956 return null; 2957 } 2958 } else { 2959 // When the user is explicitly starting a process, then clear its 2960 // crash count so that we won't make it bad until they see at 2961 // least one crash dialog again, and make the process good again 2962 // if it had been bad. 2963 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2964 + "/" + info.processName); 2965 mProcessCrashTimes.remove(info.processName, info.uid); 2966 if (mBadProcesses.get(info.processName, info.uid) != null) { 2967 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2968 UserHandle.getUserId(info.uid), info.uid, 2969 info.processName); 2970 mBadProcesses.remove(info.processName, info.uid); 2971 if (app != null) { 2972 app.bad = false; 2973 } 2974 } 2975 } 2976 } 2977 2978 if (app == null) { 2979 checkTime(startTime, "startProcess: creating new process record"); 2980 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2981 app.crashHandler = crashHandler; 2982 if (app == null) { 2983 Slog.w(TAG, "Failed making new process record for " 2984 + processName + "/" + info.uid + " isolated=" + isolated); 2985 return null; 2986 } 2987 mProcessNames.put(processName, app.uid, app); 2988 if (isolated) { 2989 mIsolatedProcesses.put(app.uid, app); 2990 } 2991 checkTime(startTime, "startProcess: done creating new process record"); 2992 } else { 2993 // If this is a new package in the process, add the package to the list 2994 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2995 checkTime(startTime, "startProcess: added package to existing proc"); 2996 } 2997 2998 // If the system is not ready yet, then hold off on starting this 2999 // process until it is. 3000 if (!mProcessesReady 3001 && !isAllowedWhileBooting(info) 3002 && !allowWhileBooting) { 3003 if (!mProcessesOnHold.contains(app)) { 3004 mProcessesOnHold.add(app); 3005 } 3006 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3007 checkTime(startTime, "startProcess: returning with proc on hold"); 3008 return app; 3009 } 3010 3011 checkTime(startTime, "startProcess: stepping in to startProcess"); 3012 startProcessLocked( 3013 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3014 checkTime(startTime, "startProcess: done starting proc!"); 3015 return (app.pid != 0) ? app : null; 3016 } 3017 3018 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3019 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3020 } 3021 3022 private final void startProcessLocked(ProcessRecord app, 3023 String hostingType, String hostingNameStr) { 3024 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3025 null /* entryPoint */, null /* entryPointArgs */); 3026 } 3027 3028 private final void startProcessLocked(ProcessRecord app, String hostingType, 3029 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3030 long startTime = SystemClock.elapsedRealtime(); 3031 if (app.pid > 0 && app.pid != MY_PID) { 3032 checkTime(startTime, "startProcess: removing from pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 mPidsSelfLocked.remove(app.pid); 3035 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3036 } 3037 checkTime(startTime, "startProcess: done removing from pids map"); 3038 app.setPid(0); 3039 } 3040 3041 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3042 "startProcessLocked removing on hold: " + app); 3043 mProcessesOnHold.remove(app); 3044 3045 checkTime(startTime, "startProcess: starting to update cpu stats"); 3046 updateCpuStats(); 3047 checkTime(startTime, "startProcess: done updating cpu stats"); 3048 3049 try { 3050 int uid = app.uid; 3051 3052 int[] gids = null; 3053 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3054 if (!app.isolated) { 3055 int[] permGids = null; 3056 try { 3057 checkTime(startTime, "startProcess: getting gids from package manager"); 3058 final PackageManager pm = mContext.getPackageManager(); 3059 permGids = pm.getPackageGids(app.info.packageName); 3060 3061 if (Environment.isExternalStorageEmulated()) { 3062 checkTime(startTime, "startProcess: checking external storage perm"); 3063 if (pm.checkPermission( 3064 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3065 app.info.packageName) == PERMISSION_GRANTED) { 3066 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3067 } else { 3068 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3069 } 3070 } 3071 } catch (PackageManager.NameNotFoundException e) { 3072 Slog.w(TAG, "Unable to retrieve gids", e); 3073 } 3074 3075 /* 3076 * Add shared application and profile GIDs so applications can share some 3077 * resources like shared libraries and access user-wide resources 3078 */ 3079 if (permGids == null) { 3080 gids = new int[2]; 3081 } else { 3082 gids = new int[permGids.length + 2]; 3083 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3084 } 3085 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3086 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3087 } 3088 checkTime(startTime, "startProcess: building args"); 3089 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3090 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3091 && mTopComponent != null 3092 && app.processName.equals(mTopComponent.getPackageName())) { 3093 uid = 0; 3094 } 3095 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3096 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3097 uid = 0; 3098 } 3099 } 3100 int debugFlags = 0; 3101 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3102 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3103 // Also turn on CheckJNI for debuggable apps. It's quite 3104 // awkward to turn on otherwise. 3105 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3106 } 3107 // Run the app in safe mode if its manifest requests so or the 3108 // system is booted in safe mode. 3109 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3110 mSafeMode == true) { 3111 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3112 } 3113 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3114 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3115 } 3116 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3117 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3118 } 3119 if ("1".equals(SystemProperties.get("debug.assert"))) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3121 } 3122 3123 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3124 if (requiredAbi == null) { 3125 requiredAbi = Build.SUPPORTED_ABIS[0]; 3126 } 3127 3128 String instructionSet = null; 3129 if (app.info.primaryCpuAbi != null) { 3130 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3131 } 3132 3133 // Start the process. It will either succeed and return a result containing 3134 // the PID of the new process, or else throw a RuntimeException. 3135 boolean isActivityProcess = (entryPoint == null); 3136 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3137 checkTime(startTime, "startProcess: asking zygote to start proc"); 3138 Process.ProcessStartResult startResult = Process.start(entryPoint, 3139 app.processName, uid, uid, gids, debugFlags, mountExternal, 3140 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3141 entryPointArgs); 3142 checkTime(startTime, "startProcess: returned from zygote!"); 3143 3144 if (app.isolated) { 3145 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3146 } 3147 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3148 checkTime(startTime, "startProcess: done updating battery stats"); 3149 3150 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3151 UserHandle.getUserId(uid), startResult.pid, uid, 3152 app.processName, hostingType, 3153 hostingNameStr != null ? hostingNameStr : ""); 3154 3155 if (app.persistent) { 3156 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3157 } 3158 3159 checkTime(startTime, "startProcess: building log message"); 3160 StringBuilder buf = mStringBuilder; 3161 buf.setLength(0); 3162 buf.append("Start proc "); 3163 buf.append(app.processName); 3164 if (!isActivityProcess) { 3165 buf.append(" ["); 3166 buf.append(entryPoint); 3167 buf.append("]"); 3168 } 3169 buf.append(" for "); 3170 buf.append(hostingType); 3171 if (hostingNameStr != null) { 3172 buf.append(" "); 3173 buf.append(hostingNameStr); 3174 } 3175 buf.append(": pid="); 3176 buf.append(startResult.pid); 3177 buf.append(" uid="); 3178 buf.append(uid); 3179 buf.append(" gids={"); 3180 if (gids != null) { 3181 for (int gi=0; gi<gids.length; gi++) { 3182 if (gi != 0) buf.append(", "); 3183 buf.append(gids[gi]); 3184 3185 } 3186 } 3187 buf.append("}"); 3188 if (requiredAbi != null) { 3189 buf.append(" abi="); 3190 buf.append(requiredAbi); 3191 } 3192 Slog.i(TAG, buf.toString()); 3193 app.setPid(startResult.pid); 3194 app.usingWrapper = startResult.usingWrapper; 3195 app.removed = false; 3196 app.killedByAm = false; 3197 checkTime(startTime, "startProcess: starting to update pids map"); 3198 synchronized (mPidsSelfLocked) { 3199 this.mPidsSelfLocked.put(startResult.pid, app); 3200 if (isActivityProcess) { 3201 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3202 msg.obj = app; 3203 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3204 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3205 } 3206 } 3207 checkTime(startTime, "startProcess: done updating pids map"); 3208 } catch (RuntimeException e) { 3209 // XXX do better error recovery. 3210 app.setPid(0); 3211 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3212 if (app.isolated) { 3213 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3214 } 3215 Slog.e(TAG, "Failure starting process " + app.processName, e); 3216 } 3217 } 3218 3219 void updateUsageStats(ActivityRecord component, boolean resumed) { 3220 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3221 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3222 if (resumed) { 3223 if (mUsageStatsService != null) { 3224 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3225 UsageEvents.Event.MOVE_TO_FOREGROUND); 3226 } 3227 synchronized (stats) { 3228 stats.noteActivityResumedLocked(component.app.uid); 3229 } 3230 } else { 3231 if (mUsageStatsService != null) { 3232 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3233 UsageEvents.Event.MOVE_TO_BACKGROUND); 3234 } 3235 synchronized (stats) { 3236 stats.noteActivityPausedLocked(component.app.uid); 3237 } 3238 } 3239 } 3240 3241 Intent getHomeIntent() { 3242 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3243 intent.setComponent(mTopComponent); 3244 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3245 intent.addCategory(Intent.CATEGORY_HOME); 3246 } 3247 return intent; 3248 } 3249 3250 boolean startHomeActivityLocked(int userId) { 3251 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3252 && mTopAction == null) { 3253 // We are running in factory test mode, but unable to find 3254 // the factory test app, so just sit around displaying the 3255 // error message and don't try to start anything. 3256 return false; 3257 } 3258 Intent intent = getHomeIntent(); 3259 ActivityInfo aInfo = 3260 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3261 if (aInfo != null) { 3262 intent.setComponent(new ComponentName( 3263 aInfo.applicationInfo.packageName, aInfo.name)); 3264 // Don't do this if the home app is currently being 3265 // instrumented. 3266 aInfo = new ActivityInfo(aInfo); 3267 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3268 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3269 aInfo.applicationInfo.uid, true); 3270 if (app == null || app.instrumentationClass == null) { 3271 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3272 mStackSupervisor.startHomeActivity(intent, aInfo); 3273 } 3274 } 3275 3276 return true; 3277 } 3278 3279 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3280 ActivityInfo ai = null; 3281 ComponentName comp = intent.getComponent(); 3282 try { 3283 if (comp != null) { 3284 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3285 } else { 3286 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3287 intent, 3288 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3289 flags, userId); 3290 3291 if (info != null) { 3292 ai = info.activityInfo; 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 // ignore 3297 } 3298 3299 return ai; 3300 } 3301 3302 /** 3303 * Starts the "new version setup screen" if appropriate. 3304 */ 3305 void startSetupActivityLocked() { 3306 // Only do this once per boot. 3307 if (mCheckedForSetup) { 3308 return; 3309 } 3310 3311 // We will show this screen if the current one is a different 3312 // version than the last one shown, and we are not running in 3313 // low-level factory test mode. 3314 final ContentResolver resolver = mContext.getContentResolver(); 3315 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3316 Settings.Global.getInt(resolver, 3317 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3318 mCheckedForSetup = true; 3319 3320 // See if we should be showing the platform update setup UI. 3321 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3322 List<ResolveInfo> ris = mContext.getPackageManager() 3323 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3324 3325 // We don't allow third party apps to replace this. 3326 ResolveInfo ri = null; 3327 for (int i=0; ris != null && i<ris.size(); i++) { 3328 if ((ris.get(i).activityInfo.applicationInfo.flags 3329 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3330 ri = ris.get(i); 3331 break; 3332 } 3333 } 3334 3335 if (ri != null) { 3336 String vers = ri.activityInfo.metaData != null 3337 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3338 : null; 3339 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3340 vers = ri.activityInfo.applicationInfo.metaData.getString( 3341 Intent.METADATA_SETUP_VERSION); 3342 } 3343 String lastVers = Settings.Secure.getString( 3344 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3345 if (vers != null && !vers.equals(lastVers)) { 3346 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3347 intent.setComponent(new ComponentName( 3348 ri.activityInfo.packageName, ri.activityInfo.name)); 3349 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3350 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3351 null); 3352 } 3353 } 3354 } 3355 } 3356 3357 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3358 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3359 } 3360 3361 void enforceNotIsolatedCaller(String caller) { 3362 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3363 throw new SecurityException("Isolated process not allowed to call " + caller); 3364 } 3365 } 3366 3367 @Override 3368 public int getFrontActivityScreenCompatMode() { 3369 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3370 synchronized (this) { 3371 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3372 } 3373 } 3374 3375 @Override 3376 public void setFrontActivityScreenCompatMode(int mode) { 3377 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3378 "setFrontActivityScreenCompatMode"); 3379 synchronized (this) { 3380 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3381 } 3382 } 3383 3384 @Override 3385 public int getPackageScreenCompatMode(String packageName) { 3386 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3387 synchronized (this) { 3388 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3389 } 3390 } 3391 3392 @Override 3393 public void setPackageScreenCompatMode(String packageName, int mode) { 3394 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3395 "setPackageScreenCompatMode"); 3396 synchronized (this) { 3397 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3398 } 3399 } 3400 3401 @Override 3402 public boolean getPackageAskScreenCompat(String packageName) { 3403 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3404 synchronized (this) { 3405 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3406 } 3407 } 3408 3409 @Override 3410 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3412 "setPackageAskScreenCompat"); 3413 synchronized (this) { 3414 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3415 } 3416 } 3417 3418 private void dispatchProcessesChanged() { 3419 int N; 3420 synchronized (this) { 3421 N = mPendingProcessChanges.size(); 3422 if (mActiveProcessChanges.length < N) { 3423 mActiveProcessChanges = new ProcessChangeItem[N]; 3424 } 3425 mPendingProcessChanges.toArray(mActiveProcessChanges); 3426 mAvailProcessChanges.addAll(mPendingProcessChanges); 3427 mPendingProcessChanges.clear(); 3428 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3429 } 3430 3431 int i = mProcessObservers.beginBroadcast(); 3432 while (i > 0) { 3433 i--; 3434 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3435 if (observer != null) { 3436 try { 3437 for (int j=0; j<N; j++) { 3438 ProcessChangeItem item = mActiveProcessChanges[j]; 3439 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3440 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3441 + item.pid + " uid=" + item.uid + ": " 3442 + item.foregroundActivities); 3443 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3444 item.foregroundActivities); 3445 } 3446 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3447 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3448 + item.pid + " uid=" + item.uid + ": " + item.processState); 3449 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3450 } 3451 } 3452 } catch (RemoteException e) { 3453 } 3454 } 3455 } 3456 mProcessObservers.finishBroadcast(); 3457 } 3458 3459 private void dispatchProcessDied(int pid, int uid) { 3460 int i = mProcessObservers.beginBroadcast(); 3461 while (i > 0) { 3462 i--; 3463 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3464 if (observer != null) { 3465 try { 3466 observer.onProcessDied(pid, uid); 3467 } catch (RemoteException e) { 3468 } 3469 } 3470 } 3471 mProcessObservers.finishBroadcast(); 3472 } 3473 3474 @Override 3475 public final int startActivity(IApplicationThread caller, String callingPackage, 3476 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3477 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3478 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3479 resultWho, requestCode, startFlags, profilerInfo, options, 3480 UserHandle.getCallingUserId()); 3481 } 3482 3483 @Override 3484 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3485 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3486 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3487 enforceNotIsolatedCaller("startActivity"); 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3489 false, ALLOW_FULL_ONLY, "startActivity", null); 3490 // TODO: Switch to user app stacks here. 3491 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3492 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3493 profilerInfo, null, null, options, userId, null, null); 3494 } 3495 3496 @Override 3497 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3498 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3499 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3500 3501 // This is very dangerous -- it allows you to perform a start activity (including 3502 // permission grants) as any app that may launch one of your own activities. So 3503 // we will only allow this to be done from activities that are part of the core framework, 3504 // and then only when they are running as the system. 3505 final ActivityRecord sourceRecord; 3506 final int targetUid; 3507 final String targetPackage; 3508 synchronized (this) { 3509 if (resultTo == null) { 3510 throw new SecurityException("Must be called from an activity"); 3511 } 3512 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3513 if (sourceRecord == null) { 3514 throw new SecurityException("Called with bad activity token: " + resultTo); 3515 } 3516 if (!sourceRecord.info.packageName.equals("android")) { 3517 throw new SecurityException( 3518 "Must be called from an activity that is declared in the android package"); 3519 } 3520 if (sourceRecord.app == null) { 3521 throw new SecurityException("Called without a process attached to activity"); 3522 } 3523 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3524 // This is still okay, as long as this activity is running under the 3525 // uid of the original calling activity. 3526 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3527 throw new SecurityException( 3528 "Calling activity in uid " + sourceRecord.app.uid 3529 + " must be system uid or original calling uid " 3530 + sourceRecord.launchedFromUid); 3531 } 3532 } 3533 targetUid = sourceRecord.launchedFromUid; 3534 targetPackage = sourceRecord.launchedFromPackage; 3535 } 3536 3537 // TODO: Switch to user app stacks here. 3538 try { 3539 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3540 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3541 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3542 return ret; 3543 } catch (SecurityException e) { 3544 // XXX need to figure out how to propagate to original app. 3545 // A SecurityException here is generally actually a fault of the original 3546 // calling activity (such as a fairly granting permissions), so propagate it 3547 // back to them. 3548 /* 3549 StringBuilder msg = new StringBuilder(); 3550 msg.append("While launching"); 3551 msg.append(intent.toString()); 3552 msg.append(": "); 3553 msg.append(e.getMessage()); 3554 */ 3555 throw e; 3556 } 3557 } 3558 3559 @Override 3560 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3561 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3562 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3563 enforceNotIsolatedCaller("startActivityAndWait"); 3564 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3565 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3566 WaitResult res = new WaitResult(); 3567 // TODO: Switch to user app stacks here. 3568 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3569 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3570 options, userId, null, null); 3571 return res; 3572 } 3573 3574 @Override 3575 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3576 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3577 int startFlags, Configuration config, Bundle options, int userId) { 3578 enforceNotIsolatedCaller("startActivityWithConfig"); 3579 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3580 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3581 // TODO: Switch to user app stacks here. 3582 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3583 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3584 null, null, config, options, userId, null, null); 3585 return ret; 3586 } 3587 3588 @Override 3589 public int startActivityIntentSender(IApplicationThread caller, 3590 IntentSender intent, Intent fillInIntent, String resolvedType, 3591 IBinder resultTo, String resultWho, int requestCode, 3592 int flagsMask, int flagsValues, Bundle options) { 3593 enforceNotIsolatedCaller("startActivityIntentSender"); 3594 // Refuse possible leaked file descriptors 3595 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3596 throw new IllegalArgumentException("File descriptors passed in Intent"); 3597 } 3598 3599 IIntentSender sender = intent.getTarget(); 3600 if (!(sender instanceof PendingIntentRecord)) { 3601 throw new IllegalArgumentException("Bad PendingIntent object"); 3602 } 3603 3604 PendingIntentRecord pir = (PendingIntentRecord)sender; 3605 3606 synchronized (this) { 3607 // If this is coming from the currently resumed activity, it is 3608 // effectively saying that app switches are allowed at this point. 3609 final ActivityStack stack = getFocusedStack(); 3610 if (stack.mResumedActivity != null && 3611 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3612 mAppSwitchesAllowedTime = 0; 3613 } 3614 } 3615 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3616 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3617 return ret; 3618 } 3619 3620 @Override 3621 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3622 Intent intent, String resolvedType, IVoiceInteractionSession session, 3623 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3624 Bundle options, int userId) { 3625 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3626 != PackageManager.PERMISSION_GRANTED) { 3627 String msg = "Permission Denial: startVoiceActivity() from pid=" 3628 + Binder.getCallingPid() 3629 + ", uid=" + Binder.getCallingUid() 3630 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3631 Slog.w(TAG, msg); 3632 throw new SecurityException(msg); 3633 } 3634 if (session == null || interactor == null) { 3635 throw new NullPointerException("null session or interactor"); 3636 } 3637 userId = handleIncomingUser(callingPid, callingUid, userId, 3638 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3639 // TODO: Switch to user app stacks here. 3640 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3641 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3642 null, options, userId, null, null); 3643 } 3644 3645 @Override 3646 public boolean startNextMatchingActivity(IBinder callingActivity, 3647 Intent intent, Bundle options) { 3648 // Refuse possible leaked file descriptors 3649 if (intent != null && intent.hasFileDescriptors() == true) { 3650 throw new IllegalArgumentException("File descriptors passed in Intent"); 3651 } 3652 3653 synchronized (this) { 3654 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3655 if (r == null) { 3656 ActivityOptions.abort(options); 3657 return false; 3658 } 3659 if (r.app == null || r.app.thread == null) { 3660 // The caller is not running... d'oh! 3661 ActivityOptions.abort(options); 3662 return false; 3663 } 3664 intent = new Intent(intent); 3665 // The caller is not allowed to change the data. 3666 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3667 // And we are resetting to find the next component... 3668 intent.setComponent(null); 3669 3670 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3671 3672 ActivityInfo aInfo = null; 3673 try { 3674 List<ResolveInfo> resolves = 3675 AppGlobals.getPackageManager().queryIntentActivities( 3676 intent, r.resolvedType, 3677 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3678 UserHandle.getCallingUserId()); 3679 3680 // Look for the original activity in the list... 3681 final int N = resolves != null ? resolves.size() : 0; 3682 for (int i=0; i<N; i++) { 3683 ResolveInfo rInfo = resolves.get(i); 3684 if (rInfo.activityInfo.packageName.equals(r.packageName) 3685 && rInfo.activityInfo.name.equals(r.info.name)) { 3686 // We found the current one... the next matching is 3687 // after it. 3688 i++; 3689 if (i<N) { 3690 aInfo = resolves.get(i).activityInfo; 3691 } 3692 if (debug) { 3693 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3694 + "/" + r.info.name); 3695 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3696 + "/" + aInfo.name); 3697 } 3698 break; 3699 } 3700 } 3701 } catch (RemoteException e) { 3702 } 3703 3704 if (aInfo == null) { 3705 // Nobody who is next! 3706 ActivityOptions.abort(options); 3707 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3708 return false; 3709 } 3710 3711 intent.setComponent(new ComponentName( 3712 aInfo.applicationInfo.packageName, aInfo.name)); 3713 intent.setFlags(intent.getFlags()&~( 3714 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3715 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3716 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3717 Intent.FLAG_ACTIVITY_NEW_TASK)); 3718 3719 // Okay now we need to start the new activity, replacing the 3720 // currently running activity. This is a little tricky because 3721 // we want to start the new one as if the current one is finished, 3722 // but not finish the current one first so that there is no flicker. 3723 // And thus... 3724 final boolean wasFinishing = r.finishing; 3725 r.finishing = true; 3726 3727 // Propagate reply information over to the new activity. 3728 final ActivityRecord resultTo = r.resultTo; 3729 final String resultWho = r.resultWho; 3730 final int requestCode = r.requestCode; 3731 r.resultTo = null; 3732 if (resultTo != null) { 3733 resultTo.removeResultsLocked(r, resultWho, requestCode); 3734 } 3735 3736 final long origId = Binder.clearCallingIdentity(); 3737 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3738 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3739 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3740 options, false, null, null, null); 3741 Binder.restoreCallingIdentity(origId); 3742 3743 r.finishing = wasFinishing; 3744 if (res != ActivityManager.START_SUCCESS) { 3745 return false; 3746 } 3747 return true; 3748 } 3749 } 3750 3751 @Override 3752 public final int startActivityFromRecents(int taskId, Bundle options) { 3753 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3754 String msg = "Permission Denial: startActivityFromRecents called without " + 3755 START_TASKS_FROM_RECENTS; 3756 Slog.w(TAG, msg); 3757 throw new SecurityException(msg); 3758 } 3759 return startActivityFromRecentsInner(taskId, options); 3760 } 3761 3762 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3763 final TaskRecord task; 3764 final int callingUid; 3765 final String callingPackage; 3766 final Intent intent; 3767 final int userId; 3768 synchronized (this) { 3769 task = recentTaskForIdLocked(taskId); 3770 if (task == null) { 3771 throw new IllegalArgumentException("Task " + taskId + " not found."); 3772 } 3773 callingUid = task.mCallingUid; 3774 callingPackage = task.mCallingPackage; 3775 intent = task.intent; 3776 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3777 userId = task.userId; 3778 } 3779 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3780 options, userId, null, task); 3781 } 3782 3783 final int startActivityInPackage(int uid, String callingPackage, 3784 Intent intent, String resolvedType, IBinder resultTo, 3785 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3786 IActivityContainer container, TaskRecord inTask) { 3787 3788 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3789 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3790 3791 // TODO: Switch to user app stacks here. 3792 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3793 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3794 null, null, null, options, userId, container, inTask); 3795 return ret; 3796 } 3797 3798 @Override 3799 public final int startActivities(IApplicationThread caller, String callingPackage, 3800 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3801 int userId) { 3802 enforceNotIsolatedCaller("startActivities"); 3803 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3804 false, ALLOW_FULL_ONLY, "startActivity", null); 3805 // TODO: Switch to user app stacks here. 3806 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3807 resolvedTypes, resultTo, options, userId); 3808 return ret; 3809 } 3810 3811 final int startActivitiesInPackage(int uid, String callingPackage, 3812 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3813 Bundle options, int userId) { 3814 3815 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3816 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3817 // TODO: Switch to user app stacks here. 3818 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3819 resultTo, options, userId); 3820 return ret; 3821 } 3822 3823 //explicitly remove thd old information in mRecentTasks when removing existing user. 3824 private void removeRecentTasksForUserLocked(int userId) { 3825 if(userId <= 0) { 3826 Slog.i(TAG, "Can't remove recent task on user " + userId); 3827 return; 3828 } 3829 3830 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3831 TaskRecord tr = mRecentTasks.get(i); 3832 if (tr.userId == userId) { 3833 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3834 + " when finishing user" + userId); 3835 mRecentTasks.remove(i); 3836 tr.removedFromRecents(mTaskPersister); 3837 } 3838 } 3839 3840 // Remove tasks from persistent storage. 3841 mTaskPersister.wakeup(null, true); 3842 } 3843 3844 /** 3845 * Update the recent tasks lists: make sure tasks should still be here (their 3846 * applications / activities still exist), update their availability, fixup ordering 3847 * of affiliations. 3848 */ 3849 void cleanupRecentTasksLocked(int userId) { 3850 if (mRecentTasks == null) { 3851 // Happens when called from the packagemanager broadcast before boot. 3852 return; 3853 } 3854 3855 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3856 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3857 final IPackageManager pm = AppGlobals.getPackageManager(); 3858 final ActivityInfo dummyAct = new ActivityInfo(); 3859 final ApplicationInfo dummyApp = new ApplicationInfo(); 3860 3861 int N = mRecentTasks.size(); 3862 3863 int[] users = userId == UserHandle.USER_ALL 3864 ? getUsersLocked() : new int[] { userId }; 3865 for (int user : users) { 3866 for (int i = 0; i < N; i++) { 3867 TaskRecord task = mRecentTasks.get(i); 3868 if (task.userId != user) { 3869 // Only look at tasks for the user ID of interest. 3870 continue; 3871 } 3872 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3873 // This situation is broken, and we should just get rid of it now. 3874 mRecentTasks.remove(i); 3875 task.removedFromRecents(mTaskPersister); 3876 i--; 3877 N--; 3878 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3879 continue; 3880 } 3881 // Check whether this activity is currently available. 3882 if (task.realActivity != null) { 3883 ActivityInfo ai = availActCache.get(task.realActivity); 3884 if (ai == null) { 3885 try { 3886 ai = pm.getActivityInfo(task.realActivity, 3887 PackageManager.GET_UNINSTALLED_PACKAGES 3888 | PackageManager.GET_DISABLED_COMPONENTS, user); 3889 } catch (RemoteException e) { 3890 // Will never happen. 3891 continue; 3892 } 3893 if (ai == null) { 3894 ai = dummyAct; 3895 } 3896 availActCache.put(task.realActivity, ai); 3897 } 3898 if (ai == dummyAct) { 3899 // This could be either because the activity no longer exists, or the 3900 // app is temporarily gone. For the former we want to remove the recents 3901 // entry; for the latter we want to mark it as unavailable. 3902 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3903 if (app == null) { 3904 try { 3905 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3906 PackageManager.GET_UNINSTALLED_PACKAGES 3907 | PackageManager.GET_DISABLED_COMPONENTS, user); 3908 } catch (RemoteException e) { 3909 // Will never happen. 3910 continue; 3911 } 3912 if (app == null) { 3913 app = dummyApp; 3914 } 3915 availAppCache.put(task.realActivity.getPackageName(), app); 3916 } 3917 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3918 // Doesn't exist any more! Good-bye. 3919 mRecentTasks.remove(i); 3920 task.removedFromRecents(mTaskPersister); 3921 i--; 3922 N--; 3923 Slog.w(TAG, "Removing no longer valid recent: " + task); 3924 continue; 3925 } else { 3926 // Otherwise just not available for now. 3927 if (task.isAvailable) { 3928 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3929 + task); 3930 } 3931 task.isAvailable = false; 3932 } 3933 } else { 3934 if (!ai.enabled || !ai.applicationInfo.enabled 3935 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3936 if (task.isAvailable) { 3937 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3938 + task + " (enabled=" + ai.enabled + "/" 3939 + ai.applicationInfo.enabled + " flags=" 3940 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3941 } 3942 task.isAvailable = false; 3943 } else { 3944 if (!task.isAvailable) { 3945 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3946 + task); 3947 } 3948 task.isAvailable = true; 3949 } 3950 } 3951 } 3952 } 3953 } 3954 3955 // Verify the affiliate chain for each task. 3956 for (int i = 0; i < N; ) { 3957 TaskRecord task = mRecentTasks.remove(i); 3958 if (mTmpRecents.contains(task)) { 3959 continue; 3960 } 3961 int affiliatedTaskId = task.mAffiliatedTaskId; 3962 while (true) { 3963 TaskRecord next = task.mNextAffiliate; 3964 if (next == null) { 3965 break; 3966 } 3967 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3968 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3969 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3970 task.setNextAffiliate(null); 3971 if (next.mPrevAffiliate == task) { 3972 next.setPrevAffiliate(null); 3973 } 3974 break; 3975 } 3976 if (next.mPrevAffiliate != task) { 3977 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3978 next.mPrevAffiliate + " task=" + task); 3979 next.setPrevAffiliate(null); 3980 task.setNextAffiliate(null); 3981 break; 3982 } 3983 if (!mRecentTasks.contains(next)) { 3984 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3985 task.setNextAffiliate(null); 3986 // We know that next.mPrevAffiliate is always task, from above, so clear 3987 // its previous affiliate. 3988 next.setPrevAffiliate(null); 3989 break; 3990 } 3991 task = next; 3992 } 3993 // task is now the end of the list 3994 do { 3995 mRecentTasks.remove(task); 3996 mRecentTasks.add(i++, task); 3997 mTmpRecents.add(task); 3998 task.inRecents = true; 3999 } while ((task = task.mPrevAffiliate) != null); 4000 } 4001 mTmpRecents.clear(); 4002 // mRecentTasks is now in sorted, affiliated order. 4003 } 4004 4005 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4006 int N = mRecentTasks.size(); 4007 TaskRecord top = task; 4008 int topIndex = taskIndex; 4009 while (top.mNextAffiliate != null && topIndex > 0) { 4010 top = top.mNextAffiliate; 4011 topIndex--; 4012 } 4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4014 + topIndex + " from intial " + taskIndex); 4015 // Find the end of the chain, doing a sanity check along the way. 4016 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4017 int endIndex = topIndex; 4018 TaskRecord prev = top; 4019 while (endIndex < N) { 4020 TaskRecord cur = mRecentTasks.get(endIndex); 4021 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4022 + endIndex + " " + cur); 4023 if (cur == top) { 4024 // Verify start of the chain. 4025 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4026 Slog.wtf(TAG, "Bad chain @" + endIndex 4027 + ": first task has next affiliate: " + prev); 4028 sane = false; 4029 break; 4030 } 4031 } else { 4032 // Verify middle of the chain's next points back to the one before. 4033 if (cur.mNextAffiliate != prev 4034 || cur.mNextAffiliateTaskId != prev.taskId) { 4035 Slog.wtf(TAG, "Bad chain @" + endIndex 4036 + ": middle task " + cur + " @" + endIndex 4037 + " has bad next affiliate " 4038 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4039 + ", expected " + prev); 4040 sane = false; 4041 break; 4042 } 4043 } 4044 if (cur.mPrevAffiliateTaskId == -1) { 4045 // Chain ends here. 4046 if (cur.mPrevAffiliate != null) { 4047 Slog.wtf(TAG, "Bad chain @" + endIndex 4048 + ": last task " + cur + " has previous affiliate " 4049 + cur.mPrevAffiliate); 4050 sane = false; 4051 } 4052 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4053 break; 4054 } else { 4055 // Verify middle of the chain's prev points to a valid item. 4056 if (cur.mPrevAffiliate == null) { 4057 Slog.wtf(TAG, "Bad chain @" + endIndex 4058 + ": task " + cur + " has previous affiliate " 4059 + cur.mPrevAffiliate + " but should be id " 4060 + cur.mPrevAffiliate); 4061 sane = false; 4062 break; 4063 } 4064 } 4065 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4066 Slog.wtf(TAG, "Bad chain @" + endIndex 4067 + ": task " + cur + " has affiliated id " 4068 + cur.mAffiliatedTaskId + " but should be " 4069 + task.mAffiliatedTaskId); 4070 sane = false; 4071 break; 4072 } 4073 prev = cur; 4074 endIndex++; 4075 if (endIndex >= N) { 4076 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4077 + ": last task " + prev); 4078 sane = false; 4079 break; 4080 } 4081 } 4082 if (sane) { 4083 if (endIndex < taskIndex) { 4084 Slog.wtf(TAG, "Bad chain @" + endIndex 4085 + ": did not extend to task " + task + " @" + taskIndex); 4086 sane = false; 4087 } 4088 } 4089 if (sane) { 4090 // All looks good, we can just move all of the affiliated tasks 4091 // to the top. 4092 for (int i=topIndex; i<=endIndex; i++) { 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4094 + " from " + i + " to " + (i-topIndex)); 4095 TaskRecord cur = mRecentTasks.remove(i); 4096 mRecentTasks.add(i-topIndex, cur); 4097 } 4098 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4099 + " to " + endIndex); 4100 return true; 4101 } 4102 4103 // Whoops, couldn't do it. 4104 return false; 4105 } 4106 4107 final void addRecentTaskLocked(TaskRecord task) { 4108 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4109 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4110 4111 int N = mRecentTasks.size(); 4112 // Quick case: check if the top-most recent task is the same. 4113 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4114 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4115 return; 4116 } 4117 // Another quick case: check if this is part of a set of affiliated 4118 // tasks that are at the top. 4119 if (isAffiliated && N > 0 && task.inRecents 4120 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4121 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4122 + " at top when adding " + task); 4123 return; 4124 } 4125 // Another quick case: never add voice sessions. 4126 if (task.voiceSession != null) { 4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4128 return; 4129 } 4130 4131 boolean needAffiliationFix = false; 4132 4133 // Slightly less quick case: the task is already in recents, so all we need 4134 // to do is move it. 4135 if (task.inRecents) { 4136 int taskIndex = mRecentTasks.indexOf(task); 4137 if (taskIndex >= 0) { 4138 if (!isAffiliated) { 4139 // Simple case: this is not an affiliated task, so we just move it to the front. 4140 mRecentTasks.remove(taskIndex); 4141 mRecentTasks.add(0, task); 4142 notifyTaskPersisterLocked(task, false); 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4144 + " from " + taskIndex); 4145 return; 4146 } else { 4147 // More complicated: need to keep all affiliated tasks together. 4148 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4149 // All went well. 4150 return; 4151 } 4152 4153 // Uh oh... something bad in the affiliation chain, try to rebuild 4154 // everything and then go through our general path of adding a new task. 4155 needAffiliationFix = true; 4156 } 4157 } else { 4158 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4159 needAffiliationFix = true; 4160 } 4161 } 4162 4163 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4164 trimRecentsForTask(task, true); 4165 4166 N = mRecentTasks.size(); 4167 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4168 final TaskRecord tr = mRecentTasks.remove(N - 1); 4169 tr.removedFromRecents(mTaskPersister); 4170 N--; 4171 } 4172 task.inRecents = true; 4173 if (!isAffiliated || needAffiliationFix) { 4174 // If this is a simple non-affiliated task, or we had some failure trying to 4175 // handle it as part of an affilated task, then just place it at the top. 4176 mRecentTasks.add(0, task); 4177 } else if (isAffiliated) { 4178 // If this is a new affiliated task, then move all of the affiliated tasks 4179 // to the front and insert this new one. 4180 TaskRecord other = task.mNextAffiliate; 4181 if (other == null) { 4182 other = task.mPrevAffiliate; 4183 } 4184 if (other != null) { 4185 int otherIndex = mRecentTasks.indexOf(other); 4186 if (otherIndex >= 0) { 4187 // Insert new task at appropriate location. 4188 int taskIndex; 4189 if (other == task.mNextAffiliate) { 4190 // We found the index of our next affiliation, which is who is 4191 // before us in the list, so add after that point. 4192 taskIndex = otherIndex+1; 4193 } else { 4194 // We found the index of our previous affiliation, which is who is 4195 // after us in the list, so add at their position. 4196 taskIndex = otherIndex; 4197 } 4198 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4199 + taskIndex + ": " + task); 4200 mRecentTasks.add(taskIndex, task); 4201 4202 // Now move everything to the front. 4203 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4204 // All went well. 4205 return; 4206 } 4207 4208 // Uh oh... something bad in the affiliation chain, try to rebuild 4209 // everything and then go through our general path of adding a new task. 4210 needAffiliationFix = true; 4211 } else { 4212 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4213 + other); 4214 needAffiliationFix = true; 4215 } 4216 } else { 4217 if (DEBUG_RECENTS) Slog.d(TAG, 4218 "addRecent: adding affiliated task without next/prev:" + task); 4219 needAffiliationFix = true; 4220 } 4221 } 4222 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4223 4224 if (needAffiliationFix) { 4225 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4226 cleanupRecentTasksLocked(task.userId); 4227 } 4228 } 4229 4230 /** 4231 * If needed, remove oldest existing entries in recents that are for the same kind 4232 * of task as the given one. 4233 */ 4234 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4235 int N = mRecentTasks.size(); 4236 final Intent intent = task.intent; 4237 final boolean document = intent != null && intent.isDocument(); 4238 4239 int maxRecents = task.maxRecents - 1; 4240 for (int i=0; i<N; i++) { 4241 final TaskRecord tr = mRecentTasks.get(i); 4242 if (task != tr) { 4243 if (task.userId != tr.userId) { 4244 continue; 4245 } 4246 if (i > MAX_RECENT_BITMAPS) { 4247 tr.freeLastThumbnail(); 4248 } 4249 final Intent trIntent = tr.intent; 4250 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4251 (intent == null || !intent.filterEquals(trIntent))) { 4252 continue; 4253 } 4254 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4255 if (document && trIsDocument) { 4256 // These are the same document activity (not necessarily the same doc). 4257 if (maxRecents > 0) { 4258 --maxRecents; 4259 continue; 4260 } 4261 // Hit the maximum number of documents for this task. Fall through 4262 // and remove this document from recents. 4263 } else if (document || trIsDocument) { 4264 // Only one of these is a document. Not the droid we're looking for. 4265 continue; 4266 } 4267 } 4268 4269 if (!doTrim) { 4270 // If the caller is not actually asking for a trim, just tell them we reached 4271 // a point where the trim would happen. 4272 return i; 4273 } 4274 4275 // Either task and tr are the same or, their affinities match or their intents match 4276 // and neither of them is a document, or they are documents using the same activity 4277 // and their maxRecents has been reached. 4278 tr.disposeThumbnail(); 4279 mRecentTasks.remove(i); 4280 if (task != tr) { 4281 tr.removedFromRecents(mTaskPersister); 4282 } 4283 i--; 4284 N--; 4285 if (task.intent == null) { 4286 // If the new recent task we are adding is not fully 4287 // specified, then replace it with the existing recent task. 4288 task = tr; 4289 } 4290 notifyTaskPersisterLocked(tr, false); 4291 } 4292 4293 return -1; 4294 } 4295 4296 @Override 4297 public void reportActivityFullyDrawn(IBinder token) { 4298 synchronized (this) { 4299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4300 if (r == null) { 4301 return; 4302 } 4303 r.reportFullyDrawnLocked(); 4304 } 4305 } 4306 4307 @Override 4308 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4309 synchronized (this) { 4310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4311 if (r == null) { 4312 return; 4313 } 4314 final long origId = Binder.clearCallingIdentity(); 4315 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4316 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4317 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4318 if (config != null) { 4319 r.frozenBeforeDestroy = true; 4320 if (!updateConfigurationLocked(config, r, false, false)) { 4321 mStackSupervisor.resumeTopActivitiesLocked(); 4322 } 4323 } 4324 Binder.restoreCallingIdentity(origId); 4325 } 4326 } 4327 4328 @Override 4329 public int getRequestedOrientation(IBinder token) { 4330 synchronized (this) { 4331 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4332 if (r == null) { 4333 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4334 } 4335 return mWindowManager.getAppOrientation(r.appToken); 4336 } 4337 } 4338 4339 /** 4340 * This is the internal entry point for handling Activity.finish(). 4341 * 4342 * @param token The Binder token referencing the Activity we want to finish. 4343 * @param resultCode Result code, if any, from this Activity. 4344 * @param resultData Result data (Intent), if any, from this Activity. 4345 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4346 * the root Activity in the task. 4347 * 4348 * @return Returns true if the activity successfully finished, or false if it is still running. 4349 */ 4350 @Override 4351 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4352 boolean finishTask) { 4353 // Refuse possible leaked file descriptors 4354 if (resultData != null && resultData.hasFileDescriptors() == true) { 4355 throw new IllegalArgumentException("File descriptors passed in Intent"); 4356 } 4357 4358 synchronized(this) { 4359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4360 if (r == null) { 4361 return true; 4362 } 4363 // Keep track of the root activity of the task before we finish it 4364 TaskRecord tr = r.task; 4365 ActivityRecord rootR = tr.getRootActivity(); 4366 // Do not allow task to finish in Lock Task mode. 4367 if (tr == mStackSupervisor.mLockTaskModeTask) { 4368 if (rootR == r) { 4369 mStackSupervisor.showLockTaskToast(); 4370 return false; 4371 } 4372 } 4373 if (mController != null) { 4374 // Find the first activity that is not finishing. 4375 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4376 if (next != null) { 4377 // ask watcher if this is allowed 4378 boolean resumeOK = true; 4379 try { 4380 resumeOK = mController.activityResuming(next.packageName); 4381 } catch (RemoteException e) { 4382 mController = null; 4383 Watchdog.getInstance().setActivityController(null); 4384 } 4385 4386 if (!resumeOK) { 4387 return false; 4388 } 4389 } 4390 } 4391 final long origId = Binder.clearCallingIdentity(); 4392 try { 4393 boolean res; 4394 if (finishTask && r == rootR) { 4395 // If requested, remove the task that is associated to this activity only if it 4396 // was the root activity in the task. The result code and data is ignored because 4397 // we don't support returning them across task boundaries. 4398 res = removeTaskByIdLocked(tr.taskId, 0); 4399 } else { 4400 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4401 resultData, "app-request", true); 4402 } 4403 return res; 4404 } finally { 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 } 4409 4410 @Override 4411 public final void finishHeavyWeightApp() { 4412 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4413 != PackageManager.PERMISSION_GRANTED) { 4414 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4415 + Binder.getCallingPid() 4416 + ", uid=" + Binder.getCallingUid() 4417 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4418 Slog.w(TAG, msg); 4419 throw new SecurityException(msg); 4420 } 4421 4422 synchronized(this) { 4423 if (mHeavyWeightProcess == null) { 4424 return; 4425 } 4426 4427 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4428 mHeavyWeightProcess.activities); 4429 for (int i=0; i<activities.size(); i++) { 4430 ActivityRecord r = activities.get(i); 4431 if (!r.finishing) { 4432 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4433 null, "finish-heavy", true); 4434 } 4435 } 4436 4437 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4438 mHeavyWeightProcess.userId, 0)); 4439 mHeavyWeightProcess = null; 4440 } 4441 } 4442 4443 @Override 4444 public void crashApplication(int uid, int initialPid, String packageName, 4445 String message) { 4446 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4447 != PackageManager.PERMISSION_GRANTED) { 4448 String msg = "Permission Denial: crashApplication() from pid=" 4449 + Binder.getCallingPid() 4450 + ", uid=" + Binder.getCallingUid() 4451 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4452 Slog.w(TAG, msg); 4453 throw new SecurityException(msg); 4454 } 4455 4456 synchronized(this) { 4457 ProcessRecord proc = null; 4458 4459 // Figure out which process to kill. We don't trust that initialPid 4460 // still has any relation to current pids, so must scan through the 4461 // list. 4462 synchronized (mPidsSelfLocked) { 4463 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4464 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4465 if (p.uid != uid) { 4466 continue; 4467 } 4468 if (p.pid == initialPid) { 4469 proc = p; 4470 break; 4471 } 4472 if (p.pkgList.containsKey(packageName)) { 4473 proc = p; 4474 } 4475 } 4476 } 4477 4478 if (proc == null) { 4479 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4480 + " initialPid=" + initialPid 4481 + " packageName=" + packageName); 4482 return; 4483 } 4484 4485 if (proc.thread != null) { 4486 if (proc.pid == Process.myPid()) { 4487 Log.w(TAG, "crashApplication: trying to crash self!"); 4488 return; 4489 } 4490 long ident = Binder.clearCallingIdentity(); 4491 try { 4492 proc.thread.scheduleCrash(message); 4493 } catch (RemoteException e) { 4494 } 4495 Binder.restoreCallingIdentity(ident); 4496 } 4497 } 4498 } 4499 4500 @Override 4501 public final void finishSubActivity(IBinder token, String resultWho, 4502 int requestCode) { 4503 synchronized(this) { 4504 final long origId = Binder.clearCallingIdentity(); 4505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4506 if (r != null) { 4507 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4508 } 4509 Binder.restoreCallingIdentity(origId); 4510 } 4511 } 4512 4513 @Override 4514 public boolean finishActivityAffinity(IBinder token) { 4515 synchronized(this) { 4516 final long origId = Binder.clearCallingIdentity(); 4517 try { 4518 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4519 4520 ActivityRecord rootR = r.task.getRootActivity(); 4521 // Do not allow task to finish in Lock Task mode. 4522 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4523 if (rootR == r) { 4524 mStackSupervisor.showLockTaskToast(); 4525 return false; 4526 } 4527 } 4528 boolean res = false; 4529 if (r != null) { 4530 res = r.task.stack.finishActivityAffinityLocked(r); 4531 } 4532 return res; 4533 } finally { 4534 Binder.restoreCallingIdentity(origId); 4535 } 4536 } 4537 } 4538 4539 @Override 4540 public void finishVoiceTask(IVoiceInteractionSession session) { 4541 synchronized(this) { 4542 final long origId = Binder.clearCallingIdentity(); 4543 try { 4544 mStackSupervisor.finishVoiceTask(session); 4545 } finally { 4546 Binder.restoreCallingIdentity(origId); 4547 } 4548 } 4549 4550 } 4551 4552 @Override 4553 public boolean releaseActivityInstance(IBinder token) { 4554 synchronized(this) { 4555 final long origId = Binder.clearCallingIdentity(); 4556 try { 4557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4558 if (r.task == null || r.task.stack == null) { 4559 return false; 4560 } 4561 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4562 } finally { 4563 Binder.restoreCallingIdentity(origId); 4564 } 4565 } 4566 } 4567 4568 @Override 4569 public void releaseSomeActivities(IApplicationThread appInt) { 4570 synchronized(this) { 4571 final long origId = Binder.clearCallingIdentity(); 4572 try { 4573 ProcessRecord app = getRecordForAppLocked(appInt); 4574 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4575 } finally { 4576 Binder.restoreCallingIdentity(origId); 4577 } 4578 } 4579 } 4580 4581 @Override 4582 public boolean willActivityBeVisible(IBinder token) { 4583 synchronized(this) { 4584 ActivityStack stack = ActivityRecord.getStackLocked(token); 4585 if (stack != null) { 4586 return stack.willActivityBeVisibleLocked(token); 4587 } 4588 return false; 4589 } 4590 } 4591 4592 @Override 4593 public void overridePendingTransition(IBinder token, String packageName, 4594 int enterAnim, int exitAnim) { 4595 synchronized(this) { 4596 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4597 if (self == null) { 4598 return; 4599 } 4600 4601 final long origId = Binder.clearCallingIdentity(); 4602 4603 if (self.state == ActivityState.RESUMED 4604 || self.state == ActivityState.PAUSING) { 4605 mWindowManager.overridePendingAppTransition(packageName, 4606 enterAnim, exitAnim, null); 4607 } 4608 4609 Binder.restoreCallingIdentity(origId); 4610 } 4611 } 4612 4613 /** 4614 * Main function for removing an existing process from the activity manager 4615 * as a result of that process going away. Clears out all connections 4616 * to the process. 4617 */ 4618 private final void handleAppDiedLocked(ProcessRecord app, 4619 boolean restarting, boolean allowRestart) { 4620 int pid = app.pid; 4621 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4622 if (!restarting) { 4623 removeLruProcessLocked(app); 4624 if (pid > 0) { 4625 ProcessList.remove(pid); 4626 } 4627 } 4628 4629 if (mProfileProc == app) { 4630 clearProfilerLocked(); 4631 } 4632 4633 // Remove this application's activities from active lists. 4634 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4635 4636 app.activities.clear(); 4637 4638 if (app.instrumentationClass != null) { 4639 Slog.w(TAG, "Crash of app " + app.processName 4640 + " running instrumentation " + app.instrumentationClass); 4641 Bundle info = new Bundle(); 4642 info.putString("shortMsg", "Process crashed."); 4643 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4644 } 4645 4646 if (!restarting) { 4647 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4648 // If there was nothing to resume, and we are not already 4649 // restarting this process, but there is a visible activity that 4650 // is hosted by the process... then make sure all visible 4651 // activities are running, taking care of restarting this 4652 // process. 4653 if (hasVisibleActivities) { 4654 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4655 } 4656 } 4657 } 4658 } 4659 4660 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4661 IBinder threadBinder = thread.asBinder(); 4662 // Find the application record. 4663 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4664 ProcessRecord rec = mLruProcesses.get(i); 4665 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4666 return i; 4667 } 4668 } 4669 return -1; 4670 } 4671 4672 final ProcessRecord getRecordForAppLocked( 4673 IApplicationThread thread) { 4674 if (thread == null) { 4675 return null; 4676 } 4677 4678 int appIndex = getLRURecordIndexForAppLocked(thread); 4679 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4680 } 4681 4682 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4683 // If there are no longer any background processes running, 4684 // and the app that died was not running instrumentation, 4685 // then tell everyone we are now low on memory. 4686 boolean haveBg = false; 4687 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4688 ProcessRecord rec = mLruProcesses.get(i); 4689 if (rec.thread != null 4690 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4691 haveBg = true; 4692 break; 4693 } 4694 } 4695 4696 if (!haveBg) { 4697 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4698 if (doReport) { 4699 long now = SystemClock.uptimeMillis(); 4700 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4701 doReport = false; 4702 } else { 4703 mLastMemUsageReportTime = now; 4704 } 4705 } 4706 final ArrayList<ProcessMemInfo> memInfos 4707 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4708 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4709 long now = SystemClock.uptimeMillis(); 4710 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4711 ProcessRecord rec = mLruProcesses.get(i); 4712 if (rec == dyingProc || rec.thread == null) { 4713 continue; 4714 } 4715 if (doReport) { 4716 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4717 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4718 } 4719 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4720 // The low memory report is overriding any current 4721 // state for a GC request. Make sure to do 4722 // heavy/important/visible/foreground processes first. 4723 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4724 rec.lastRequestedGc = 0; 4725 } else { 4726 rec.lastRequestedGc = rec.lastLowMemory; 4727 } 4728 rec.reportLowMemory = true; 4729 rec.lastLowMemory = now; 4730 mProcessesToGc.remove(rec); 4731 addProcessToGcListLocked(rec); 4732 } 4733 } 4734 if (doReport) { 4735 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4736 mHandler.sendMessage(msg); 4737 } 4738 scheduleAppGcsLocked(); 4739 } 4740 } 4741 4742 final void appDiedLocked(ProcessRecord app) { 4743 appDiedLocked(app, app.pid, app.thread); 4744 } 4745 4746 final void appDiedLocked(ProcessRecord app, int pid, 4747 IApplicationThread thread) { 4748 4749 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4750 synchronized (stats) { 4751 stats.noteProcessDiedLocked(app.info.uid, pid); 4752 } 4753 4754 Process.killProcessGroup(app.info.uid, pid); 4755 4756 // Clean up already done if the process has been re-started. 4757 if (app.pid == pid && app.thread != null && 4758 app.thread.asBinder() == thread.asBinder()) { 4759 boolean doLowMem = app.instrumentationClass == null; 4760 boolean doOomAdj = doLowMem; 4761 if (!app.killedByAm) { 4762 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4763 + ") has died."); 4764 mAllowLowerMemLevel = true; 4765 } else { 4766 // Note that we always want to do oom adj to update our state with the 4767 // new number of procs. 4768 mAllowLowerMemLevel = false; 4769 doLowMem = false; 4770 } 4771 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4772 if (DEBUG_CLEANUP) Slog.v( 4773 TAG, "Dying app: " + app + ", pid: " + pid 4774 + ", thread: " + thread.asBinder()); 4775 handleAppDiedLocked(app, false, true); 4776 4777 if (doOomAdj) { 4778 updateOomAdjLocked(); 4779 } 4780 if (doLowMem) { 4781 doLowMemReportIfNeededLocked(app); 4782 } 4783 } else if (app.pid != pid) { 4784 // A new process has already been started. 4785 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4786 + ") has died and restarted (pid " + app.pid + ")."); 4787 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4788 } else if (DEBUG_PROCESSES) { 4789 Slog.d(TAG, "Received spurious death notification for thread " 4790 + thread.asBinder()); 4791 } 4792 } 4793 4794 /** 4795 * If a stack trace dump file is configured, dump process stack traces. 4796 * @param clearTraces causes the dump file to be erased prior to the new 4797 * traces being written, if true; when false, the new traces will be 4798 * appended to any existing file content. 4799 * @param firstPids of dalvik VM processes to dump stack traces for first 4800 * @param lastPids of dalvik VM processes to dump stack traces for last 4801 * @param nativeProcs optional list of native process names to dump stack crawls 4802 * @return file containing stack traces, or null if no dump file is configured 4803 */ 4804 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4805 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4806 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4807 if (tracesPath == null || tracesPath.length() == 0) { 4808 return null; 4809 } 4810 4811 File tracesFile = new File(tracesPath); 4812 try { 4813 File tracesDir = tracesFile.getParentFile(); 4814 if (!tracesDir.exists()) { 4815 tracesFile.mkdirs(); 4816 if (!SELinux.restorecon(tracesDir)) { 4817 return null; 4818 } 4819 } 4820 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4821 4822 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4823 tracesFile.createNewFile(); 4824 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4825 } catch (IOException e) { 4826 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4827 return null; 4828 } 4829 4830 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4831 return tracesFile; 4832 } 4833 4834 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4835 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4836 // Use a FileObserver to detect when traces finish writing. 4837 // The order of traces is considered important to maintain for legibility. 4838 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4839 @Override 4840 public synchronized void onEvent(int event, String path) { notify(); } 4841 }; 4842 4843 try { 4844 observer.startWatching(); 4845 4846 // First collect all of the stacks of the most important pids. 4847 if (firstPids != null) { 4848 try { 4849 int num = firstPids.size(); 4850 for (int i = 0; i < num; i++) { 4851 synchronized (observer) { 4852 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4853 observer.wait(200); // Wait for write-close, give up after 200msec 4854 } 4855 } 4856 } catch (InterruptedException e) { 4857 Log.wtf(TAG, e); 4858 } 4859 } 4860 4861 // Next collect the stacks of the native pids 4862 if (nativeProcs != null) { 4863 int[] pids = Process.getPidsForCommands(nativeProcs); 4864 if (pids != null) { 4865 for (int pid : pids) { 4866 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4867 } 4868 } 4869 } 4870 4871 // Lastly, measure CPU usage. 4872 if (processCpuTracker != null) { 4873 processCpuTracker.init(); 4874 System.gc(); 4875 processCpuTracker.update(); 4876 try { 4877 synchronized (processCpuTracker) { 4878 processCpuTracker.wait(500); // measure over 1/2 second. 4879 } 4880 } catch (InterruptedException e) { 4881 } 4882 processCpuTracker.update(); 4883 4884 // We'll take the stack crawls of just the top apps using CPU. 4885 final int N = processCpuTracker.countWorkingStats(); 4886 int numProcs = 0; 4887 for (int i=0; i<N && numProcs<5; i++) { 4888 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4889 if (lastPids.indexOfKey(stats.pid) >= 0) { 4890 numProcs++; 4891 try { 4892 synchronized (observer) { 4893 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4894 observer.wait(200); // Wait for write-close, give up after 200msec 4895 } 4896 } catch (InterruptedException e) { 4897 Log.wtf(TAG, e); 4898 } 4899 4900 } 4901 } 4902 } 4903 } finally { 4904 observer.stopWatching(); 4905 } 4906 } 4907 4908 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4909 if (true || IS_USER_BUILD) { 4910 return; 4911 } 4912 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4913 if (tracesPath == null || tracesPath.length() == 0) { 4914 return; 4915 } 4916 4917 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4918 StrictMode.allowThreadDiskWrites(); 4919 try { 4920 final File tracesFile = new File(tracesPath); 4921 final File tracesDir = tracesFile.getParentFile(); 4922 final File tracesTmp = new File(tracesDir, "__tmp__"); 4923 try { 4924 if (!tracesDir.exists()) { 4925 tracesFile.mkdirs(); 4926 if (!SELinux.restorecon(tracesDir.getPath())) { 4927 return; 4928 } 4929 } 4930 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4931 4932 if (tracesFile.exists()) { 4933 tracesTmp.delete(); 4934 tracesFile.renameTo(tracesTmp); 4935 } 4936 StringBuilder sb = new StringBuilder(); 4937 Time tobj = new Time(); 4938 tobj.set(System.currentTimeMillis()); 4939 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4940 sb.append(": "); 4941 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4942 sb.append(" since "); 4943 sb.append(msg); 4944 FileOutputStream fos = new FileOutputStream(tracesFile); 4945 fos.write(sb.toString().getBytes()); 4946 if (app == null) { 4947 fos.write("\n*** No application process!".getBytes()); 4948 } 4949 fos.close(); 4950 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4951 } catch (IOException e) { 4952 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4953 return; 4954 } 4955 4956 if (app != null) { 4957 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4958 firstPids.add(app.pid); 4959 dumpStackTraces(tracesPath, firstPids, null, null, null); 4960 } 4961 4962 File lastTracesFile = null; 4963 File curTracesFile = null; 4964 for (int i=9; i>=0; i--) { 4965 String name = String.format(Locale.US, "slow%02d.txt", i); 4966 curTracesFile = new File(tracesDir, name); 4967 if (curTracesFile.exists()) { 4968 if (lastTracesFile != null) { 4969 curTracesFile.renameTo(lastTracesFile); 4970 } else { 4971 curTracesFile.delete(); 4972 } 4973 } 4974 lastTracesFile = curTracesFile; 4975 } 4976 tracesFile.renameTo(curTracesFile); 4977 if (tracesTmp.exists()) { 4978 tracesTmp.renameTo(tracesFile); 4979 } 4980 } finally { 4981 StrictMode.setThreadPolicy(oldPolicy); 4982 } 4983 } 4984 4985 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4986 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4987 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4988 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4989 4990 if (mController != null) { 4991 try { 4992 // 0 == continue, -1 = kill process immediately 4993 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4994 if (res < 0 && app.pid != MY_PID) { 4995 app.kill("anr", true); 4996 } 4997 } catch (RemoteException e) { 4998 mController = null; 4999 Watchdog.getInstance().setActivityController(null); 5000 } 5001 } 5002 5003 long anrTime = SystemClock.uptimeMillis(); 5004 if (MONITOR_CPU_USAGE) { 5005 updateCpuStatsNow(); 5006 } 5007 5008 synchronized (this) { 5009 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5010 if (mShuttingDown) { 5011 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5012 return; 5013 } else if (app.notResponding) { 5014 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5015 return; 5016 } else if (app.crashing) { 5017 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5018 return; 5019 } 5020 5021 // In case we come through here for the same app before completing 5022 // this one, mark as anring now so we will bail out. 5023 app.notResponding = true; 5024 5025 // Log the ANR to the event log. 5026 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5027 app.processName, app.info.flags, annotation); 5028 5029 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5030 firstPids.add(app.pid); 5031 5032 int parentPid = app.pid; 5033 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5034 if (parentPid != app.pid) firstPids.add(parentPid); 5035 5036 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5037 5038 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5039 ProcessRecord r = mLruProcesses.get(i); 5040 if (r != null && r.thread != null) { 5041 int pid = r.pid; 5042 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5043 if (r.persistent) { 5044 firstPids.add(pid); 5045 } else { 5046 lastPids.put(pid, Boolean.TRUE); 5047 } 5048 } 5049 } 5050 } 5051 } 5052 5053 // Log the ANR to the main log. 5054 StringBuilder info = new StringBuilder(); 5055 info.setLength(0); 5056 info.append("ANR in ").append(app.processName); 5057 if (activity != null && activity.shortComponentName != null) { 5058 info.append(" (").append(activity.shortComponentName).append(")"); 5059 } 5060 info.append("\n"); 5061 info.append("PID: ").append(app.pid).append("\n"); 5062 if (annotation != null) { 5063 info.append("Reason: ").append(annotation).append("\n"); 5064 } 5065 if (parent != null && parent != activity) { 5066 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5067 } 5068 5069 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5070 5071 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5072 NATIVE_STACKS_OF_INTEREST); 5073 5074 String cpuInfo = null; 5075 if (MONITOR_CPU_USAGE) { 5076 updateCpuStatsNow(); 5077 synchronized (mProcessCpuThread) { 5078 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5079 } 5080 info.append(processCpuTracker.printCurrentLoad()); 5081 info.append(cpuInfo); 5082 } 5083 5084 info.append(processCpuTracker.printCurrentState(anrTime)); 5085 5086 Slog.e(TAG, info.toString()); 5087 if (tracesFile == null) { 5088 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5089 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5090 } 5091 5092 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5093 cpuInfo, tracesFile, null); 5094 5095 if (mController != null) { 5096 try { 5097 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5098 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5099 if (res != 0) { 5100 if (res < 0 && app.pid != MY_PID) { 5101 app.kill("anr", true); 5102 } else { 5103 synchronized (this) { 5104 mServices.scheduleServiceTimeoutLocked(app); 5105 } 5106 } 5107 return; 5108 } 5109 } catch (RemoteException e) { 5110 mController = null; 5111 Watchdog.getInstance().setActivityController(null); 5112 } 5113 } 5114 5115 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5116 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5117 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5118 5119 synchronized (this) { 5120 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5121 app.kill("bg anr", true); 5122 return; 5123 } 5124 5125 // Set the app's notResponding state, and look up the errorReportReceiver 5126 makeAppNotRespondingLocked(app, 5127 activity != null ? activity.shortComponentName : null, 5128 annotation != null ? "ANR " + annotation : "ANR", 5129 info.toString()); 5130 5131 // Bring up the infamous App Not Responding dialog 5132 Message msg = Message.obtain(); 5133 HashMap<String, Object> map = new HashMap<String, Object>(); 5134 msg.what = SHOW_NOT_RESPONDING_MSG; 5135 msg.obj = map; 5136 msg.arg1 = aboveSystem ? 1 : 0; 5137 map.put("app", app); 5138 if (activity != null) { 5139 map.put("activity", activity); 5140 } 5141 5142 mHandler.sendMessage(msg); 5143 } 5144 } 5145 5146 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5147 if (!mLaunchWarningShown) { 5148 mLaunchWarningShown = true; 5149 mHandler.post(new Runnable() { 5150 @Override 5151 public void run() { 5152 synchronized (ActivityManagerService.this) { 5153 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5154 d.show(); 5155 mHandler.postDelayed(new Runnable() { 5156 @Override 5157 public void run() { 5158 synchronized (ActivityManagerService.this) { 5159 d.dismiss(); 5160 mLaunchWarningShown = false; 5161 } 5162 } 5163 }, 4000); 5164 } 5165 } 5166 }); 5167 } 5168 } 5169 5170 @Override 5171 public boolean clearApplicationUserData(final String packageName, 5172 final IPackageDataObserver observer, int userId) { 5173 enforceNotIsolatedCaller("clearApplicationUserData"); 5174 int uid = Binder.getCallingUid(); 5175 int pid = Binder.getCallingPid(); 5176 userId = handleIncomingUser(pid, uid, 5177 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5178 long callingId = Binder.clearCallingIdentity(); 5179 try { 5180 IPackageManager pm = AppGlobals.getPackageManager(); 5181 int pkgUid = -1; 5182 synchronized(this) { 5183 try { 5184 pkgUid = pm.getPackageUid(packageName, userId); 5185 } catch (RemoteException e) { 5186 } 5187 if (pkgUid == -1) { 5188 Slog.w(TAG, "Invalid packageName: " + packageName); 5189 if (observer != null) { 5190 try { 5191 observer.onRemoveCompleted(packageName, false); 5192 } catch (RemoteException e) { 5193 Slog.i(TAG, "Observer no longer exists."); 5194 } 5195 } 5196 return false; 5197 } 5198 if (uid == pkgUid || checkComponentPermission( 5199 android.Manifest.permission.CLEAR_APP_USER_DATA, 5200 pid, uid, -1, true) 5201 == PackageManager.PERMISSION_GRANTED) { 5202 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5203 } else { 5204 throw new SecurityException("PID " + pid + " does not have permission " 5205 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5206 + " of package " + packageName); 5207 } 5208 5209 // Remove all tasks match the cleared application package and user 5210 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5211 final TaskRecord tr = mRecentTasks.get(i); 5212 final String taskPackageName = 5213 tr.getBaseIntent().getComponent().getPackageName(); 5214 if (tr.userId != userId) continue; 5215 if (!taskPackageName.equals(packageName)) continue; 5216 removeTaskByIdLocked(tr.taskId, 0); 5217 } 5218 } 5219 5220 try { 5221 // Clear application user data 5222 pm.clearApplicationUserData(packageName, observer, userId); 5223 5224 synchronized(this) { 5225 // Remove all permissions granted from/to this package 5226 removeUriPermissionsForPackageLocked(packageName, userId, true); 5227 } 5228 5229 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5230 Uri.fromParts("package", packageName, null)); 5231 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5232 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5233 null, null, 0, null, null, null, false, false, userId); 5234 } catch (RemoteException e) { 5235 } 5236 } finally { 5237 Binder.restoreCallingIdentity(callingId); 5238 } 5239 return true; 5240 } 5241 5242 @Override 5243 public void killBackgroundProcesses(final String packageName, int userId) { 5244 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5245 != PackageManager.PERMISSION_GRANTED && 5246 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5247 != PackageManager.PERMISSION_GRANTED) { 5248 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5249 + Binder.getCallingPid() 5250 + ", uid=" + Binder.getCallingUid() 5251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5252 Slog.w(TAG, msg); 5253 throw new SecurityException(msg); 5254 } 5255 5256 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5257 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5258 long callingId = Binder.clearCallingIdentity(); 5259 try { 5260 IPackageManager pm = AppGlobals.getPackageManager(); 5261 synchronized(this) { 5262 int appId = -1; 5263 try { 5264 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5265 } catch (RemoteException e) { 5266 } 5267 if (appId == -1) { 5268 Slog.w(TAG, "Invalid packageName: " + packageName); 5269 return; 5270 } 5271 killPackageProcessesLocked(packageName, appId, userId, 5272 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 } 5278 5279 @Override 5280 public void killAllBackgroundProcesses() { 5281 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5282 != PackageManager.PERMISSION_GRANTED) { 5283 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5284 + Binder.getCallingPid() 5285 + ", uid=" + Binder.getCallingUid() 5286 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5287 Slog.w(TAG, msg); 5288 throw new SecurityException(msg); 5289 } 5290 5291 long callingId = Binder.clearCallingIdentity(); 5292 try { 5293 synchronized(this) { 5294 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5295 final int NP = mProcessNames.getMap().size(); 5296 for (int ip=0; ip<NP; ip++) { 5297 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5298 final int NA = apps.size(); 5299 for (int ia=0; ia<NA; ia++) { 5300 ProcessRecord app = apps.valueAt(ia); 5301 if (app.persistent) { 5302 // we don't kill persistent processes 5303 continue; 5304 } 5305 if (app.removed) { 5306 procs.add(app); 5307 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5308 app.removed = true; 5309 procs.add(app); 5310 } 5311 } 5312 } 5313 5314 int N = procs.size(); 5315 for (int i=0; i<N; i++) { 5316 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5317 } 5318 mAllowLowerMemLevel = true; 5319 updateOomAdjLocked(); 5320 doLowMemReportIfNeededLocked(null); 5321 } 5322 } finally { 5323 Binder.restoreCallingIdentity(callingId); 5324 } 5325 } 5326 5327 @Override 5328 public void forceStopPackage(final String packageName, int userId) { 5329 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5330 != PackageManager.PERMISSION_GRANTED) { 5331 String msg = "Permission Denial: forceStopPackage() from pid=" 5332 + Binder.getCallingPid() 5333 + ", uid=" + Binder.getCallingUid() 5334 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5335 Slog.w(TAG, msg); 5336 throw new SecurityException(msg); 5337 } 5338 final int callingPid = Binder.getCallingPid(); 5339 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5340 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5341 long callingId = Binder.clearCallingIdentity(); 5342 try { 5343 IPackageManager pm = AppGlobals.getPackageManager(); 5344 synchronized(this) { 5345 int[] users = userId == UserHandle.USER_ALL 5346 ? getUsersLocked() : new int[] { userId }; 5347 for (int user : users) { 5348 int pkgUid = -1; 5349 try { 5350 pkgUid = pm.getPackageUid(packageName, user); 5351 } catch (RemoteException e) { 5352 } 5353 if (pkgUid == -1) { 5354 Slog.w(TAG, "Invalid packageName: " + packageName); 5355 continue; 5356 } 5357 try { 5358 pm.setPackageStoppedState(packageName, true, user); 5359 } catch (RemoteException e) { 5360 } catch (IllegalArgumentException e) { 5361 Slog.w(TAG, "Failed trying to unstop package " 5362 + packageName + ": " + e); 5363 } 5364 if (isUserRunningLocked(user, false)) { 5365 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5366 } 5367 } 5368 } 5369 } finally { 5370 Binder.restoreCallingIdentity(callingId); 5371 } 5372 } 5373 5374 @Override 5375 public void addPackageDependency(String packageName) { 5376 synchronized (this) { 5377 int callingPid = Binder.getCallingPid(); 5378 if (callingPid == Process.myPid()) { 5379 // Yeah, um, no. 5380 Slog.w(TAG, "Can't addPackageDependency on system process"); 5381 return; 5382 } 5383 ProcessRecord proc; 5384 synchronized (mPidsSelfLocked) { 5385 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5386 } 5387 if (proc != null) { 5388 if (proc.pkgDeps == null) { 5389 proc.pkgDeps = new ArraySet<String>(1); 5390 } 5391 proc.pkgDeps.add(packageName); 5392 } 5393 } 5394 } 5395 5396 /* 5397 * The pkg name and app id have to be specified. 5398 */ 5399 @Override 5400 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5401 if (pkg == null) { 5402 return; 5403 } 5404 // Make sure the uid is valid. 5405 if (appid < 0) { 5406 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5407 return; 5408 } 5409 int callerUid = Binder.getCallingUid(); 5410 // Only the system server can kill an application 5411 if (callerUid == Process.SYSTEM_UID) { 5412 // Post an aysnc message to kill the application 5413 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5414 msg.arg1 = appid; 5415 msg.arg2 = 0; 5416 Bundle bundle = new Bundle(); 5417 bundle.putString("pkg", pkg); 5418 bundle.putString("reason", reason); 5419 msg.obj = bundle; 5420 mHandler.sendMessage(msg); 5421 } else { 5422 throw new SecurityException(callerUid + " cannot kill pkg: " + 5423 pkg); 5424 } 5425 } 5426 5427 @Override 5428 public void closeSystemDialogs(String reason) { 5429 enforceNotIsolatedCaller("closeSystemDialogs"); 5430 5431 final int pid = Binder.getCallingPid(); 5432 final int uid = Binder.getCallingUid(); 5433 final long origId = Binder.clearCallingIdentity(); 5434 try { 5435 synchronized (this) { 5436 // Only allow this from foreground processes, so that background 5437 // applications can't abuse it to prevent system UI from being shown. 5438 if (uid >= Process.FIRST_APPLICATION_UID) { 5439 ProcessRecord proc; 5440 synchronized (mPidsSelfLocked) { 5441 proc = mPidsSelfLocked.get(pid); 5442 } 5443 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5444 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5445 + " from background process " + proc); 5446 return; 5447 } 5448 } 5449 closeSystemDialogsLocked(reason); 5450 } 5451 } finally { 5452 Binder.restoreCallingIdentity(origId); 5453 } 5454 } 5455 5456 void closeSystemDialogsLocked(String reason) { 5457 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5458 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5459 | Intent.FLAG_RECEIVER_FOREGROUND); 5460 if (reason != null) { 5461 intent.putExtra("reason", reason); 5462 } 5463 mWindowManager.closeSystemDialogs(reason); 5464 5465 mStackSupervisor.closeSystemDialogsLocked(); 5466 5467 broadcastIntentLocked(null, null, intent, null, 5468 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5469 Process.SYSTEM_UID, UserHandle.USER_ALL); 5470 } 5471 5472 @Override 5473 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5474 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5475 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5476 for (int i=pids.length-1; i>=0; i--) { 5477 ProcessRecord proc; 5478 int oomAdj; 5479 synchronized (this) { 5480 synchronized (mPidsSelfLocked) { 5481 proc = mPidsSelfLocked.get(pids[i]); 5482 oomAdj = proc != null ? proc.setAdj : 0; 5483 } 5484 } 5485 infos[i] = new Debug.MemoryInfo(); 5486 Debug.getMemoryInfo(pids[i], infos[i]); 5487 if (proc != null) { 5488 synchronized (this) { 5489 if (proc.thread != null && proc.setAdj == oomAdj) { 5490 // Record this for posterity if the process has been stable. 5491 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5492 infos[i].getTotalUss(), false, proc.pkgList); 5493 } 5494 } 5495 } 5496 } 5497 return infos; 5498 } 5499 5500 @Override 5501 public long[] getProcessPss(int[] pids) { 5502 enforceNotIsolatedCaller("getProcessPss"); 5503 long[] pss = new long[pids.length]; 5504 for (int i=pids.length-1; i>=0; i--) { 5505 ProcessRecord proc; 5506 int oomAdj; 5507 synchronized (this) { 5508 synchronized (mPidsSelfLocked) { 5509 proc = mPidsSelfLocked.get(pids[i]); 5510 oomAdj = proc != null ? proc.setAdj : 0; 5511 } 5512 } 5513 long[] tmpUss = new long[1]; 5514 pss[i] = Debug.getPss(pids[i], tmpUss); 5515 if (proc != null) { 5516 synchronized (this) { 5517 if (proc.thread != null && proc.setAdj == oomAdj) { 5518 // Record this for posterity if the process has been stable. 5519 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5520 } 5521 } 5522 } 5523 } 5524 return pss; 5525 } 5526 5527 @Override 5528 public void killApplicationProcess(String processName, int uid) { 5529 if (processName == null) { 5530 return; 5531 } 5532 5533 int callerUid = Binder.getCallingUid(); 5534 // Only the system server can kill an application 5535 if (callerUid == Process.SYSTEM_UID) { 5536 synchronized (this) { 5537 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5538 if (app != null && app.thread != null) { 5539 try { 5540 app.thread.scheduleSuicide(); 5541 } catch (RemoteException e) { 5542 // If the other end already died, then our work here is done. 5543 } 5544 } else { 5545 Slog.w(TAG, "Process/uid not found attempting kill of " 5546 + processName + " / " + uid); 5547 } 5548 } 5549 } else { 5550 throw new SecurityException(callerUid + " cannot kill app process: " + 5551 processName); 5552 } 5553 } 5554 5555 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5556 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5557 false, true, false, false, UserHandle.getUserId(uid), reason); 5558 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5559 Uri.fromParts("package", packageName, null)); 5560 if (!mProcessesReady) { 5561 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5562 | Intent.FLAG_RECEIVER_FOREGROUND); 5563 } 5564 intent.putExtra(Intent.EXTRA_UID, uid); 5565 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5566 broadcastIntentLocked(null, null, intent, 5567 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5568 false, false, 5569 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5570 } 5571 5572 private void forceStopUserLocked(int userId, String reason) { 5573 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5574 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5575 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5576 | Intent.FLAG_RECEIVER_FOREGROUND); 5577 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5578 broadcastIntentLocked(null, null, intent, 5579 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5580 false, false, 5581 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5582 } 5583 5584 private final boolean killPackageProcessesLocked(String packageName, int appId, 5585 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5586 boolean doit, boolean evenPersistent, String reason) { 5587 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5588 5589 // Remove all processes this package may have touched: all with the 5590 // same UID (except for the system or root user), and all whose name 5591 // matches the package name. 5592 final int NP = mProcessNames.getMap().size(); 5593 for (int ip=0; ip<NP; ip++) { 5594 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5595 final int NA = apps.size(); 5596 for (int ia=0; ia<NA; ia++) { 5597 ProcessRecord app = apps.valueAt(ia); 5598 if (app.persistent && !evenPersistent) { 5599 // we don't kill persistent processes 5600 continue; 5601 } 5602 if (app.removed) { 5603 if (doit) { 5604 procs.add(app); 5605 } 5606 continue; 5607 } 5608 5609 // Skip process if it doesn't meet our oom adj requirement. 5610 if (app.setAdj < minOomAdj) { 5611 continue; 5612 } 5613 5614 // If no package is specified, we call all processes under the 5615 // give user id. 5616 if (packageName == null) { 5617 if (app.userId != userId) { 5618 continue; 5619 } 5620 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5621 continue; 5622 } 5623 // Package has been specified, we want to hit all processes 5624 // that match it. We need to qualify this by the processes 5625 // that are running under the specified app and user ID. 5626 } else { 5627 final boolean isDep = app.pkgDeps != null 5628 && app.pkgDeps.contains(packageName); 5629 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5630 continue; 5631 } 5632 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5633 continue; 5634 } 5635 if (!app.pkgList.containsKey(packageName) && !isDep) { 5636 continue; 5637 } 5638 } 5639 5640 // Process has passed all conditions, kill it! 5641 if (!doit) { 5642 return true; 5643 } 5644 app.removed = true; 5645 procs.add(app); 5646 } 5647 } 5648 5649 int N = procs.size(); 5650 for (int i=0; i<N; i++) { 5651 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5652 } 5653 updateOomAdjLocked(); 5654 return N > 0; 5655 } 5656 5657 private final boolean forceStopPackageLocked(String name, int appId, 5658 boolean callerWillRestart, boolean purgeCache, boolean doit, 5659 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5660 int i; 5661 int N; 5662 5663 if (userId == UserHandle.USER_ALL && name == null) { 5664 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5665 } 5666 5667 if (appId < 0 && name != null) { 5668 try { 5669 appId = UserHandle.getAppId( 5670 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5671 } catch (RemoteException e) { 5672 } 5673 } 5674 5675 if (doit) { 5676 if (name != null) { 5677 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5678 + " user=" + userId + ": " + reason); 5679 } else { 5680 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5681 } 5682 5683 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5684 for (int ip=pmap.size()-1; ip>=0; ip--) { 5685 SparseArray<Long> ba = pmap.valueAt(ip); 5686 for (i=ba.size()-1; i>=0; i--) { 5687 boolean remove = false; 5688 final int entUid = ba.keyAt(i); 5689 if (name != null) { 5690 if (userId == UserHandle.USER_ALL) { 5691 if (UserHandle.getAppId(entUid) == appId) { 5692 remove = true; 5693 } 5694 } else { 5695 if (entUid == UserHandle.getUid(userId, appId)) { 5696 remove = true; 5697 } 5698 } 5699 } else if (UserHandle.getUserId(entUid) == userId) { 5700 remove = true; 5701 } 5702 if (remove) { 5703 ba.removeAt(i); 5704 } 5705 } 5706 if (ba.size() == 0) { 5707 pmap.removeAt(ip); 5708 } 5709 } 5710 } 5711 5712 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5713 -100, callerWillRestart, true, doit, evenPersistent, 5714 name == null ? ("stop user " + userId) : ("stop " + name)); 5715 5716 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5717 if (!doit) { 5718 return true; 5719 } 5720 didSomething = true; 5721 } 5722 5723 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5724 if (!doit) { 5725 return true; 5726 } 5727 didSomething = true; 5728 } 5729 5730 if (name == null) { 5731 // Remove all sticky broadcasts from this user. 5732 mStickyBroadcasts.remove(userId); 5733 } 5734 5735 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5736 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5737 userId, providers)) { 5738 if (!doit) { 5739 return true; 5740 } 5741 didSomething = true; 5742 } 5743 N = providers.size(); 5744 for (i=0; i<N; i++) { 5745 removeDyingProviderLocked(null, providers.get(i), true); 5746 } 5747 5748 // Remove transient permissions granted from/to this package/user 5749 removeUriPermissionsForPackageLocked(name, userId, false); 5750 5751 if (name == null || uninstalling) { 5752 // Remove pending intents. For now we only do this when force 5753 // stopping users, because we have some problems when doing this 5754 // for packages -- app widgets are not currently cleaned up for 5755 // such packages, so they can be left with bad pending intents. 5756 if (mIntentSenderRecords.size() > 0) { 5757 Iterator<WeakReference<PendingIntentRecord>> it 5758 = mIntentSenderRecords.values().iterator(); 5759 while (it.hasNext()) { 5760 WeakReference<PendingIntentRecord> wpir = it.next(); 5761 if (wpir == null) { 5762 it.remove(); 5763 continue; 5764 } 5765 PendingIntentRecord pir = wpir.get(); 5766 if (pir == null) { 5767 it.remove(); 5768 continue; 5769 } 5770 if (name == null) { 5771 // Stopping user, remove all objects for the user. 5772 if (pir.key.userId != userId) { 5773 // Not the same user, skip it. 5774 continue; 5775 } 5776 } else { 5777 if (UserHandle.getAppId(pir.uid) != appId) { 5778 // Different app id, skip it. 5779 continue; 5780 } 5781 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5782 // Different user, skip it. 5783 continue; 5784 } 5785 if (!pir.key.packageName.equals(name)) { 5786 // Different package, skip it. 5787 continue; 5788 } 5789 } 5790 if (!doit) { 5791 return true; 5792 } 5793 didSomething = true; 5794 it.remove(); 5795 pir.canceled = true; 5796 if (pir.key.activity != null) { 5797 pir.key.activity.pendingResults.remove(pir.ref); 5798 } 5799 } 5800 } 5801 } 5802 5803 if (doit) { 5804 if (purgeCache && name != null) { 5805 AttributeCache ac = AttributeCache.instance(); 5806 if (ac != null) { 5807 ac.removePackage(name); 5808 } 5809 } 5810 if (mBooted) { 5811 mStackSupervisor.resumeTopActivitiesLocked(); 5812 mStackSupervisor.scheduleIdleLocked(); 5813 } 5814 } 5815 5816 return didSomething; 5817 } 5818 5819 private final boolean removeProcessLocked(ProcessRecord app, 5820 boolean callerWillRestart, boolean allowRestart, String reason) { 5821 final String name = app.processName; 5822 final int uid = app.uid; 5823 if (DEBUG_PROCESSES) Slog.d( 5824 TAG, "Force removing proc " + app.toShortString() + " (" + name 5825 + "/" + uid + ")"); 5826 5827 mProcessNames.remove(name, uid); 5828 mIsolatedProcesses.remove(app.uid); 5829 if (mHeavyWeightProcess == app) { 5830 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5831 mHeavyWeightProcess.userId, 0)); 5832 mHeavyWeightProcess = null; 5833 } 5834 boolean needRestart = false; 5835 if (app.pid > 0 && app.pid != MY_PID) { 5836 int pid = app.pid; 5837 synchronized (mPidsSelfLocked) { 5838 mPidsSelfLocked.remove(pid); 5839 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5840 } 5841 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5842 if (app.isolated) { 5843 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5844 } 5845 app.kill(reason, true); 5846 handleAppDiedLocked(app, true, allowRestart); 5847 removeLruProcessLocked(app); 5848 5849 if (app.persistent && !app.isolated) { 5850 if (!callerWillRestart) { 5851 addAppLocked(app.info, false, null /* ABI override */); 5852 } else { 5853 needRestart = true; 5854 } 5855 } 5856 } else { 5857 mRemovedProcesses.add(app); 5858 } 5859 5860 return needRestart; 5861 } 5862 5863 private final void processStartTimedOutLocked(ProcessRecord app) { 5864 final int pid = app.pid; 5865 boolean gone = false; 5866 synchronized (mPidsSelfLocked) { 5867 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5868 if (knownApp != null && knownApp.thread == null) { 5869 mPidsSelfLocked.remove(pid); 5870 gone = true; 5871 } 5872 } 5873 5874 if (gone) { 5875 Slog.w(TAG, "Process " + app + " failed to attach"); 5876 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5877 pid, app.uid, app.processName); 5878 mProcessNames.remove(app.processName, app.uid); 5879 mIsolatedProcesses.remove(app.uid); 5880 if (mHeavyWeightProcess == app) { 5881 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5882 mHeavyWeightProcess.userId, 0)); 5883 mHeavyWeightProcess = null; 5884 } 5885 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5886 if (app.isolated) { 5887 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5888 } 5889 // Take care of any launching providers waiting for this process. 5890 checkAppInLaunchingProvidersLocked(app, true); 5891 // Take care of any services that are waiting for the process. 5892 mServices.processStartTimedOutLocked(app); 5893 app.kill("start timeout", true); 5894 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5895 Slog.w(TAG, "Unattached app died before backup, skipping"); 5896 try { 5897 IBackupManager bm = IBackupManager.Stub.asInterface( 5898 ServiceManager.getService(Context.BACKUP_SERVICE)); 5899 bm.agentDisconnected(app.info.packageName); 5900 } catch (RemoteException e) { 5901 // Can't happen; the backup manager is local 5902 } 5903 } 5904 if (isPendingBroadcastProcessLocked(pid)) { 5905 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5906 skipPendingBroadcastLocked(pid); 5907 } 5908 } else { 5909 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5910 } 5911 } 5912 5913 private final boolean attachApplicationLocked(IApplicationThread thread, 5914 int pid) { 5915 5916 // Find the application record that is being attached... either via 5917 // the pid if we are running in multiple processes, or just pull the 5918 // next app record if we are emulating process with anonymous threads. 5919 ProcessRecord app; 5920 if (pid != MY_PID && pid >= 0) { 5921 synchronized (mPidsSelfLocked) { 5922 app = mPidsSelfLocked.get(pid); 5923 } 5924 } else { 5925 app = null; 5926 } 5927 5928 if (app == null) { 5929 Slog.w(TAG, "No pending application record for pid " + pid 5930 + " (IApplicationThread " + thread + "); dropping process"); 5931 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5932 if (pid > 0 && pid != MY_PID) { 5933 Process.killProcessQuiet(pid); 5934 //TODO: Process.killProcessGroup(app.info.uid, pid); 5935 } else { 5936 try { 5937 thread.scheduleExit(); 5938 } catch (Exception e) { 5939 // Ignore exceptions. 5940 } 5941 } 5942 return false; 5943 } 5944 5945 // If this application record is still attached to a previous 5946 // process, clean it up now. 5947 if (app.thread != null) { 5948 handleAppDiedLocked(app, true, true); 5949 } 5950 5951 // Tell the process all about itself. 5952 5953 if (localLOGV) Slog.v( 5954 TAG, "Binding process pid " + pid + " to record " + app); 5955 5956 final String processName = app.processName; 5957 try { 5958 AppDeathRecipient adr = new AppDeathRecipient( 5959 app, pid, thread); 5960 thread.asBinder().linkToDeath(adr, 0); 5961 app.deathRecipient = adr; 5962 } catch (RemoteException e) { 5963 app.resetPackageList(mProcessStats); 5964 startProcessLocked(app, "link fail", processName); 5965 return false; 5966 } 5967 5968 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5969 5970 app.makeActive(thread, mProcessStats); 5971 app.curAdj = app.setAdj = -100; 5972 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5973 app.forcingToForeground = null; 5974 updateProcessForegroundLocked(app, false, false); 5975 app.hasShownUi = false; 5976 app.debugging = false; 5977 app.cached = false; 5978 5979 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5980 5981 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5982 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5983 5984 if (!normalMode) { 5985 Slog.i(TAG, "Launching preboot mode app: " + app); 5986 } 5987 5988 if (localLOGV) Slog.v( 5989 TAG, "New app record " + app 5990 + " thread=" + thread.asBinder() + " pid=" + pid); 5991 try { 5992 int testMode = IApplicationThread.DEBUG_OFF; 5993 if (mDebugApp != null && mDebugApp.equals(processName)) { 5994 testMode = mWaitForDebugger 5995 ? IApplicationThread.DEBUG_WAIT 5996 : IApplicationThread.DEBUG_ON; 5997 app.debugging = true; 5998 if (mDebugTransient) { 5999 mDebugApp = mOrigDebugApp; 6000 mWaitForDebugger = mOrigWaitForDebugger; 6001 } 6002 } 6003 String profileFile = app.instrumentationProfileFile; 6004 ParcelFileDescriptor profileFd = null; 6005 int samplingInterval = 0; 6006 boolean profileAutoStop = false; 6007 if (mProfileApp != null && mProfileApp.equals(processName)) { 6008 mProfileProc = app; 6009 profileFile = mProfileFile; 6010 profileFd = mProfileFd; 6011 samplingInterval = mSamplingInterval; 6012 profileAutoStop = mAutoStopProfiler; 6013 } 6014 boolean enableOpenGlTrace = false; 6015 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6016 enableOpenGlTrace = true; 6017 mOpenGlTraceApp = null; 6018 } 6019 6020 // If the app is being launched for restore or full backup, set it up specially 6021 boolean isRestrictedBackupMode = false; 6022 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6023 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6024 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6025 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6026 } 6027 6028 ensurePackageDexOpt(app.instrumentationInfo != null 6029 ? app.instrumentationInfo.packageName 6030 : app.info.packageName); 6031 if (app.instrumentationClass != null) { 6032 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6033 } 6034 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6035 + processName + " with config " + mConfiguration); 6036 ApplicationInfo appInfo = app.instrumentationInfo != null 6037 ? app.instrumentationInfo : app.info; 6038 app.compat = compatibilityInfoForPackageLocked(appInfo); 6039 if (profileFd != null) { 6040 profileFd = profileFd.dup(); 6041 } 6042 ProfilerInfo profilerInfo = profileFile == null ? null 6043 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6044 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6045 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6046 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6047 isRestrictedBackupMode || !normalMode, app.persistent, 6048 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6049 mCoreSettingsObserver.getCoreSettingsLocked()); 6050 updateLruProcessLocked(app, false, null); 6051 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6052 } catch (Exception e) { 6053 // todo: Yikes! What should we do? For now we will try to 6054 // start another process, but that could easily get us in 6055 // an infinite loop of restarting processes... 6056 Slog.w(TAG, "Exception thrown during bind!", e); 6057 6058 app.resetPackageList(mProcessStats); 6059 app.unlinkDeathRecipient(); 6060 startProcessLocked(app, "bind fail", processName); 6061 return false; 6062 } 6063 6064 // Remove this record from the list of starting applications. 6065 mPersistentStartingProcesses.remove(app); 6066 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6067 "Attach application locked removing on hold: " + app); 6068 mProcessesOnHold.remove(app); 6069 6070 boolean badApp = false; 6071 boolean didSomething = false; 6072 6073 // See if the top visible activity is waiting to run in this process... 6074 if (normalMode) { 6075 try { 6076 if (mStackSupervisor.attachApplicationLocked(app)) { 6077 didSomething = true; 6078 } 6079 } catch (Exception e) { 6080 badApp = true; 6081 } 6082 } 6083 6084 // Find any services that should be running in this process... 6085 if (!badApp) { 6086 try { 6087 didSomething |= mServices.attachApplicationLocked(app, processName); 6088 } catch (Exception e) { 6089 badApp = true; 6090 } 6091 } 6092 6093 // Check if a next-broadcast receiver is in this process... 6094 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6095 try { 6096 didSomething |= sendPendingBroadcastsLocked(app); 6097 } catch (Exception e) { 6098 // If the app died trying to launch the receiver we declare it 'bad' 6099 badApp = true; 6100 } 6101 } 6102 6103 // Check whether the next backup agent is in this process... 6104 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6105 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6106 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6107 try { 6108 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6109 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6110 mBackupTarget.backupMode); 6111 } catch (Exception e) { 6112 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6113 e.printStackTrace(); 6114 } 6115 } 6116 6117 if (badApp) { 6118 // todo: Also need to kill application to deal with all 6119 // kinds of exceptions. 6120 handleAppDiedLocked(app, false, true); 6121 return false; 6122 } 6123 6124 if (!didSomething) { 6125 updateOomAdjLocked(); 6126 } 6127 6128 return true; 6129 } 6130 6131 @Override 6132 public final void attachApplication(IApplicationThread thread) { 6133 synchronized (this) { 6134 int callingPid = Binder.getCallingPid(); 6135 final long origId = Binder.clearCallingIdentity(); 6136 attachApplicationLocked(thread, callingPid); 6137 Binder.restoreCallingIdentity(origId); 6138 } 6139 } 6140 6141 @Override 6142 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6143 final long origId = Binder.clearCallingIdentity(); 6144 synchronized (this) { 6145 ActivityStack stack = ActivityRecord.getStackLocked(token); 6146 if (stack != null) { 6147 ActivityRecord r = 6148 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6149 if (stopProfiling) { 6150 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6151 try { 6152 mProfileFd.close(); 6153 } catch (IOException e) { 6154 } 6155 clearProfilerLocked(); 6156 } 6157 } 6158 } 6159 } 6160 Binder.restoreCallingIdentity(origId); 6161 } 6162 6163 void postEnableScreenAfterBootLocked() { 6164 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6165 } 6166 6167 void enableScreenAfterBoot() { 6168 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6169 SystemClock.uptimeMillis()); 6170 mWindowManager.enableScreenAfterBoot(); 6171 6172 synchronized (this) { 6173 updateEventDispatchingLocked(); 6174 } 6175 } 6176 6177 @Override 6178 public void showBootMessage(final CharSequence msg, final boolean always) { 6179 enforceNotIsolatedCaller("showBootMessage"); 6180 mWindowManager.showBootMessage(msg, always); 6181 } 6182 6183 @Override 6184 public void keyguardWaitingForActivityDrawn() { 6185 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6186 final long token = Binder.clearCallingIdentity(); 6187 try { 6188 synchronized (this) { 6189 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6190 mWindowManager.keyguardWaitingForActivityDrawn(); 6191 } 6192 } finally { 6193 Binder.restoreCallingIdentity(token); 6194 } 6195 } 6196 6197 final void finishBooting() { 6198 // Register receivers to handle package update events 6199 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6200 6201 // Let system services know. 6202 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6203 6204 synchronized (this) { 6205 // Ensure that any processes we had put on hold are now started 6206 // up. 6207 final int NP = mProcessesOnHold.size(); 6208 if (NP > 0) { 6209 ArrayList<ProcessRecord> procs = 6210 new ArrayList<ProcessRecord>(mProcessesOnHold); 6211 for (int ip=0; ip<NP; ip++) { 6212 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6213 + procs.get(ip)); 6214 startProcessLocked(procs.get(ip), "on-hold", null); 6215 } 6216 } 6217 6218 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6219 // Start looking for apps that are abusing wake locks. 6220 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6221 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6222 // Tell anyone interested that we are done booting! 6223 SystemProperties.set("sys.boot_completed", "1"); 6224 SystemProperties.set("dev.bootcomplete", "1"); 6225 for (int i=0; i<mStartedUsers.size(); i++) { 6226 UserStartedState uss = mStartedUsers.valueAt(i); 6227 if (uss.mState == UserStartedState.STATE_BOOTING) { 6228 uss.mState = UserStartedState.STATE_RUNNING; 6229 final int userId = mStartedUsers.keyAt(i); 6230 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6231 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6232 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6233 broadcastIntentLocked(null, null, intent, null, 6234 new IIntentReceiver.Stub() { 6235 @Override 6236 public void performReceive(Intent intent, int resultCode, 6237 String data, Bundle extras, boolean ordered, 6238 boolean sticky, int sendingUser) { 6239 synchronized (ActivityManagerService.this) { 6240 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6241 true, false); 6242 } 6243 } 6244 }, 6245 0, null, null, 6246 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6247 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6248 userId); 6249 } 6250 } 6251 scheduleStartProfilesLocked(); 6252 } 6253 } 6254 } 6255 6256 final void ensureBootCompleted() { 6257 boolean booting; 6258 boolean enableScreen; 6259 synchronized (this) { 6260 booting = mBooting; 6261 mBooting = false; 6262 enableScreen = !mBooted; 6263 mBooted = true; 6264 } 6265 6266 if (booting) { 6267 finishBooting(); 6268 } 6269 6270 if (enableScreen) { 6271 enableScreenAfterBoot(); 6272 } 6273 } 6274 6275 @Override 6276 public final void activityResumed(IBinder token) { 6277 final long origId = Binder.clearCallingIdentity(); 6278 synchronized(this) { 6279 ActivityStack stack = ActivityRecord.getStackLocked(token); 6280 if (stack != null) { 6281 ActivityRecord.activityResumedLocked(token); 6282 } 6283 } 6284 Binder.restoreCallingIdentity(origId); 6285 } 6286 6287 @Override 6288 public final void activityPaused(IBinder token) { 6289 final long origId = Binder.clearCallingIdentity(); 6290 synchronized(this) { 6291 ActivityStack stack = ActivityRecord.getStackLocked(token); 6292 if (stack != null) { 6293 stack.activityPausedLocked(token, false); 6294 } 6295 } 6296 Binder.restoreCallingIdentity(origId); 6297 } 6298 6299 @Override 6300 public final void activityStopped(IBinder token, Bundle icicle, 6301 PersistableBundle persistentState, CharSequence description) { 6302 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6303 6304 // Refuse possible leaked file descriptors 6305 if (icicle != null && icicle.hasFileDescriptors()) { 6306 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6307 } 6308 6309 final long origId = Binder.clearCallingIdentity(); 6310 6311 synchronized (this) { 6312 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6313 if (r != null) { 6314 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6315 } 6316 } 6317 6318 trimApplications(); 6319 6320 Binder.restoreCallingIdentity(origId); 6321 } 6322 6323 @Override 6324 public final void activityDestroyed(IBinder token) { 6325 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6326 synchronized (this) { 6327 ActivityStack stack = ActivityRecord.getStackLocked(token); 6328 if (stack != null) { 6329 stack.activityDestroyedLocked(token); 6330 } 6331 } 6332 } 6333 6334 @Override 6335 public final void backgroundResourcesReleased(IBinder token) { 6336 final long origId = Binder.clearCallingIdentity(); 6337 try { 6338 synchronized (this) { 6339 ActivityStack stack = ActivityRecord.getStackLocked(token); 6340 if (stack != null) { 6341 stack.backgroundResourcesReleased(token); 6342 } 6343 } 6344 } finally { 6345 Binder.restoreCallingIdentity(origId); 6346 } 6347 } 6348 6349 @Override 6350 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6351 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6352 } 6353 6354 @Override 6355 public final void notifyEnterAnimationComplete(IBinder token) { 6356 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6357 } 6358 6359 @Override 6360 public String getCallingPackage(IBinder token) { 6361 synchronized (this) { 6362 ActivityRecord r = getCallingRecordLocked(token); 6363 return r != null ? r.info.packageName : null; 6364 } 6365 } 6366 6367 @Override 6368 public ComponentName getCallingActivity(IBinder token) { 6369 synchronized (this) { 6370 ActivityRecord r = getCallingRecordLocked(token); 6371 return r != null ? r.intent.getComponent() : null; 6372 } 6373 } 6374 6375 private ActivityRecord getCallingRecordLocked(IBinder token) { 6376 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6377 if (r == null) { 6378 return null; 6379 } 6380 return r.resultTo; 6381 } 6382 6383 @Override 6384 public ComponentName getActivityClassForToken(IBinder token) { 6385 synchronized(this) { 6386 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6387 if (r == null) { 6388 return null; 6389 } 6390 return r.intent.getComponent(); 6391 } 6392 } 6393 6394 @Override 6395 public String getPackageForToken(IBinder token) { 6396 synchronized(this) { 6397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6398 if (r == null) { 6399 return null; 6400 } 6401 return r.packageName; 6402 } 6403 } 6404 6405 @Override 6406 public IIntentSender getIntentSender(int type, 6407 String packageName, IBinder token, String resultWho, 6408 int requestCode, Intent[] intents, String[] resolvedTypes, 6409 int flags, Bundle options, int userId) { 6410 enforceNotIsolatedCaller("getIntentSender"); 6411 // Refuse possible leaked file descriptors 6412 if (intents != null) { 6413 if (intents.length < 1) { 6414 throw new IllegalArgumentException("Intents array length must be >= 1"); 6415 } 6416 for (int i=0; i<intents.length; i++) { 6417 Intent intent = intents[i]; 6418 if (intent != null) { 6419 if (intent.hasFileDescriptors()) { 6420 throw new IllegalArgumentException("File descriptors passed in Intent"); 6421 } 6422 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6423 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6424 throw new IllegalArgumentException( 6425 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6426 } 6427 intents[i] = new Intent(intent); 6428 } 6429 } 6430 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6431 throw new IllegalArgumentException( 6432 "Intent array length does not match resolvedTypes length"); 6433 } 6434 } 6435 if (options != null) { 6436 if (options.hasFileDescriptors()) { 6437 throw new IllegalArgumentException("File descriptors passed in options"); 6438 } 6439 } 6440 6441 synchronized(this) { 6442 int callingUid = Binder.getCallingUid(); 6443 int origUserId = userId; 6444 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6445 type == ActivityManager.INTENT_SENDER_BROADCAST, 6446 ALLOW_NON_FULL, "getIntentSender", null); 6447 if (origUserId == UserHandle.USER_CURRENT) { 6448 // We don't want to evaluate this until the pending intent is 6449 // actually executed. However, we do want to always do the 6450 // security checking for it above. 6451 userId = UserHandle.USER_CURRENT; 6452 } 6453 try { 6454 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6455 int uid = AppGlobals.getPackageManager() 6456 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6457 if (!UserHandle.isSameApp(callingUid, uid)) { 6458 String msg = "Permission Denial: getIntentSender() from pid=" 6459 + Binder.getCallingPid() 6460 + ", uid=" + Binder.getCallingUid() 6461 + ", (need uid=" + uid + ")" 6462 + " is not allowed to send as package " + packageName; 6463 Slog.w(TAG, msg); 6464 throw new SecurityException(msg); 6465 } 6466 } 6467 6468 return getIntentSenderLocked(type, packageName, callingUid, userId, 6469 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6470 6471 } catch (RemoteException e) { 6472 throw new SecurityException(e); 6473 } 6474 } 6475 } 6476 6477 IIntentSender getIntentSenderLocked(int type, String packageName, 6478 int callingUid, int userId, IBinder token, String resultWho, 6479 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6480 Bundle options) { 6481 if (DEBUG_MU) 6482 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6483 ActivityRecord activity = null; 6484 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6485 activity = ActivityRecord.isInStackLocked(token); 6486 if (activity == null) { 6487 return null; 6488 } 6489 if (activity.finishing) { 6490 return null; 6491 } 6492 } 6493 6494 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6495 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6496 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6497 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6498 |PendingIntent.FLAG_UPDATE_CURRENT); 6499 6500 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6501 type, packageName, activity, resultWho, 6502 requestCode, intents, resolvedTypes, flags, options, userId); 6503 WeakReference<PendingIntentRecord> ref; 6504 ref = mIntentSenderRecords.get(key); 6505 PendingIntentRecord rec = ref != null ? ref.get() : null; 6506 if (rec != null) { 6507 if (!cancelCurrent) { 6508 if (updateCurrent) { 6509 if (rec.key.requestIntent != null) { 6510 rec.key.requestIntent.replaceExtras(intents != null ? 6511 intents[intents.length - 1] : null); 6512 } 6513 if (intents != null) { 6514 intents[intents.length-1] = rec.key.requestIntent; 6515 rec.key.allIntents = intents; 6516 rec.key.allResolvedTypes = resolvedTypes; 6517 } else { 6518 rec.key.allIntents = null; 6519 rec.key.allResolvedTypes = null; 6520 } 6521 } 6522 return rec; 6523 } 6524 rec.canceled = true; 6525 mIntentSenderRecords.remove(key); 6526 } 6527 if (noCreate) { 6528 return rec; 6529 } 6530 rec = new PendingIntentRecord(this, key, callingUid); 6531 mIntentSenderRecords.put(key, rec.ref); 6532 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6533 if (activity.pendingResults == null) { 6534 activity.pendingResults 6535 = new HashSet<WeakReference<PendingIntentRecord>>(); 6536 } 6537 activity.pendingResults.add(rec.ref); 6538 } 6539 return rec; 6540 } 6541 6542 @Override 6543 public void cancelIntentSender(IIntentSender sender) { 6544 if (!(sender instanceof PendingIntentRecord)) { 6545 return; 6546 } 6547 synchronized(this) { 6548 PendingIntentRecord rec = (PendingIntentRecord)sender; 6549 try { 6550 int uid = AppGlobals.getPackageManager() 6551 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6552 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6553 String msg = "Permission Denial: cancelIntentSender() from pid=" 6554 + Binder.getCallingPid() 6555 + ", uid=" + Binder.getCallingUid() 6556 + " is not allowed to cancel packges " 6557 + rec.key.packageName; 6558 Slog.w(TAG, msg); 6559 throw new SecurityException(msg); 6560 } 6561 } catch (RemoteException e) { 6562 throw new SecurityException(e); 6563 } 6564 cancelIntentSenderLocked(rec, true); 6565 } 6566 } 6567 6568 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6569 rec.canceled = true; 6570 mIntentSenderRecords.remove(rec.key); 6571 if (cleanActivity && rec.key.activity != null) { 6572 rec.key.activity.pendingResults.remove(rec.ref); 6573 } 6574 } 6575 6576 @Override 6577 public String getPackageForIntentSender(IIntentSender pendingResult) { 6578 if (!(pendingResult instanceof PendingIntentRecord)) { 6579 return null; 6580 } 6581 try { 6582 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6583 return res.key.packageName; 6584 } catch (ClassCastException e) { 6585 } 6586 return null; 6587 } 6588 6589 @Override 6590 public int getUidForIntentSender(IIntentSender sender) { 6591 if (sender instanceof PendingIntentRecord) { 6592 try { 6593 PendingIntentRecord res = (PendingIntentRecord)sender; 6594 return res.uid; 6595 } catch (ClassCastException e) { 6596 } 6597 } 6598 return -1; 6599 } 6600 6601 @Override 6602 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6603 if (!(pendingResult instanceof PendingIntentRecord)) { 6604 return false; 6605 } 6606 try { 6607 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6608 if (res.key.allIntents == null) { 6609 return false; 6610 } 6611 for (int i=0; i<res.key.allIntents.length; i++) { 6612 Intent intent = res.key.allIntents[i]; 6613 if (intent.getPackage() != null && intent.getComponent() != null) { 6614 return false; 6615 } 6616 } 6617 return true; 6618 } catch (ClassCastException e) { 6619 } 6620 return false; 6621 } 6622 6623 @Override 6624 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6625 if (!(pendingResult instanceof PendingIntentRecord)) { 6626 return false; 6627 } 6628 try { 6629 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6630 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6631 return true; 6632 } 6633 return false; 6634 } catch (ClassCastException e) { 6635 } 6636 return false; 6637 } 6638 6639 @Override 6640 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6641 if (!(pendingResult instanceof PendingIntentRecord)) { 6642 return null; 6643 } 6644 try { 6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6646 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6647 } catch (ClassCastException e) { 6648 } 6649 return null; 6650 } 6651 6652 @Override 6653 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6654 if (!(pendingResult instanceof PendingIntentRecord)) { 6655 return null; 6656 } 6657 try { 6658 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6659 Intent intent = res.key.requestIntent; 6660 if (intent != null) { 6661 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6662 || res.lastTagPrefix.equals(prefix))) { 6663 return res.lastTag; 6664 } 6665 res.lastTagPrefix = prefix; 6666 StringBuilder sb = new StringBuilder(128); 6667 if (prefix != null) { 6668 sb.append(prefix); 6669 } 6670 if (intent.getAction() != null) { 6671 sb.append(intent.getAction()); 6672 } else if (intent.getComponent() != null) { 6673 intent.getComponent().appendShortString(sb); 6674 } else { 6675 sb.append("?"); 6676 } 6677 return res.lastTag = sb.toString(); 6678 } 6679 } catch (ClassCastException e) { 6680 } 6681 return null; 6682 } 6683 6684 @Override 6685 public void setProcessLimit(int max) { 6686 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6687 "setProcessLimit()"); 6688 synchronized (this) { 6689 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6690 mProcessLimitOverride = max; 6691 } 6692 trimApplications(); 6693 } 6694 6695 @Override 6696 public int getProcessLimit() { 6697 synchronized (this) { 6698 return mProcessLimitOverride; 6699 } 6700 } 6701 6702 void foregroundTokenDied(ForegroundToken token) { 6703 synchronized (ActivityManagerService.this) { 6704 synchronized (mPidsSelfLocked) { 6705 ForegroundToken cur 6706 = mForegroundProcesses.get(token.pid); 6707 if (cur != token) { 6708 return; 6709 } 6710 mForegroundProcesses.remove(token.pid); 6711 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6712 if (pr == null) { 6713 return; 6714 } 6715 pr.forcingToForeground = null; 6716 updateProcessForegroundLocked(pr, false, false); 6717 } 6718 updateOomAdjLocked(); 6719 } 6720 } 6721 6722 @Override 6723 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6724 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6725 "setProcessForeground()"); 6726 synchronized(this) { 6727 boolean changed = false; 6728 6729 synchronized (mPidsSelfLocked) { 6730 ProcessRecord pr = mPidsSelfLocked.get(pid); 6731 if (pr == null && isForeground) { 6732 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6733 return; 6734 } 6735 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6736 if (oldToken != null) { 6737 oldToken.token.unlinkToDeath(oldToken, 0); 6738 mForegroundProcesses.remove(pid); 6739 if (pr != null) { 6740 pr.forcingToForeground = null; 6741 } 6742 changed = true; 6743 } 6744 if (isForeground && token != null) { 6745 ForegroundToken newToken = new ForegroundToken() { 6746 @Override 6747 public void binderDied() { 6748 foregroundTokenDied(this); 6749 } 6750 }; 6751 newToken.pid = pid; 6752 newToken.token = token; 6753 try { 6754 token.linkToDeath(newToken, 0); 6755 mForegroundProcesses.put(pid, newToken); 6756 pr.forcingToForeground = token; 6757 changed = true; 6758 } catch (RemoteException e) { 6759 // If the process died while doing this, we will later 6760 // do the cleanup with the process death link. 6761 } 6762 } 6763 } 6764 6765 if (changed) { 6766 updateOomAdjLocked(); 6767 } 6768 } 6769 } 6770 6771 // ========================================================= 6772 // PERMISSIONS 6773 // ========================================================= 6774 6775 static class PermissionController extends IPermissionController.Stub { 6776 ActivityManagerService mActivityManagerService; 6777 PermissionController(ActivityManagerService activityManagerService) { 6778 mActivityManagerService = activityManagerService; 6779 } 6780 6781 @Override 6782 public boolean checkPermission(String permission, int pid, int uid) { 6783 return mActivityManagerService.checkPermission(permission, pid, 6784 uid) == PackageManager.PERMISSION_GRANTED; 6785 } 6786 } 6787 6788 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6789 @Override 6790 public int checkComponentPermission(String permission, int pid, int uid, 6791 int owningUid, boolean exported) { 6792 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6793 owningUid, exported); 6794 } 6795 6796 @Override 6797 public Object getAMSLock() { 6798 return ActivityManagerService.this; 6799 } 6800 } 6801 6802 /** 6803 * This can be called with or without the global lock held. 6804 */ 6805 int checkComponentPermission(String permission, int pid, int uid, 6806 int owningUid, boolean exported) { 6807 // We might be performing an operation on behalf of an indirect binder 6808 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6809 // client identity accordingly before proceeding. 6810 Identity tlsIdentity = sCallerIdentity.get(); 6811 if (tlsIdentity != null) { 6812 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6813 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6814 uid = tlsIdentity.uid; 6815 pid = tlsIdentity.pid; 6816 } 6817 6818 if (pid == MY_PID) { 6819 return PackageManager.PERMISSION_GRANTED; 6820 } 6821 6822 return ActivityManager.checkComponentPermission(permission, uid, 6823 owningUid, exported); 6824 } 6825 6826 /** 6827 * As the only public entry point for permissions checking, this method 6828 * can enforce the semantic that requesting a check on a null global 6829 * permission is automatically denied. (Internally a null permission 6830 * string is used when calling {@link #checkComponentPermission} in cases 6831 * when only uid-based security is needed.) 6832 * 6833 * This can be called with or without the global lock held. 6834 */ 6835 @Override 6836 public int checkPermission(String permission, int pid, int uid) { 6837 if (permission == null) { 6838 return PackageManager.PERMISSION_DENIED; 6839 } 6840 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6841 } 6842 6843 /** 6844 * Binder IPC calls go through the public entry point. 6845 * This can be called with or without the global lock held. 6846 */ 6847 int checkCallingPermission(String permission) { 6848 return checkPermission(permission, 6849 Binder.getCallingPid(), 6850 UserHandle.getAppId(Binder.getCallingUid())); 6851 } 6852 6853 /** 6854 * This can be called with or without the global lock held. 6855 */ 6856 void enforceCallingPermission(String permission, String func) { 6857 if (checkCallingPermission(permission) 6858 == PackageManager.PERMISSION_GRANTED) { 6859 return; 6860 } 6861 6862 String msg = "Permission Denial: " + func + " from pid=" 6863 + Binder.getCallingPid() 6864 + ", uid=" + Binder.getCallingUid() 6865 + " requires " + permission; 6866 Slog.w(TAG, msg); 6867 throw new SecurityException(msg); 6868 } 6869 6870 /** 6871 * Determine if UID is holding permissions required to access {@link Uri} in 6872 * the given {@link ProviderInfo}. Final permission checking is always done 6873 * in {@link ContentProvider}. 6874 */ 6875 private final boolean checkHoldingPermissionsLocked( 6876 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6877 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6878 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6879 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6880 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6881 != PERMISSION_GRANTED) { 6882 return false; 6883 } 6884 } 6885 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6886 } 6887 6888 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6889 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6890 if (pi.applicationInfo.uid == uid) { 6891 return true; 6892 } else if (!pi.exported) { 6893 return false; 6894 } 6895 6896 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6897 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6898 try { 6899 // check if target holds top-level <provider> permissions 6900 if (!readMet && pi.readPermission != null && considerUidPermissions 6901 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6902 readMet = true; 6903 } 6904 if (!writeMet && pi.writePermission != null && considerUidPermissions 6905 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6906 writeMet = true; 6907 } 6908 6909 // track if unprotected read/write is allowed; any denied 6910 // <path-permission> below removes this ability 6911 boolean allowDefaultRead = pi.readPermission == null; 6912 boolean allowDefaultWrite = pi.writePermission == null; 6913 6914 // check if target holds any <path-permission> that match uri 6915 final PathPermission[] pps = pi.pathPermissions; 6916 if (pps != null) { 6917 final String path = grantUri.uri.getPath(); 6918 int i = pps.length; 6919 while (i > 0 && (!readMet || !writeMet)) { 6920 i--; 6921 PathPermission pp = pps[i]; 6922 if (pp.match(path)) { 6923 if (!readMet) { 6924 final String pprperm = pp.getReadPermission(); 6925 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6926 + pprperm + " for " + pp.getPath() 6927 + ": match=" + pp.match(path) 6928 + " check=" + pm.checkUidPermission(pprperm, uid)); 6929 if (pprperm != null) { 6930 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6931 == PERMISSION_GRANTED) { 6932 readMet = true; 6933 } else { 6934 allowDefaultRead = false; 6935 } 6936 } 6937 } 6938 if (!writeMet) { 6939 final String ppwperm = pp.getWritePermission(); 6940 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6941 + ppwperm + " for " + pp.getPath() 6942 + ": match=" + pp.match(path) 6943 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6944 if (ppwperm != null) { 6945 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6946 == PERMISSION_GRANTED) { 6947 writeMet = true; 6948 } else { 6949 allowDefaultWrite = false; 6950 } 6951 } 6952 } 6953 } 6954 } 6955 } 6956 6957 // grant unprotected <provider> read/write, if not blocked by 6958 // <path-permission> above 6959 if (allowDefaultRead) readMet = true; 6960 if (allowDefaultWrite) writeMet = true; 6961 6962 } catch (RemoteException e) { 6963 return false; 6964 } 6965 6966 return readMet && writeMet; 6967 } 6968 6969 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6970 ProviderInfo pi = null; 6971 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6972 if (cpr != null) { 6973 pi = cpr.info; 6974 } else { 6975 try { 6976 pi = AppGlobals.getPackageManager().resolveContentProvider( 6977 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6978 } catch (RemoteException ex) { 6979 } 6980 } 6981 return pi; 6982 } 6983 6984 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6985 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6986 if (targetUris != null) { 6987 return targetUris.get(grantUri); 6988 } 6989 return null; 6990 } 6991 6992 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6993 String targetPkg, int targetUid, GrantUri grantUri) { 6994 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6995 if (targetUris == null) { 6996 targetUris = Maps.newArrayMap(); 6997 mGrantedUriPermissions.put(targetUid, targetUris); 6998 } 6999 7000 UriPermission perm = targetUris.get(grantUri); 7001 if (perm == null) { 7002 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7003 targetUris.put(grantUri, perm); 7004 } 7005 7006 return perm; 7007 } 7008 7009 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7010 final int modeFlags) { 7011 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7012 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7013 : UriPermission.STRENGTH_OWNED; 7014 7015 // Root gets to do everything. 7016 if (uid == 0) { 7017 return true; 7018 } 7019 7020 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7021 if (perms == null) return false; 7022 7023 // First look for exact match 7024 final UriPermission exactPerm = perms.get(grantUri); 7025 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7026 return true; 7027 } 7028 7029 // No exact match, look for prefixes 7030 final int N = perms.size(); 7031 for (int i = 0; i < N; i++) { 7032 final UriPermission perm = perms.valueAt(i); 7033 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7034 && perm.getStrength(modeFlags) >= minStrength) { 7035 return true; 7036 } 7037 } 7038 7039 return false; 7040 } 7041 7042 /** 7043 * @param uri This uri must NOT contain an embedded userId. 7044 * @param userId The userId in which the uri is to be resolved. 7045 */ 7046 @Override 7047 public int checkUriPermission(Uri uri, int pid, int uid, 7048 final int modeFlags, int userId) { 7049 enforceNotIsolatedCaller("checkUriPermission"); 7050 7051 // Another redirected-binder-call permissions check as in 7052 // {@link checkComponentPermission}. 7053 Identity tlsIdentity = sCallerIdentity.get(); 7054 if (tlsIdentity != null) { 7055 uid = tlsIdentity.uid; 7056 pid = tlsIdentity.pid; 7057 } 7058 7059 // Our own process gets to do everything. 7060 if (pid == MY_PID) { 7061 return PackageManager.PERMISSION_GRANTED; 7062 } 7063 synchronized (this) { 7064 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7065 ? PackageManager.PERMISSION_GRANTED 7066 : PackageManager.PERMISSION_DENIED; 7067 } 7068 } 7069 7070 /** 7071 * Check if the targetPkg can be granted permission to access uri by 7072 * the callingUid using the given modeFlags. Throws a security exception 7073 * if callingUid is not allowed to do this. Returns the uid of the target 7074 * if the URI permission grant should be performed; returns -1 if it is not 7075 * needed (for example targetPkg already has permission to access the URI). 7076 * If you already know the uid of the target, you can supply it in 7077 * lastTargetUid else set that to -1. 7078 */ 7079 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7080 final int modeFlags, int lastTargetUid) { 7081 if (!Intent.isAccessUriMode(modeFlags)) { 7082 return -1; 7083 } 7084 7085 if (targetPkg != null) { 7086 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7087 "Checking grant " + targetPkg + " permission to " + grantUri); 7088 } 7089 7090 final IPackageManager pm = AppGlobals.getPackageManager(); 7091 7092 // If this is not a content: uri, we can't do anything with it. 7093 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7094 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7095 "Can't grant URI permission for non-content URI: " + grantUri); 7096 return -1; 7097 } 7098 7099 final String authority = grantUri.uri.getAuthority(); 7100 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7101 if (pi == null) { 7102 Slog.w(TAG, "No content provider found for permission check: " + 7103 grantUri.uri.toSafeString()); 7104 return -1; 7105 } 7106 7107 int targetUid = lastTargetUid; 7108 if (targetUid < 0 && targetPkg != null) { 7109 try { 7110 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7111 if (targetUid < 0) { 7112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7113 "Can't grant URI permission no uid for: " + targetPkg); 7114 return -1; 7115 } 7116 } catch (RemoteException ex) { 7117 return -1; 7118 } 7119 } 7120 7121 if (targetUid >= 0) { 7122 // First... does the target actually need this permission? 7123 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7124 // No need to grant the target this permission. 7125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7126 "Target " + targetPkg + " already has full permission to " + grantUri); 7127 return -1; 7128 } 7129 } else { 7130 // First... there is no target package, so can anyone access it? 7131 boolean allowed = pi.exported; 7132 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7133 if (pi.readPermission != null) { 7134 allowed = false; 7135 } 7136 } 7137 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7138 if (pi.writePermission != null) { 7139 allowed = false; 7140 } 7141 } 7142 if (allowed) { 7143 return -1; 7144 } 7145 } 7146 7147 /* There is a special cross user grant if: 7148 * - The target is on another user. 7149 * - Apps on the current user can access the uri without any uid permissions. 7150 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7151 * grant uri permissions. 7152 */ 7153 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7154 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7155 modeFlags, false /*without considering the uid permissions*/); 7156 7157 // Second... is the provider allowing granting of URI permissions? 7158 if (!specialCrossUserGrant) { 7159 if (!pi.grantUriPermissions) { 7160 throw new SecurityException("Provider " + pi.packageName 7161 + "/" + pi.name 7162 + " does not allow granting of Uri permissions (uri " 7163 + grantUri + ")"); 7164 } 7165 if (pi.uriPermissionPatterns != null) { 7166 final int N = pi.uriPermissionPatterns.length; 7167 boolean allowed = false; 7168 for (int i=0; i<N; i++) { 7169 if (pi.uriPermissionPatterns[i] != null 7170 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7171 allowed = true; 7172 break; 7173 } 7174 } 7175 if (!allowed) { 7176 throw new SecurityException("Provider " + pi.packageName 7177 + "/" + pi.name 7178 + " does not allow granting of permission to path of Uri " 7179 + grantUri); 7180 } 7181 } 7182 } 7183 7184 // Third... does the caller itself have permission to access 7185 // this uri? 7186 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7187 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7188 // Require they hold a strong enough Uri permission 7189 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7190 throw new SecurityException("Uid " + callingUid 7191 + " does not have permission to uri " + grantUri); 7192 } 7193 } 7194 } 7195 return targetUid; 7196 } 7197 7198 /** 7199 * @param uri This uri must NOT contain an embedded userId. 7200 * @param userId The userId in which the uri is to be resolved. 7201 */ 7202 @Override 7203 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7204 final int modeFlags, int userId) { 7205 enforceNotIsolatedCaller("checkGrantUriPermission"); 7206 synchronized(this) { 7207 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7208 new GrantUri(userId, uri, false), modeFlags, -1); 7209 } 7210 } 7211 7212 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7213 final int modeFlags, UriPermissionOwner owner) { 7214 if (!Intent.isAccessUriMode(modeFlags)) { 7215 return; 7216 } 7217 7218 // So here we are: the caller has the assumed permission 7219 // to the uri, and the target doesn't. Let's now give this to 7220 // the target. 7221 7222 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7223 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7224 7225 final String authority = grantUri.uri.getAuthority(); 7226 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7227 if (pi == null) { 7228 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7229 return; 7230 } 7231 7232 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7233 grantUri.prefix = true; 7234 } 7235 final UriPermission perm = findOrCreateUriPermissionLocked( 7236 pi.packageName, targetPkg, targetUid, grantUri); 7237 perm.grantModes(modeFlags, owner); 7238 } 7239 7240 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7241 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7242 if (targetPkg == null) { 7243 throw new NullPointerException("targetPkg"); 7244 } 7245 int targetUid; 7246 final IPackageManager pm = AppGlobals.getPackageManager(); 7247 try { 7248 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7249 } catch (RemoteException ex) { 7250 return; 7251 } 7252 7253 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7254 targetUid); 7255 if (targetUid < 0) { 7256 return; 7257 } 7258 7259 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7260 owner); 7261 } 7262 7263 static class NeededUriGrants extends ArrayList<GrantUri> { 7264 final String targetPkg; 7265 final int targetUid; 7266 final int flags; 7267 7268 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7269 this.targetPkg = targetPkg; 7270 this.targetUid = targetUid; 7271 this.flags = flags; 7272 } 7273 } 7274 7275 /** 7276 * Like checkGrantUriPermissionLocked, but takes an Intent. 7277 */ 7278 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7279 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7280 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7281 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7282 + " clip=" + (intent != null ? intent.getClipData() : null) 7283 + " from " + intent + "; flags=0x" 7284 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7285 7286 if (targetPkg == null) { 7287 throw new NullPointerException("targetPkg"); 7288 } 7289 7290 if (intent == null) { 7291 return null; 7292 } 7293 Uri data = intent.getData(); 7294 ClipData clip = intent.getClipData(); 7295 if (data == null && clip == null) { 7296 return null; 7297 } 7298 // Default userId for uris in the intent (if they don't specify it themselves) 7299 int contentUserHint = intent.getContentUserHint(); 7300 if (contentUserHint == UserHandle.USER_CURRENT) { 7301 contentUserHint = UserHandle.getUserId(callingUid); 7302 } 7303 final IPackageManager pm = AppGlobals.getPackageManager(); 7304 int targetUid; 7305 if (needed != null) { 7306 targetUid = needed.targetUid; 7307 } else { 7308 try { 7309 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7310 } catch (RemoteException ex) { 7311 return null; 7312 } 7313 if (targetUid < 0) { 7314 if (DEBUG_URI_PERMISSION) { 7315 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7316 + " on user " + targetUserId); 7317 } 7318 return null; 7319 } 7320 } 7321 if (data != null) { 7322 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7323 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7324 targetUid); 7325 if (targetUid > 0) { 7326 if (needed == null) { 7327 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7328 } 7329 needed.add(grantUri); 7330 } 7331 } 7332 if (clip != null) { 7333 for (int i=0; i<clip.getItemCount(); i++) { 7334 Uri uri = clip.getItemAt(i).getUri(); 7335 if (uri != null) { 7336 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7337 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7338 targetUid); 7339 if (targetUid > 0) { 7340 if (needed == null) { 7341 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7342 } 7343 needed.add(grantUri); 7344 } 7345 } else { 7346 Intent clipIntent = clip.getItemAt(i).getIntent(); 7347 if (clipIntent != null) { 7348 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7349 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7350 if (newNeeded != null) { 7351 needed = newNeeded; 7352 } 7353 } 7354 } 7355 } 7356 } 7357 7358 return needed; 7359 } 7360 7361 /** 7362 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7363 */ 7364 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7365 UriPermissionOwner owner) { 7366 if (needed != null) { 7367 for (int i=0; i<needed.size(); i++) { 7368 GrantUri grantUri = needed.get(i); 7369 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7370 grantUri, needed.flags, owner); 7371 } 7372 } 7373 } 7374 7375 void grantUriPermissionFromIntentLocked(int callingUid, 7376 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7377 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7378 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7379 if (needed == null) { 7380 return; 7381 } 7382 7383 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7384 } 7385 7386 /** 7387 * @param uri This uri must NOT contain an embedded userId. 7388 * @param userId The userId in which the uri is to be resolved. 7389 */ 7390 @Override 7391 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7392 final int modeFlags, int userId) { 7393 enforceNotIsolatedCaller("grantUriPermission"); 7394 GrantUri grantUri = new GrantUri(userId, uri, false); 7395 synchronized(this) { 7396 final ProcessRecord r = getRecordForAppLocked(caller); 7397 if (r == null) { 7398 throw new SecurityException("Unable to find app for caller " 7399 + caller 7400 + " when granting permission to uri " + grantUri); 7401 } 7402 if (targetPkg == null) { 7403 throw new IllegalArgumentException("null target"); 7404 } 7405 if (grantUri == null) { 7406 throw new IllegalArgumentException("null uri"); 7407 } 7408 7409 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7410 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7411 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7412 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7413 7414 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7415 UserHandle.getUserId(r.uid)); 7416 } 7417 } 7418 7419 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7420 if (perm.modeFlags == 0) { 7421 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7422 perm.targetUid); 7423 if (perms != null) { 7424 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7425 "Removing " + perm.targetUid + " permission to " + perm.uri); 7426 7427 perms.remove(perm.uri); 7428 if (perms.isEmpty()) { 7429 mGrantedUriPermissions.remove(perm.targetUid); 7430 } 7431 } 7432 } 7433 } 7434 7435 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7436 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7437 7438 final IPackageManager pm = AppGlobals.getPackageManager(); 7439 final String authority = grantUri.uri.getAuthority(); 7440 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7441 if (pi == null) { 7442 Slog.w(TAG, "No content provider found for permission revoke: " 7443 + grantUri.toSafeString()); 7444 return; 7445 } 7446 7447 // Does the caller have this permission on the URI? 7448 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7449 // Have they don't have direct access to the URI, then revoke any URI 7450 // permissions that have been granted to them. 7451 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7452 if (perms != null) { 7453 boolean persistChanged = false; 7454 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7455 final UriPermission perm = it.next(); 7456 if (perm.uri.sourceUserId == grantUri.sourceUserId 7457 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7458 if (DEBUG_URI_PERMISSION) 7459 Slog.v(TAG, 7460 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7461 persistChanged |= perm.revokeModes( 7462 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7463 if (perm.modeFlags == 0) { 7464 it.remove(); 7465 } 7466 } 7467 } 7468 if (perms.isEmpty()) { 7469 mGrantedUriPermissions.remove(callingUid); 7470 } 7471 if (persistChanged) { 7472 schedulePersistUriGrants(); 7473 } 7474 } 7475 return; 7476 } 7477 7478 boolean persistChanged = false; 7479 7480 // Go through all of the permissions and remove any that match. 7481 int N = mGrantedUriPermissions.size(); 7482 for (int i = 0; i < N; i++) { 7483 final int targetUid = mGrantedUriPermissions.keyAt(i); 7484 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7485 7486 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7487 final UriPermission perm = it.next(); 7488 if (perm.uri.sourceUserId == grantUri.sourceUserId 7489 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7490 if (DEBUG_URI_PERMISSION) 7491 Slog.v(TAG, 7492 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7493 persistChanged |= perm.revokeModes( 7494 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7495 if (perm.modeFlags == 0) { 7496 it.remove(); 7497 } 7498 } 7499 } 7500 7501 if (perms.isEmpty()) { 7502 mGrantedUriPermissions.remove(targetUid); 7503 N--; 7504 i--; 7505 } 7506 } 7507 7508 if (persistChanged) { 7509 schedulePersistUriGrants(); 7510 } 7511 } 7512 7513 /** 7514 * @param uri This uri must NOT contain an embedded userId. 7515 * @param userId The userId in which the uri is to be resolved. 7516 */ 7517 @Override 7518 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7519 int userId) { 7520 enforceNotIsolatedCaller("revokeUriPermission"); 7521 synchronized(this) { 7522 final ProcessRecord r = getRecordForAppLocked(caller); 7523 if (r == null) { 7524 throw new SecurityException("Unable to find app for caller " 7525 + caller 7526 + " when revoking permission to uri " + uri); 7527 } 7528 if (uri == null) { 7529 Slog.w(TAG, "revokeUriPermission: null uri"); 7530 return; 7531 } 7532 7533 if (!Intent.isAccessUriMode(modeFlags)) { 7534 return; 7535 } 7536 7537 final IPackageManager pm = AppGlobals.getPackageManager(); 7538 final String authority = uri.getAuthority(); 7539 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7540 if (pi == null) { 7541 Slog.w(TAG, "No content provider found for permission revoke: " 7542 + uri.toSafeString()); 7543 return; 7544 } 7545 7546 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7547 } 7548 } 7549 7550 /** 7551 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7552 * given package. 7553 * 7554 * @param packageName Package name to match, or {@code null} to apply to all 7555 * packages. 7556 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7557 * to all users. 7558 * @param persistable If persistable grants should be removed. 7559 */ 7560 private void removeUriPermissionsForPackageLocked( 7561 String packageName, int userHandle, boolean persistable) { 7562 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7563 throw new IllegalArgumentException("Must narrow by either package or user"); 7564 } 7565 7566 boolean persistChanged = false; 7567 7568 int N = mGrantedUriPermissions.size(); 7569 for (int i = 0; i < N; i++) { 7570 final int targetUid = mGrantedUriPermissions.keyAt(i); 7571 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7572 7573 // Only inspect grants matching user 7574 if (userHandle == UserHandle.USER_ALL 7575 || userHandle == UserHandle.getUserId(targetUid)) { 7576 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7577 final UriPermission perm = it.next(); 7578 7579 // Only inspect grants matching package 7580 if (packageName == null || perm.sourcePkg.equals(packageName) 7581 || perm.targetPkg.equals(packageName)) { 7582 persistChanged |= perm.revokeModes( 7583 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7584 7585 // Only remove when no modes remain; any persisted grants 7586 // will keep this alive. 7587 if (perm.modeFlags == 0) { 7588 it.remove(); 7589 } 7590 } 7591 } 7592 7593 if (perms.isEmpty()) { 7594 mGrantedUriPermissions.remove(targetUid); 7595 N--; 7596 i--; 7597 } 7598 } 7599 } 7600 7601 if (persistChanged) { 7602 schedulePersistUriGrants(); 7603 } 7604 } 7605 7606 @Override 7607 public IBinder newUriPermissionOwner(String name) { 7608 enforceNotIsolatedCaller("newUriPermissionOwner"); 7609 synchronized(this) { 7610 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7611 return owner.getExternalTokenLocked(); 7612 } 7613 } 7614 7615 /** 7616 * @param uri This uri must NOT contain an embedded userId. 7617 * @param sourceUserId The userId in which the uri is to be resolved. 7618 * @param targetUserId The userId of the app that receives the grant. 7619 */ 7620 @Override 7621 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7622 final int modeFlags, int sourceUserId, int targetUserId) { 7623 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7624 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7625 synchronized(this) { 7626 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7627 if (owner == null) { 7628 throw new IllegalArgumentException("Unknown owner: " + token); 7629 } 7630 if (fromUid != Binder.getCallingUid()) { 7631 if (Binder.getCallingUid() != Process.myUid()) { 7632 // Only system code can grant URI permissions on behalf 7633 // of other users. 7634 throw new SecurityException("nice try"); 7635 } 7636 } 7637 if (targetPkg == null) { 7638 throw new IllegalArgumentException("null target"); 7639 } 7640 if (uri == null) { 7641 throw new IllegalArgumentException("null uri"); 7642 } 7643 7644 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7645 modeFlags, owner, targetUserId); 7646 } 7647 } 7648 7649 /** 7650 * @param uri This uri must NOT contain an embedded userId. 7651 * @param userId The userId in which the uri is to be resolved. 7652 */ 7653 @Override 7654 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7655 synchronized(this) { 7656 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7657 if (owner == null) { 7658 throw new IllegalArgumentException("Unknown owner: " + token); 7659 } 7660 7661 if (uri == null) { 7662 owner.removeUriPermissionsLocked(mode); 7663 } else { 7664 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7665 } 7666 } 7667 } 7668 7669 private void schedulePersistUriGrants() { 7670 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7671 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7672 10 * DateUtils.SECOND_IN_MILLIS); 7673 } 7674 } 7675 7676 private void writeGrantedUriPermissions() { 7677 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7678 7679 // Snapshot permissions so we can persist without lock 7680 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7681 synchronized (this) { 7682 final int size = mGrantedUriPermissions.size(); 7683 for (int i = 0; i < size; i++) { 7684 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7685 for (UriPermission perm : perms.values()) { 7686 if (perm.persistedModeFlags != 0) { 7687 persist.add(perm.snapshot()); 7688 } 7689 } 7690 } 7691 } 7692 7693 FileOutputStream fos = null; 7694 try { 7695 fos = mGrantFile.startWrite(); 7696 7697 XmlSerializer out = new FastXmlSerializer(); 7698 out.setOutput(fos, "utf-8"); 7699 out.startDocument(null, true); 7700 out.startTag(null, TAG_URI_GRANTS); 7701 for (UriPermission.Snapshot perm : persist) { 7702 out.startTag(null, TAG_URI_GRANT); 7703 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7704 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7705 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7706 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7707 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7708 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7709 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7710 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7711 out.endTag(null, TAG_URI_GRANT); 7712 } 7713 out.endTag(null, TAG_URI_GRANTS); 7714 out.endDocument(); 7715 7716 mGrantFile.finishWrite(fos); 7717 } catch (IOException e) { 7718 if (fos != null) { 7719 mGrantFile.failWrite(fos); 7720 } 7721 } 7722 } 7723 7724 private void readGrantedUriPermissionsLocked() { 7725 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7726 7727 final long now = System.currentTimeMillis(); 7728 7729 FileInputStream fis = null; 7730 try { 7731 fis = mGrantFile.openRead(); 7732 final XmlPullParser in = Xml.newPullParser(); 7733 in.setInput(fis, null); 7734 7735 int type; 7736 while ((type = in.next()) != END_DOCUMENT) { 7737 final String tag = in.getName(); 7738 if (type == START_TAG) { 7739 if (TAG_URI_GRANT.equals(tag)) { 7740 final int sourceUserId; 7741 final int targetUserId; 7742 final int userHandle = readIntAttribute(in, 7743 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7744 if (userHandle != UserHandle.USER_NULL) { 7745 // For backwards compatibility. 7746 sourceUserId = userHandle; 7747 targetUserId = userHandle; 7748 } else { 7749 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7750 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7751 } 7752 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7753 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7754 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7755 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7756 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7757 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7758 7759 // Sanity check that provider still belongs to source package 7760 final ProviderInfo pi = getProviderInfoLocked( 7761 uri.getAuthority(), sourceUserId); 7762 if (pi != null && sourcePkg.equals(pi.packageName)) { 7763 int targetUid = -1; 7764 try { 7765 targetUid = AppGlobals.getPackageManager() 7766 .getPackageUid(targetPkg, targetUserId); 7767 } catch (RemoteException e) { 7768 } 7769 if (targetUid != -1) { 7770 final UriPermission perm = findOrCreateUriPermissionLocked( 7771 sourcePkg, targetPkg, targetUid, 7772 new GrantUri(sourceUserId, uri, prefix)); 7773 perm.initPersistedModes(modeFlags, createdTime); 7774 } 7775 } else { 7776 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7777 + " but instead found " + pi); 7778 } 7779 } 7780 } 7781 } 7782 } catch (FileNotFoundException e) { 7783 // Missing grants is okay 7784 } catch (IOException e) { 7785 Log.wtf(TAG, "Failed reading Uri grants", e); 7786 } catch (XmlPullParserException e) { 7787 Log.wtf(TAG, "Failed reading Uri grants", e); 7788 } finally { 7789 IoUtils.closeQuietly(fis); 7790 } 7791 } 7792 7793 /** 7794 * @param uri This uri must NOT contain an embedded userId. 7795 * @param userId The userId in which the uri is to be resolved. 7796 */ 7797 @Override 7798 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7799 enforceNotIsolatedCaller("takePersistableUriPermission"); 7800 7801 Preconditions.checkFlagsArgument(modeFlags, 7802 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7803 7804 synchronized (this) { 7805 final int callingUid = Binder.getCallingUid(); 7806 boolean persistChanged = false; 7807 GrantUri grantUri = new GrantUri(userId, uri, false); 7808 7809 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7810 new GrantUri(userId, uri, false)); 7811 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7812 new GrantUri(userId, uri, true)); 7813 7814 final boolean exactValid = (exactPerm != null) 7815 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7816 final boolean prefixValid = (prefixPerm != null) 7817 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7818 7819 if (!(exactValid || prefixValid)) { 7820 throw new SecurityException("No persistable permission grants found for UID " 7821 + callingUid + " and Uri " + grantUri.toSafeString()); 7822 } 7823 7824 if (exactValid) { 7825 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7826 } 7827 if (prefixValid) { 7828 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7829 } 7830 7831 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7832 7833 if (persistChanged) { 7834 schedulePersistUriGrants(); 7835 } 7836 } 7837 } 7838 7839 /** 7840 * @param uri This uri must NOT contain an embedded userId. 7841 * @param userId The userId in which the uri is to be resolved. 7842 */ 7843 @Override 7844 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7845 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7846 7847 Preconditions.checkFlagsArgument(modeFlags, 7848 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7849 7850 synchronized (this) { 7851 final int callingUid = Binder.getCallingUid(); 7852 boolean persistChanged = false; 7853 7854 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7855 new GrantUri(userId, uri, false)); 7856 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7857 new GrantUri(userId, uri, true)); 7858 if (exactPerm == null && prefixPerm == null) { 7859 throw new SecurityException("No permission grants found for UID " + callingUid 7860 + " and Uri " + uri.toSafeString()); 7861 } 7862 7863 if (exactPerm != null) { 7864 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7865 removeUriPermissionIfNeededLocked(exactPerm); 7866 } 7867 if (prefixPerm != null) { 7868 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7869 removeUriPermissionIfNeededLocked(prefixPerm); 7870 } 7871 7872 if (persistChanged) { 7873 schedulePersistUriGrants(); 7874 } 7875 } 7876 } 7877 7878 /** 7879 * Prune any older {@link UriPermission} for the given UID until outstanding 7880 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7881 * 7882 * @return if any mutations occured that require persisting. 7883 */ 7884 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7885 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7886 if (perms == null) return false; 7887 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7888 7889 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7890 for (UriPermission perm : perms.values()) { 7891 if (perm.persistedModeFlags != 0) { 7892 persisted.add(perm); 7893 } 7894 } 7895 7896 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7897 if (trimCount <= 0) return false; 7898 7899 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7900 for (int i = 0; i < trimCount; i++) { 7901 final UriPermission perm = persisted.get(i); 7902 7903 if (DEBUG_URI_PERMISSION) { 7904 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7905 } 7906 7907 perm.releasePersistableModes(~0); 7908 removeUriPermissionIfNeededLocked(perm); 7909 } 7910 7911 return true; 7912 } 7913 7914 @Override 7915 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7916 String packageName, boolean incoming) { 7917 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7918 Preconditions.checkNotNull(packageName, "packageName"); 7919 7920 final int callingUid = Binder.getCallingUid(); 7921 final IPackageManager pm = AppGlobals.getPackageManager(); 7922 try { 7923 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7924 if (packageUid != callingUid) { 7925 throw new SecurityException( 7926 "Package " + packageName + " does not belong to calling UID " + callingUid); 7927 } 7928 } catch (RemoteException e) { 7929 throw new SecurityException("Failed to verify package name ownership"); 7930 } 7931 7932 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7933 synchronized (this) { 7934 if (incoming) { 7935 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7936 callingUid); 7937 if (perms == null) { 7938 Slog.w(TAG, "No permission grants found for " + packageName); 7939 } else { 7940 for (UriPermission perm : perms.values()) { 7941 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7942 result.add(perm.buildPersistedPublicApiObject()); 7943 } 7944 } 7945 } 7946 } else { 7947 final int size = mGrantedUriPermissions.size(); 7948 for (int i = 0; i < size; i++) { 7949 final ArrayMap<GrantUri, UriPermission> perms = 7950 mGrantedUriPermissions.valueAt(i); 7951 for (UriPermission perm : perms.values()) { 7952 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7953 result.add(perm.buildPersistedPublicApiObject()); 7954 } 7955 } 7956 } 7957 } 7958 } 7959 return new ParceledListSlice<android.content.UriPermission>(result); 7960 } 7961 7962 @Override 7963 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7964 synchronized (this) { 7965 ProcessRecord app = 7966 who != null ? getRecordForAppLocked(who) : null; 7967 if (app == null) return; 7968 7969 Message msg = Message.obtain(); 7970 msg.what = WAIT_FOR_DEBUGGER_MSG; 7971 msg.obj = app; 7972 msg.arg1 = waiting ? 1 : 0; 7973 mHandler.sendMessage(msg); 7974 } 7975 } 7976 7977 @Override 7978 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7979 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7980 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7981 outInfo.availMem = Process.getFreeMemory(); 7982 outInfo.totalMem = Process.getTotalMemory(); 7983 outInfo.threshold = homeAppMem; 7984 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7985 outInfo.hiddenAppThreshold = cachedAppMem; 7986 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7987 ProcessList.SERVICE_ADJ); 7988 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7989 ProcessList.VISIBLE_APP_ADJ); 7990 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7991 ProcessList.FOREGROUND_APP_ADJ); 7992 } 7993 7994 // ========================================================= 7995 // TASK MANAGEMENT 7996 // ========================================================= 7997 7998 @Override 7999 public List<IAppTask> getAppTasks(String callingPackage) { 8000 int callingUid = Binder.getCallingUid(); 8001 long ident = Binder.clearCallingIdentity(); 8002 8003 synchronized(this) { 8004 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8005 try { 8006 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8007 8008 final int N = mRecentTasks.size(); 8009 for (int i = 0; i < N; i++) { 8010 TaskRecord tr = mRecentTasks.get(i); 8011 // Skip tasks that do not match the caller. We don't need to verify 8012 // callingPackage, because we are also limiting to callingUid and know 8013 // that will limit to the correct security sandbox. 8014 if (tr.effectiveUid != callingUid) { 8015 continue; 8016 } 8017 Intent intent = tr.getBaseIntent(); 8018 if (intent == null || 8019 !callingPackage.equals(intent.getComponent().getPackageName())) { 8020 continue; 8021 } 8022 ActivityManager.RecentTaskInfo taskInfo = 8023 createRecentTaskInfoFromTaskRecord(tr); 8024 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8025 list.add(taskImpl); 8026 } 8027 } finally { 8028 Binder.restoreCallingIdentity(ident); 8029 } 8030 return list; 8031 } 8032 } 8033 8034 @Override 8035 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8036 final int callingUid = Binder.getCallingUid(); 8037 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8038 8039 synchronized(this) { 8040 if (localLOGV) Slog.v( 8041 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8042 8043 final boolean allowed = checkCallingPermission( 8044 android.Manifest.permission.GET_TASKS) 8045 == PackageManager.PERMISSION_GRANTED; 8046 if (!allowed) { 8047 Slog.w(TAG, "getTasks: caller " + callingUid 8048 + " does not hold GET_TASKS; limiting output"); 8049 } 8050 8051 // TODO: Improve with MRU list from all ActivityStacks. 8052 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8053 } 8054 8055 return list; 8056 } 8057 8058 TaskRecord getMostRecentTask() { 8059 return mRecentTasks.get(0); 8060 } 8061 8062 /** 8063 * Creates a new RecentTaskInfo from a TaskRecord. 8064 */ 8065 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8066 // Update the task description to reflect any changes in the task stack 8067 tr.updateTaskDescription(); 8068 8069 // Compose the recent task info 8070 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8071 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8072 rti.persistentId = tr.taskId; 8073 rti.baseIntent = new Intent(tr.getBaseIntent()); 8074 rti.origActivity = tr.origActivity; 8075 rti.description = tr.lastDescription; 8076 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8077 rti.userId = tr.userId; 8078 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8079 rti.firstActiveTime = tr.firstActiveTime; 8080 rti.lastActiveTime = tr.lastActiveTime; 8081 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8082 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8083 return rti; 8084 } 8085 8086 @Override 8087 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8088 final int callingUid = Binder.getCallingUid(); 8089 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8090 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8091 8092 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8093 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8094 synchronized (this) { 8095 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8096 == PackageManager.PERMISSION_GRANTED; 8097 if (!allowed) { 8098 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8099 + " does not hold GET_TASKS; limiting output"); 8100 } 8101 final boolean detailed = checkCallingPermission( 8102 android.Manifest.permission.GET_DETAILED_TASKS) 8103 == PackageManager.PERMISSION_GRANTED; 8104 8105 final int N = mRecentTasks.size(); 8106 ArrayList<ActivityManager.RecentTaskInfo> res 8107 = new ArrayList<ActivityManager.RecentTaskInfo>( 8108 maxNum < N ? maxNum : N); 8109 8110 final Set<Integer> includedUsers; 8111 if (includeProfiles) { 8112 includedUsers = getProfileIdsLocked(userId); 8113 } else { 8114 includedUsers = new HashSet<Integer>(); 8115 } 8116 includedUsers.add(Integer.valueOf(userId)); 8117 8118 for (int i=0; i<N && maxNum > 0; i++) { 8119 TaskRecord tr = mRecentTasks.get(i); 8120 // Only add calling user or related users recent tasks 8121 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8122 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8123 continue; 8124 } 8125 8126 // Return the entry if desired by the caller. We always return 8127 // the first entry, because callers always expect this to be the 8128 // foreground app. We may filter others if the caller has 8129 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8130 // we should exclude the entry. 8131 8132 if (i == 0 8133 || withExcluded 8134 || (tr.intent == null) 8135 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8136 == 0)) { 8137 if (!allowed) { 8138 // If the caller doesn't have the GET_TASKS permission, then only 8139 // allow them to see a small subset of tasks -- their own and home. 8140 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8141 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8142 continue; 8143 } 8144 } 8145 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8146 if (tr.stack != null && tr.stack.isHomeStack()) { 8147 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8148 continue; 8149 } 8150 } 8151 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8152 // Don't include auto remove tasks that are finished or finishing. 8153 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8154 + tr); 8155 continue; 8156 } 8157 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8158 && !tr.isAvailable) { 8159 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8160 continue; 8161 } 8162 8163 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8164 if (!detailed) { 8165 rti.baseIntent.replaceExtras((Bundle)null); 8166 } 8167 8168 res.add(rti); 8169 maxNum--; 8170 } 8171 } 8172 return res; 8173 } 8174 } 8175 8176 private TaskRecord recentTaskForIdLocked(int id) { 8177 final int N = mRecentTasks.size(); 8178 for (int i=0; i<N; i++) { 8179 TaskRecord tr = mRecentTasks.get(i); 8180 if (tr.taskId == id) { 8181 return tr; 8182 } 8183 } 8184 return null; 8185 } 8186 8187 @Override 8188 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8189 synchronized (this) { 8190 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8191 "getTaskThumbnail()"); 8192 TaskRecord tr = recentTaskForIdLocked(id); 8193 if (tr != null) { 8194 return tr.getTaskThumbnailLocked(); 8195 } 8196 } 8197 return null; 8198 } 8199 8200 @Override 8201 public int addAppTask(IBinder activityToken, Intent intent, 8202 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8203 final int callingUid = Binder.getCallingUid(); 8204 final long callingIdent = Binder.clearCallingIdentity(); 8205 8206 try { 8207 synchronized (this) { 8208 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8209 if (r == null) { 8210 throw new IllegalArgumentException("Activity does not exist; token=" 8211 + activityToken); 8212 } 8213 ComponentName comp = intent.getComponent(); 8214 if (comp == null) { 8215 throw new IllegalArgumentException("Intent " + intent 8216 + " must specify explicit component"); 8217 } 8218 if (thumbnail.getWidth() != mThumbnailWidth 8219 || thumbnail.getHeight() != mThumbnailHeight) { 8220 throw new IllegalArgumentException("Bad thumbnail size: got " 8221 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8222 + mThumbnailWidth + "x" + mThumbnailHeight); 8223 } 8224 if (intent.getSelector() != null) { 8225 intent.setSelector(null); 8226 } 8227 if (intent.getSourceBounds() != null) { 8228 intent.setSourceBounds(null); 8229 } 8230 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8231 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8232 // The caller has added this as an auto-remove task... that makes no 8233 // sense, so turn off auto-remove. 8234 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8235 } 8236 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8237 // Must be a new task. 8238 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8239 } 8240 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8241 mLastAddedTaskActivity = null; 8242 } 8243 ActivityInfo ainfo = mLastAddedTaskActivity; 8244 if (ainfo == null) { 8245 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8246 comp, 0, UserHandle.getUserId(callingUid)); 8247 if (ainfo.applicationInfo.uid != callingUid) { 8248 throw new SecurityException( 8249 "Can't add task for another application: target uid=" 8250 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8251 } 8252 } 8253 8254 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8255 intent, description); 8256 8257 int trimIdx = trimRecentsForTask(task, false); 8258 if (trimIdx >= 0) { 8259 // If this would have caused a trim, then we'll abort because that 8260 // means it would be added at the end of the list but then just removed. 8261 return -1; 8262 } 8263 8264 final int N = mRecentTasks.size(); 8265 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8266 final TaskRecord tr = mRecentTasks.remove(N - 1); 8267 tr.removedFromRecents(mTaskPersister); 8268 } 8269 8270 task.inRecents = true; 8271 mRecentTasks.add(task); 8272 r.task.stack.addTask(task, false, false); 8273 8274 task.setLastThumbnail(thumbnail); 8275 task.freeLastThumbnail(); 8276 8277 return task.taskId; 8278 } 8279 } finally { 8280 Binder.restoreCallingIdentity(callingIdent); 8281 } 8282 } 8283 8284 @Override 8285 public Point getAppTaskThumbnailSize() { 8286 synchronized (this) { 8287 return new Point(mThumbnailWidth, mThumbnailHeight); 8288 } 8289 } 8290 8291 @Override 8292 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8293 synchronized (this) { 8294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8295 if (r != null) { 8296 r.taskDescription = td; 8297 r.task.updateTaskDescription(); 8298 } 8299 } 8300 } 8301 8302 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8303 mRecentTasks.remove(tr); 8304 tr.removedFromRecents(mTaskPersister); 8305 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8306 Intent baseIntent = new Intent( 8307 tr.intent != null ? tr.intent : tr.affinityIntent); 8308 ComponentName component = baseIntent.getComponent(); 8309 if (component == null) { 8310 Slog.w(TAG, "Now component for base intent of task: " + tr); 8311 return; 8312 } 8313 8314 // Find any running services associated with this app. 8315 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8316 8317 if (killProcesses) { 8318 // Find any running processes associated with this app. 8319 final String pkg = component.getPackageName(); 8320 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8321 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8322 for (int i=0; i<pmap.size(); i++) { 8323 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8324 for (int j=0; j<uids.size(); j++) { 8325 ProcessRecord proc = uids.valueAt(j); 8326 if (proc.userId != tr.userId) { 8327 continue; 8328 } 8329 if (!proc.pkgList.containsKey(pkg)) { 8330 continue; 8331 } 8332 procs.add(proc); 8333 } 8334 } 8335 8336 // Kill the running processes. 8337 for (int i=0; i<procs.size(); i++) { 8338 ProcessRecord pr = procs.get(i); 8339 if (pr == mHomeProcess) { 8340 // Don't kill the home process along with tasks from the same package. 8341 continue; 8342 } 8343 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8344 pr.kill("remove task", true); 8345 } else { 8346 pr.waitingToKill = "remove task"; 8347 } 8348 } 8349 } 8350 } 8351 8352 /** 8353 * Removes the task with the specified task id. 8354 * 8355 * @param taskId Identifier of the task to be removed. 8356 * @param flags Additional operational flags. May be 0 or 8357 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8358 * @return Returns true if the given task was found and removed. 8359 */ 8360 private boolean removeTaskByIdLocked(int taskId, int flags) { 8361 TaskRecord tr = recentTaskForIdLocked(taskId); 8362 if (tr != null) { 8363 tr.removeTaskActivitiesLocked(); 8364 cleanUpRemovedTaskLocked(tr, flags); 8365 if (tr.isPersistable) { 8366 notifyTaskPersisterLocked(null, true); 8367 } 8368 return true; 8369 } 8370 return false; 8371 } 8372 8373 @Override 8374 public boolean removeTask(int taskId, int flags) { 8375 synchronized (this) { 8376 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8377 "removeTask()"); 8378 long ident = Binder.clearCallingIdentity(); 8379 try { 8380 return removeTaskByIdLocked(taskId, flags); 8381 } finally { 8382 Binder.restoreCallingIdentity(ident); 8383 } 8384 } 8385 } 8386 8387 /** 8388 * TODO: Add mController hook 8389 */ 8390 @Override 8391 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8392 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8393 "moveTaskToFront()"); 8394 8395 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8396 synchronized(this) { 8397 moveTaskToFrontLocked(taskId, flags, options); 8398 } 8399 } 8400 8401 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8402 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8403 Binder.getCallingUid(), "Task to front")) { 8404 ActivityOptions.abort(options); 8405 return; 8406 } 8407 final long origId = Binder.clearCallingIdentity(); 8408 try { 8409 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8410 if (task == null) { 8411 return; 8412 } 8413 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8414 mStackSupervisor.showLockTaskToast(); 8415 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8416 return; 8417 } 8418 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8419 if (prev != null && prev.isRecentsActivity()) { 8420 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8421 } 8422 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8423 } finally { 8424 Binder.restoreCallingIdentity(origId); 8425 } 8426 ActivityOptions.abort(options); 8427 } 8428 8429 @Override 8430 public void moveTaskToBack(int taskId) { 8431 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8432 "moveTaskToBack()"); 8433 8434 synchronized(this) { 8435 TaskRecord tr = recentTaskForIdLocked(taskId); 8436 if (tr != null) { 8437 if (tr == mStackSupervisor.mLockTaskModeTask) { 8438 mStackSupervisor.showLockTaskToast(); 8439 return; 8440 } 8441 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8442 ActivityStack stack = tr.stack; 8443 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8444 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8445 Binder.getCallingUid(), "Task to back")) { 8446 return; 8447 } 8448 } 8449 final long origId = Binder.clearCallingIdentity(); 8450 try { 8451 stack.moveTaskToBackLocked(taskId, null); 8452 } finally { 8453 Binder.restoreCallingIdentity(origId); 8454 } 8455 } 8456 } 8457 } 8458 8459 /** 8460 * Moves an activity, and all of the other activities within the same task, to the bottom 8461 * of the history stack. The activity's order within the task is unchanged. 8462 * 8463 * @param token A reference to the activity we wish to move 8464 * @param nonRoot If false then this only works if the activity is the root 8465 * of a task; if true it will work for any activity in a task. 8466 * @return Returns true if the move completed, false if not. 8467 */ 8468 @Override 8469 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8470 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8471 synchronized(this) { 8472 final long origId = Binder.clearCallingIdentity(); 8473 try { 8474 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8475 if (taskId >= 0) { 8476 if ((mStackSupervisor.mLockTaskModeTask != null) 8477 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8478 mStackSupervisor.showLockTaskToast(); 8479 return false; 8480 } 8481 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8482 } 8483 } finally { 8484 Binder.restoreCallingIdentity(origId); 8485 } 8486 } 8487 return false; 8488 } 8489 8490 @Override 8491 public void moveTaskBackwards(int task) { 8492 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8493 "moveTaskBackwards()"); 8494 8495 synchronized(this) { 8496 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8497 Binder.getCallingUid(), "Task backwards")) { 8498 return; 8499 } 8500 final long origId = Binder.clearCallingIdentity(); 8501 moveTaskBackwardsLocked(task); 8502 Binder.restoreCallingIdentity(origId); 8503 } 8504 } 8505 8506 private final void moveTaskBackwardsLocked(int task) { 8507 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8508 } 8509 8510 @Override 8511 public IBinder getHomeActivityToken() throws RemoteException { 8512 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8513 "getHomeActivityToken()"); 8514 synchronized (this) { 8515 return mStackSupervisor.getHomeActivityToken(); 8516 } 8517 } 8518 8519 @Override 8520 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8521 IActivityContainerCallback callback) throws RemoteException { 8522 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8523 "createActivityContainer()"); 8524 synchronized (this) { 8525 if (parentActivityToken == null) { 8526 throw new IllegalArgumentException("parent token must not be null"); 8527 } 8528 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8529 if (r == null) { 8530 return null; 8531 } 8532 if (callback == null) { 8533 throw new IllegalArgumentException("callback must not be null"); 8534 } 8535 return mStackSupervisor.createActivityContainer(r, callback); 8536 } 8537 } 8538 8539 @Override 8540 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8541 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8542 "deleteActivityContainer()"); 8543 synchronized (this) { 8544 mStackSupervisor.deleteActivityContainer(container); 8545 } 8546 } 8547 8548 @Override 8549 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8550 throws RemoteException { 8551 synchronized (this) { 8552 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8553 if (stack != null) { 8554 return stack.mActivityContainer; 8555 } 8556 return null; 8557 } 8558 } 8559 8560 @Override 8561 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8562 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8563 "moveTaskToStack()"); 8564 if (stackId == HOME_STACK_ID) { 8565 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8566 new RuntimeException("here").fillInStackTrace()); 8567 } 8568 synchronized (this) { 8569 long ident = Binder.clearCallingIdentity(); 8570 try { 8571 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8572 + stackId + " toTop=" + toTop); 8573 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8574 } finally { 8575 Binder.restoreCallingIdentity(ident); 8576 } 8577 } 8578 } 8579 8580 @Override 8581 public void resizeStack(int stackBoxId, Rect bounds) { 8582 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8583 "resizeStackBox()"); 8584 long ident = Binder.clearCallingIdentity(); 8585 try { 8586 mWindowManager.resizeStack(stackBoxId, bounds); 8587 } finally { 8588 Binder.restoreCallingIdentity(ident); 8589 } 8590 } 8591 8592 @Override 8593 public List<StackInfo> getAllStackInfos() { 8594 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8595 "getAllStackInfos()"); 8596 long ident = Binder.clearCallingIdentity(); 8597 try { 8598 synchronized (this) { 8599 return mStackSupervisor.getAllStackInfosLocked(); 8600 } 8601 } finally { 8602 Binder.restoreCallingIdentity(ident); 8603 } 8604 } 8605 8606 @Override 8607 public StackInfo getStackInfo(int stackId) { 8608 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8609 "getStackInfo()"); 8610 long ident = Binder.clearCallingIdentity(); 8611 try { 8612 synchronized (this) { 8613 return mStackSupervisor.getStackInfoLocked(stackId); 8614 } 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public boolean isInHomeStack(int taskId) { 8622 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8623 "getStackInfo()"); 8624 long ident = Binder.clearCallingIdentity(); 8625 try { 8626 synchronized (this) { 8627 TaskRecord tr = recentTaskForIdLocked(taskId); 8628 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8629 } 8630 } finally { 8631 Binder.restoreCallingIdentity(ident); 8632 } 8633 } 8634 8635 @Override 8636 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8637 synchronized(this) { 8638 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8639 } 8640 } 8641 8642 private boolean isLockTaskAuthorized(String pkg) { 8643 final DevicePolicyManager dpm = (DevicePolicyManager) 8644 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8645 try { 8646 int uid = mContext.getPackageManager().getPackageUid(pkg, 8647 Binder.getCallingUserHandle().getIdentifier()); 8648 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8649 } catch (NameNotFoundException e) { 8650 return false; 8651 } 8652 } 8653 8654 void startLockTaskMode(TaskRecord task) { 8655 final String pkg; 8656 synchronized (this) { 8657 pkg = task.intent.getComponent().getPackageName(); 8658 } 8659 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8660 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8661 final TaskRecord taskRecord = task; 8662 mHandler.post(new Runnable() { 8663 @Override 8664 public void run() { 8665 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8666 } 8667 }); 8668 return; 8669 } 8670 long ident = Binder.clearCallingIdentity(); 8671 try { 8672 synchronized (this) { 8673 // Since we lost lock on task, make sure it is still there. 8674 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8675 if (task != null) { 8676 if (!isSystemInitiated 8677 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8678 throw new IllegalArgumentException("Invalid task, not in foreground"); 8679 } 8680 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8681 } 8682 } 8683 } finally { 8684 Binder.restoreCallingIdentity(ident); 8685 } 8686 } 8687 8688 @Override 8689 public void startLockTaskMode(int taskId) { 8690 final TaskRecord task; 8691 long ident = Binder.clearCallingIdentity(); 8692 try { 8693 synchronized (this) { 8694 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8695 } 8696 } finally { 8697 Binder.restoreCallingIdentity(ident); 8698 } 8699 if (task != null) { 8700 startLockTaskMode(task); 8701 } 8702 } 8703 8704 @Override 8705 public void startLockTaskMode(IBinder token) { 8706 final TaskRecord task; 8707 long ident = Binder.clearCallingIdentity(); 8708 try { 8709 synchronized (this) { 8710 final ActivityRecord r = ActivityRecord.forToken(token); 8711 if (r == null) { 8712 return; 8713 } 8714 task = r.task; 8715 } 8716 } finally { 8717 Binder.restoreCallingIdentity(ident); 8718 } 8719 if (task != null) { 8720 startLockTaskMode(task); 8721 } 8722 } 8723 8724 @Override 8725 public void startLockTaskModeOnCurrent() throws RemoteException { 8726 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8727 "startLockTaskModeOnCurrent"); 8728 ActivityRecord r = null; 8729 synchronized (this) { 8730 r = mStackSupervisor.topRunningActivityLocked(); 8731 } 8732 startLockTaskMode(r.task); 8733 } 8734 8735 @Override 8736 public void stopLockTaskMode() { 8737 // Verify that the user matches the package of the intent for the TaskRecord 8738 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8739 // and stopLockTaskMode. 8740 final int callingUid = Binder.getCallingUid(); 8741 if (callingUid != Process.SYSTEM_UID) { 8742 try { 8743 String pkg = 8744 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8745 int uid = mContext.getPackageManager().getPackageUid(pkg, 8746 Binder.getCallingUserHandle().getIdentifier()); 8747 if (uid != callingUid) { 8748 throw new SecurityException("Invalid uid, expected " + uid); 8749 } 8750 } catch (NameNotFoundException e) { 8751 Log.d(TAG, "stopLockTaskMode " + e); 8752 return; 8753 } 8754 } 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 Log.d(TAG, "stopLockTaskMode"); 8758 // Stop lock task 8759 synchronized (this) { 8760 mStackSupervisor.setLockTaskModeLocked(null, false); 8761 } 8762 } finally { 8763 Binder.restoreCallingIdentity(ident); 8764 } 8765 } 8766 8767 @Override 8768 public void stopLockTaskModeOnCurrent() throws RemoteException { 8769 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8770 "stopLockTaskModeOnCurrent"); 8771 long ident = Binder.clearCallingIdentity(); 8772 try { 8773 stopLockTaskMode(); 8774 } finally { 8775 Binder.restoreCallingIdentity(ident); 8776 } 8777 } 8778 8779 @Override 8780 public boolean isInLockTaskMode() { 8781 synchronized (this) { 8782 return mStackSupervisor.isInLockTaskMode(); 8783 } 8784 } 8785 8786 // ========================================================= 8787 // CONTENT PROVIDERS 8788 // ========================================================= 8789 8790 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8791 List<ProviderInfo> providers = null; 8792 try { 8793 providers = AppGlobals.getPackageManager(). 8794 queryContentProviders(app.processName, app.uid, 8795 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8796 } catch (RemoteException ex) { 8797 } 8798 if (DEBUG_MU) 8799 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8800 int userId = app.userId; 8801 if (providers != null) { 8802 int N = providers.size(); 8803 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8804 for (int i=0; i<N; i++) { 8805 ProviderInfo cpi = 8806 (ProviderInfo)providers.get(i); 8807 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8808 cpi.name, cpi.flags); 8809 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8810 // This is a singleton provider, but a user besides the 8811 // default user is asking to initialize a process it runs 8812 // in... well, no, it doesn't actually run in this process, 8813 // it runs in the process of the default user. Get rid of it. 8814 providers.remove(i); 8815 N--; 8816 i--; 8817 continue; 8818 } 8819 8820 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8821 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8822 if (cpr == null) { 8823 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8824 mProviderMap.putProviderByClass(comp, cpr); 8825 } 8826 if (DEBUG_MU) 8827 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8828 app.pubProviders.put(cpi.name, cpr); 8829 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8830 // Don't add this if it is a platform component that is marked 8831 // to run in multiple processes, because this is actually 8832 // part of the framework so doesn't make sense to track as a 8833 // separate apk in the process. 8834 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8835 mProcessStats); 8836 } 8837 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8838 } 8839 } 8840 return providers; 8841 } 8842 8843 /** 8844 * Check if {@link ProcessRecord} has a possible chance at accessing the 8845 * given {@link ProviderInfo}. Final permission checking is always done 8846 * in {@link ContentProvider}. 8847 */ 8848 private final String checkContentProviderPermissionLocked( 8849 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8850 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8851 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8852 boolean checkedGrants = false; 8853 if (checkUser) { 8854 // Looking for cross-user grants before enforcing the typical cross-users permissions 8855 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8856 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8857 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8858 return null; 8859 } 8860 checkedGrants = true; 8861 } 8862 userId = handleIncomingUser(callingPid, callingUid, userId, 8863 false, ALLOW_NON_FULL, 8864 "checkContentProviderPermissionLocked " + cpi.authority, null); 8865 if (userId != tmpTargetUserId) { 8866 // When we actually went to determine the final targer user ID, this ended 8867 // up different than our initial check for the authority. This is because 8868 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8869 // SELF. So we need to re-check the grants again. 8870 checkedGrants = false; 8871 } 8872 } 8873 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8874 cpi.applicationInfo.uid, cpi.exported) 8875 == PackageManager.PERMISSION_GRANTED) { 8876 return null; 8877 } 8878 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8879 cpi.applicationInfo.uid, cpi.exported) 8880 == PackageManager.PERMISSION_GRANTED) { 8881 return null; 8882 } 8883 8884 PathPermission[] pps = cpi.pathPermissions; 8885 if (pps != null) { 8886 int i = pps.length; 8887 while (i > 0) { 8888 i--; 8889 PathPermission pp = pps[i]; 8890 String pprperm = pp.getReadPermission(); 8891 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8892 cpi.applicationInfo.uid, cpi.exported) 8893 == PackageManager.PERMISSION_GRANTED) { 8894 return null; 8895 } 8896 String ppwperm = pp.getWritePermission(); 8897 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8898 cpi.applicationInfo.uid, cpi.exported) 8899 == PackageManager.PERMISSION_GRANTED) { 8900 return null; 8901 } 8902 } 8903 } 8904 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8905 return null; 8906 } 8907 8908 String msg; 8909 if (!cpi.exported) { 8910 msg = "Permission Denial: opening provider " + cpi.name 8911 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8912 + ", uid=" + callingUid + ") that is not exported from uid " 8913 + cpi.applicationInfo.uid; 8914 } else { 8915 msg = "Permission Denial: opening provider " + cpi.name 8916 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8917 + ", uid=" + callingUid + ") requires " 8918 + cpi.readPermission + " or " + cpi.writePermission; 8919 } 8920 Slog.w(TAG, msg); 8921 return msg; 8922 } 8923 8924 /** 8925 * Returns if the ContentProvider has granted a uri to callingUid 8926 */ 8927 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8928 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8929 if (perms != null) { 8930 for (int i=perms.size()-1; i>=0; i--) { 8931 GrantUri grantUri = perms.keyAt(i); 8932 if (grantUri.sourceUserId == userId || !checkUser) { 8933 if (matchesProvider(grantUri.uri, cpi)) { 8934 return true; 8935 } 8936 } 8937 } 8938 } 8939 return false; 8940 } 8941 8942 /** 8943 * Returns true if the uri authority is one of the authorities specified in the provider. 8944 */ 8945 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8946 String uriAuth = uri.getAuthority(); 8947 String cpiAuth = cpi.authority; 8948 if (cpiAuth.indexOf(';') == -1) { 8949 return cpiAuth.equals(uriAuth); 8950 } 8951 String[] cpiAuths = cpiAuth.split(";"); 8952 int length = cpiAuths.length; 8953 for (int i = 0; i < length; i++) { 8954 if (cpiAuths[i].equals(uriAuth)) return true; 8955 } 8956 return false; 8957 } 8958 8959 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8960 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8961 if (r != null) { 8962 for (int i=0; i<r.conProviders.size(); i++) { 8963 ContentProviderConnection conn = r.conProviders.get(i); 8964 if (conn.provider == cpr) { 8965 if (DEBUG_PROVIDER) Slog.v(TAG, 8966 "Adding provider requested by " 8967 + r.processName + " from process " 8968 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8969 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8970 if (stable) { 8971 conn.stableCount++; 8972 conn.numStableIncs++; 8973 } else { 8974 conn.unstableCount++; 8975 conn.numUnstableIncs++; 8976 } 8977 return conn; 8978 } 8979 } 8980 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8981 if (stable) { 8982 conn.stableCount = 1; 8983 conn.numStableIncs = 1; 8984 } else { 8985 conn.unstableCount = 1; 8986 conn.numUnstableIncs = 1; 8987 } 8988 cpr.connections.add(conn); 8989 r.conProviders.add(conn); 8990 return conn; 8991 } 8992 cpr.addExternalProcessHandleLocked(externalProcessToken); 8993 return null; 8994 } 8995 8996 boolean decProviderCountLocked(ContentProviderConnection conn, 8997 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8998 if (conn != null) { 8999 cpr = conn.provider; 9000 if (DEBUG_PROVIDER) Slog.v(TAG, 9001 "Removing provider requested by " 9002 + conn.client.processName + " from process " 9003 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9004 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9005 if (stable) { 9006 conn.stableCount--; 9007 } else { 9008 conn.unstableCount--; 9009 } 9010 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9011 cpr.connections.remove(conn); 9012 conn.client.conProviders.remove(conn); 9013 return true; 9014 } 9015 return false; 9016 } 9017 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9018 return false; 9019 } 9020 9021 private void checkTime(long startTime, String where) { 9022 long now = SystemClock.elapsedRealtime(); 9023 if ((now-startTime) > 1000) { 9024 // If we are taking more than a second, log about it. 9025 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9026 } 9027 } 9028 9029 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9030 String name, IBinder token, boolean stable, int userId) { 9031 ContentProviderRecord cpr; 9032 ContentProviderConnection conn = null; 9033 ProviderInfo cpi = null; 9034 9035 synchronized(this) { 9036 long startTime = SystemClock.elapsedRealtime(); 9037 9038 ProcessRecord r = null; 9039 if (caller != null) { 9040 r = getRecordForAppLocked(caller); 9041 if (r == null) { 9042 throw new SecurityException( 9043 "Unable to find app for caller " + caller 9044 + " (pid=" + Binder.getCallingPid() 9045 + ") when getting content provider " + name); 9046 } 9047 } 9048 9049 boolean checkCrossUser = true; 9050 9051 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9052 9053 // First check if this content provider has been published... 9054 cpr = mProviderMap.getProviderByName(name, userId); 9055 // If that didn't work, check if it exists for user 0 and then 9056 // verify that it's a singleton provider before using it. 9057 if (cpr == null && userId != UserHandle.USER_OWNER) { 9058 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9059 if (cpr != null) { 9060 cpi = cpr.info; 9061 if (isSingleton(cpi.processName, cpi.applicationInfo, 9062 cpi.name, cpi.flags) 9063 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9064 userId = UserHandle.USER_OWNER; 9065 checkCrossUser = false; 9066 } else { 9067 cpr = null; 9068 cpi = null; 9069 } 9070 } 9071 } 9072 9073 boolean providerRunning = cpr != null; 9074 if (providerRunning) { 9075 cpi = cpr.info; 9076 String msg; 9077 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9078 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9079 != null) { 9080 throw new SecurityException(msg); 9081 } 9082 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9083 9084 if (r != null && cpr.canRunHere(r)) { 9085 // This provider has been published or is in the process 9086 // of being published... but it is also allowed to run 9087 // in the caller's process, so don't make a connection 9088 // and just let the caller instantiate its own instance. 9089 ContentProviderHolder holder = cpr.newHolder(null); 9090 // don't give caller the provider object, it needs 9091 // to make its own. 9092 holder.provider = null; 9093 return holder; 9094 } 9095 9096 final long origId = Binder.clearCallingIdentity(); 9097 9098 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9099 9100 // In this case the provider instance already exists, so we can 9101 // return it right away. 9102 conn = incProviderCountLocked(r, cpr, token, stable); 9103 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9104 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9105 // If this is a perceptible app accessing the provider, 9106 // make sure to count it as being accessed and thus 9107 // back up on the LRU list. This is good because 9108 // content providers are often expensive to start. 9109 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9110 updateLruProcessLocked(cpr.proc, false, null); 9111 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9112 } 9113 } 9114 9115 if (cpr.proc != null) { 9116 if (false) { 9117 if (cpr.name.flattenToShortString().equals( 9118 "com.android.providers.calendar/.CalendarProvider2")) { 9119 Slog.v(TAG, "****************** KILLING " 9120 + cpr.name.flattenToShortString()); 9121 Process.killProcess(cpr.proc.pid); 9122 } 9123 } 9124 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9125 boolean success = updateOomAdjLocked(cpr.proc); 9126 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9127 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9128 // NOTE: there is still a race here where a signal could be 9129 // pending on the process even though we managed to update its 9130 // adj level. Not sure what to do about this, but at least 9131 // the race is now smaller. 9132 if (!success) { 9133 // Uh oh... it looks like the provider's process 9134 // has been killed on us. We need to wait for a new 9135 // process to be started, and make sure its death 9136 // doesn't kill our process. 9137 Slog.i(TAG, 9138 "Existing provider " + cpr.name.flattenToShortString() 9139 + " is crashing; detaching " + r); 9140 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9141 checkTime(startTime, "getContentProviderImpl: before appDied"); 9142 appDiedLocked(cpr.proc); 9143 checkTime(startTime, "getContentProviderImpl: after appDied"); 9144 if (!lastRef) { 9145 // This wasn't the last ref our process had on 9146 // the provider... we have now been killed, bail. 9147 return null; 9148 } 9149 providerRunning = false; 9150 conn = null; 9151 } 9152 } 9153 9154 Binder.restoreCallingIdentity(origId); 9155 } 9156 9157 boolean singleton; 9158 if (!providerRunning) { 9159 try { 9160 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9161 cpi = AppGlobals.getPackageManager(). 9162 resolveContentProvider(name, 9163 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9164 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9165 } catch (RemoteException ex) { 9166 } 9167 if (cpi == null) { 9168 return null; 9169 } 9170 // If the provider is a singleton AND 9171 // (it's a call within the same user || the provider is a 9172 // privileged app) 9173 // Then allow connecting to the singleton provider 9174 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9175 cpi.name, cpi.flags) 9176 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9177 if (singleton) { 9178 userId = UserHandle.USER_OWNER; 9179 } 9180 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9181 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9182 9183 String msg; 9184 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9185 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9186 != null) { 9187 throw new SecurityException(msg); 9188 } 9189 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9190 9191 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9192 && !cpi.processName.equals("system")) { 9193 // If this content provider does not run in the system 9194 // process, and the system is not yet ready to run other 9195 // processes, then fail fast instead of hanging. 9196 throw new IllegalArgumentException( 9197 "Attempt to launch content provider before system ready"); 9198 } 9199 9200 // Make sure that the user who owns this provider is started. If not, 9201 // we don't want to allow it to run. 9202 if (mStartedUsers.get(userId) == null) { 9203 Slog.w(TAG, "Unable to launch app " 9204 + cpi.applicationInfo.packageName + "/" 9205 + cpi.applicationInfo.uid + " for provider " 9206 + name + ": user " + userId + " is stopped"); 9207 return null; 9208 } 9209 9210 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9211 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9212 cpr = mProviderMap.getProviderByClass(comp, userId); 9213 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9214 final boolean firstClass = cpr == null; 9215 if (firstClass) { 9216 try { 9217 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9218 ApplicationInfo ai = 9219 AppGlobals.getPackageManager(). 9220 getApplicationInfo( 9221 cpi.applicationInfo.packageName, 9222 STOCK_PM_FLAGS, userId); 9223 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9224 if (ai == null) { 9225 Slog.w(TAG, "No package info for content provider " 9226 + cpi.name); 9227 return null; 9228 } 9229 ai = getAppInfoForUser(ai, userId); 9230 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9231 } catch (RemoteException ex) { 9232 // pm is in same process, this will never happen. 9233 } 9234 } 9235 9236 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9237 9238 if (r != null && cpr.canRunHere(r)) { 9239 // If this is a multiprocess provider, then just return its 9240 // info and allow the caller to instantiate it. Only do 9241 // this if the provider is the same user as the caller's 9242 // process, or can run as root (so can be in any process). 9243 return cpr.newHolder(null); 9244 } 9245 9246 if (DEBUG_PROVIDER) { 9247 RuntimeException e = new RuntimeException("here"); 9248 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9249 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9250 } 9251 9252 // This is single process, and our app is now connecting to it. 9253 // See if we are already in the process of launching this 9254 // provider. 9255 final int N = mLaunchingProviders.size(); 9256 int i; 9257 for (i=0; i<N; i++) { 9258 if (mLaunchingProviders.get(i) == cpr) { 9259 break; 9260 } 9261 } 9262 9263 // If the provider is not already being launched, then get it 9264 // started. 9265 if (i >= N) { 9266 final long origId = Binder.clearCallingIdentity(); 9267 9268 try { 9269 // Content provider is now in use, its package can't be stopped. 9270 try { 9271 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9272 AppGlobals.getPackageManager().setPackageStoppedState( 9273 cpr.appInfo.packageName, false, userId); 9274 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9275 } catch (RemoteException e) { 9276 } catch (IllegalArgumentException e) { 9277 Slog.w(TAG, "Failed trying to unstop package " 9278 + cpr.appInfo.packageName + ": " + e); 9279 } 9280 9281 // Use existing process if already started 9282 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9283 ProcessRecord proc = getProcessRecordLocked( 9284 cpi.processName, cpr.appInfo.uid, false); 9285 if (proc != null && proc.thread != null) { 9286 if (DEBUG_PROVIDER) { 9287 Slog.d(TAG, "Installing in existing process " + proc); 9288 } 9289 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9290 proc.pubProviders.put(cpi.name, cpr); 9291 try { 9292 proc.thread.scheduleInstallProvider(cpi); 9293 } catch (RemoteException e) { 9294 } 9295 } else { 9296 checkTime(startTime, "getContentProviderImpl: before start process"); 9297 proc = startProcessLocked(cpi.processName, 9298 cpr.appInfo, false, 0, "content provider", 9299 new ComponentName(cpi.applicationInfo.packageName, 9300 cpi.name), false, false, false); 9301 checkTime(startTime, "getContentProviderImpl: after start process"); 9302 if (proc == null) { 9303 Slog.w(TAG, "Unable to launch app " 9304 + cpi.applicationInfo.packageName + "/" 9305 + cpi.applicationInfo.uid + " for provider " 9306 + name + ": process is bad"); 9307 return null; 9308 } 9309 } 9310 cpr.launchingApp = proc; 9311 mLaunchingProviders.add(cpr); 9312 } finally { 9313 Binder.restoreCallingIdentity(origId); 9314 } 9315 } 9316 9317 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9318 9319 // Make sure the provider is published (the same provider class 9320 // may be published under multiple names). 9321 if (firstClass) { 9322 mProviderMap.putProviderByClass(comp, cpr); 9323 } 9324 9325 mProviderMap.putProviderByName(name, cpr); 9326 conn = incProviderCountLocked(r, cpr, token, stable); 9327 if (conn != null) { 9328 conn.waiting = true; 9329 } 9330 } 9331 checkTime(startTime, "getContentProviderImpl: done!"); 9332 } 9333 9334 // Wait for the provider to be published... 9335 synchronized (cpr) { 9336 while (cpr.provider == null) { 9337 if (cpr.launchingApp == null) { 9338 Slog.w(TAG, "Unable to launch app " 9339 + cpi.applicationInfo.packageName + "/" 9340 + cpi.applicationInfo.uid + " for provider " 9341 + name + ": launching app became null"); 9342 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9343 UserHandle.getUserId(cpi.applicationInfo.uid), 9344 cpi.applicationInfo.packageName, 9345 cpi.applicationInfo.uid, name); 9346 return null; 9347 } 9348 try { 9349 if (DEBUG_MU) { 9350 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9351 + cpr.launchingApp); 9352 } 9353 if (conn != null) { 9354 conn.waiting = true; 9355 } 9356 cpr.wait(); 9357 } catch (InterruptedException ex) { 9358 } finally { 9359 if (conn != null) { 9360 conn.waiting = false; 9361 } 9362 } 9363 } 9364 } 9365 return cpr != null ? cpr.newHolder(conn) : null; 9366 } 9367 9368 @Override 9369 public final ContentProviderHolder getContentProvider( 9370 IApplicationThread caller, String name, int userId, boolean stable) { 9371 enforceNotIsolatedCaller("getContentProvider"); 9372 if (caller == null) { 9373 String msg = "null IApplicationThread when getting content provider " 9374 + name; 9375 Slog.w(TAG, msg); 9376 throw new SecurityException(msg); 9377 } 9378 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9379 // with cross-user grant. 9380 return getContentProviderImpl(caller, name, null, stable, userId); 9381 } 9382 9383 public ContentProviderHolder getContentProviderExternal( 9384 String name, int userId, IBinder token) { 9385 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9386 "Do not have permission in call getContentProviderExternal()"); 9387 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9388 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9389 return getContentProviderExternalUnchecked(name, token, userId); 9390 } 9391 9392 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9393 IBinder token, int userId) { 9394 return getContentProviderImpl(null, name, token, true, userId); 9395 } 9396 9397 /** 9398 * Drop a content provider from a ProcessRecord's bookkeeping 9399 */ 9400 public void removeContentProvider(IBinder connection, boolean stable) { 9401 enforceNotIsolatedCaller("removeContentProvider"); 9402 long ident = Binder.clearCallingIdentity(); 9403 try { 9404 synchronized (this) { 9405 ContentProviderConnection conn; 9406 try { 9407 conn = (ContentProviderConnection)connection; 9408 } catch (ClassCastException e) { 9409 String msg ="removeContentProvider: " + connection 9410 + " not a ContentProviderConnection"; 9411 Slog.w(TAG, msg); 9412 throw new IllegalArgumentException(msg); 9413 } 9414 if (conn == null) { 9415 throw new NullPointerException("connection is null"); 9416 } 9417 if (decProviderCountLocked(conn, null, null, stable)) { 9418 updateOomAdjLocked(); 9419 } 9420 } 9421 } finally { 9422 Binder.restoreCallingIdentity(ident); 9423 } 9424 } 9425 9426 public void removeContentProviderExternal(String name, IBinder token) { 9427 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9428 "Do not have permission in call removeContentProviderExternal()"); 9429 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9430 } 9431 9432 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9433 synchronized (this) { 9434 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9435 if(cpr == null) { 9436 //remove from mProvidersByClass 9437 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9438 return; 9439 } 9440 9441 //update content provider record entry info 9442 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9443 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9444 if (localCpr.hasExternalProcessHandles()) { 9445 if (localCpr.removeExternalProcessHandleLocked(token)) { 9446 updateOomAdjLocked(); 9447 } else { 9448 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9449 + " with no external reference for token: " 9450 + token + "."); 9451 } 9452 } else { 9453 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9454 + " with no external references."); 9455 } 9456 } 9457 } 9458 9459 public final void publishContentProviders(IApplicationThread caller, 9460 List<ContentProviderHolder> providers) { 9461 if (providers == null) { 9462 return; 9463 } 9464 9465 enforceNotIsolatedCaller("publishContentProviders"); 9466 synchronized (this) { 9467 final ProcessRecord r = getRecordForAppLocked(caller); 9468 if (DEBUG_MU) 9469 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9470 if (r == null) { 9471 throw new SecurityException( 9472 "Unable to find app for caller " + caller 9473 + " (pid=" + Binder.getCallingPid() 9474 + ") when publishing content providers"); 9475 } 9476 9477 final long origId = Binder.clearCallingIdentity(); 9478 9479 final int N = providers.size(); 9480 for (int i=0; i<N; i++) { 9481 ContentProviderHolder src = providers.get(i); 9482 if (src == null || src.info == null || src.provider == null) { 9483 continue; 9484 } 9485 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9486 if (DEBUG_MU) 9487 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9488 if (dst != null) { 9489 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9490 mProviderMap.putProviderByClass(comp, dst); 9491 String names[] = dst.info.authority.split(";"); 9492 for (int j = 0; j < names.length; j++) { 9493 mProviderMap.putProviderByName(names[j], dst); 9494 } 9495 9496 int NL = mLaunchingProviders.size(); 9497 int j; 9498 for (j=0; j<NL; j++) { 9499 if (mLaunchingProviders.get(j) == dst) { 9500 mLaunchingProviders.remove(j); 9501 j--; 9502 NL--; 9503 } 9504 } 9505 synchronized (dst) { 9506 dst.provider = src.provider; 9507 dst.proc = r; 9508 dst.notifyAll(); 9509 } 9510 updateOomAdjLocked(r); 9511 } 9512 } 9513 9514 Binder.restoreCallingIdentity(origId); 9515 } 9516 } 9517 9518 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9519 ContentProviderConnection conn; 9520 try { 9521 conn = (ContentProviderConnection)connection; 9522 } catch (ClassCastException e) { 9523 String msg ="refContentProvider: " + connection 9524 + " not a ContentProviderConnection"; 9525 Slog.w(TAG, msg); 9526 throw new IllegalArgumentException(msg); 9527 } 9528 if (conn == null) { 9529 throw new NullPointerException("connection is null"); 9530 } 9531 9532 synchronized (this) { 9533 if (stable > 0) { 9534 conn.numStableIncs += stable; 9535 } 9536 stable = conn.stableCount + stable; 9537 if (stable < 0) { 9538 throw new IllegalStateException("stableCount < 0: " + stable); 9539 } 9540 9541 if (unstable > 0) { 9542 conn.numUnstableIncs += unstable; 9543 } 9544 unstable = conn.unstableCount + unstable; 9545 if (unstable < 0) { 9546 throw new IllegalStateException("unstableCount < 0: " + unstable); 9547 } 9548 9549 if ((stable+unstable) <= 0) { 9550 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9551 + stable + " unstable=" + unstable); 9552 } 9553 conn.stableCount = stable; 9554 conn.unstableCount = unstable; 9555 return !conn.dead; 9556 } 9557 } 9558 9559 public void unstableProviderDied(IBinder connection) { 9560 ContentProviderConnection conn; 9561 try { 9562 conn = (ContentProviderConnection)connection; 9563 } catch (ClassCastException e) { 9564 String msg ="refContentProvider: " + connection 9565 + " not a ContentProviderConnection"; 9566 Slog.w(TAG, msg); 9567 throw new IllegalArgumentException(msg); 9568 } 9569 if (conn == null) { 9570 throw new NullPointerException("connection is null"); 9571 } 9572 9573 // Safely retrieve the content provider associated with the connection. 9574 IContentProvider provider; 9575 synchronized (this) { 9576 provider = conn.provider.provider; 9577 } 9578 9579 if (provider == null) { 9580 // Um, yeah, we're way ahead of you. 9581 return; 9582 } 9583 9584 // Make sure the caller is being honest with us. 9585 if (provider.asBinder().pingBinder()) { 9586 // Er, no, still looks good to us. 9587 synchronized (this) { 9588 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9589 + " says " + conn + " died, but we don't agree"); 9590 return; 9591 } 9592 } 9593 9594 // Well look at that! It's dead! 9595 synchronized (this) { 9596 if (conn.provider.provider != provider) { 9597 // But something changed... good enough. 9598 return; 9599 } 9600 9601 ProcessRecord proc = conn.provider.proc; 9602 if (proc == null || proc.thread == null) { 9603 // Seems like the process is already cleaned up. 9604 return; 9605 } 9606 9607 // As far as we're concerned, this is just like receiving a 9608 // death notification... just a bit prematurely. 9609 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9610 + ") early provider death"); 9611 final long ident = Binder.clearCallingIdentity(); 9612 try { 9613 appDiedLocked(proc); 9614 } finally { 9615 Binder.restoreCallingIdentity(ident); 9616 } 9617 } 9618 } 9619 9620 @Override 9621 public void appNotRespondingViaProvider(IBinder connection) { 9622 enforceCallingPermission( 9623 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9624 9625 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9626 if (conn == null) { 9627 Slog.w(TAG, "ContentProviderConnection is null"); 9628 return; 9629 } 9630 9631 final ProcessRecord host = conn.provider.proc; 9632 if (host == null) { 9633 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9634 return; 9635 } 9636 9637 final long token = Binder.clearCallingIdentity(); 9638 try { 9639 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9640 } finally { 9641 Binder.restoreCallingIdentity(token); 9642 } 9643 } 9644 9645 public final void installSystemProviders() { 9646 List<ProviderInfo> providers; 9647 synchronized (this) { 9648 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9649 providers = generateApplicationProvidersLocked(app); 9650 if (providers != null) { 9651 for (int i=providers.size()-1; i>=0; i--) { 9652 ProviderInfo pi = (ProviderInfo)providers.get(i); 9653 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9654 Slog.w(TAG, "Not installing system proc provider " + pi.name 9655 + ": not system .apk"); 9656 providers.remove(i); 9657 } 9658 } 9659 } 9660 } 9661 if (providers != null) { 9662 mSystemThread.installSystemProviders(providers); 9663 } 9664 9665 mCoreSettingsObserver = new CoreSettingsObserver(this); 9666 9667 //mUsageStatsService.monitorPackages(); 9668 } 9669 9670 /** 9671 * Allows apps to retrieve the MIME type of a URI. 9672 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9673 * users, then it does not need permission to access the ContentProvider. 9674 * Either, it needs cross-user uri grants. 9675 * 9676 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9677 * 9678 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9679 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9680 */ 9681 public String getProviderMimeType(Uri uri, int userId) { 9682 enforceNotIsolatedCaller("getProviderMimeType"); 9683 final String name = uri.getAuthority(); 9684 int callingUid = Binder.getCallingUid(); 9685 int callingPid = Binder.getCallingPid(); 9686 long ident = 0; 9687 boolean clearedIdentity = false; 9688 userId = unsafeConvertIncomingUser(userId); 9689 if (UserHandle.getUserId(callingUid) != userId) { 9690 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9691 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9692 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9693 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9694 clearedIdentity = true; 9695 ident = Binder.clearCallingIdentity(); 9696 } 9697 } 9698 ContentProviderHolder holder = null; 9699 try { 9700 holder = getContentProviderExternalUnchecked(name, null, userId); 9701 if (holder != null) { 9702 return holder.provider.getType(uri); 9703 } 9704 } catch (RemoteException e) { 9705 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9706 return null; 9707 } finally { 9708 // We need to clear the identity to call removeContentProviderExternalUnchecked 9709 if (!clearedIdentity) { 9710 ident = Binder.clearCallingIdentity(); 9711 } 9712 try { 9713 if (holder != null) { 9714 removeContentProviderExternalUnchecked(name, null, userId); 9715 } 9716 } finally { 9717 Binder.restoreCallingIdentity(ident); 9718 } 9719 } 9720 9721 return null; 9722 } 9723 9724 // ========================================================= 9725 // GLOBAL MANAGEMENT 9726 // ========================================================= 9727 9728 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9729 boolean isolated, int isolatedUid) { 9730 String proc = customProcess != null ? customProcess : info.processName; 9731 BatteryStatsImpl.Uid.Proc ps = null; 9732 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9733 int uid = info.uid; 9734 if (isolated) { 9735 if (isolatedUid == 0) { 9736 int userId = UserHandle.getUserId(uid); 9737 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9738 while (true) { 9739 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9740 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9741 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9742 } 9743 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9744 mNextIsolatedProcessUid++; 9745 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9746 // No process for this uid, use it. 9747 break; 9748 } 9749 stepsLeft--; 9750 if (stepsLeft <= 0) { 9751 return null; 9752 } 9753 } 9754 } else { 9755 // Special case for startIsolatedProcess (internal only), where 9756 // the uid of the isolated process is specified by the caller. 9757 uid = isolatedUid; 9758 } 9759 } 9760 return new ProcessRecord(stats, info, proc, uid); 9761 } 9762 9763 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9764 String abiOverride) { 9765 ProcessRecord app; 9766 if (!isolated) { 9767 app = getProcessRecordLocked(info.processName, info.uid, true); 9768 } else { 9769 app = null; 9770 } 9771 9772 if (app == null) { 9773 app = newProcessRecordLocked(info, null, isolated, 0); 9774 mProcessNames.put(info.processName, app.uid, app); 9775 if (isolated) { 9776 mIsolatedProcesses.put(app.uid, app); 9777 } 9778 updateLruProcessLocked(app, false, null); 9779 updateOomAdjLocked(); 9780 } 9781 9782 // This package really, really can not be stopped. 9783 try { 9784 AppGlobals.getPackageManager().setPackageStoppedState( 9785 info.packageName, false, UserHandle.getUserId(app.uid)); 9786 } catch (RemoteException e) { 9787 } catch (IllegalArgumentException e) { 9788 Slog.w(TAG, "Failed trying to unstop package " 9789 + info.packageName + ": " + e); 9790 } 9791 9792 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9793 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9794 app.persistent = true; 9795 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9796 } 9797 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9798 mPersistentStartingProcesses.add(app); 9799 startProcessLocked(app, "added application", app.processName, abiOverride, 9800 null /* entryPoint */, null /* entryPointArgs */); 9801 } 9802 9803 return app; 9804 } 9805 9806 public void unhandledBack() { 9807 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9808 "unhandledBack()"); 9809 9810 synchronized(this) { 9811 final long origId = Binder.clearCallingIdentity(); 9812 try { 9813 getFocusedStack().unhandledBackLocked(); 9814 } finally { 9815 Binder.restoreCallingIdentity(origId); 9816 } 9817 } 9818 } 9819 9820 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9821 enforceNotIsolatedCaller("openContentUri"); 9822 final int userId = UserHandle.getCallingUserId(); 9823 String name = uri.getAuthority(); 9824 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9825 ParcelFileDescriptor pfd = null; 9826 if (cph != null) { 9827 // We record the binder invoker's uid in thread-local storage before 9828 // going to the content provider to open the file. Later, in the code 9829 // that handles all permissions checks, we look for this uid and use 9830 // that rather than the Activity Manager's own uid. The effect is that 9831 // we do the check against the caller's permissions even though it looks 9832 // to the content provider like the Activity Manager itself is making 9833 // the request. 9834 sCallerIdentity.set(new Identity( 9835 Binder.getCallingPid(), Binder.getCallingUid())); 9836 try { 9837 pfd = cph.provider.openFile(null, uri, "r", null); 9838 } catch (FileNotFoundException e) { 9839 // do nothing; pfd will be returned null 9840 } finally { 9841 // Ensure that whatever happens, we clean up the identity state 9842 sCallerIdentity.remove(); 9843 } 9844 9845 // We've got the fd now, so we're done with the provider. 9846 removeContentProviderExternalUnchecked(name, null, userId); 9847 } else { 9848 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9849 } 9850 return pfd; 9851 } 9852 9853 // Actually is sleeping or shutting down or whatever else in the future 9854 // is an inactive state. 9855 public boolean isSleepingOrShuttingDown() { 9856 return mSleeping || mShuttingDown; 9857 } 9858 9859 public boolean isSleeping() { 9860 return mSleeping; 9861 } 9862 9863 void goingToSleep() { 9864 synchronized(this) { 9865 mWentToSleep = true; 9866 updateEventDispatchingLocked(); 9867 goToSleepIfNeededLocked(); 9868 } 9869 } 9870 9871 void finishRunningVoiceLocked() { 9872 if (mRunningVoice) { 9873 mRunningVoice = false; 9874 goToSleepIfNeededLocked(); 9875 } 9876 } 9877 9878 void goToSleepIfNeededLocked() { 9879 if (mWentToSleep && !mRunningVoice) { 9880 if (!mSleeping) { 9881 mSleeping = true; 9882 mStackSupervisor.goingToSleepLocked(); 9883 9884 // Initialize the wake times of all processes. 9885 checkExcessivePowerUsageLocked(false); 9886 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9887 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9888 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9889 } 9890 } 9891 } 9892 9893 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9894 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9895 // Never persist the home stack. 9896 return; 9897 } 9898 mTaskPersister.wakeup(task, flush); 9899 } 9900 9901 @Override 9902 public boolean shutdown(int timeout) { 9903 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9904 != PackageManager.PERMISSION_GRANTED) { 9905 throw new SecurityException("Requires permission " 9906 + android.Manifest.permission.SHUTDOWN); 9907 } 9908 9909 boolean timedout = false; 9910 9911 synchronized(this) { 9912 mShuttingDown = true; 9913 updateEventDispatchingLocked(); 9914 timedout = mStackSupervisor.shutdownLocked(timeout); 9915 } 9916 9917 mAppOpsService.shutdown(); 9918 if (mUsageStatsService != null) { 9919 mUsageStatsService.prepareShutdown(); 9920 } 9921 mBatteryStatsService.shutdown(); 9922 synchronized (this) { 9923 mProcessStats.shutdownLocked(); 9924 } 9925 notifyTaskPersisterLocked(null, true); 9926 9927 return timedout; 9928 } 9929 9930 public final void activitySlept(IBinder token) { 9931 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9932 9933 final long origId = Binder.clearCallingIdentity(); 9934 9935 synchronized (this) { 9936 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9937 if (r != null) { 9938 mStackSupervisor.activitySleptLocked(r); 9939 } 9940 } 9941 9942 Binder.restoreCallingIdentity(origId); 9943 } 9944 9945 void logLockScreen(String msg) { 9946 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9947 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9948 mWentToSleep + " mSleeping=" + mSleeping); 9949 } 9950 9951 private void comeOutOfSleepIfNeededLocked() { 9952 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9953 if (mSleeping) { 9954 mSleeping = false; 9955 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9956 } 9957 } 9958 } 9959 9960 void wakingUp() { 9961 synchronized(this) { 9962 mWentToSleep = false; 9963 updateEventDispatchingLocked(); 9964 comeOutOfSleepIfNeededLocked(); 9965 } 9966 } 9967 9968 void startRunningVoiceLocked() { 9969 if (!mRunningVoice) { 9970 mRunningVoice = true; 9971 comeOutOfSleepIfNeededLocked(); 9972 } 9973 } 9974 9975 private void updateEventDispatchingLocked() { 9976 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9977 } 9978 9979 public void setLockScreenShown(boolean shown) { 9980 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9981 != PackageManager.PERMISSION_GRANTED) { 9982 throw new SecurityException("Requires permission " 9983 + android.Manifest.permission.DEVICE_POWER); 9984 } 9985 9986 synchronized(this) { 9987 long ident = Binder.clearCallingIdentity(); 9988 try { 9989 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9990 mLockScreenShown = shown; 9991 comeOutOfSleepIfNeededLocked(); 9992 } finally { 9993 Binder.restoreCallingIdentity(ident); 9994 } 9995 } 9996 } 9997 9998 @Override 9999 public void stopAppSwitches() { 10000 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10001 != PackageManager.PERMISSION_GRANTED) { 10002 throw new SecurityException("Requires permission " 10003 + android.Manifest.permission.STOP_APP_SWITCHES); 10004 } 10005 10006 synchronized(this) { 10007 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10008 + APP_SWITCH_DELAY_TIME; 10009 mDidAppSwitch = false; 10010 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10011 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10012 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10013 } 10014 } 10015 10016 public void resumeAppSwitches() { 10017 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10018 != PackageManager.PERMISSION_GRANTED) { 10019 throw new SecurityException("Requires permission " 10020 + android.Manifest.permission.STOP_APP_SWITCHES); 10021 } 10022 10023 synchronized(this) { 10024 // Note that we don't execute any pending app switches... we will 10025 // let those wait until either the timeout, or the next start 10026 // activity request. 10027 mAppSwitchesAllowedTime = 0; 10028 } 10029 } 10030 10031 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10032 String name) { 10033 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10034 return true; 10035 } 10036 10037 final int perm = checkComponentPermission( 10038 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10039 callingUid, -1, true); 10040 if (perm == PackageManager.PERMISSION_GRANTED) { 10041 return true; 10042 } 10043 10044 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10045 return false; 10046 } 10047 10048 public void setDebugApp(String packageName, boolean waitForDebugger, 10049 boolean persistent) { 10050 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10051 "setDebugApp()"); 10052 10053 long ident = Binder.clearCallingIdentity(); 10054 try { 10055 // Note that this is not really thread safe if there are multiple 10056 // callers into it at the same time, but that's not a situation we 10057 // care about. 10058 if (persistent) { 10059 final ContentResolver resolver = mContext.getContentResolver(); 10060 Settings.Global.putString( 10061 resolver, Settings.Global.DEBUG_APP, 10062 packageName); 10063 Settings.Global.putInt( 10064 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10065 waitForDebugger ? 1 : 0); 10066 } 10067 10068 synchronized (this) { 10069 if (!persistent) { 10070 mOrigDebugApp = mDebugApp; 10071 mOrigWaitForDebugger = mWaitForDebugger; 10072 } 10073 mDebugApp = packageName; 10074 mWaitForDebugger = waitForDebugger; 10075 mDebugTransient = !persistent; 10076 if (packageName != null) { 10077 forceStopPackageLocked(packageName, -1, false, false, true, true, 10078 false, UserHandle.USER_ALL, "set debug app"); 10079 } 10080 } 10081 } finally { 10082 Binder.restoreCallingIdentity(ident); 10083 } 10084 } 10085 10086 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10087 synchronized (this) { 10088 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10089 if (!isDebuggable) { 10090 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10091 throw new SecurityException("Process not debuggable: " + app.packageName); 10092 } 10093 } 10094 10095 mOpenGlTraceApp = processName; 10096 } 10097 } 10098 10099 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10100 synchronized (this) { 10101 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10102 if (!isDebuggable) { 10103 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10104 throw new SecurityException("Process not debuggable: " + app.packageName); 10105 } 10106 } 10107 mProfileApp = processName; 10108 mProfileFile = profilerInfo.profileFile; 10109 if (mProfileFd != null) { 10110 try { 10111 mProfileFd.close(); 10112 } catch (IOException e) { 10113 } 10114 mProfileFd = null; 10115 } 10116 mProfileFd = profilerInfo.profileFd; 10117 mSamplingInterval = profilerInfo.samplingInterval; 10118 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10119 mProfileType = 0; 10120 } 10121 } 10122 10123 @Override 10124 public void setAlwaysFinish(boolean enabled) { 10125 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10126 "setAlwaysFinish()"); 10127 10128 Settings.Global.putInt( 10129 mContext.getContentResolver(), 10130 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10131 10132 synchronized (this) { 10133 mAlwaysFinishActivities = enabled; 10134 } 10135 } 10136 10137 @Override 10138 public void setActivityController(IActivityController controller) { 10139 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10140 "setActivityController()"); 10141 synchronized (this) { 10142 mController = controller; 10143 Watchdog.getInstance().setActivityController(controller); 10144 } 10145 } 10146 10147 @Override 10148 public void setUserIsMonkey(boolean userIsMonkey) { 10149 synchronized (this) { 10150 synchronized (mPidsSelfLocked) { 10151 final int callingPid = Binder.getCallingPid(); 10152 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10153 if (precessRecord == null) { 10154 throw new SecurityException("Unknown process: " + callingPid); 10155 } 10156 if (precessRecord.instrumentationUiAutomationConnection == null) { 10157 throw new SecurityException("Only an instrumentation process " 10158 + "with a UiAutomation can call setUserIsMonkey"); 10159 } 10160 } 10161 mUserIsMonkey = userIsMonkey; 10162 } 10163 } 10164 10165 @Override 10166 public boolean isUserAMonkey() { 10167 synchronized (this) { 10168 // If there is a controller also implies the user is a monkey. 10169 return (mUserIsMonkey || mController != null); 10170 } 10171 } 10172 10173 public void requestBugReport() { 10174 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10175 SystemProperties.set("ctl.start", "bugreport"); 10176 } 10177 10178 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10179 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10180 } 10181 10182 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10183 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10184 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10185 } 10186 return KEY_DISPATCHING_TIMEOUT; 10187 } 10188 10189 @Override 10190 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10191 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10192 != PackageManager.PERMISSION_GRANTED) { 10193 throw new SecurityException("Requires permission " 10194 + android.Manifest.permission.FILTER_EVENTS); 10195 } 10196 ProcessRecord proc; 10197 long timeout; 10198 synchronized (this) { 10199 synchronized (mPidsSelfLocked) { 10200 proc = mPidsSelfLocked.get(pid); 10201 } 10202 timeout = getInputDispatchingTimeoutLocked(proc); 10203 } 10204 10205 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10206 return -1; 10207 } 10208 10209 return timeout; 10210 } 10211 10212 /** 10213 * Handle input dispatching timeouts. 10214 * Returns whether input dispatching should be aborted or not. 10215 */ 10216 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10217 final ActivityRecord activity, final ActivityRecord parent, 10218 final boolean aboveSystem, String reason) { 10219 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10220 != PackageManager.PERMISSION_GRANTED) { 10221 throw new SecurityException("Requires permission " 10222 + android.Manifest.permission.FILTER_EVENTS); 10223 } 10224 10225 final String annotation; 10226 if (reason == null) { 10227 annotation = "Input dispatching timed out"; 10228 } else { 10229 annotation = "Input dispatching timed out (" + reason + ")"; 10230 } 10231 10232 if (proc != null) { 10233 synchronized (this) { 10234 if (proc.debugging) { 10235 return false; 10236 } 10237 10238 if (mDidDexOpt) { 10239 // Give more time since we were dexopting. 10240 mDidDexOpt = false; 10241 return false; 10242 } 10243 10244 if (proc.instrumentationClass != null) { 10245 Bundle info = new Bundle(); 10246 info.putString("shortMsg", "keyDispatchingTimedOut"); 10247 info.putString("longMsg", annotation); 10248 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10249 return true; 10250 } 10251 } 10252 mHandler.post(new Runnable() { 10253 @Override 10254 public void run() { 10255 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10256 } 10257 }); 10258 } 10259 10260 return true; 10261 } 10262 10263 public Bundle getAssistContextExtras(int requestType) { 10264 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10265 "getAssistContextExtras()"); 10266 PendingAssistExtras pae; 10267 Bundle extras = new Bundle(); 10268 synchronized (this) { 10269 ActivityRecord activity = getFocusedStack().mResumedActivity; 10270 if (activity == null) { 10271 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10272 return null; 10273 } 10274 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10275 if (activity.app == null || activity.app.thread == null) { 10276 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10277 return extras; 10278 } 10279 if (activity.app.pid == Binder.getCallingPid()) { 10280 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10281 return extras; 10282 } 10283 pae = new PendingAssistExtras(activity); 10284 try { 10285 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10286 requestType); 10287 mPendingAssistExtras.add(pae); 10288 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10289 } catch (RemoteException e) { 10290 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10291 return extras; 10292 } 10293 } 10294 synchronized (pae) { 10295 while (!pae.haveResult) { 10296 try { 10297 pae.wait(); 10298 } catch (InterruptedException e) { 10299 } 10300 } 10301 if (pae.result != null) { 10302 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10303 } 10304 } 10305 synchronized (this) { 10306 mPendingAssistExtras.remove(pae); 10307 mHandler.removeCallbacks(pae); 10308 } 10309 return extras; 10310 } 10311 10312 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10313 PendingAssistExtras pae = (PendingAssistExtras)token; 10314 synchronized (pae) { 10315 pae.result = extras; 10316 pae.haveResult = true; 10317 pae.notifyAll(); 10318 } 10319 } 10320 10321 public void registerProcessObserver(IProcessObserver observer) { 10322 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10323 "registerProcessObserver()"); 10324 synchronized (this) { 10325 mProcessObservers.register(observer); 10326 } 10327 } 10328 10329 @Override 10330 public void unregisterProcessObserver(IProcessObserver observer) { 10331 synchronized (this) { 10332 mProcessObservers.unregister(observer); 10333 } 10334 } 10335 10336 @Override 10337 public boolean convertFromTranslucent(IBinder token) { 10338 final long origId = Binder.clearCallingIdentity(); 10339 try { 10340 synchronized (this) { 10341 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10342 if (r == null) { 10343 return false; 10344 } 10345 final boolean translucentChanged = r.changeWindowTranslucency(true); 10346 if (translucentChanged) { 10347 r.task.stack.releaseBackgroundResources(); 10348 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10349 } 10350 mWindowManager.setAppFullscreen(token, true); 10351 return translucentChanged; 10352 } 10353 } finally { 10354 Binder.restoreCallingIdentity(origId); 10355 } 10356 } 10357 10358 @Override 10359 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10360 final long origId = Binder.clearCallingIdentity(); 10361 try { 10362 synchronized (this) { 10363 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10364 if (r == null) { 10365 return false; 10366 } 10367 int index = r.task.mActivities.lastIndexOf(r); 10368 if (index > 0) { 10369 ActivityRecord under = r.task.mActivities.get(index - 1); 10370 under.returningOptions = options; 10371 } 10372 final boolean translucentChanged = r.changeWindowTranslucency(false); 10373 if (translucentChanged) { 10374 r.task.stack.convertToTranslucent(r); 10375 } 10376 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10377 mWindowManager.setAppFullscreen(token, false); 10378 return translucentChanged; 10379 } 10380 } finally { 10381 Binder.restoreCallingIdentity(origId); 10382 } 10383 } 10384 10385 @Override 10386 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10387 final long origId = Binder.clearCallingIdentity(); 10388 try { 10389 synchronized (this) { 10390 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10391 if (r != null) { 10392 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10393 } 10394 } 10395 return false; 10396 } finally { 10397 Binder.restoreCallingIdentity(origId); 10398 } 10399 } 10400 10401 @Override 10402 public boolean isBackgroundVisibleBehind(IBinder token) { 10403 final long origId = Binder.clearCallingIdentity(); 10404 try { 10405 synchronized (this) { 10406 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10407 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10408 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10409 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10410 return visible; 10411 } 10412 } finally { 10413 Binder.restoreCallingIdentity(origId); 10414 } 10415 } 10416 10417 @Override 10418 public ActivityOptions getActivityOptions(IBinder token) { 10419 final long origId = Binder.clearCallingIdentity(); 10420 try { 10421 synchronized (this) { 10422 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10423 if (r != null) { 10424 final ActivityOptions activityOptions = r.pendingOptions; 10425 r.pendingOptions = null; 10426 return activityOptions; 10427 } 10428 return null; 10429 } 10430 } finally { 10431 Binder.restoreCallingIdentity(origId); 10432 } 10433 } 10434 10435 @Override 10436 public void setImmersive(IBinder token, boolean immersive) { 10437 synchronized(this) { 10438 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10439 if (r == null) { 10440 throw new IllegalArgumentException(); 10441 } 10442 r.immersive = immersive; 10443 10444 // update associated state if we're frontmost 10445 if (r == mFocusedActivity) { 10446 if (DEBUG_IMMERSIVE) { 10447 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10448 } 10449 applyUpdateLockStateLocked(r); 10450 } 10451 } 10452 } 10453 10454 @Override 10455 public boolean isImmersive(IBinder token) { 10456 synchronized (this) { 10457 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10458 if (r == null) { 10459 throw new IllegalArgumentException(); 10460 } 10461 return r.immersive; 10462 } 10463 } 10464 10465 public boolean isTopActivityImmersive() { 10466 enforceNotIsolatedCaller("startActivity"); 10467 synchronized (this) { 10468 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10469 return (r != null) ? r.immersive : false; 10470 } 10471 } 10472 10473 @Override 10474 public boolean isTopOfTask(IBinder token) { 10475 synchronized (this) { 10476 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10477 if (r == null) { 10478 throw new IllegalArgumentException(); 10479 } 10480 return r.task.getTopActivity() == r; 10481 } 10482 } 10483 10484 public final void enterSafeMode() { 10485 synchronized(this) { 10486 // It only makes sense to do this before the system is ready 10487 // and started launching other packages. 10488 if (!mSystemReady) { 10489 try { 10490 AppGlobals.getPackageManager().enterSafeMode(); 10491 } catch (RemoteException e) { 10492 } 10493 } 10494 10495 mSafeMode = true; 10496 } 10497 } 10498 10499 public final void showSafeModeOverlay() { 10500 View v = LayoutInflater.from(mContext).inflate( 10501 com.android.internal.R.layout.safe_mode, null); 10502 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10503 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10504 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10505 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10506 lp.gravity = Gravity.BOTTOM | Gravity.START; 10507 lp.format = v.getBackground().getOpacity(); 10508 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10509 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10510 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10511 ((WindowManager)mContext.getSystemService( 10512 Context.WINDOW_SERVICE)).addView(v, lp); 10513 } 10514 10515 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10516 if (!(sender instanceof PendingIntentRecord)) { 10517 return; 10518 } 10519 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10520 synchronized (stats) { 10521 if (mBatteryStatsService.isOnBattery()) { 10522 mBatteryStatsService.enforceCallingPermission(); 10523 PendingIntentRecord rec = (PendingIntentRecord)sender; 10524 int MY_UID = Binder.getCallingUid(); 10525 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10526 BatteryStatsImpl.Uid.Pkg pkg = 10527 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10528 sourcePkg != null ? sourcePkg : rec.key.packageName); 10529 pkg.incWakeupsLocked(); 10530 } 10531 } 10532 } 10533 10534 public boolean killPids(int[] pids, String pReason, boolean secure) { 10535 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10536 throw new SecurityException("killPids only available to the system"); 10537 } 10538 String reason = (pReason == null) ? "Unknown" : pReason; 10539 // XXX Note: don't acquire main activity lock here, because the window 10540 // manager calls in with its locks held. 10541 10542 boolean killed = false; 10543 synchronized (mPidsSelfLocked) { 10544 int[] types = new int[pids.length]; 10545 int worstType = 0; 10546 for (int i=0; i<pids.length; i++) { 10547 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10548 if (proc != null) { 10549 int type = proc.setAdj; 10550 types[i] = type; 10551 if (type > worstType) { 10552 worstType = type; 10553 } 10554 } 10555 } 10556 10557 // If the worst oom_adj is somewhere in the cached proc LRU range, 10558 // then constrain it so we will kill all cached procs. 10559 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10560 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10561 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10562 } 10563 10564 // If this is not a secure call, don't let it kill processes that 10565 // are important. 10566 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10567 worstType = ProcessList.SERVICE_ADJ; 10568 } 10569 10570 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10571 for (int i=0; i<pids.length; i++) { 10572 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10573 if (proc == null) { 10574 continue; 10575 } 10576 int adj = proc.setAdj; 10577 if (adj >= worstType && !proc.killedByAm) { 10578 proc.kill(reason, true); 10579 killed = true; 10580 } 10581 } 10582 } 10583 return killed; 10584 } 10585 10586 @Override 10587 public void killUid(int uid, String reason) { 10588 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10589 throw new SecurityException("killUid only available to the system"); 10590 } 10591 synchronized (this) { 10592 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10593 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10594 reason != null ? reason : "kill uid"); 10595 } 10596 } 10597 10598 @Override 10599 public boolean killProcessesBelowForeground(String reason) { 10600 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10601 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10602 } 10603 10604 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10605 } 10606 10607 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10608 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10609 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10610 } 10611 10612 boolean killed = false; 10613 synchronized (mPidsSelfLocked) { 10614 final int size = mPidsSelfLocked.size(); 10615 for (int i = 0; i < size; i++) { 10616 final int pid = mPidsSelfLocked.keyAt(i); 10617 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10618 if (proc == null) continue; 10619 10620 final int adj = proc.setAdj; 10621 if (adj > belowAdj && !proc.killedByAm) { 10622 proc.kill(reason, true); 10623 killed = true; 10624 } 10625 } 10626 } 10627 return killed; 10628 } 10629 10630 @Override 10631 public void hang(final IBinder who, boolean allowRestart) { 10632 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10633 != PackageManager.PERMISSION_GRANTED) { 10634 throw new SecurityException("Requires permission " 10635 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10636 } 10637 10638 final IBinder.DeathRecipient death = new DeathRecipient() { 10639 @Override 10640 public void binderDied() { 10641 synchronized (this) { 10642 notifyAll(); 10643 } 10644 } 10645 }; 10646 10647 try { 10648 who.linkToDeath(death, 0); 10649 } catch (RemoteException e) { 10650 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10651 return; 10652 } 10653 10654 synchronized (this) { 10655 Watchdog.getInstance().setAllowRestart(allowRestart); 10656 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10657 synchronized (death) { 10658 while (who.isBinderAlive()) { 10659 try { 10660 death.wait(); 10661 } catch (InterruptedException e) { 10662 } 10663 } 10664 } 10665 Watchdog.getInstance().setAllowRestart(true); 10666 } 10667 } 10668 10669 @Override 10670 public void restart() { 10671 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10672 != PackageManager.PERMISSION_GRANTED) { 10673 throw new SecurityException("Requires permission " 10674 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10675 } 10676 10677 Log.i(TAG, "Sending shutdown broadcast..."); 10678 10679 BroadcastReceiver br = new BroadcastReceiver() { 10680 @Override public void onReceive(Context context, Intent intent) { 10681 // Now the broadcast is done, finish up the low-level shutdown. 10682 Log.i(TAG, "Shutting down activity manager..."); 10683 shutdown(10000); 10684 Log.i(TAG, "Shutdown complete, restarting!"); 10685 Process.killProcess(Process.myPid()); 10686 System.exit(10); 10687 } 10688 }; 10689 10690 // First send the high-level shut down broadcast. 10691 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10692 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10693 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10694 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10695 mContext.sendOrderedBroadcastAsUser(intent, 10696 UserHandle.ALL, null, br, mHandler, 0, null, null); 10697 */ 10698 br.onReceive(mContext, intent); 10699 } 10700 10701 private long getLowRamTimeSinceIdle(long now) { 10702 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10703 } 10704 10705 @Override 10706 public void performIdleMaintenance() { 10707 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10708 != PackageManager.PERMISSION_GRANTED) { 10709 throw new SecurityException("Requires permission " 10710 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10711 } 10712 10713 synchronized (this) { 10714 final long now = SystemClock.uptimeMillis(); 10715 final long timeSinceLastIdle = now - mLastIdleTime; 10716 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10717 mLastIdleTime = now; 10718 mLowRamTimeSinceLastIdle = 0; 10719 if (mLowRamStartTime != 0) { 10720 mLowRamStartTime = now; 10721 } 10722 10723 StringBuilder sb = new StringBuilder(128); 10724 sb.append("Idle maintenance over "); 10725 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10726 sb.append(" low RAM for "); 10727 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10728 Slog.i(TAG, sb.toString()); 10729 10730 // If at least 1/3 of our time since the last idle period has been spent 10731 // with RAM low, then we want to kill processes. 10732 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10733 10734 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10735 ProcessRecord proc = mLruProcesses.get(i); 10736 if (proc.notCachedSinceIdle) { 10737 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10738 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10739 if (doKilling && proc.initialIdlePss != 0 10740 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10741 proc.kill("idle maint (pss " + proc.lastPss 10742 + " from " + proc.initialIdlePss + ")", true); 10743 } 10744 } 10745 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10746 proc.notCachedSinceIdle = true; 10747 proc.initialIdlePss = 0; 10748 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10749 isSleeping(), now); 10750 } 10751 } 10752 10753 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10754 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10755 } 10756 } 10757 10758 private void retrieveSettings() { 10759 final ContentResolver resolver = mContext.getContentResolver(); 10760 String debugApp = Settings.Global.getString( 10761 resolver, Settings.Global.DEBUG_APP); 10762 boolean waitForDebugger = Settings.Global.getInt( 10763 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10764 boolean alwaysFinishActivities = Settings.Global.getInt( 10765 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10766 boolean forceRtl = Settings.Global.getInt( 10767 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10768 // Transfer any global setting for forcing RTL layout, into a System Property 10769 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10770 10771 Configuration configuration = new Configuration(); 10772 Settings.System.getConfiguration(resolver, configuration); 10773 if (forceRtl) { 10774 // This will take care of setting the correct layout direction flags 10775 configuration.setLayoutDirection(configuration.locale); 10776 } 10777 10778 synchronized (this) { 10779 mDebugApp = mOrigDebugApp = debugApp; 10780 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10781 mAlwaysFinishActivities = alwaysFinishActivities; 10782 // This happens before any activities are started, so we can 10783 // change mConfiguration in-place. 10784 updateConfigurationLocked(configuration, null, false, true); 10785 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10786 } 10787 } 10788 10789 /** Loads resources after the current configuration has been set. */ 10790 private void loadResourcesOnSystemReady() { 10791 final Resources res = mContext.getResources(); 10792 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10793 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10794 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10795 } 10796 10797 public boolean testIsSystemReady() { 10798 // no need to synchronize(this) just to read & return the value 10799 return mSystemReady; 10800 } 10801 10802 private static File getCalledPreBootReceiversFile() { 10803 File dataDir = Environment.getDataDirectory(); 10804 File systemDir = new File(dataDir, "system"); 10805 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10806 return fname; 10807 } 10808 10809 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10810 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10811 File file = getCalledPreBootReceiversFile(); 10812 FileInputStream fis = null; 10813 try { 10814 fis = new FileInputStream(file); 10815 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10816 int fvers = dis.readInt(); 10817 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10818 String vers = dis.readUTF(); 10819 String codename = dis.readUTF(); 10820 String build = dis.readUTF(); 10821 if (android.os.Build.VERSION.RELEASE.equals(vers) 10822 && android.os.Build.VERSION.CODENAME.equals(codename) 10823 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10824 int num = dis.readInt(); 10825 while (num > 0) { 10826 num--; 10827 String pkg = dis.readUTF(); 10828 String cls = dis.readUTF(); 10829 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10830 } 10831 } 10832 } 10833 } catch (FileNotFoundException e) { 10834 } catch (IOException e) { 10835 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10836 } finally { 10837 if (fis != null) { 10838 try { 10839 fis.close(); 10840 } catch (IOException e) { 10841 } 10842 } 10843 } 10844 return lastDoneReceivers; 10845 } 10846 10847 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10848 File file = getCalledPreBootReceiversFile(); 10849 FileOutputStream fos = null; 10850 DataOutputStream dos = null; 10851 try { 10852 fos = new FileOutputStream(file); 10853 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10854 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10855 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10856 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10857 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10858 dos.writeInt(list.size()); 10859 for (int i=0; i<list.size(); i++) { 10860 dos.writeUTF(list.get(i).getPackageName()); 10861 dos.writeUTF(list.get(i).getClassName()); 10862 } 10863 } catch (IOException e) { 10864 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10865 file.delete(); 10866 } finally { 10867 FileUtils.sync(fos); 10868 if (dos != null) { 10869 try { 10870 dos.close(); 10871 } catch (IOException e) { 10872 // TODO Auto-generated catch block 10873 e.printStackTrace(); 10874 } 10875 } 10876 } 10877 } 10878 10879 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10880 ArrayList<ComponentName> doneReceivers, int userId) { 10881 boolean waitingUpdate = false; 10882 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10883 List<ResolveInfo> ris = null; 10884 try { 10885 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10886 intent, null, 0, userId); 10887 } catch (RemoteException e) { 10888 } 10889 if (ris != null) { 10890 for (int i=ris.size()-1; i>=0; i--) { 10891 if ((ris.get(i).activityInfo.applicationInfo.flags 10892 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10893 ris.remove(i); 10894 } 10895 } 10896 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10897 10898 // For User 0, load the version number. When delivering to a new user, deliver 10899 // to all receivers. 10900 if (userId == UserHandle.USER_OWNER) { 10901 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10902 for (int i=0; i<ris.size(); i++) { 10903 ActivityInfo ai = ris.get(i).activityInfo; 10904 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10905 if (lastDoneReceivers.contains(comp)) { 10906 // We already did the pre boot receiver for this app with the current 10907 // platform version, so don't do it again... 10908 ris.remove(i); 10909 i--; 10910 // ...however, do keep it as one that has been done, so we don't 10911 // forget about it when rewriting the file of last done receivers. 10912 doneReceivers.add(comp); 10913 } 10914 } 10915 } 10916 10917 // If primary user, send broadcast to all available users, else just to userId 10918 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10919 : new int[] { userId }; 10920 for (int i = 0; i < ris.size(); i++) { 10921 ActivityInfo ai = ris.get(i).activityInfo; 10922 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10923 doneReceivers.add(comp); 10924 intent.setComponent(comp); 10925 for (int j=0; j<users.length; j++) { 10926 IIntentReceiver finisher = null; 10927 // On last receiver and user, set up a completion callback 10928 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10929 finisher = new IIntentReceiver.Stub() { 10930 public void performReceive(Intent intent, int resultCode, 10931 String data, Bundle extras, boolean ordered, 10932 boolean sticky, int sendingUser) { 10933 // The raw IIntentReceiver interface is called 10934 // with the AM lock held, so redispatch to 10935 // execute our code without the lock. 10936 mHandler.post(onFinishCallback); 10937 } 10938 }; 10939 } 10940 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10941 + " for user " + users[j]); 10942 broadcastIntentLocked(null, null, intent, null, finisher, 10943 0, null, null, null, AppOpsManager.OP_NONE, 10944 true, false, MY_PID, Process.SYSTEM_UID, 10945 users[j]); 10946 if (finisher != null) { 10947 waitingUpdate = true; 10948 } 10949 } 10950 } 10951 } 10952 10953 return waitingUpdate; 10954 } 10955 10956 public void systemReady(final Runnable goingCallback) { 10957 synchronized(this) { 10958 if (mSystemReady) { 10959 // If we're done calling all the receivers, run the next "boot phase" passed in 10960 // by the SystemServer 10961 if (goingCallback != null) { 10962 goingCallback.run(); 10963 } 10964 return; 10965 } 10966 10967 // Make sure we have the current profile info, since it is needed for 10968 // security checks. 10969 updateCurrentProfileIdsLocked(); 10970 10971 if (mRecentTasks == null) { 10972 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10973 if (!mRecentTasks.isEmpty()) { 10974 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10975 } 10976 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10977 mTaskPersister.startPersisting(); 10978 } 10979 10980 // Check to see if there are any update receivers to run. 10981 if (!mDidUpdate) { 10982 if (mWaitingUpdate) { 10983 return; 10984 } 10985 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10986 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10987 public void run() { 10988 synchronized (ActivityManagerService.this) { 10989 mDidUpdate = true; 10990 } 10991 writeLastDonePreBootReceivers(doneReceivers); 10992 showBootMessage(mContext.getText( 10993 R.string.android_upgrading_complete), 10994 false); 10995 systemReady(goingCallback); 10996 } 10997 }, doneReceivers, UserHandle.USER_OWNER); 10998 10999 if (mWaitingUpdate) { 11000 return; 11001 } 11002 mDidUpdate = true; 11003 } 11004 11005 mAppOpsService.systemReady(); 11006 mSystemReady = true; 11007 } 11008 11009 ArrayList<ProcessRecord> procsToKill = null; 11010 synchronized(mPidsSelfLocked) { 11011 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11012 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11013 if (!isAllowedWhileBooting(proc.info)){ 11014 if (procsToKill == null) { 11015 procsToKill = new ArrayList<ProcessRecord>(); 11016 } 11017 procsToKill.add(proc); 11018 } 11019 } 11020 } 11021 11022 synchronized(this) { 11023 if (procsToKill != null) { 11024 for (int i=procsToKill.size()-1; i>=0; i--) { 11025 ProcessRecord proc = procsToKill.get(i); 11026 Slog.i(TAG, "Removing system update proc: " + proc); 11027 removeProcessLocked(proc, true, false, "system update done"); 11028 } 11029 } 11030 11031 // Now that we have cleaned up any update processes, we 11032 // are ready to start launching real processes and know that 11033 // we won't trample on them any more. 11034 mProcessesReady = true; 11035 } 11036 11037 Slog.i(TAG, "System now ready"); 11038 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11039 SystemClock.uptimeMillis()); 11040 11041 synchronized(this) { 11042 // Make sure we have no pre-ready processes sitting around. 11043 11044 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11045 ResolveInfo ri = mContext.getPackageManager() 11046 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11047 STOCK_PM_FLAGS); 11048 CharSequence errorMsg = null; 11049 if (ri != null) { 11050 ActivityInfo ai = ri.activityInfo; 11051 ApplicationInfo app = ai.applicationInfo; 11052 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11053 mTopAction = Intent.ACTION_FACTORY_TEST; 11054 mTopData = null; 11055 mTopComponent = new ComponentName(app.packageName, 11056 ai.name); 11057 } else { 11058 errorMsg = mContext.getResources().getText( 11059 com.android.internal.R.string.factorytest_not_system); 11060 } 11061 } else { 11062 errorMsg = mContext.getResources().getText( 11063 com.android.internal.R.string.factorytest_no_action); 11064 } 11065 if (errorMsg != null) { 11066 mTopAction = null; 11067 mTopData = null; 11068 mTopComponent = null; 11069 Message msg = Message.obtain(); 11070 msg.what = SHOW_FACTORY_ERROR_MSG; 11071 msg.getData().putCharSequence("msg", errorMsg); 11072 mHandler.sendMessage(msg); 11073 } 11074 } 11075 } 11076 11077 retrieveSettings(); 11078 loadResourcesOnSystemReady(); 11079 11080 synchronized (this) { 11081 readGrantedUriPermissionsLocked(); 11082 } 11083 11084 if (goingCallback != null) goingCallback.run(); 11085 11086 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11087 Integer.toString(mCurrentUserId), mCurrentUserId); 11088 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11089 Integer.toString(mCurrentUserId), mCurrentUserId); 11090 mSystemServiceManager.startUser(mCurrentUserId); 11091 11092 synchronized (this) { 11093 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11094 try { 11095 List apps = AppGlobals.getPackageManager(). 11096 getPersistentApplications(STOCK_PM_FLAGS); 11097 if (apps != null) { 11098 int N = apps.size(); 11099 int i; 11100 for (i=0; i<N; i++) { 11101 ApplicationInfo info 11102 = (ApplicationInfo)apps.get(i); 11103 if (info != null && 11104 !info.packageName.equals("android")) { 11105 addAppLocked(info, false, null /* ABI override */); 11106 } 11107 } 11108 } 11109 } catch (RemoteException ex) { 11110 // pm is in same process, this will never happen. 11111 } 11112 } 11113 11114 // Start up initial activity. 11115 mBooting = true; 11116 11117 try { 11118 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11119 Message msg = Message.obtain(); 11120 msg.what = SHOW_UID_ERROR_MSG; 11121 mHandler.sendMessage(msg); 11122 } 11123 } catch (RemoteException e) { 11124 } 11125 11126 long ident = Binder.clearCallingIdentity(); 11127 try { 11128 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11129 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11130 | Intent.FLAG_RECEIVER_FOREGROUND); 11131 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11132 broadcastIntentLocked(null, null, intent, 11133 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11134 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11135 intent = new Intent(Intent.ACTION_USER_STARTING); 11136 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11137 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11138 broadcastIntentLocked(null, null, intent, 11139 null, new IIntentReceiver.Stub() { 11140 @Override 11141 public void performReceive(Intent intent, int resultCode, String data, 11142 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11143 throws RemoteException { 11144 } 11145 }, 0, null, null, 11146 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11147 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11148 } catch (Throwable t) { 11149 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11150 } finally { 11151 Binder.restoreCallingIdentity(ident); 11152 } 11153 mStackSupervisor.resumeTopActivitiesLocked(); 11154 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11155 } 11156 } 11157 11158 private boolean makeAppCrashingLocked(ProcessRecord app, 11159 String shortMsg, String longMsg, String stackTrace) { 11160 app.crashing = true; 11161 app.crashingReport = generateProcessError(app, 11162 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11163 startAppProblemLocked(app); 11164 app.stopFreezingAllLocked(); 11165 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11166 } 11167 11168 private void makeAppNotRespondingLocked(ProcessRecord app, 11169 String activity, String shortMsg, String longMsg) { 11170 app.notResponding = true; 11171 app.notRespondingReport = generateProcessError(app, 11172 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11173 activity, shortMsg, longMsg, null); 11174 startAppProblemLocked(app); 11175 app.stopFreezingAllLocked(); 11176 } 11177 11178 /** 11179 * Generate a process error record, suitable for attachment to a ProcessRecord. 11180 * 11181 * @param app The ProcessRecord in which the error occurred. 11182 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11183 * ActivityManager.AppErrorStateInfo 11184 * @param activity The activity associated with the crash, if known. 11185 * @param shortMsg Short message describing the crash. 11186 * @param longMsg Long message describing the crash. 11187 * @param stackTrace Full crash stack trace, may be null. 11188 * 11189 * @return Returns a fully-formed AppErrorStateInfo record. 11190 */ 11191 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11192 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11193 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11194 11195 report.condition = condition; 11196 report.processName = app.processName; 11197 report.pid = app.pid; 11198 report.uid = app.info.uid; 11199 report.tag = activity; 11200 report.shortMsg = shortMsg; 11201 report.longMsg = longMsg; 11202 report.stackTrace = stackTrace; 11203 11204 return report; 11205 } 11206 11207 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11208 synchronized (this) { 11209 app.crashing = false; 11210 app.crashingReport = null; 11211 app.notResponding = false; 11212 app.notRespondingReport = null; 11213 if (app.anrDialog == fromDialog) { 11214 app.anrDialog = null; 11215 } 11216 if (app.waitDialog == fromDialog) { 11217 app.waitDialog = null; 11218 } 11219 if (app.pid > 0 && app.pid != MY_PID) { 11220 handleAppCrashLocked(app, null, null, null); 11221 app.kill("user request after error", true); 11222 } 11223 } 11224 } 11225 11226 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11227 String stackTrace) { 11228 long now = SystemClock.uptimeMillis(); 11229 11230 Long crashTime; 11231 if (!app.isolated) { 11232 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11233 } else { 11234 crashTime = null; 11235 } 11236 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11237 // This process loses! 11238 Slog.w(TAG, "Process " + app.info.processName 11239 + " has crashed too many times: killing!"); 11240 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11241 app.userId, app.info.processName, app.uid); 11242 mStackSupervisor.handleAppCrashLocked(app); 11243 if (!app.persistent) { 11244 // We don't want to start this process again until the user 11245 // explicitly does so... but for persistent process, we really 11246 // need to keep it running. If a persistent process is actually 11247 // repeatedly crashing, then badness for everyone. 11248 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11249 app.info.processName); 11250 if (!app.isolated) { 11251 // XXX We don't have a way to mark isolated processes 11252 // as bad, since they don't have a peristent identity. 11253 mBadProcesses.put(app.info.processName, app.uid, 11254 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11255 mProcessCrashTimes.remove(app.info.processName, app.uid); 11256 } 11257 app.bad = true; 11258 app.removed = true; 11259 // Don't let services in this process be restarted and potentially 11260 // annoy the user repeatedly. Unless it is persistent, since those 11261 // processes run critical code. 11262 removeProcessLocked(app, false, false, "crash"); 11263 mStackSupervisor.resumeTopActivitiesLocked(); 11264 return false; 11265 } 11266 mStackSupervisor.resumeTopActivitiesLocked(); 11267 } else { 11268 mStackSupervisor.finishTopRunningActivityLocked(app); 11269 } 11270 11271 // Bump up the crash count of any services currently running in the proc. 11272 for (int i=app.services.size()-1; i>=0; i--) { 11273 // Any services running in the application need to be placed 11274 // back in the pending list. 11275 ServiceRecord sr = app.services.valueAt(i); 11276 sr.crashCount++; 11277 } 11278 11279 // If the crashing process is what we consider to be the "home process" and it has been 11280 // replaced by a third-party app, clear the package preferred activities from packages 11281 // with a home activity running in the process to prevent a repeatedly crashing app 11282 // from blocking the user to manually clear the list. 11283 final ArrayList<ActivityRecord> activities = app.activities; 11284 if (app == mHomeProcess && activities.size() > 0 11285 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11286 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11287 final ActivityRecord r = activities.get(activityNdx); 11288 if (r.isHomeActivity()) { 11289 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11290 try { 11291 ActivityThread.getPackageManager() 11292 .clearPackagePreferredActivities(r.packageName); 11293 } catch (RemoteException c) { 11294 // pm is in same process, this will never happen. 11295 } 11296 } 11297 } 11298 } 11299 11300 if (!app.isolated) { 11301 // XXX Can't keep track of crash times for isolated processes, 11302 // because they don't have a perisistent identity. 11303 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11304 } 11305 11306 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11307 return true; 11308 } 11309 11310 void startAppProblemLocked(ProcessRecord app) { 11311 // If this app is not running under the current user, then we 11312 // can't give it a report button because that would require 11313 // launching the report UI under a different user. 11314 app.errorReportReceiver = null; 11315 11316 for (int userId : mCurrentProfileIds) { 11317 if (app.userId == userId) { 11318 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11319 mContext, app.info.packageName, app.info.flags); 11320 } 11321 } 11322 skipCurrentReceiverLocked(app); 11323 } 11324 11325 void skipCurrentReceiverLocked(ProcessRecord app) { 11326 for (BroadcastQueue queue : mBroadcastQueues) { 11327 queue.skipCurrentReceiverLocked(app); 11328 } 11329 } 11330 11331 /** 11332 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11333 * The application process will exit immediately after this call returns. 11334 * @param app object of the crashing app, null for the system server 11335 * @param crashInfo describing the exception 11336 */ 11337 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11338 ProcessRecord r = findAppProcess(app, "Crash"); 11339 final String processName = app == null ? "system_server" 11340 : (r == null ? "unknown" : r.processName); 11341 11342 handleApplicationCrashInner("crash", r, processName, crashInfo); 11343 } 11344 11345 /* Native crash reporting uses this inner version because it needs to be somewhat 11346 * decoupled from the AM-managed cleanup lifecycle 11347 */ 11348 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11349 ApplicationErrorReport.CrashInfo crashInfo) { 11350 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11351 UserHandle.getUserId(Binder.getCallingUid()), processName, 11352 r == null ? -1 : r.info.flags, 11353 crashInfo.exceptionClassName, 11354 crashInfo.exceptionMessage, 11355 crashInfo.throwFileName, 11356 crashInfo.throwLineNumber); 11357 11358 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11359 11360 crashApplication(r, crashInfo); 11361 } 11362 11363 public void handleApplicationStrictModeViolation( 11364 IBinder app, 11365 int violationMask, 11366 StrictMode.ViolationInfo info) { 11367 ProcessRecord r = findAppProcess(app, "StrictMode"); 11368 if (r == null) { 11369 return; 11370 } 11371 11372 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11373 Integer stackFingerprint = info.hashCode(); 11374 boolean logIt = true; 11375 synchronized (mAlreadyLoggedViolatedStacks) { 11376 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11377 logIt = false; 11378 // TODO: sub-sample into EventLog for these, with 11379 // the info.durationMillis? Then we'd get 11380 // the relative pain numbers, without logging all 11381 // the stack traces repeatedly. We'd want to do 11382 // likewise in the client code, which also does 11383 // dup suppression, before the Binder call. 11384 } else { 11385 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11386 mAlreadyLoggedViolatedStacks.clear(); 11387 } 11388 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11389 } 11390 } 11391 if (logIt) { 11392 logStrictModeViolationToDropBox(r, info); 11393 } 11394 } 11395 11396 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11397 AppErrorResult result = new AppErrorResult(); 11398 synchronized (this) { 11399 final long origId = Binder.clearCallingIdentity(); 11400 11401 Message msg = Message.obtain(); 11402 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11403 HashMap<String, Object> data = new HashMap<String, Object>(); 11404 data.put("result", result); 11405 data.put("app", r); 11406 data.put("violationMask", violationMask); 11407 data.put("info", info); 11408 msg.obj = data; 11409 mHandler.sendMessage(msg); 11410 11411 Binder.restoreCallingIdentity(origId); 11412 } 11413 int res = result.get(); 11414 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11415 } 11416 } 11417 11418 // Depending on the policy in effect, there could be a bunch of 11419 // these in quick succession so we try to batch these together to 11420 // minimize disk writes, number of dropbox entries, and maximize 11421 // compression, by having more fewer, larger records. 11422 private void logStrictModeViolationToDropBox( 11423 ProcessRecord process, 11424 StrictMode.ViolationInfo info) { 11425 if (info == null) { 11426 return; 11427 } 11428 final boolean isSystemApp = process == null || 11429 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11430 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11431 final String processName = process == null ? "unknown" : process.processName; 11432 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11433 final DropBoxManager dbox = (DropBoxManager) 11434 mContext.getSystemService(Context.DROPBOX_SERVICE); 11435 11436 // Exit early if the dropbox isn't configured to accept this report type. 11437 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11438 11439 boolean bufferWasEmpty; 11440 boolean needsFlush; 11441 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11442 synchronized (sb) { 11443 bufferWasEmpty = sb.length() == 0; 11444 appendDropBoxProcessHeaders(process, processName, sb); 11445 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11446 sb.append("System-App: ").append(isSystemApp).append("\n"); 11447 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11448 if (info.violationNumThisLoop != 0) { 11449 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11450 } 11451 if (info.numAnimationsRunning != 0) { 11452 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11453 } 11454 if (info.broadcastIntentAction != null) { 11455 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11456 } 11457 if (info.durationMillis != -1) { 11458 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11459 } 11460 if (info.numInstances != -1) { 11461 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11462 } 11463 if (info.tags != null) { 11464 for (String tag : info.tags) { 11465 sb.append("Span-Tag: ").append(tag).append("\n"); 11466 } 11467 } 11468 sb.append("\n"); 11469 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11470 sb.append(info.crashInfo.stackTrace); 11471 } 11472 sb.append("\n"); 11473 11474 // Only buffer up to ~64k. Various logging bits truncate 11475 // things at 128k. 11476 needsFlush = (sb.length() > 64 * 1024); 11477 } 11478 11479 // Flush immediately if the buffer's grown too large, or this 11480 // is a non-system app. Non-system apps are isolated with a 11481 // different tag & policy and not batched. 11482 // 11483 // Batching is useful during internal testing with 11484 // StrictMode settings turned up high. Without batching, 11485 // thousands of separate files could be created on boot. 11486 if (!isSystemApp || needsFlush) { 11487 new Thread("Error dump: " + dropboxTag) { 11488 @Override 11489 public void run() { 11490 String report; 11491 synchronized (sb) { 11492 report = sb.toString(); 11493 sb.delete(0, sb.length()); 11494 sb.trimToSize(); 11495 } 11496 if (report.length() != 0) { 11497 dbox.addText(dropboxTag, report); 11498 } 11499 } 11500 }.start(); 11501 return; 11502 } 11503 11504 // System app batching: 11505 if (!bufferWasEmpty) { 11506 // An existing dropbox-writing thread is outstanding, so 11507 // we don't need to start it up. The existing thread will 11508 // catch the buffer appends we just did. 11509 return; 11510 } 11511 11512 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11513 // (After this point, we shouldn't access AMS internal data structures.) 11514 new Thread("Error dump: " + dropboxTag) { 11515 @Override 11516 public void run() { 11517 // 5 second sleep to let stacks arrive and be batched together 11518 try { 11519 Thread.sleep(5000); // 5 seconds 11520 } catch (InterruptedException e) {} 11521 11522 String errorReport; 11523 synchronized (mStrictModeBuffer) { 11524 errorReport = mStrictModeBuffer.toString(); 11525 if (errorReport.length() == 0) { 11526 return; 11527 } 11528 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11529 mStrictModeBuffer.trimToSize(); 11530 } 11531 dbox.addText(dropboxTag, errorReport); 11532 } 11533 }.start(); 11534 } 11535 11536 /** 11537 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11538 * @param app object of the crashing app, null for the system server 11539 * @param tag reported by the caller 11540 * @param system whether this wtf is coming from the system 11541 * @param crashInfo describing the context of the error 11542 * @return true if the process should exit immediately (WTF is fatal) 11543 */ 11544 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11545 final ApplicationErrorReport.CrashInfo crashInfo) { 11546 final ProcessRecord r = findAppProcess(app, "WTF"); 11547 final String processName = app == null ? "system_server" 11548 : (r == null ? "unknown" : r.processName); 11549 11550 EventLog.writeEvent(EventLogTags.AM_WTF, 11551 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11552 processName, 11553 r == null ? -1 : r.info.flags, 11554 tag, crashInfo.exceptionMessage); 11555 11556 if (system) { 11557 // If this is coming from the system, we could very well have low-level 11558 // system locks held, so we want to do this all asynchronously. And we 11559 // never want this to become fatal, so there is that too. 11560 mHandler.post(new Runnable() { 11561 @Override public void run() { 11562 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11563 crashInfo); 11564 } 11565 }); 11566 return false; 11567 } 11568 11569 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11570 11571 if (r != null && r.pid != Process.myPid() && 11572 Settings.Global.getInt(mContext.getContentResolver(), 11573 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11574 crashApplication(r, crashInfo); 11575 return true; 11576 } else { 11577 return false; 11578 } 11579 } 11580 11581 /** 11582 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11583 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11584 */ 11585 private ProcessRecord findAppProcess(IBinder app, String reason) { 11586 if (app == null) { 11587 return null; 11588 } 11589 11590 synchronized (this) { 11591 final int NP = mProcessNames.getMap().size(); 11592 for (int ip=0; ip<NP; ip++) { 11593 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11594 final int NA = apps.size(); 11595 for (int ia=0; ia<NA; ia++) { 11596 ProcessRecord p = apps.valueAt(ia); 11597 if (p.thread != null && p.thread.asBinder() == app) { 11598 return p; 11599 } 11600 } 11601 } 11602 11603 Slog.w(TAG, "Can't find mystery application for " + reason 11604 + " from pid=" + Binder.getCallingPid() 11605 + " uid=" + Binder.getCallingUid() + ": " + app); 11606 return null; 11607 } 11608 } 11609 11610 /** 11611 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11612 * to append various headers to the dropbox log text. 11613 */ 11614 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11615 StringBuilder sb) { 11616 // Watchdog thread ends up invoking this function (with 11617 // a null ProcessRecord) to add the stack file to dropbox. 11618 // Do not acquire a lock on this (am) in such cases, as it 11619 // could cause a potential deadlock, if and when watchdog 11620 // is invoked due to unavailability of lock on am and it 11621 // would prevent watchdog from killing system_server. 11622 if (process == null) { 11623 sb.append("Process: ").append(processName).append("\n"); 11624 return; 11625 } 11626 // Note: ProcessRecord 'process' is guarded by the service 11627 // instance. (notably process.pkgList, which could otherwise change 11628 // concurrently during execution of this method) 11629 synchronized (this) { 11630 sb.append("Process: ").append(processName).append("\n"); 11631 int flags = process.info.flags; 11632 IPackageManager pm = AppGlobals.getPackageManager(); 11633 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11634 for (int ip=0; ip<process.pkgList.size(); ip++) { 11635 String pkg = process.pkgList.keyAt(ip); 11636 sb.append("Package: ").append(pkg); 11637 try { 11638 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11639 if (pi != null) { 11640 sb.append(" v").append(pi.versionCode); 11641 if (pi.versionName != null) { 11642 sb.append(" (").append(pi.versionName).append(")"); 11643 } 11644 } 11645 } catch (RemoteException e) { 11646 Slog.e(TAG, "Error getting package info: " + pkg, e); 11647 } 11648 sb.append("\n"); 11649 } 11650 } 11651 } 11652 11653 private static String processClass(ProcessRecord process) { 11654 if (process == null || process.pid == MY_PID) { 11655 return "system_server"; 11656 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11657 return "system_app"; 11658 } else { 11659 return "data_app"; 11660 } 11661 } 11662 11663 /** 11664 * Write a description of an error (crash, WTF, ANR) to the drop box. 11665 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11666 * @param process which caused the error, null means the system server 11667 * @param activity which triggered the error, null if unknown 11668 * @param parent activity related to the error, null if unknown 11669 * @param subject line related to the error, null if absent 11670 * @param report in long form describing the error, null if absent 11671 * @param logFile to include in the report, null if none 11672 * @param crashInfo giving an application stack trace, null if absent 11673 */ 11674 public void addErrorToDropBox(String eventType, 11675 ProcessRecord process, String processName, ActivityRecord activity, 11676 ActivityRecord parent, String subject, 11677 final String report, final File logFile, 11678 final ApplicationErrorReport.CrashInfo crashInfo) { 11679 // NOTE -- this must never acquire the ActivityManagerService lock, 11680 // otherwise the watchdog may be prevented from resetting the system. 11681 11682 final String dropboxTag = processClass(process) + "_" + eventType; 11683 final DropBoxManager dbox = (DropBoxManager) 11684 mContext.getSystemService(Context.DROPBOX_SERVICE); 11685 11686 // Exit early if the dropbox isn't configured to accept this report type. 11687 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11688 11689 final StringBuilder sb = new StringBuilder(1024); 11690 appendDropBoxProcessHeaders(process, processName, sb); 11691 if (activity != null) { 11692 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11693 } 11694 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11695 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11696 } 11697 if (parent != null && parent != activity) { 11698 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11699 } 11700 if (subject != null) { 11701 sb.append("Subject: ").append(subject).append("\n"); 11702 } 11703 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11704 if (Debug.isDebuggerConnected()) { 11705 sb.append("Debugger: Connected\n"); 11706 } 11707 sb.append("\n"); 11708 11709 // Do the rest in a worker thread to avoid blocking the caller on I/O 11710 // (After this point, we shouldn't access AMS internal data structures.) 11711 Thread worker = new Thread("Error dump: " + dropboxTag) { 11712 @Override 11713 public void run() { 11714 if (report != null) { 11715 sb.append(report); 11716 } 11717 if (logFile != null) { 11718 try { 11719 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11720 "\n\n[[TRUNCATED]]")); 11721 } catch (IOException e) { 11722 Slog.e(TAG, "Error reading " + logFile, e); 11723 } 11724 } 11725 if (crashInfo != null && crashInfo.stackTrace != null) { 11726 sb.append(crashInfo.stackTrace); 11727 } 11728 11729 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11730 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11731 if (lines > 0) { 11732 sb.append("\n"); 11733 11734 // Merge several logcat streams, and take the last N lines 11735 InputStreamReader input = null; 11736 try { 11737 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11738 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11739 "-b", "crash", 11740 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11741 11742 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11743 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11744 input = new InputStreamReader(logcat.getInputStream()); 11745 11746 int num; 11747 char[] buf = new char[8192]; 11748 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11749 } catch (IOException e) { 11750 Slog.e(TAG, "Error running logcat", e); 11751 } finally { 11752 if (input != null) try { input.close(); } catch (IOException e) {} 11753 } 11754 } 11755 11756 dbox.addText(dropboxTag, sb.toString()); 11757 } 11758 }; 11759 11760 if (process == null) { 11761 // If process is null, we are being called from some internal code 11762 // and may be about to die -- run this synchronously. 11763 worker.run(); 11764 } else { 11765 worker.start(); 11766 } 11767 } 11768 11769 /** 11770 * Bring up the "unexpected error" dialog box for a crashing app. 11771 * Deal with edge cases (intercepts from instrumented applications, 11772 * ActivityController, error intent receivers, that sort of thing). 11773 * @param r the application crashing 11774 * @param crashInfo describing the failure 11775 */ 11776 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11777 long timeMillis = System.currentTimeMillis(); 11778 String shortMsg = crashInfo.exceptionClassName; 11779 String longMsg = crashInfo.exceptionMessage; 11780 String stackTrace = crashInfo.stackTrace; 11781 if (shortMsg != null && longMsg != null) { 11782 longMsg = shortMsg + ": " + longMsg; 11783 } else if (shortMsg != null) { 11784 longMsg = shortMsg; 11785 } 11786 11787 AppErrorResult result = new AppErrorResult(); 11788 synchronized (this) { 11789 if (mController != null) { 11790 try { 11791 String name = r != null ? r.processName : null; 11792 int pid = r != null ? r.pid : Binder.getCallingPid(); 11793 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11794 if (!mController.appCrashed(name, pid, 11795 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11796 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11797 && "Native crash".equals(crashInfo.exceptionClassName)) { 11798 Slog.w(TAG, "Skip killing native crashed app " + name 11799 + "(" + pid + ") during testing"); 11800 } else { 11801 Slog.w(TAG, "Force-killing crashed app " + name 11802 + " at watcher's request"); 11803 if (r != null) { 11804 r.kill("crash", true); 11805 } else { 11806 // Huh. 11807 Process.killProcess(pid); 11808 Process.killProcessGroup(uid, pid); 11809 } 11810 } 11811 return; 11812 } 11813 } catch (RemoteException e) { 11814 mController = null; 11815 Watchdog.getInstance().setActivityController(null); 11816 } 11817 } 11818 11819 final long origId = Binder.clearCallingIdentity(); 11820 11821 // If this process is running instrumentation, finish it. 11822 if (r != null && r.instrumentationClass != null) { 11823 Slog.w(TAG, "Error in app " + r.processName 11824 + " running instrumentation " + r.instrumentationClass + ":"); 11825 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11826 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11827 Bundle info = new Bundle(); 11828 info.putString("shortMsg", shortMsg); 11829 info.putString("longMsg", longMsg); 11830 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11831 Binder.restoreCallingIdentity(origId); 11832 return; 11833 } 11834 11835 // If we can't identify the process or it's already exceeded its crash quota, 11836 // quit right away without showing a crash dialog. 11837 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11838 Binder.restoreCallingIdentity(origId); 11839 return; 11840 } 11841 11842 Message msg = Message.obtain(); 11843 msg.what = SHOW_ERROR_MSG; 11844 HashMap data = new HashMap(); 11845 data.put("result", result); 11846 data.put("app", r); 11847 msg.obj = data; 11848 mHandler.sendMessage(msg); 11849 11850 Binder.restoreCallingIdentity(origId); 11851 } 11852 11853 int res = result.get(); 11854 11855 Intent appErrorIntent = null; 11856 synchronized (this) { 11857 if (r != null && !r.isolated) { 11858 // XXX Can't keep track of crash time for isolated processes, 11859 // since they don't have a persistent identity. 11860 mProcessCrashTimes.put(r.info.processName, r.uid, 11861 SystemClock.uptimeMillis()); 11862 } 11863 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11864 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11865 } 11866 } 11867 11868 if (appErrorIntent != null) { 11869 try { 11870 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11871 } catch (ActivityNotFoundException e) { 11872 Slog.w(TAG, "bug report receiver dissappeared", e); 11873 } 11874 } 11875 } 11876 11877 Intent createAppErrorIntentLocked(ProcessRecord r, 11878 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11879 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11880 if (report == null) { 11881 return null; 11882 } 11883 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11884 result.setComponent(r.errorReportReceiver); 11885 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11886 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11887 return result; 11888 } 11889 11890 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11891 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11892 if (r.errorReportReceiver == null) { 11893 return null; 11894 } 11895 11896 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11897 return null; 11898 } 11899 11900 ApplicationErrorReport report = new ApplicationErrorReport(); 11901 report.packageName = r.info.packageName; 11902 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11903 report.processName = r.processName; 11904 report.time = timeMillis; 11905 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11906 11907 if (r.crashing || r.forceCrashReport) { 11908 report.type = ApplicationErrorReport.TYPE_CRASH; 11909 report.crashInfo = crashInfo; 11910 } else if (r.notResponding) { 11911 report.type = ApplicationErrorReport.TYPE_ANR; 11912 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11913 11914 report.anrInfo.activity = r.notRespondingReport.tag; 11915 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11916 report.anrInfo.info = r.notRespondingReport.longMsg; 11917 } 11918 11919 return report; 11920 } 11921 11922 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11923 enforceNotIsolatedCaller("getProcessesInErrorState"); 11924 // assume our apps are happy - lazy create the list 11925 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11926 11927 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11928 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11929 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11930 11931 synchronized (this) { 11932 11933 // iterate across all processes 11934 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11935 ProcessRecord app = mLruProcesses.get(i); 11936 if (!allUsers && app.userId != userId) { 11937 continue; 11938 } 11939 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11940 // This one's in trouble, so we'll generate a report for it 11941 // crashes are higher priority (in case there's a crash *and* an anr) 11942 ActivityManager.ProcessErrorStateInfo report = null; 11943 if (app.crashing) { 11944 report = app.crashingReport; 11945 } else if (app.notResponding) { 11946 report = app.notRespondingReport; 11947 } 11948 11949 if (report != null) { 11950 if (errList == null) { 11951 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11952 } 11953 errList.add(report); 11954 } else { 11955 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11956 " crashing = " + app.crashing + 11957 " notResponding = " + app.notResponding); 11958 } 11959 } 11960 } 11961 } 11962 11963 return errList; 11964 } 11965 11966 static int procStateToImportance(int procState, int memAdj, 11967 ActivityManager.RunningAppProcessInfo currApp) { 11968 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11969 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11970 currApp.lru = memAdj; 11971 } else { 11972 currApp.lru = 0; 11973 } 11974 return imp; 11975 } 11976 11977 private void fillInProcMemInfo(ProcessRecord app, 11978 ActivityManager.RunningAppProcessInfo outInfo) { 11979 outInfo.pid = app.pid; 11980 outInfo.uid = app.info.uid; 11981 if (mHeavyWeightProcess == app) { 11982 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11983 } 11984 if (app.persistent) { 11985 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11986 } 11987 if (app.activities.size() > 0) { 11988 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11989 } 11990 outInfo.lastTrimLevel = app.trimMemoryLevel; 11991 int adj = app.curAdj; 11992 int procState = app.curProcState; 11993 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11994 outInfo.importanceReasonCode = app.adjTypeCode; 11995 outInfo.processState = app.curProcState; 11996 } 11997 11998 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11999 enforceNotIsolatedCaller("getRunningAppProcesses"); 12000 // Lazy instantiation of list 12001 List<ActivityManager.RunningAppProcessInfo> runList = null; 12002 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12003 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12004 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12005 synchronized (this) { 12006 // Iterate across all processes 12007 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12008 ProcessRecord app = mLruProcesses.get(i); 12009 if (!allUsers && app.userId != userId) { 12010 continue; 12011 } 12012 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12013 // Generate process state info for running application 12014 ActivityManager.RunningAppProcessInfo currApp = 12015 new ActivityManager.RunningAppProcessInfo(app.processName, 12016 app.pid, app.getPackageList()); 12017 fillInProcMemInfo(app, currApp); 12018 if (app.adjSource instanceof ProcessRecord) { 12019 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12020 currApp.importanceReasonImportance = 12021 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12022 app.adjSourceProcState); 12023 } else if (app.adjSource instanceof ActivityRecord) { 12024 ActivityRecord r = (ActivityRecord)app.adjSource; 12025 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12026 } 12027 if (app.adjTarget instanceof ComponentName) { 12028 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12029 } 12030 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12031 // + " lru=" + currApp.lru); 12032 if (runList == null) { 12033 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12034 } 12035 runList.add(currApp); 12036 } 12037 } 12038 } 12039 return runList; 12040 } 12041 12042 public List<ApplicationInfo> getRunningExternalApplications() { 12043 enforceNotIsolatedCaller("getRunningExternalApplications"); 12044 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12045 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12046 if (runningApps != null && runningApps.size() > 0) { 12047 Set<String> extList = new HashSet<String>(); 12048 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12049 if (app.pkgList != null) { 12050 for (String pkg : app.pkgList) { 12051 extList.add(pkg); 12052 } 12053 } 12054 } 12055 IPackageManager pm = AppGlobals.getPackageManager(); 12056 for (String pkg : extList) { 12057 try { 12058 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12059 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12060 retList.add(info); 12061 } 12062 } catch (RemoteException e) { 12063 } 12064 } 12065 } 12066 return retList; 12067 } 12068 12069 @Override 12070 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12071 enforceNotIsolatedCaller("getMyMemoryState"); 12072 synchronized (this) { 12073 ProcessRecord proc; 12074 synchronized (mPidsSelfLocked) { 12075 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12076 } 12077 fillInProcMemInfo(proc, outInfo); 12078 } 12079 } 12080 12081 @Override 12082 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12083 if (checkCallingPermission(android.Manifest.permission.DUMP) 12084 != PackageManager.PERMISSION_GRANTED) { 12085 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12086 + Binder.getCallingPid() 12087 + ", uid=" + Binder.getCallingUid() 12088 + " without permission " 12089 + android.Manifest.permission.DUMP); 12090 return; 12091 } 12092 12093 boolean dumpAll = false; 12094 boolean dumpClient = false; 12095 String dumpPackage = null; 12096 12097 int opti = 0; 12098 while (opti < args.length) { 12099 String opt = args[opti]; 12100 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12101 break; 12102 } 12103 opti++; 12104 if ("-a".equals(opt)) { 12105 dumpAll = true; 12106 } else if ("-c".equals(opt)) { 12107 dumpClient = true; 12108 } else if ("-h".equals(opt)) { 12109 pw.println("Activity manager dump options:"); 12110 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12111 pw.println(" cmd may be one of:"); 12112 pw.println(" a[ctivities]: activity stack state"); 12113 pw.println(" r[recents]: recent activities state"); 12114 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12115 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12116 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12117 pw.println(" o[om]: out of memory management"); 12118 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12119 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12120 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12121 pw.println(" service [COMP_SPEC]: service client-side state"); 12122 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12123 pw.println(" all: dump all activities"); 12124 pw.println(" top: dump the top activity"); 12125 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12126 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12127 pw.println(" a partial substring in a component name, a"); 12128 pw.println(" hex object identifier."); 12129 pw.println(" -a: include all available server state."); 12130 pw.println(" -c: include client state."); 12131 return; 12132 } else { 12133 pw.println("Unknown argument: " + opt + "; use -h for help"); 12134 } 12135 } 12136 12137 long origId = Binder.clearCallingIdentity(); 12138 boolean more = false; 12139 // Is the caller requesting to dump a particular piece of data? 12140 if (opti < args.length) { 12141 String cmd = args[opti]; 12142 opti++; 12143 if ("activities".equals(cmd) || "a".equals(cmd)) { 12144 synchronized (this) { 12145 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12146 } 12147 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12148 synchronized (this) { 12149 dumpRecentsLocked(fd, pw, args, opti, true, null); 12150 } 12151 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12152 String[] newArgs; 12153 String name; 12154 if (opti >= args.length) { 12155 name = null; 12156 newArgs = EMPTY_STRING_ARRAY; 12157 } else { 12158 name = args[opti]; 12159 opti++; 12160 newArgs = new String[args.length - opti]; 12161 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12162 args.length - opti); 12163 } 12164 synchronized (this) { 12165 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12166 } 12167 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12168 String[] newArgs; 12169 String name; 12170 if (opti >= args.length) { 12171 name = null; 12172 newArgs = EMPTY_STRING_ARRAY; 12173 } else { 12174 name = args[opti]; 12175 opti++; 12176 newArgs = new String[args.length - opti]; 12177 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12178 args.length - opti); 12179 } 12180 synchronized (this) { 12181 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12182 } 12183 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12184 String[] newArgs; 12185 String name; 12186 if (opti >= args.length) { 12187 name = null; 12188 newArgs = EMPTY_STRING_ARRAY; 12189 } else { 12190 name = args[opti]; 12191 opti++; 12192 newArgs = new String[args.length - opti]; 12193 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12194 args.length - opti); 12195 } 12196 synchronized (this) { 12197 dumpProcessesLocked(fd, pw, args, opti, true, name); 12198 } 12199 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12200 synchronized (this) { 12201 dumpOomLocked(fd, pw, args, opti, true); 12202 } 12203 } else if ("provider".equals(cmd)) { 12204 String[] newArgs; 12205 String name; 12206 if (opti >= args.length) { 12207 name = null; 12208 newArgs = EMPTY_STRING_ARRAY; 12209 } else { 12210 name = args[opti]; 12211 opti++; 12212 newArgs = new String[args.length - opti]; 12213 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12214 } 12215 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12216 pw.println("No providers match: " + name); 12217 pw.println("Use -h for help."); 12218 } 12219 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12220 synchronized (this) { 12221 dumpProvidersLocked(fd, pw, args, opti, true, null); 12222 } 12223 } else if ("service".equals(cmd)) { 12224 String[] newArgs; 12225 String name; 12226 if (opti >= args.length) { 12227 name = null; 12228 newArgs = EMPTY_STRING_ARRAY; 12229 } else { 12230 name = args[opti]; 12231 opti++; 12232 newArgs = new String[args.length - opti]; 12233 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12234 args.length - opti); 12235 } 12236 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12237 pw.println("No services match: " + name); 12238 pw.println("Use -h for help."); 12239 } 12240 } else if ("package".equals(cmd)) { 12241 String[] newArgs; 12242 if (opti >= args.length) { 12243 pw.println("package: no package name specified"); 12244 pw.println("Use -h for help."); 12245 } else { 12246 dumpPackage = args[opti]; 12247 opti++; 12248 newArgs = new String[args.length - opti]; 12249 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12250 args.length - opti); 12251 args = newArgs; 12252 opti = 0; 12253 more = true; 12254 } 12255 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12256 synchronized (this) { 12257 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12258 } 12259 } else { 12260 // Dumping a single activity? 12261 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12262 pw.println("Bad activity command, or no activities match: " + cmd); 12263 pw.println("Use -h for help."); 12264 } 12265 } 12266 if (!more) { 12267 Binder.restoreCallingIdentity(origId); 12268 return; 12269 } 12270 } 12271 12272 // No piece of data specified, dump everything. 12273 synchronized (this) { 12274 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12275 pw.println(); 12276 if (dumpAll) { 12277 pw.println("-------------------------------------------------------------------------------"); 12278 } 12279 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12280 pw.println(); 12281 if (dumpAll) { 12282 pw.println("-------------------------------------------------------------------------------"); 12283 } 12284 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12285 pw.println(); 12286 if (dumpAll) { 12287 pw.println("-------------------------------------------------------------------------------"); 12288 } 12289 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12290 pw.println(); 12291 if (dumpAll) { 12292 pw.println("-------------------------------------------------------------------------------"); 12293 } 12294 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12295 pw.println(); 12296 if (dumpAll) { 12297 pw.println("-------------------------------------------------------------------------------"); 12298 } 12299 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12300 pw.println(); 12301 if (dumpAll) { 12302 pw.println("-------------------------------------------------------------------------------"); 12303 } 12304 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12305 } 12306 Binder.restoreCallingIdentity(origId); 12307 } 12308 12309 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12310 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12311 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12312 12313 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12314 dumpPackage); 12315 boolean needSep = printedAnything; 12316 12317 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12318 dumpPackage, needSep, " mFocusedActivity: "); 12319 if (printed) { 12320 printedAnything = true; 12321 needSep = false; 12322 } 12323 12324 if (dumpPackage == null) { 12325 if (needSep) { 12326 pw.println(); 12327 } 12328 needSep = true; 12329 printedAnything = true; 12330 mStackSupervisor.dump(pw, " "); 12331 } 12332 12333 if (!printedAnything) { 12334 pw.println(" (nothing)"); 12335 } 12336 } 12337 12338 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12339 int opti, boolean dumpAll, String dumpPackage) { 12340 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12341 12342 boolean printedAnything = false; 12343 12344 if (mRecentTasks.size() > 0) { 12345 boolean printedHeader = false; 12346 12347 final int N = mRecentTasks.size(); 12348 for (int i=0; i<N; i++) { 12349 TaskRecord tr = mRecentTasks.get(i); 12350 if (dumpPackage != null) { 12351 if (tr.realActivity == null || 12352 !dumpPackage.equals(tr.realActivity)) { 12353 continue; 12354 } 12355 } 12356 if (!printedHeader) { 12357 pw.println(" Recent tasks:"); 12358 printedHeader = true; 12359 printedAnything = true; 12360 } 12361 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12362 pw.println(tr); 12363 if (dumpAll) { 12364 mRecentTasks.get(i).dump(pw, " "); 12365 } 12366 } 12367 } 12368 12369 if (!printedAnything) { 12370 pw.println(" (nothing)"); 12371 } 12372 } 12373 12374 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12375 int opti, boolean dumpAll, String dumpPackage) { 12376 boolean needSep = false; 12377 boolean printedAnything = false; 12378 int numPers = 0; 12379 12380 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12381 12382 if (dumpAll) { 12383 final int NP = mProcessNames.getMap().size(); 12384 for (int ip=0; ip<NP; ip++) { 12385 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12386 final int NA = procs.size(); 12387 for (int ia=0; ia<NA; ia++) { 12388 ProcessRecord r = procs.valueAt(ia); 12389 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12390 continue; 12391 } 12392 if (!needSep) { 12393 pw.println(" All known processes:"); 12394 needSep = true; 12395 printedAnything = true; 12396 } 12397 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12398 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12399 pw.print(" "); pw.println(r); 12400 r.dump(pw, " "); 12401 if (r.persistent) { 12402 numPers++; 12403 } 12404 } 12405 } 12406 } 12407 12408 if (mIsolatedProcesses.size() > 0) { 12409 boolean printed = false; 12410 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12411 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12412 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12413 continue; 12414 } 12415 if (!printed) { 12416 if (needSep) { 12417 pw.println(); 12418 } 12419 pw.println(" Isolated process list (sorted by uid):"); 12420 printedAnything = true; 12421 printed = true; 12422 needSep = true; 12423 } 12424 pw.println(String.format("%sIsolated #%2d: %s", 12425 " ", i, r.toString())); 12426 } 12427 } 12428 12429 if (mLruProcesses.size() > 0) { 12430 if (needSep) { 12431 pw.println(); 12432 } 12433 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12434 pw.print(" total, non-act at "); 12435 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12436 pw.print(", non-svc at "); 12437 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12438 pw.println("):"); 12439 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12440 needSep = true; 12441 printedAnything = true; 12442 } 12443 12444 if (dumpAll || dumpPackage != null) { 12445 synchronized (mPidsSelfLocked) { 12446 boolean printed = false; 12447 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12448 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12449 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12450 continue; 12451 } 12452 if (!printed) { 12453 if (needSep) pw.println(); 12454 needSep = true; 12455 pw.println(" PID mappings:"); 12456 printed = true; 12457 printedAnything = true; 12458 } 12459 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12460 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12461 } 12462 } 12463 } 12464 12465 if (mForegroundProcesses.size() > 0) { 12466 synchronized (mPidsSelfLocked) { 12467 boolean printed = false; 12468 for (int i=0; i<mForegroundProcesses.size(); i++) { 12469 ProcessRecord r = mPidsSelfLocked.get( 12470 mForegroundProcesses.valueAt(i).pid); 12471 if (dumpPackage != null && (r == null 12472 || !r.pkgList.containsKey(dumpPackage))) { 12473 continue; 12474 } 12475 if (!printed) { 12476 if (needSep) pw.println(); 12477 needSep = true; 12478 pw.println(" Foreground Processes:"); 12479 printed = true; 12480 printedAnything = true; 12481 } 12482 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12483 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12484 } 12485 } 12486 } 12487 12488 if (mPersistentStartingProcesses.size() > 0) { 12489 if (needSep) pw.println(); 12490 needSep = true; 12491 printedAnything = true; 12492 pw.println(" Persisent processes that are starting:"); 12493 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12494 "Starting Norm", "Restarting PERS", dumpPackage); 12495 } 12496 12497 if (mRemovedProcesses.size() > 0) { 12498 if (needSep) pw.println(); 12499 needSep = true; 12500 printedAnything = true; 12501 pw.println(" Processes that are being removed:"); 12502 dumpProcessList(pw, this, mRemovedProcesses, " ", 12503 "Removed Norm", "Removed PERS", dumpPackage); 12504 } 12505 12506 if (mProcessesOnHold.size() > 0) { 12507 if (needSep) pw.println(); 12508 needSep = true; 12509 printedAnything = true; 12510 pw.println(" Processes that are on old until the system is ready:"); 12511 dumpProcessList(pw, this, mProcessesOnHold, " ", 12512 "OnHold Norm", "OnHold PERS", dumpPackage); 12513 } 12514 12515 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12516 12517 if (mProcessCrashTimes.getMap().size() > 0) { 12518 boolean printed = false; 12519 long now = SystemClock.uptimeMillis(); 12520 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12521 final int NP = pmap.size(); 12522 for (int ip=0; ip<NP; ip++) { 12523 String pname = pmap.keyAt(ip); 12524 SparseArray<Long> uids = pmap.valueAt(ip); 12525 final int N = uids.size(); 12526 for (int i=0; i<N; i++) { 12527 int puid = uids.keyAt(i); 12528 ProcessRecord r = mProcessNames.get(pname, puid); 12529 if (dumpPackage != null && (r == null 12530 || !r.pkgList.containsKey(dumpPackage))) { 12531 continue; 12532 } 12533 if (!printed) { 12534 if (needSep) pw.println(); 12535 needSep = true; 12536 pw.println(" Time since processes crashed:"); 12537 printed = true; 12538 printedAnything = true; 12539 } 12540 pw.print(" Process "); pw.print(pname); 12541 pw.print(" uid "); pw.print(puid); 12542 pw.print(": last crashed "); 12543 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12544 pw.println(" ago"); 12545 } 12546 } 12547 } 12548 12549 if (mBadProcesses.getMap().size() > 0) { 12550 boolean printed = false; 12551 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12552 final int NP = pmap.size(); 12553 for (int ip=0; ip<NP; ip++) { 12554 String pname = pmap.keyAt(ip); 12555 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12556 final int N = uids.size(); 12557 for (int i=0; i<N; i++) { 12558 int puid = uids.keyAt(i); 12559 ProcessRecord r = mProcessNames.get(pname, puid); 12560 if (dumpPackage != null && (r == null 12561 || !r.pkgList.containsKey(dumpPackage))) { 12562 continue; 12563 } 12564 if (!printed) { 12565 if (needSep) pw.println(); 12566 needSep = true; 12567 pw.println(" Bad processes:"); 12568 printedAnything = true; 12569 } 12570 BadProcessInfo info = uids.valueAt(i); 12571 pw.print(" Bad process "); pw.print(pname); 12572 pw.print(" uid "); pw.print(puid); 12573 pw.print(": crashed at time "); pw.println(info.time); 12574 if (info.shortMsg != null) { 12575 pw.print(" Short msg: "); pw.println(info.shortMsg); 12576 } 12577 if (info.longMsg != null) { 12578 pw.print(" Long msg: "); pw.println(info.longMsg); 12579 } 12580 if (info.stack != null) { 12581 pw.println(" Stack:"); 12582 int lastPos = 0; 12583 for (int pos=0; pos<info.stack.length(); pos++) { 12584 if (info.stack.charAt(pos) == '\n') { 12585 pw.print(" "); 12586 pw.write(info.stack, lastPos, pos-lastPos); 12587 pw.println(); 12588 lastPos = pos+1; 12589 } 12590 } 12591 if (lastPos < info.stack.length()) { 12592 pw.print(" "); 12593 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12594 pw.println(); 12595 } 12596 } 12597 } 12598 } 12599 } 12600 12601 if (dumpPackage == null) { 12602 pw.println(); 12603 needSep = false; 12604 pw.println(" mStartedUsers:"); 12605 for (int i=0; i<mStartedUsers.size(); i++) { 12606 UserStartedState uss = mStartedUsers.valueAt(i); 12607 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12608 pw.print(": "); uss.dump("", pw); 12609 } 12610 pw.print(" mStartedUserArray: ["); 12611 for (int i=0; i<mStartedUserArray.length; i++) { 12612 if (i > 0) pw.print(", "); 12613 pw.print(mStartedUserArray[i]); 12614 } 12615 pw.println("]"); 12616 pw.print(" mUserLru: ["); 12617 for (int i=0; i<mUserLru.size(); i++) { 12618 if (i > 0) pw.print(", "); 12619 pw.print(mUserLru.get(i)); 12620 } 12621 pw.println("]"); 12622 if (dumpAll) { 12623 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12624 } 12625 synchronized (mUserProfileGroupIdsSelfLocked) { 12626 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12627 pw.println(" mUserProfileGroupIds:"); 12628 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12629 pw.print(" User #"); 12630 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12631 pw.print(" -> profile #"); 12632 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12633 } 12634 } 12635 } 12636 } 12637 if (mHomeProcess != null && (dumpPackage == null 12638 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12639 if (needSep) { 12640 pw.println(); 12641 needSep = false; 12642 } 12643 pw.println(" mHomeProcess: " + mHomeProcess); 12644 } 12645 if (mPreviousProcess != null && (dumpPackage == null 12646 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12647 if (needSep) { 12648 pw.println(); 12649 needSep = false; 12650 } 12651 pw.println(" mPreviousProcess: " + mPreviousProcess); 12652 } 12653 if (dumpAll) { 12654 StringBuilder sb = new StringBuilder(128); 12655 sb.append(" mPreviousProcessVisibleTime: "); 12656 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12657 pw.println(sb); 12658 } 12659 if (mHeavyWeightProcess != null && (dumpPackage == null 12660 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12661 if (needSep) { 12662 pw.println(); 12663 needSep = false; 12664 } 12665 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12666 } 12667 if (dumpPackage == null) { 12668 pw.println(" mConfiguration: " + mConfiguration); 12669 } 12670 if (dumpAll) { 12671 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12672 if (mCompatModePackages.getPackages().size() > 0) { 12673 boolean printed = false; 12674 for (Map.Entry<String, Integer> entry 12675 : mCompatModePackages.getPackages().entrySet()) { 12676 String pkg = entry.getKey(); 12677 int mode = entry.getValue(); 12678 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12679 continue; 12680 } 12681 if (!printed) { 12682 pw.println(" mScreenCompatPackages:"); 12683 printed = true; 12684 } 12685 pw.print(" "); pw.print(pkg); pw.print(": "); 12686 pw.print(mode); pw.println(); 12687 } 12688 } 12689 } 12690 if (dumpPackage == null) { 12691 if (mSleeping || mWentToSleep || mLockScreenShown) { 12692 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12693 + " mLockScreenShown " + mLockScreenShown); 12694 } 12695 if (mShuttingDown || mRunningVoice) { 12696 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12697 } 12698 } 12699 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12700 || mOrigWaitForDebugger) { 12701 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12702 || dumpPackage.equals(mOrigDebugApp)) { 12703 if (needSep) { 12704 pw.println(); 12705 needSep = false; 12706 } 12707 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12708 + " mDebugTransient=" + mDebugTransient 12709 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12710 } 12711 } 12712 if (mOpenGlTraceApp != null) { 12713 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12714 if (needSep) { 12715 pw.println(); 12716 needSep = false; 12717 } 12718 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12719 } 12720 } 12721 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12722 || mProfileFd != null) { 12723 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12724 if (needSep) { 12725 pw.println(); 12726 needSep = false; 12727 } 12728 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12729 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12730 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12731 + mAutoStopProfiler); 12732 pw.println(" mProfileType=" + mProfileType); 12733 } 12734 } 12735 if (dumpPackage == null) { 12736 if (mAlwaysFinishActivities || mController != null) { 12737 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12738 + " mController=" + mController); 12739 } 12740 if (dumpAll) { 12741 pw.println(" Total persistent processes: " + numPers); 12742 pw.println(" mProcessesReady=" + mProcessesReady 12743 + " mSystemReady=" + mSystemReady); 12744 pw.println(" mBooting=" + mBooting 12745 + " mBooted=" + mBooted 12746 + " mFactoryTest=" + mFactoryTest); 12747 pw.print(" mLastPowerCheckRealtime="); 12748 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12749 pw.println(""); 12750 pw.print(" mLastPowerCheckUptime="); 12751 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12752 pw.println(""); 12753 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12754 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12755 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12756 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12757 + " (" + mLruProcesses.size() + " total)" 12758 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12759 + " mNumServiceProcs=" + mNumServiceProcs 12760 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12761 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12762 + " mLastMemoryLevel" + mLastMemoryLevel 12763 + " mLastNumProcesses" + mLastNumProcesses); 12764 long now = SystemClock.uptimeMillis(); 12765 pw.print(" mLastIdleTime="); 12766 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12767 pw.print(" mLowRamSinceLastIdle="); 12768 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12769 pw.println(); 12770 } 12771 } 12772 12773 if (!printedAnything) { 12774 pw.println(" (nothing)"); 12775 } 12776 } 12777 12778 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12779 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12780 if (mProcessesToGc.size() > 0) { 12781 boolean printed = false; 12782 long now = SystemClock.uptimeMillis(); 12783 for (int i=0; i<mProcessesToGc.size(); i++) { 12784 ProcessRecord proc = mProcessesToGc.get(i); 12785 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12786 continue; 12787 } 12788 if (!printed) { 12789 if (needSep) pw.println(); 12790 needSep = true; 12791 pw.println(" Processes that are waiting to GC:"); 12792 printed = true; 12793 } 12794 pw.print(" Process "); pw.println(proc); 12795 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12796 pw.print(", last gced="); 12797 pw.print(now-proc.lastRequestedGc); 12798 pw.print(" ms ago, last lowMem="); 12799 pw.print(now-proc.lastLowMemory); 12800 pw.println(" ms ago"); 12801 12802 } 12803 } 12804 return needSep; 12805 } 12806 12807 void printOomLevel(PrintWriter pw, String name, int adj) { 12808 pw.print(" "); 12809 if (adj >= 0) { 12810 pw.print(' '); 12811 if (adj < 10) pw.print(' '); 12812 } else { 12813 if (adj > -10) pw.print(' '); 12814 } 12815 pw.print(adj); 12816 pw.print(": "); 12817 pw.print(name); 12818 pw.print(" ("); 12819 pw.print(mProcessList.getMemLevel(adj)/1024); 12820 pw.println(" kB)"); 12821 } 12822 12823 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12824 int opti, boolean dumpAll) { 12825 boolean needSep = false; 12826 12827 if (mLruProcesses.size() > 0) { 12828 if (needSep) pw.println(); 12829 needSep = true; 12830 pw.println(" OOM levels:"); 12831 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12832 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12833 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12834 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12835 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12836 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12837 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12838 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12839 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12840 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12841 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12842 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12843 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12844 12845 if (needSep) pw.println(); 12846 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12847 pw.print(" total, non-act at "); 12848 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12849 pw.print(", non-svc at "); 12850 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12851 pw.println("):"); 12852 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12853 needSep = true; 12854 } 12855 12856 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12857 12858 pw.println(); 12859 pw.println(" mHomeProcess: " + mHomeProcess); 12860 pw.println(" mPreviousProcess: " + mPreviousProcess); 12861 if (mHeavyWeightProcess != null) { 12862 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12863 } 12864 12865 return true; 12866 } 12867 12868 /** 12869 * There are three ways to call this: 12870 * - no provider specified: dump all the providers 12871 * - a flattened component name that matched an existing provider was specified as the 12872 * first arg: dump that one provider 12873 * - the first arg isn't the flattened component name of an existing provider: 12874 * dump all providers whose component contains the first arg as a substring 12875 */ 12876 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12877 int opti, boolean dumpAll) { 12878 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12879 } 12880 12881 static class ItemMatcher { 12882 ArrayList<ComponentName> components; 12883 ArrayList<String> strings; 12884 ArrayList<Integer> objects; 12885 boolean all; 12886 12887 ItemMatcher() { 12888 all = true; 12889 } 12890 12891 void build(String name) { 12892 ComponentName componentName = ComponentName.unflattenFromString(name); 12893 if (componentName != null) { 12894 if (components == null) { 12895 components = new ArrayList<ComponentName>(); 12896 } 12897 components.add(componentName); 12898 all = false; 12899 } else { 12900 int objectId = 0; 12901 // Not a '/' separated full component name; maybe an object ID? 12902 try { 12903 objectId = Integer.parseInt(name, 16); 12904 if (objects == null) { 12905 objects = new ArrayList<Integer>(); 12906 } 12907 objects.add(objectId); 12908 all = false; 12909 } catch (RuntimeException e) { 12910 // Not an integer; just do string match. 12911 if (strings == null) { 12912 strings = new ArrayList<String>(); 12913 } 12914 strings.add(name); 12915 all = false; 12916 } 12917 } 12918 } 12919 12920 int build(String[] args, int opti) { 12921 for (; opti<args.length; opti++) { 12922 String name = args[opti]; 12923 if ("--".equals(name)) { 12924 return opti+1; 12925 } 12926 build(name); 12927 } 12928 return opti; 12929 } 12930 12931 boolean match(Object object, ComponentName comp) { 12932 if (all) { 12933 return true; 12934 } 12935 if (components != null) { 12936 for (int i=0; i<components.size(); i++) { 12937 if (components.get(i).equals(comp)) { 12938 return true; 12939 } 12940 } 12941 } 12942 if (objects != null) { 12943 for (int i=0; i<objects.size(); i++) { 12944 if (System.identityHashCode(object) == objects.get(i)) { 12945 return true; 12946 } 12947 } 12948 } 12949 if (strings != null) { 12950 String flat = comp.flattenToString(); 12951 for (int i=0; i<strings.size(); i++) { 12952 if (flat.contains(strings.get(i))) { 12953 return true; 12954 } 12955 } 12956 } 12957 return false; 12958 } 12959 } 12960 12961 /** 12962 * There are three things that cmd can be: 12963 * - a flattened component name that matches an existing activity 12964 * - the cmd arg isn't the flattened component name of an existing activity: 12965 * dump all activity whose component contains the cmd as a substring 12966 * - A hex number of the ActivityRecord object instance. 12967 */ 12968 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12969 int opti, boolean dumpAll) { 12970 ArrayList<ActivityRecord> activities; 12971 12972 synchronized (this) { 12973 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12974 } 12975 12976 if (activities.size() <= 0) { 12977 return false; 12978 } 12979 12980 String[] newArgs = new String[args.length - opti]; 12981 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12982 12983 TaskRecord lastTask = null; 12984 boolean needSep = false; 12985 for (int i=activities.size()-1; i>=0; i--) { 12986 ActivityRecord r = activities.get(i); 12987 if (needSep) { 12988 pw.println(); 12989 } 12990 needSep = true; 12991 synchronized (this) { 12992 if (lastTask != r.task) { 12993 lastTask = r.task; 12994 pw.print("TASK "); pw.print(lastTask.affinity); 12995 pw.print(" id="); pw.println(lastTask.taskId); 12996 if (dumpAll) { 12997 lastTask.dump(pw, " "); 12998 } 12999 } 13000 } 13001 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13002 } 13003 return true; 13004 } 13005 13006 /** 13007 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13008 * there is a thread associated with the activity. 13009 */ 13010 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13011 final ActivityRecord r, String[] args, boolean dumpAll) { 13012 String innerPrefix = prefix + " "; 13013 synchronized (this) { 13014 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13015 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13016 pw.print(" pid="); 13017 if (r.app != null) pw.println(r.app.pid); 13018 else pw.println("(not running)"); 13019 if (dumpAll) { 13020 r.dump(pw, innerPrefix); 13021 } 13022 } 13023 if (r.app != null && r.app.thread != null) { 13024 // flush anything that is already in the PrintWriter since the thread is going 13025 // to write to the file descriptor directly 13026 pw.flush(); 13027 try { 13028 TransferPipe tp = new TransferPipe(); 13029 try { 13030 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13031 r.appToken, innerPrefix, args); 13032 tp.go(fd); 13033 } finally { 13034 tp.kill(); 13035 } 13036 } catch (IOException e) { 13037 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13038 } catch (RemoteException e) { 13039 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13040 } 13041 } 13042 } 13043 13044 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13045 int opti, boolean dumpAll, String dumpPackage) { 13046 boolean needSep = false; 13047 boolean onlyHistory = false; 13048 boolean printedAnything = false; 13049 13050 if ("history".equals(dumpPackage)) { 13051 if (opti < args.length && "-s".equals(args[opti])) { 13052 dumpAll = false; 13053 } 13054 onlyHistory = true; 13055 dumpPackage = null; 13056 } 13057 13058 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13059 if (!onlyHistory && dumpAll) { 13060 if (mRegisteredReceivers.size() > 0) { 13061 boolean printed = false; 13062 Iterator it = mRegisteredReceivers.values().iterator(); 13063 while (it.hasNext()) { 13064 ReceiverList r = (ReceiverList)it.next(); 13065 if (dumpPackage != null && (r.app == null || 13066 !dumpPackage.equals(r.app.info.packageName))) { 13067 continue; 13068 } 13069 if (!printed) { 13070 pw.println(" Registered Receivers:"); 13071 needSep = true; 13072 printed = true; 13073 printedAnything = true; 13074 } 13075 pw.print(" * "); pw.println(r); 13076 r.dump(pw, " "); 13077 } 13078 } 13079 13080 if (mReceiverResolver.dump(pw, needSep ? 13081 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13082 " ", dumpPackage, false)) { 13083 needSep = true; 13084 printedAnything = true; 13085 } 13086 } 13087 13088 for (BroadcastQueue q : mBroadcastQueues) { 13089 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13090 printedAnything |= needSep; 13091 } 13092 13093 needSep = true; 13094 13095 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13096 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13097 if (needSep) { 13098 pw.println(); 13099 } 13100 needSep = true; 13101 printedAnything = true; 13102 pw.print(" Sticky broadcasts for user "); 13103 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13104 StringBuilder sb = new StringBuilder(128); 13105 for (Map.Entry<String, ArrayList<Intent>> ent 13106 : mStickyBroadcasts.valueAt(user).entrySet()) { 13107 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13108 if (dumpAll) { 13109 pw.println(":"); 13110 ArrayList<Intent> intents = ent.getValue(); 13111 final int N = intents.size(); 13112 for (int i=0; i<N; i++) { 13113 sb.setLength(0); 13114 sb.append(" Intent: "); 13115 intents.get(i).toShortString(sb, false, true, false, false); 13116 pw.println(sb.toString()); 13117 Bundle bundle = intents.get(i).getExtras(); 13118 if (bundle != null) { 13119 pw.print(" "); 13120 pw.println(bundle.toString()); 13121 } 13122 } 13123 } else { 13124 pw.println(""); 13125 } 13126 } 13127 } 13128 } 13129 13130 if (!onlyHistory && dumpAll) { 13131 pw.println(); 13132 for (BroadcastQueue queue : mBroadcastQueues) { 13133 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13134 + queue.mBroadcastsScheduled); 13135 } 13136 pw.println(" mHandler:"); 13137 mHandler.dump(new PrintWriterPrinter(pw), " "); 13138 needSep = true; 13139 printedAnything = true; 13140 } 13141 13142 if (!printedAnything) { 13143 pw.println(" (nothing)"); 13144 } 13145 } 13146 13147 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13148 int opti, boolean dumpAll, String dumpPackage) { 13149 boolean needSep; 13150 boolean printedAnything = false; 13151 13152 ItemMatcher matcher = new ItemMatcher(); 13153 matcher.build(args, opti); 13154 13155 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13156 13157 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13158 printedAnything |= needSep; 13159 13160 if (mLaunchingProviders.size() > 0) { 13161 boolean printed = false; 13162 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13163 ContentProviderRecord r = mLaunchingProviders.get(i); 13164 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13165 continue; 13166 } 13167 if (!printed) { 13168 if (needSep) pw.println(); 13169 needSep = true; 13170 pw.println(" Launching content providers:"); 13171 printed = true; 13172 printedAnything = true; 13173 } 13174 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13175 pw.println(r); 13176 } 13177 } 13178 13179 if (mGrantedUriPermissions.size() > 0) { 13180 boolean printed = false; 13181 int dumpUid = -2; 13182 if (dumpPackage != null) { 13183 try { 13184 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13185 } catch (NameNotFoundException e) { 13186 dumpUid = -1; 13187 } 13188 } 13189 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13190 int uid = mGrantedUriPermissions.keyAt(i); 13191 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13192 continue; 13193 } 13194 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13195 if (!printed) { 13196 if (needSep) pw.println(); 13197 needSep = true; 13198 pw.println(" Granted Uri Permissions:"); 13199 printed = true; 13200 printedAnything = true; 13201 } 13202 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13203 for (UriPermission perm : perms.values()) { 13204 pw.print(" "); pw.println(perm); 13205 if (dumpAll) { 13206 perm.dump(pw, " "); 13207 } 13208 } 13209 } 13210 } 13211 13212 if (!printedAnything) { 13213 pw.println(" (nothing)"); 13214 } 13215 } 13216 13217 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13218 int opti, boolean dumpAll, String dumpPackage) { 13219 boolean printed = false; 13220 13221 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13222 13223 if (mIntentSenderRecords.size() > 0) { 13224 Iterator<WeakReference<PendingIntentRecord>> it 13225 = mIntentSenderRecords.values().iterator(); 13226 while (it.hasNext()) { 13227 WeakReference<PendingIntentRecord> ref = it.next(); 13228 PendingIntentRecord rec = ref != null ? ref.get(): null; 13229 if (dumpPackage != null && (rec == null 13230 || !dumpPackage.equals(rec.key.packageName))) { 13231 continue; 13232 } 13233 printed = true; 13234 if (rec != null) { 13235 pw.print(" * "); pw.println(rec); 13236 if (dumpAll) { 13237 rec.dump(pw, " "); 13238 } 13239 } else { 13240 pw.print(" * "); pw.println(ref); 13241 } 13242 } 13243 } 13244 13245 if (!printed) { 13246 pw.println(" (nothing)"); 13247 } 13248 } 13249 13250 private static final int dumpProcessList(PrintWriter pw, 13251 ActivityManagerService service, List list, 13252 String prefix, String normalLabel, String persistentLabel, 13253 String dumpPackage) { 13254 int numPers = 0; 13255 final int N = list.size()-1; 13256 for (int i=N; i>=0; i--) { 13257 ProcessRecord r = (ProcessRecord)list.get(i); 13258 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13259 continue; 13260 } 13261 pw.println(String.format("%s%s #%2d: %s", 13262 prefix, (r.persistent ? persistentLabel : normalLabel), 13263 i, r.toString())); 13264 if (r.persistent) { 13265 numPers++; 13266 } 13267 } 13268 return numPers; 13269 } 13270 13271 private static final boolean dumpProcessOomList(PrintWriter pw, 13272 ActivityManagerService service, List<ProcessRecord> origList, 13273 String prefix, String normalLabel, String persistentLabel, 13274 boolean inclDetails, String dumpPackage) { 13275 13276 ArrayList<Pair<ProcessRecord, Integer>> list 13277 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13278 for (int i=0; i<origList.size(); i++) { 13279 ProcessRecord r = origList.get(i); 13280 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13281 continue; 13282 } 13283 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13284 } 13285 13286 if (list.size() <= 0) { 13287 return false; 13288 } 13289 13290 Comparator<Pair<ProcessRecord, Integer>> comparator 13291 = new Comparator<Pair<ProcessRecord, Integer>>() { 13292 @Override 13293 public int compare(Pair<ProcessRecord, Integer> object1, 13294 Pair<ProcessRecord, Integer> object2) { 13295 if (object1.first.setAdj != object2.first.setAdj) { 13296 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13297 } 13298 if (object1.second.intValue() != object2.second.intValue()) { 13299 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13300 } 13301 return 0; 13302 } 13303 }; 13304 13305 Collections.sort(list, comparator); 13306 13307 final long curRealtime = SystemClock.elapsedRealtime(); 13308 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13309 final long curUptime = SystemClock.uptimeMillis(); 13310 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13311 13312 for (int i=list.size()-1; i>=0; i--) { 13313 ProcessRecord r = list.get(i).first; 13314 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13315 char schedGroup; 13316 switch (r.setSchedGroup) { 13317 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13318 schedGroup = 'B'; 13319 break; 13320 case Process.THREAD_GROUP_DEFAULT: 13321 schedGroup = 'F'; 13322 break; 13323 default: 13324 schedGroup = '?'; 13325 break; 13326 } 13327 char foreground; 13328 if (r.foregroundActivities) { 13329 foreground = 'A'; 13330 } else if (r.foregroundServices) { 13331 foreground = 'S'; 13332 } else { 13333 foreground = ' '; 13334 } 13335 String procState = ProcessList.makeProcStateString(r.curProcState); 13336 pw.print(prefix); 13337 pw.print(r.persistent ? persistentLabel : normalLabel); 13338 pw.print(" #"); 13339 int num = (origList.size()-1)-list.get(i).second; 13340 if (num < 10) pw.print(' '); 13341 pw.print(num); 13342 pw.print(": "); 13343 pw.print(oomAdj); 13344 pw.print(' '); 13345 pw.print(schedGroup); 13346 pw.print('/'); 13347 pw.print(foreground); 13348 pw.print('/'); 13349 pw.print(procState); 13350 pw.print(" trm:"); 13351 if (r.trimMemoryLevel < 10) pw.print(' '); 13352 pw.print(r.trimMemoryLevel); 13353 pw.print(' '); 13354 pw.print(r.toShortString()); 13355 pw.print(" ("); 13356 pw.print(r.adjType); 13357 pw.println(')'); 13358 if (r.adjSource != null || r.adjTarget != null) { 13359 pw.print(prefix); 13360 pw.print(" "); 13361 if (r.adjTarget instanceof ComponentName) { 13362 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13363 } else if (r.adjTarget != null) { 13364 pw.print(r.adjTarget.toString()); 13365 } else { 13366 pw.print("{null}"); 13367 } 13368 pw.print("<="); 13369 if (r.adjSource instanceof ProcessRecord) { 13370 pw.print("Proc{"); 13371 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13372 pw.println("}"); 13373 } else if (r.adjSource != null) { 13374 pw.println(r.adjSource.toString()); 13375 } else { 13376 pw.println("{null}"); 13377 } 13378 } 13379 if (inclDetails) { 13380 pw.print(prefix); 13381 pw.print(" "); 13382 pw.print("oom: max="); pw.print(r.maxAdj); 13383 pw.print(" curRaw="); pw.print(r.curRawAdj); 13384 pw.print(" setRaw="); pw.print(r.setRawAdj); 13385 pw.print(" cur="); pw.print(r.curAdj); 13386 pw.print(" set="); pw.println(r.setAdj); 13387 pw.print(prefix); 13388 pw.print(" "); 13389 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13390 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13391 pw.print(" lastPss="); pw.print(r.lastPss); 13392 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13393 pw.print(prefix); 13394 pw.print(" "); 13395 pw.print("cached="); pw.print(r.cached); 13396 pw.print(" empty="); pw.print(r.empty); 13397 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13398 13399 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13400 if (r.lastWakeTime != 0) { 13401 long wtime; 13402 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13403 synchronized (stats) { 13404 wtime = stats.getProcessWakeTime(r.info.uid, 13405 r.pid, curRealtime); 13406 } 13407 long timeUsed = wtime - r.lastWakeTime; 13408 pw.print(prefix); 13409 pw.print(" "); 13410 pw.print("keep awake over "); 13411 TimeUtils.formatDuration(realtimeSince, pw); 13412 pw.print(" used "); 13413 TimeUtils.formatDuration(timeUsed, pw); 13414 pw.print(" ("); 13415 pw.print((timeUsed*100)/realtimeSince); 13416 pw.println("%)"); 13417 } 13418 if (r.lastCpuTime != 0) { 13419 long timeUsed = r.curCpuTime - r.lastCpuTime; 13420 pw.print(prefix); 13421 pw.print(" "); 13422 pw.print("run cpu over "); 13423 TimeUtils.formatDuration(uptimeSince, pw); 13424 pw.print(" used "); 13425 TimeUtils.formatDuration(timeUsed, pw); 13426 pw.print(" ("); 13427 pw.print((timeUsed*100)/uptimeSince); 13428 pw.println("%)"); 13429 } 13430 } 13431 } 13432 } 13433 return true; 13434 } 13435 13436 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13437 ArrayList<ProcessRecord> procs; 13438 synchronized (this) { 13439 if (args != null && args.length > start 13440 && args[start].charAt(0) != '-') { 13441 procs = new ArrayList<ProcessRecord>(); 13442 int pid = -1; 13443 try { 13444 pid = Integer.parseInt(args[start]); 13445 } catch (NumberFormatException e) { 13446 } 13447 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13448 ProcessRecord proc = mLruProcesses.get(i); 13449 if (proc.pid == pid) { 13450 procs.add(proc); 13451 } else if (proc.processName.equals(args[start])) { 13452 procs.add(proc); 13453 } 13454 } 13455 if (procs.size() <= 0) { 13456 return null; 13457 } 13458 } else { 13459 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13460 } 13461 } 13462 return procs; 13463 } 13464 13465 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13466 PrintWriter pw, String[] args) { 13467 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13468 if (procs == null) { 13469 pw.println("No process found for: " + args[0]); 13470 return; 13471 } 13472 13473 long uptime = SystemClock.uptimeMillis(); 13474 long realtime = SystemClock.elapsedRealtime(); 13475 pw.println("Applications Graphics Acceleration Info:"); 13476 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13477 13478 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13479 ProcessRecord r = procs.get(i); 13480 if (r.thread != null) { 13481 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13482 pw.flush(); 13483 try { 13484 TransferPipe tp = new TransferPipe(); 13485 try { 13486 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13487 tp.go(fd); 13488 } finally { 13489 tp.kill(); 13490 } 13491 } catch (IOException e) { 13492 pw.println("Failure while dumping the app: " + r); 13493 pw.flush(); 13494 } catch (RemoteException e) { 13495 pw.println("Got a RemoteException while dumping the app " + r); 13496 pw.flush(); 13497 } 13498 } 13499 } 13500 } 13501 13502 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13503 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13504 if (procs == null) { 13505 pw.println("No process found for: " + args[0]); 13506 return; 13507 } 13508 13509 pw.println("Applications Database Info:"); 13510 13511 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13512 ProcessRecord r = procs.get(i); 13513 if (r.thread != null) { 13514 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13515 pw.flush(); 13516 try { 13517 TransferPipe tp = new TransferPipe(); 13518 try { 13519 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13520 tp.go(fd); 13521 } finally { 13522 tp.kill(); 13523 } 13524 } catch (IOException e) { 13525 pw.println("Failure while dumping the app: " + r); 13526 pw.flush(); 13527 } catch (RemoteException e) { 13528 pw.println("Got a RemoteException while dumping the app " + r); 13529 pw.flush(); 13530 } 13531 } 13532 } 13533 } 13534 13535 final static class MemItem { 13536 final boolean isProc; 13537 final String label; 13538 final String shortLabel; 13539 final long pss; 13540 final int id; 13541 final boolean hasActivities; 13542 ArrayList<MemItem> subitems; 13543 13544 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13545 boolean _hasActivities) { 13546 isProc = true; 13547 label = _label; 13548 shortLabel = _shortLabel; 13549 pss = _pss; 13550 id = _id; 13551 hasActivities = _hasActivities; 13552 } 13553 13554 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13555 isProc = false; 13556 label = _label; 13557 shortLabel = _shortLabel; 13558 pss = _pss; 13559 id = _id; 13560 hasActivities = false; 13561 } 13562 } 13563 13564 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13565 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13566 if (sort && !isCompact) { 13567 Collections.sort(items, new Comparator<MemItem>() { 13568 @Override 13569 public int compare(MemItem lhs, MemItem rhs) { 13570 if (lhs.pss < rhs.pss) { 13571 return 1; 13572 } else if (lhs.pss > rhs.pss) { 13573 return -1; 13574 } 13575 return 0; 13576 } 13577 }); 13578 } 13579 13580 for (int i=0; i<items.size(); i++) { 13581 MemItem mi = items.get(i); 13582 if (!isCompact) { 13583 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13584 } else if (mi.isProc) { 13585 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13586 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13587 pw.println(mi.hasActivities ? ",a" : ",e"); 13588 } else { 13589 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13590 pw.println(mi.pss); 13591 } 13592 if (mi.subitems != null) { 13593 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13594 true, isCompact); 13595 } 13596 } 13597 } 13598 13599 // These are in KB. 13600 static final long[] DUMP_MEM_BUCKETS = new long[] { 13601 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13602 120*1024, 160*1024, 200*1024, 13603 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13604 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13605 }; 13606 13607 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13608 boolean stackLike) { 13609 int start = label.lastIndexOf('.'); 13610 if (start >= 0) start++; 13611 else start = 0; 13612 int end = label.length(); 13613 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13614 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13615 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13616 out.append(bucket); 13617 out.append(stackLike ? "MB." : "MB "); 13618 out.append(label, start, end); 13619 return; 13620 } 13621 } 13622 out.append(memKB/1024); 13623 out.append(stackLike ? "MB." : "MB "); 13624 out.append(label, start, end); 13625 } 13626 13627 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13628 ProcessList.NATIVE_ADJ, 13629 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13630 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13631 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13632 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13633 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13634 }; 13635 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13636 "Native", 13637 "System", "Persistent", "Foreground", 13638 "Visible", "Perceptible", 13639 "Heavy Weight", "Backup", 13640 "A Services", "Home", 13641 "Previous", "B Services", "Cached" 13642 }; 13643 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13644 "native", 13645 "sys", "pers", "fore", 13646 "vis", "percept", 13647 "heavy", "backup", 13648 "servicea", "home", 13649 "prev", "serviceb", "cached" 13650 }; 13651 13652 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13653 long realtime, boolean isCheckinRequest, boolean isCompact) { 13654 if (isCheckinRequest || isCompact) { 13655 // short checkin version 13656 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13657 } else { 13658 pw.println("Applications Memory Usage (kB):"); 13659 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13660 } 13661 } 13662 13663 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13664 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13665 boolean dumpDetails = false; 13666 boolean dumpFullDetails = false; 13667 boolean dumpDalvik = false; 13668 boolean oomOnly = false; 13669 boolean isCompact = false; 13670 boolean localOnly = false; 13671 13672 int opti = 0; 13673 while (opti < args.length) { 13674 String opt = args[opti]; 13675 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13676 break; 13677 } 13678 opti++; 13679 if ("-a".equals(opt)) { 13680 dumpDetails = true; 13681 dumpFullDetails = true; 13682 dumpDalvik = true; 13683 } else if ("-d".equals(opt)) { 13684 dumpDalvik = true; 13685 } else if ("-c".equals(opt)) { 13686 isCompact = true; 13687 } else if ("--oom".equals(opt)) { 13688 oomOnly = true; 13689 } else if ("--local".equals(opt)) { 13690 localOnly = true; 13691 } else if ("-h".equals(opt)) { 13692 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13693 pw.println(" -a: include all available information for each process."); 13694 pw.println(" -d: include dalvik details when dumping process details."); 13695 pw.println(" -c: dump in a compact machine-parseable representation."); 13696 pw.println(" --oom: only show processes organized by oom adj."); 13697 pw.println(" --local: only collect details locally, don't call process."); 13698 pw.println("If [process] is specified it can be the name or "); 13699 pw.println("pid of a specific process to dump."); 13700 return; 13701 } else { 13702 pw.println("Unknown argument: " + opt + "; use -h for help"); 13703 } 13704 } 13705 13706 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13707 long uptime = SystemClock.uptimeMillis(); 13708 long realtime = SystemClock.elapsedRealtime(); 13709 final long[] tmpLong = new long[1]; 13710 13711 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13712 if (procs == null) { 13713 // No Java processes. Maybe they want to print a native process. 13714 if (args != null && args.length > opti 13715 && args[opti].charAt(0) != '-') { 13716 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13717 = new ArrayList<ProcessCpuTracker.Stats>(); 13718 updateCpuStatsNow(); 13719 int findPid = -1; 13720 try { 13721 findPid = Integer.parseInt(args[opti]); 13722 } catch (NumberFormatException e) { 13723 } 13724 synchronized (mProcessCpuThread) { 13725 final int N = mProcessCpuTracker.countStats(); 13726 for (int i=0; i<N; i++) { 13727 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13728 if (st.pid == findPid || (st.baseName != null 13729 && st.baseName.equals(args[opti]))) { 13730 nativeProcs.add(st); 13731 } 13732 } 13733 } 13734 if (nativeProcs.size() > 0) { 13735 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13736 isCompact); 13737 Debug.MemoryInfo mi = null; 13738 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13739 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13740 final int pid = r.pid; 13741 if (!isCheckinRequest && dumpDetails) { 13742 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13743 } 13744 if (mi == null) { 13745 mi = new Debug.MemoryInfo(); 13746 } 13747 if (dumpDetails || (!brief && !oomOnly)) { 13748 Debug.getMemoryInfo(pid, mi); 13749 } else { 13750 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13751 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13752 } 13753 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13754 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13755 if (isCheckinRequest) { 13756 pw.println(); 13757 } 13758 } 13759 return; 13760 } 13761 } 13762 pw.println("No process found for: " + args[opti]); 13763 return; 13764 } 13765 13766 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13767 dumpDetails = true; 13768 } 13769 13770 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13771 13772 String[] innerArgs = new String[args.length-opti]; 13773 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13774 13775 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13776 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13777 long nativePss=0, dalvikPss=0, otherPss=0; 13778 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13779 13780 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13781 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13782 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13783 13784 long totalPss = 0; 13785 long cachedPss = 0; 13786 13787 Debug.MemoryInfo mi = null; 13788 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13789 final ProcessRecord r = procs.get(i); 13790 final IApplicationThread thread; 13791 final int pid; 13792 final int oomAdj; 13793 final boolean hasActivities; 13794 synchronized (this) { 13795 thread = r.thread; 13796 pid = r.pid; 13797 oomAdj = r.getSetAdjWithServices(); 13798 hasActivities = r.activities.size() > 0; 13799 } 13800 if (thread != null) { 13801 if (!isCheckinRequest && dumpDetails) { 13802 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13803 } 13804 if (mi == null) { 13805 mi = new Debug.MemoryInfo(); 13806 } 13807 if (dumpDetails || (!brief && !oomOnly)) { 13808 Debug.getMemoryInfo(pid, mi); 13809 } else { 13810 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13811 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13812 } 13813 if (dumpDetails) { 13814 if (localOnly) { 13815 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13816 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13817 if (isCheckinRequest) { 13818 pw.println(); 13819 } 13820 } else { 13821 try { 13822 pw.flush(); 13823 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13824 dumpDalvik, innerArgs); 13825 } catch (RemoteException e) { 13826 if (!isCheckinRequest) { 13827 pw.println("Got RemoteException!"); 13828 pw.flush(); 13829 } 13830 } 13831 } 13832 } 13833 13834 final long myTotalPss = mi.getTotalPss(); 13835 final long myTotalUss = mi.getTotalUss(); 13836 13837 synchronized (this) { 13838 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13839 // Record this for posterity if the process has been stable. 13840 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13841 } 13842 } 13843 13844 if (!isCheckinRequest && mi != null) { 13845 totalPss += myTotalPss; 13846 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13847 (hasActivities ? " / activities)" : ")"), 13848 r.processName, myTotalPss, pid, hasActivities); 13849 procMems.add(pssItem); 13850 procMemsMap.put(pid, pssItem); 13851 13852 nativePss += mi.nativePss; 13853 dalvikPss += mi.dalvikPss; 13854 otherPss += mi.otherPss; 13855 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13856 long mem = mi.getOtherPss(j); 13857 miscPss[j] += mem; 13858 otherPss -= mem; 13859 } 13860 13861 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13862 cachedPss += myTotalPss; 13863 } 13864 13865 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13866 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13867 || oomIndex == (oomPss.length-1)) { 13868 oomPss[oomIndex] += myTotalPss; 13869 if (oomProcs[oomIndex] == null) { 13870 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13871 } 13872 oomProcs[oomIndex].add(pssItem); 13873 break; 13874 } 13875 } 13876 } 13877 } 13878 } 13879 13880 long nativeProcTotalPss = 0; 13881 13882 if (!isCheckinRequest && procs.size() > 1) { 13883 // If we are showing aggregations, also look for native processes to 13884 // include so that our aggregations are more accurate. 13885 updateCpuStatsNow(); 13886 synchronized (mProcessCpuThread) { 13887 final int N = mProcessCpuTracker.countStats(); 13888 for (int i=0; i<N; i++) { 13889 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13890 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13891 if (mi == null) { 13892 mi = new Debug.MemoryInfo(); 13893 } 13894 if (!brief && !oomOnly) { 13895 Debug.getMemoryInfo(st.pid, mi); 13896 } else { 13897 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13898 mi.nativePrivateDirty = (int)tmpLong[0]; 13899 } 13900 13901 final long myTotalPss = mi.getTotalPss(); 13902 totalPss += myTotalPss; 13903 nativeProcTotalPss += myTotalPss; 13904 13905 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13906 st.name, myTotalPss, st.pid, false); 13907 procMems.add(pssItem); 13908 13909 nativePss += mi.nativePss; 13910 dalvikPss += mi.dalvikPss; 13911 otherPss += mi.otherPss; 13912 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13913 long mem = mi.getOtherPss(j); 13914 miscPss[j] += mem; 13915 otherPss -= mem; 13916 } 13917 oomPss[0] += myTotalPss; 13918 if (oomProcs[0] == null) { 13919 oomProcs[0] = new ArrayList<MemItem>(); 13920 } 13921 oomProcs[0].add(pssItem); 13922 } 13923 } 13924 } 13925 13926 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13927 13928 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13929 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13930 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13931 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13932 String label = Debug.MemoryInfo.getOtherLabel(j); 13933 catMems.add(new MemItem(label, label, miscPss[j], j)); 13934 } 13935 13936 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13937 for (int j=0; j<oomPss.length; j++) { 13938 if (oomPss[j] != 0) { 13939 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13940 : DUMP_MEM_OOM_LABEL[j]; 13941 MemItem item = new MemItem(label, label, oomPss[j], 13942 DUMP_MEM_OOM_ADJ[j]); 13943 item.subitems = oomProcs[j]; 13944 oomMems.add(item); 13945 } 13946 } 13947 13948 if (!brief && !oomOnly && !isCompact) { 13949 pw.println(); 13950 pw.println("Total PSS by process:"); 13951 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13952 pw.println(); 13953 } 13954 if (!isCompact) { 13955 pw.println("Total PSS by OOM adjustment:"); 13956 } 13957 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13958 if (!brief && !oomOnly) { 13959 PrintWriter out = categoryPw != null ? categoryPw : pw; 13960 if (!isCompact) { 13961 out.println(); 13962 out.println("Total PSS by category:"); 13963 } 13964 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13965 } 13966 if (!isCompact) { 13967 pw.println(); 13968 } 13969 MemInfoReader memInfo = new MemInfoReader(); 13970 memInfo.readMemInfo(); 13971 if (nativeProcTotalPss > 0) { 13972 synchronized (this) { 13973 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13974 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13975 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13976 nativeProcTotalPss); 13977 } 13978 } 13979 if (!brief) { 13980 if (!isCompact) { 13981 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13982 pw.print(" kB (status "); 13983 switch (mLastMemoryLevel) { 13984 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13985 pw.println("normal)"); 13986 break; 13987 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13988 pw.println("moderate)"); 13989 break; 13990 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13991 pw.println("low)"); 13992 break; 13993 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13994 pw.println("critical)"); 13995 break; 13996 default: 13997 pw.print(mLastMemoryLevel); 13998 pw.println(")"); 13999 break; 14000 } 14001 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14002 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14003 pw.print(cachedPss); pw.print(" cached pss + "); 14004 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14005 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14006 } else { 14007 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14008 pw.print(cachedPss + memInfo.getCachedSizeKb() 14009 + memInfo.getFreeSizeKb()); pw.print(","); 14010 pw.println(totalPss - cachedPss); 14011 } 14012 } 14013 if (!isCompact) { 14014 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14015 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14016 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14017 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14018 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14019 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14020 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14021 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14022 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14023 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14024 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14025 } 14026 if (!brief) { 14027 if (memInfo.getZramTotalSizeKb() != 0) { 14028 if (!isCompact) { 14029 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14030 pw.print(" kB physical used for "); 14031 pw.print(memInfo.getSwapTotalSizeKb() 14032 - memInfo.getSwapFreeSizeKb()); 14033 pw.print(" kB in swap ("); 14034 pw.print(memInfo.getSwapTotalSizeKb()); 14035 pw.println(" kB total swap)"); 14036 } else { 14037 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14038 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14039 pw.println(memInfo.getSwapFreeSizeKb()); 14040 } 14041 } 14042 final int[] SINGLE_LONG_FORMAT = new int[] { 14043 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14044 }; 14045 long[] longOut = new long[1]; 14046 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14047 SINGLE_LONG_FORMAT, null, longOut, null); 14048 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14049 longOut[0] = 0; 14050 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14051 SINGLE_LONG_FORMAT, null, longOut, null); 14052 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14053 longOut[0] = 0; 14054 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14055 SINGLE_LONG_FORMAT, null, longOut, null); 14056 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14057 longOut[0] = 0; 14058 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14059 SINGLE_LONG_FORMAT, null, longOut, null); 14060 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14061 if (!isCompact) { 14062 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14063 pw.print(" KSM: "); pw.print(sharing); 14064 pw.print(" kB saved from shared "); 14065 pw.print(shared); pw.println(" kB"); 14066 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14067 pw.print(voltile); pw.println(" kB volatile"); 14068 } 14069 pw.print(" Tuning: "); 14070 pw.print(ActivityManager.staticGetMemoryClass()); 14071 pw.print(" (large "); 14072 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14073 pw.print("), oom "); 14074 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14075 pw.print(" kB"); 14076 pw.print(", restore limit "); 14077 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14078 pw.print(" kB"); 14079 if (ActivityManager.isLowRamDeviceStatic()) { 14080 pw.print(" (low-ram)"); 14081 } 14082 if (ActivityManager.isHighEndGfx()) { 14083 pw.print(" (high-end-gfx)"); 14084 } 14085 pw.println(); 14086 } else { 14087 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14088 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14089 pw.println(voltile); 14090 pw.print("tuning,"); 14091 pw.print(ActivityManager.staticGetMemoryClass()); 14092 pw.print(','); 14093 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14094 pw.print(','); 14095 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14096 if (ActivityManager.isLowRamDeviceStatic()) { 14097 pw.print(",low-ram"); 14098 } 14099 if (ActivityManager.isHighEndGfx()) { 14100 pw.print(",high-end-gfx"); 14101 } 14102 pw.println(); 14103 } 14104 } 14105 } 14106 } 14107 14108 /** 14109 * Searches array of arguments for the specified string 14110 * @param args array of argument strings 14111 * @param value value to search for 14112 * @return true if the value is contained in the array 14113 */ 14114 private static boolean scanArgs(String[] args, String value) { 14115 if (args != null) { 14116 for (String arg : args) { 14117 if (value.equals(arg)) { 14118 return true; 14119 } 14120 } 14121 } 14122 return false; 14123 } 14124 14125 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14126 ContentProviderRecord cpr, boolean always) { 14127 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14128 14129 if (!inLaunching || always) { 14130 synchronized (cpr) { 14131 cpr.launchingApp = null; 14132 cpr.notifyAll(); 14133 } 14134 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14135 String names[] = cpr.info.authority.split(";"); 14136 for (int j = 0; j < names.length; j++) { 14137 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14138 } 14139 } 14140 14141 for (int i=0; i<cpr.connections.size(); i++) { 14142 ContentProviderConnection conn = cpr.connections.get(i); 14143 if (conn.waiting) { 14144 // If this connection is waiting for the provider, then we don't 14145 // need to mess with its process unless we are always removing 14146 // or for some reason the provider is not currently launching. 14147 if (inLaunching && !always) { 14148 continue; 14149 } 14150 } 14151 ProcessRecord capp = conn.client; 14152 conn.dead = true; 14153 if (conn.stableCount > 0) { 14154 if (!capp.persistent && capp.thread != null 14155 && capp.pid != 0 14156 && capp.pid != MY_PID) { 14157 capp.kill("depends on provider " 14158 + cpr.name.flattenToShortString() 14159 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14160 } 14161 } else if (capp.thread != null && conn.provider.provider != null) { 14162 try { 14163 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14164 } catch (RemoteException e) { 14165 } 14166 // In the protocol here, we don't expect the client to correctly 14167 // clean up this connection, we'll just remove it. 14168 cpr.connections.remove(i); 14169 conn.client.conProviders.remove(conn); 14170 } 14171 } 14172 14173 if (inLaunching && always) { 14174 mLaunchingProviders.remove(cpr); 14175 } 14176 return inLaunching; 14177 } 14178 14179 /** 14180 * Main code for cleaning up a process when it has gone away. This is 14181 * called both as a result of the process dying, or directly when stopping 14182 * a process when running in single process mode. 14183 */ 14184 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14185 boolean restarting, boolean allowRestart, int index) { 14186 if (index >= 0) { 14187 removeLruProcessLocked(app); 14188 ProcessList.remove(app.pid); 14189 } 14190 14191 mProcessesToGc.remove(app); 14192 mPendingPssProcesses.remove(app); 14193 14194 // Dismiss any open dialogs. 14195 if (app.crashDialog != null && !app.forceCrashReport) { 14196 app.crashDialog.dismiss(); 14197 app.crashDialog = null; 14198 } 14199 if (app.anrDialog != null) { 14200 app.anrDialog.dismiss(); 14201 app.anrDialog = null; 14202 } 14203 if (app.waitDialog != null) { 14204 app.waitDialog.dismiss(); 14205 app.waitDialog = null; 14206 } 14207 14208 app.crashing = false; 14209 app.notResponding = false; 14210 14211 app.resetPackageList(mProcessStats); 14212 app.unlinkDeathRecipient(); 14213 app.makeInactive(mProcessStats); 14214 app.waitingToKill = null; 14215 app.forcingToForeground = null; 14216 updateProcessForegroundLocked(app, false, false); 14217 app.foregroundActivities = false; 14218 app.hasShownUi = false; 14219 app.treatLikeActivity = false; 14220 app.hasAboveClient = false; 14221 app.hasClientActivities = false; 14222 14223 mServices.killServicesLocked(app, allowRestart); 14224 14225 boolean restart = false; 14226 14227 // Remove published content providers. 14228 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14229 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14230 final boolean always = app.bad || !allowRestart; 14231 if (removeDyingProviderLocked(app, cpr, always) || always) { 14232 // We left the provider in the launching list, need to 14233 // restart it. 14234 restart = true; 14235 } 14236 14237 cpr.provider = null; 14238 cpr.proc = null; 14239 } 14240 app.pubProviders.clear(); 14241 14242 // Take care of any launching providers waiting for this process. 14243 if (checkAppInLaunchingProvidersLocked(app, false)) { 14244 restart = true; 14245 } 14246 14247 // Unregister from connected content providers. 14248 if (!app.conProviders.isEmpty()) { 14249 for (int i=0; i<app.conProviders.size(); i++) { 14250 ContentProviderConnection conn = app.conProviders.get(i); 14251 conn.provider.connections.remove(conn); 14252 } 14253 app.conProviders.clear(); 14254 } 14255 14256 // At this point there may be remaining entries in mLaunchingProviders 14257 // where we were the only one waiting, so they are no longer of use. 14258 // Look for these and clean up if found. 14259 // XXX Commented out for now. Trying to figure out a way to reproduce 14260 // the actual situation to identify what is actually going on. 14261 if (false) { 14262 for (int i=0; i<mLaunchingProviders.size(); i++) { 14263 ContentProviderRecord cpr = (ContentProviderRecord) 14264 mLaunchingProviders.get(i); 14265 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14266 synchronized (cpr) { 14267 cpr.launchingApp = null; 14268 cpr.notifyAll(); 14269 } 14270 } 14271 } 14272 } 14273 14274 skipCurrentReceiverLocked(app); 14275 14276 // Unregister any receivers. 14277 for (int i=app.receivers.size()-1; i>=0; i--) { 14278 removeReceiverLocked(app.receivers.valueAt(i)); 14279 } 14280 app.receivers.clear(); 14281 14282 // If the app is undergoing backup, tell the backup manager about it 14283 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14284 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14285 + mBackupTarget.appInfo + " died during backup"); 14286 try { 14287 IBackupManager bm = IBackupManager.Stub.asInterface( 14288 ServiceManager.getService(Context.BACKUP_SERVICE)); 14289 bm.agentDisconnected(app.info.packageName); 14290 } catch (RemoteException e) { 14291 // can't happen; backup manager is local 14292 } 14293 } 14294 14295 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14296 ProcessChangeItem item = mPendingProcessChanges.get(i); 14297 if (item.pid == app.pid) { 14298 mPendingProcessChanges.remove(i); 14299 mAvailProcessChanges.add(item); 14300 } 14301 } 14302 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14303 14304 // If the caller is restarting this app, then leave it in its 14305 // current lists and let the caller take care of it. 14306 if (restarting) { 14307 return; 14308 } 14309 14310 if (!app.persistent || app.isolated) { 14311 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14312 "Removing non-persistent process during cleanup: " + app); 14313 mProcessNames.remove(app.processName, app.uid); 14314 mIsolatedProcesses.remove(app.uid); 14315 if (mHeavyWeightProcess == app) { 14316 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14317 mHeavyWeightProcess.userId, 0)); 14318 mHeavyWeightProcess = null; 14319 } 14320 } else if (!app.removed) { 14321 // This app is persistent, so we need to keep its record around. 14322 // If it is not already on the pending app list, add it there 14323 // and start a new process for it. 14324 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14325 mPersistentStartingProcesses.add(app); 14326 restart = true; 14327 } 14328 } 14329 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14330 "Clean-up removing on hold: " + app); 14331 mProcessesOnHold.remove(app); 14332 14333 if (app == mHomeProcess) { 14334 mHomeProcess = null; 14335 } 14336 if (app == mPreviousProcess) { 14337 mPreviousProcess = null; 14338 } 14339 14340 if (restart && !app.isolated) { 14341 // We have components that still need to be running in the 14342 // process, so re-launch it. 14343 mProcessNames.put(app.processName, app.uid, app); 14344 startProcessLocked(app, "restart", app.processName); 14345 } else if (app.pid > 0 && app.pid != MY_PID) { 14346 // Goodbye! 14347 boolean removed; 14348 synchronized (mPidsSelfLocked) { 14349 mPidsSelfLocked.remove(app.pid); 14350 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14351 } 14352 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14353 if (app.isolated) { 14354 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14355 } 14356 app.setPid(0); 14357 } 14358 } 14359 14360 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14361 // Look through the content providers we are waiting to have launched, 14362 // and if any run in this process then either schedule a restart of 14363 // the process or kill the client waiting for it if this process has 14364 // gone bad. 14365 int NL = mLaunchingProviders.size(); 14366 boolean restart = false; 14367 for (int i=0; i<NL; i++) { 14368 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14369 if (cpr.launchingApp == app) { 14370 if (!alwaysBad && !app.bad) { 14371 restart = true; 14372 } else { 14373 removeDyingProviderLocked(app, cpr, true); 14374 // cpr should have been removed from mLaunchingProviders 14375 NL = mLaunchingProviders.size(); 14376 i--; 14377 } 14378 } 14379 } 14380 return restart; 14381 } 14382 14383 // ========================================================= 14384 // SERVICES 14385 // ========================================================= 14386 14387 @Override 14388 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14389 int flags) { 14390 enforceNotIsolatedCaller("getServices"); 14391 synchronized (this) { 14392 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14393 } 14394 } 14395 14396 @Override 14397 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14398 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14399 synchronized (this) { 14400 return mServices.getRunningServiceControlPanelLocked(name); 14401 } 14402 } 14403 14404 @Override 14405 public ComponentName startService(IApplicationThread caller, Intent service, 14406 String resolvedType, int userId) { 14407 enforceNotIsolatedCaller("startService"); 14408 // Refuse possible leaked file descriptors 14409 if (service != null && service.hasFileDescriptors() == true) { 14410 throw new IllegalArgumentException("File descriptors passed in Intent"); 14411 } 14412 14413 if (DEBUG_SERVICE) 14414 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14415 synchronized(this) { 14416 final int callingPid = Binder.getCallingPid(); 14417 final int callingUid = Binder.getCallingUid(); 14418 final long origId = Binder.clearCallingIdentity(); 14419 ComponentName res = mServices.startServiceLocked(caller, service, 14420 resolvedType, callingPid, callingUid, userId); 14421 Binder.restoreCallingIdentity(origId); 14422 return res; 14423 } 14424 } 14425 14426 ComponentName startServiceInPackage(int uid, 14427 Intent service, String resolvedType, int userId) { 14428 synchronized(this) { 14429 if (DEBUG_SERVICE) 14430 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14431 final long origId = Binder.clearCallingIdentity(); 14432 ComponentName res = mServices.startServiceLocked(null, service, 14433 resolvedType, -1, uid, userId); 14434 Binder.restoreCallingIdentity(origId); 14435 return res; 14436 } 14437 } 14438 14439 @Override 14440 public int stopService(IApplicationThread caller, Intent service, 14441 String resolvedType, int userId) { 14442 enforceNotIsolatedCaller("stopService"); 14443 // Refuse possible leaked file descriptors 14444 if (service != null && service.hasFileDescriptors() == true) { 14445 throw new IllegalArgumentException("File descriptors passed in Intent"); 14446 } 14447 14448 synchronized(this) { 14449 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14450 } 14451 } 14452 14453 @Override 14454 public IBinder peekService(Intent service, String resolvedType) { 14455 enforceNotIsolatedCaller("peekService"); 14456 // Refuse possible leaked file descriptors 14457 if (service != null && service.hasFileDescriptors() == true) { 14458 throw new IllegalArgumentException("File descriptors passed in Intent"); 14459 } 14460 synchronized(this) { 14461 return mServices.peekServiceLocked(service, resolvedType); 14462 } 14463 } 14464 14465 @Override 14466 public boolean stopServiceToken(ComponentName className, IBinder token, 14467 int startId) { 14468 synchronized(this) { 14469 return mServices.stopServiceTokenLocked(className, token, startId); 14470 } 14471 } 14472 14473 @Override 14474 public void setServiceForeground(ComponentName className, IBinder token, 14475 int id, Notification notification, boolean removeNotification) { 14476 synchronized(this) { 14477 mServices.setServiceForegroundLocked(className, token, id, notification, 14478 removeNotification); 14479 } 14480 } 14481 14482 @Override 14483 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14484 boolean requireFull, String name, String callerPackage) { 14485 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14486 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14487 } 14488 14489 int unsafeConvertIncomingUser(int userId) { 14490 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14491 ? mCurrentUserId : userId; 14492 } 14493 14494 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14495 int allowMode, String name, String callerPackage) { 14496 final int callingUserId = UserHandle.getUserId(callingUid); 14497 if (callingUserId == userId) { 14498 return userId; 14499 } 14500 14501 // Note that we may be accessing mCurrentUserId outside of a lock... 14502 // shouldn't be a big deal, if this is being called outside 14503 // of a locked context there is intrinsically a race with 14504 // the value the caller will receive and someone else changing it. 14505 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14506 // we will switch to the calling user if access to the current user fails. 14507 int targetUserId = unsafeConvertIncomingUser(userId); 14508 14509 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14510 final boolean allow; 14511 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14512 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14513 // If the caller has this permission, they always pass go. And collect $200. 14514 allow = true; 14515 } else if (allowMode == ALLOW_FULL_ONLY) { 14516 // We require full access, sucks to be you. 14517 allow = false; 14518 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14519 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14520 // If the caller does not have either permission, they are always doomed. 14521 allow = false; 14522 } else if (allowMode == ALLOW_NON_FULL) { 14523 // We are blanket allowing non-full access, you lucky caller! 14524 allow = true; 14525 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14526 // We may or may not allow this depending on whether the two users are 14527 // in the same profile. 14528 synchronized (mUserProfileGroupIdsSelfLocked) { 14529 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14530 UserInfo.NO_PROFILE_GROUP_ID); 14531 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14532 UserInfo.NO_PROFILE_GROUP_ID); 14533 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14534 && callingProfile == targetProfile; 14535 } 14536 } else { 14537 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14538 } 14539 if (!allow) { 14540 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14541 // In this case, they would like to just execute as their 14542 // owner user instead of failing. 14543 targetUserId = callingUserId; 14544 } else { 14545 StringBuilder builder = new StringBuilder(128); 14546 builder.append("Permission Denial: "); 14547 builder.append(name); 14548 if (callerPackage != null) { 14549 builder.append(" from "); 14550 builder.append(callerPackage); 14551 } 14552 builder.append(" asks to run as user "); 14553 builder.append(userId); 14554 builder.append(" but is calling from user "); 14555 builder.append(UserHandle.getUserId(callingUid)); 14556 builder.append("; this requires "); 14557 builder.append(INTERACT_ACROSS_USERS_FULL); 14558 if (allowMode != ALLOW_FULL_ONLY) { 14559 builder.append(" or "); 14560 builder.append(INTERACT_ACROSS_USERS); 14561 } 14562 String msg = builder.toString(); 14563 Slog.w(TAG, msg); 14564 throw new SecurityException(msg); 14565 } 14566 } 14567 } 14568 if (!allowAll && targetUserId < 0) { 14569 throw new IllegalArgumentException( 14570 "Call does not support special user #" + targetUserId); 14571 } 14572 return targetUserId; 14573 } 14574 14575 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14576 String className, int flags) { 14577 boolean result = false; 14578 // For apps that don't have pre-defined UIDs, check for permission 14579 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14580 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14581 if (ActivityManager.checkUidPermission( 14582 INTERACT_ACROSS_USERS, 14583 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14584 ComponentName comp = new ComponentName(aInfo.packageName, className); 14585 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14586 + " requests FLAG_SINGLE_USER, but app does not hold " 14587 + INTERACT_ACROSS_USERS; 14588 Slog.w(TAG, msg); 14589 throw new SecurityException(msg); 14590 } 14591 // Permission passed 14592 result = true; 14593 } 14594 } else if ("system".equals(componentProcessName)) { 14595 result = true; 14596 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14597 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14598 // Phone app is allowed to export singleuser providers. 14599 result = true; 14600 } else { 14601 // App with pre-defined UID, check if it's a persistent app 14602 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14603 } 14604 if (DEBUG_MU) { 14605 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14606 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14607 } 14608 return result; 14609 } 14610 14611 /** 14612 * Checks to see if the caller is in the same app as the singleton 14613 * component, or the component is in a special app. It allows special apps 14614 * to export singleton components but prevents exporting singleton 14615 * components for regular apps. 14616 */ 14617 boolean isValidSingletonCall(int callingUid, int componentUid) { 14618 int componentAppId = UserHandle.getAppId(componentUid); 14619 return UserHandle.isSameApp(callingUid, componentUid) 14620 || componentAppId == Process.SYSTEM_UID 14621 || componentAppId == Process.PHONE_UID 14622 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14623 == PackageManager.PERMISSION_GRANTED; 14624 } 14625 14626 public int bindService(IApplicationThread caller, IBinder token, 14627 Intent service, String resolvedType, 14628 IServiceConnection connection, int flags, int userId) { 14629 enforceNotIsolatedCaller("bindService"); 14630 // Refuse possible leaked file descriptors 14631 if (service != null && service.hasFileDescriptors() == true) { 14632 throw new IllegalArgumentException("File descriptors passed in Intent"); 14633 } 14634 14635 synchronized(this) { 14636 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14637 connection, flags, userId); 14638 } 14639 } 14640 14641 public boolean unbindService(IServiceConnection connection) { 14642 synchronized (this) { 14643 return mServices.unbindServiceLocked(connection); 14644 } 14645 } 14646 14647 public void publishService(IBinder token, Intent intent, IBinder service) { 14648 // Refuse possible leaked file descriptors 14649 if (intent != null && intent.hasFileDescriptors() == true) { 14650 throw new IllegalArgumentException("File descriptors passed in Intent"); 14651 } 14652 14653 synchronized(this) { 14654 if (!(token instanceof ServiceRecord)) { 14655 throw new IllegalArgumentException("Invalid service token"); 14656 } 14657 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14658 } 14659 } 14660 14661 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14662 // Refuse possible leaked file descriptors 14663 if (intent != null && intent.hasFileDescriptors() == true) { 14664 throw new IllegalArgumentException("File descriptors passed in Intent"); 14665 } 14666 14667 synchronized(this) { 14668 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14669 } 14670 } 14671 14672 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14673 synchronized(this) { 14674 if (!(token instanceof ServiceRecord)) { 14675 throw new IllegalArgumentException("Invalid service token"); 14676 } 14677 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14678 } 14679 } 14680 14681 // ========================================================= 14682 // BACKUP AND RESTORE 14683 // ========================================================= 14684 14685 // Cause the target app to be launched if necessary and its backup agent 14686 // instantiated. The backup agent will invoke backupAgentCreated() on the 14687 // activity manager to announce its creation. 14688 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14689 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14690 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14691 14692 synchronized(this) { 14693 // !!! TODO: currently no check here that we're already bound 14694 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14695 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14696 synchronized (stats) { 14697 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14698 } 14699 14700 // Backup agent is now in use, its package can't be stopped. 14701 try { 14702 AppGlobals.getPackageManager().setPackageStoppedState( 14703 app.packageName, false, UserHandle.getUserId(app.uid)); 14704 } catch (RemoteException e) { 14705 } catch (IllegalArgumentException e) { 14706 Slog.w(TAG, "Failed trying to unstop package " 14707 + app.packageName + ": " + e); 14708 } 14709 14710 BackupRecord r = new BackupRecord(ss, app, backupMode); 14711 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14712 ? new ComponentName(app.packageName, app.backupAgentName) 14713 : new ComponentName("android", "FullBackupAgent"); 14714 // startProcessLocked() returns existing proc's record if it's already running 14715 ProcessRecord proc = startProcessLocked(app.processName, app, 14716 false, 0, "backup", hostingName, false, false, false); 14717 if (proc == null) { 14718 Slog.e(TAG, "Unable to start backup agent process " + r); 14719 return false; 14720 } 14721 14722 r.app = proc; 14723 mBackupTarget = r; 14724 mBackupAppName = app.packageName; 14725 14726 // Try not to kill the process during backup 14727 updateOomAdjLocked(proc); 14728 14729 // If the process is already attached, schedule the creation of the backup agent now. 14730 // If it is not yet live, this will be done when it attaches to the framework. 14731 if (proc.thread != null) { 14732 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14733 try { 14734 proc.thread.scheduleCreateBackupAgent(app, 14735 compatibilityInfoForPackageLocked(app), backupMode); 14736 } catch (RemoteException e) { 14737 // Will time out on the backup manager side 14738 } 14739 } else { 14740 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14741 } 14742 // Invariants: at this point, the target app process exists and the application 14743 // is either already running or in the process of coming up. mBackupTarget and 14744 // mBackupAppName describe the app, so that when it binds back to the AM we 14745 // know that it's scheduled for a backup-agent operation. 14746 } 14747 14748 return true; 14749 } 14750 14751 @Override 14752 public void clearPendingBackup() { 14753 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14754 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14755 14756 synchronized (this) { 14757 mBackupTarget = null; 14758 mBackupAppName = null; 14759 } 14760 } 14761 14762 // A backup agent has just come up 14763 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14764 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14765 + " = " + agent); 14766 14767 synchronized(this) { 14768 if (!agentPackageName.equals(mBackupAppName)) { 14769 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14770 return; 14771 } 14772 } 14773 14774 long oldIdent = Binder.clearCallingIdentity(); 14775 try { 14776 IBackupManager bm = IBackupManager.Stub.asInterface( 14777 ServiceManager.getService(Context.BACKUP_SERVICE)); 14778 bm.agentConnected(agentPackageName, agent); 14779 } catch (RemoteException e) { 14780 // can't happen; the backup manager service is local 14781 } catch (Exception e) { 14782 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14783 e.printStackTrace(); 14784 } finally { 14785 Binder.restoreCallingIdentity(oldIdent); 14786 } 14787 } 14788 14789 // done with this agent 14790 public void unbindBackupAgent(ApplicationInfo appInfo) { 14791 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14792 if (appInfo == null) { 14793 Slog.w(TAG, "unbind backup agent for null app"); 14794 return; 14795 } 14796 14797 synchronized(this) { 14798 try { 14799 if (mBackupAppName == null) { 14800 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14801 return; 14802 } 14803 14804 if (!mBackupAppName.equals(appInfo.packageName)) { 14805 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14806 return; 14807 } 14808 14809 // Not backing this app up any more; reset its OOM adjustment 14810 final ProcessRecord proc = mBackupTarget.app; 14811 updateOomAdjLocked(proc); 14812 14813 // If the app crashed during backup, 'thread' will be null here 14814 if (proc.thread != null) { 14815 try { 14816 proc.thread.scheduleDestroyBackupAgent(appInfo, 14817 compatibilityInfoForPackageLocked(appInfo)); 14818 } catch (Exception e) { 14819 Slog.e(TAG, "Exception when unbinding backup agent:"); 14820 e.printStackTrace(); 14821 } 14822 } 14823 } finally { 14824 mBackupTarget = null; 14825 mBackupAppName = null; 14826 } 14827 } 14828 } 14829 // ========================================================= 14830 // BROADCASTS 14831 // ========================================================= 14832 14833 private final List getStickiesLocked(String action, IntentFilter filter, 14834 List cur, int userId) { 14835 final ContentResolver resolver = mContext.getContentResolver(); 14836 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14837 if (stickies == null) { 14838 return cur; 14839 } 14840 final ArrayList<Intent> list = stickies.get(action); 14841 if (list == null) { 14842 return cur; 14843 } 14844 int N = list.size(); 14845 for (int i=0; i<N; i++) { 14846 Intent intent = list.get(i); 14847 if (filter.match(resolver, intent, true, TAG) >= 0) { 14848 if (cur == null) { 14849 cur = new ArrayList<Intent>(); 14850 } 14851 cur.add(intent); 14852 } 14853 } 14854 return cur; 14855 } 14856 14857 boolean isPendingBroadcastProcessLocked(int pid) { 14858 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14859 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14860 } 14861 14862 void skipPendingBroadcastLocked(int pid) { 14863 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14864 for (BroadcastQueue queue : mBroadcastQueues) { 14865 queue.skipPendingBroadcastLocked(pid); 14866 } 14867 } 14868 14869 // The app just attached; send any pending broadcasts that it should receive 14870 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14871 boolean didSomething = false; 14872 for (BroadcastQueue queue : mBroadcastQueues) { 14873 didSomething |= queue.sendPendingBroadcastsLocked(app); 14874 } 14875 return didSomething; 14876 } 14877 14878 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14879 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14880 enforceNotIsolatedCaller("registerReceiver"); 14881 int callingUid; 14882 int callingPid; 14883 synchronized(this) { 14884 ProcessRecord callerApp = null; 14885 if (caller != null) { 14886 callerApp = getRecordForAppLocked(caller); 14887 if (callerApp == null) { 14888 throw new SecurityException( 14889 "Unable to find app for caller " + caller 14890 + " (pid=" + Binder.getCallingPid() 14891 + ") when registering receiver " + receiver); 14892 } 14893 if (callerApp.info.uid != Process.SYSTEM_UID && 14894 !callerApp.pkgList.containsKey(callerPackage) && 14895 !"android".equals(callerPackage)) { 14896 throw new SecurityException("Given caller package " + callerPackage 14897 + " is not running in process " + callerApp); 14898 } 14899 callingUid = callerApp.info.uid; 14900 callingPid = callerApp.pid; 14901 } else { 14902 callerPackage = null; 14903 callingUid = Binder.getCallingUid(); 14904 callingPid = Binder.getCallingPid(); 14905 } 14906 14907 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14908 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14909 14910 List allSticky = null; 14911 14912 // Look for any matching sticky broadcasts... 14913 Iterator actions = filter.actionsIterator(); 14914 if (actions != null) { 14915 while (actions.hasNext()) { 14916 String action = (String)actions.next(); 14917 allSticky = getStickiesLocked(action, filter, allSticky, 14918 UserHandle.USER_ALL); 14919 allSticky = getStickiesLocked(action, filter, allSticky, 14920 UserHandle.getUserId(callingUid)); 14921 } 14922 } else { 14923 allSticky = getStickiesLocked(null, filter, allSticky, 14924 UserHandle.USER_ALL); 14925 allSticky = getStickiesLocked(null, filter, allSticky, 14926 UserHandle.getUserId(callingUid)); 14927 } 14928 14929 // The first sticky in the list is returned directly back to 14930 // the client. 14931 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14932 14933 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14934 + ": " + sticky); 14935 14936 if (receiver == null) { 14937 return sticky; 14938 } 14939 14940 ReceiverList rl 14941 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14942 if (rl == null) { 14943 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14944 userId, receiver); 14945 if (rl.app != null) { 14946 rl.app.receivers.add(rl); 14947 } else { 14948 try { 14949 receiver.asBinder().linkToDeath(rl, 0); 14950 } catch (RemoteException e) { 14951 return sticky; 14952 } 14953 rl.linkedToDeath = true; 14954 } 14955 mRegisteredReceivers.put(receiver.asBinder(), rl); 14956 } else if (rl.uid != callingUid) { 14957 throw new IllegalArgumentException( 14958 "Receiver requested to register for uid " + callingUid 14959 + " was previously registered for uid " + rl.uid); 14960 } else if (rl.pid != callingPid) { 14961 throw new IllegalArgumentException( 14962 "Receiver requested to register for pid " + callingPid 14963 + " was previously registered for pid " + rl.pid); 14964 } else if (rl.userId != userId) { 14965 throw new IllegalArgumentException( 14966 "Receiver requested to register for user " + userId 14967 + " was previously registered for user " + rl.userId); 14968 } 14969 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14970 permission, callingUid, userId); 14971 rl.add(bf); 14972 if (!bf.debugCheck()) { 14973 Slog.w(TAG, "==> For Dynamic broadast"); 14974 } 14975 mReceiverResolver.addFilter(bf); 14976 14977 // Enqueue broadcasts for all existing stickies that match 14978 // this filter. 14979 if (allSticky != null) { 14980 ArrayList receivers = new ArrayList(); 14981 receivers.add(bf); 14982 14983 int N = allSticky.size(); 14984 for (int i=0; i<N; i++) { 14985 Intent intent = (Intent)allSticky.get(i); 14986 BroadcastQueue queue = broadcastQueueForIntent(intent); 14987 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14988 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14989 null, null, false, true, true, -1); 14990 queue.enqueueParallelBroadcastLocked(r); 14991 queue.scheduleBroadcastsLocked(); 14992 } 14993 } 14994 14995 return sticky; 14996 } 14997 } 14998 14999 public void unregisterReceiver(IIntentReceiver receiver) { 15000 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15001 15002 final long origId = Binder.clearCallingIdentity(); 15003 try { 15004 boolean doTrim = false; 15005 15006 synchronized(this) { 15007 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15008 if (rl != null) { 15009 if (rl.curBroadcast != null) { 15010 BroadcastRecord r = rl.curBroadcast; 15011 final boolean doNext = finishReceiverLocked( 15012 receiver.asBinder(), r.resultCode, r.resultData, 15013 r.resultExtras, r.resultAbort); 15014 if (doNext) { 15015 doTrim = true; 15016 r.queue.processNextBroadcast(false); 15017 } 15018 } 15019 15020 if (rl.app != null) { 15021 rl.app.receivers.remove(rl); 15022 } 15023 removeReceiverLocked(rl); 15024 if (rl.linkedToDeath) { 15025 rl.linkedToDeath = false; 15026 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15027 } 15028 } 15029 } 15030 15031 // If we actually concluded any broadcasts, we might now be able 15032 // to trim the recipients' apps from our working set 15033 if (doTrim) { 15034 trimApplications(); 15035 return; 15036 } 15037 15038 } finally { 15039 Binder.restoreCallingIdentity(origId); 15040 } 15041 } 15042 15043 void removeReceiverLocked(ReceiverList rl) { 15044 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15045 int N = rl.size(); 15046 for (int i=0; i<N; i++) { 15047 mReceiverResolver.removeFilter(rl.get(i)); 15048 } 15049 } 15050 15051 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15053 ProcessRecord r = mLruProcesses.get(i); 15054 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15055 try { 15056 r.thread.dispatchPackageBroadcast(cmd, packages); 15057 } catch (RemoteException ex) { 15058 } 15059 } 15060 } 15061 } 15062 15063 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15064 int[] users) { 15065 List<ResolveInfo> receivers = null; 15066 try { 15067 HashSet<ComponentName> singleUserReceivers = null; 15068 boolean scannedFirstReceivers = false; 15069 for (int user : users) { 15070 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15071 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15072 if (user != 0 && newReceivers != null) { 15073 // If this is not the primary user, we need to check for 15074 // any receivers that should be filtered out. 15075 for (int i=0; i<newReceivers.size(); i++) { 15076 ResolveInfo ri = newReceivers.get(i); 15077 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15078 newReceivers.remove(i); 15079 i--; 15080 } 15081 } 15082 } 15083 if (newReceivers != null && newReceivers.size() == 0) { 15084 newReceivers = null; 15085 } 15086 if (receivers == null) { 15087 receivers = newReceivers; 15088 } else if (newReceivers != null) { 15089 // We need to concatenate the additional receivers 15090 // found with what we have do far. This would be easy, 15091 // but we also need to de-dup any receivers that are 15092 // singleUser. 15093 if (!scannedFirstReceivers) { 15094 // Collect any single user receivers we had already retrieved. 15095 scannedFirstReceivers = true; 15096 for (int i=0; i<receivers.size(); i++) { 15097 ResolveInfo ri = receivers.get(i); 15098 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15099 ComponentName cn = new ComponentName( 15100 ri.activityInfo.packageName, ri.activityInfo.name); 15101 if (singleUserReceivers == null) { 15102 singleUserReceivers = new HashSet<ComponentName>(); 15103 } 15104 singleUserReceivers.add(cn); 15105 } 15106 } 15107 } 15108 // Add the new results to the existing results, tracking 15109 // and de-dupping single user receivers. 15110 for (int i=0; i<newReceivers.size(); i++) { 15111 ResolveInfo ri = newReceivers.get(i); 15112 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15113 ComponentName cn = new ComponentName( 15114 ri.activityInfo.packageName, ri.activityInfo.name); 15115 if (singleUserReceivers == null) { 15116 singleUserReceivers = new HashSet<ComponentName>(); 15117 } 15118 if (!singleUserReceivers.contains(cn)) { 15119 singleUserReceivers.add(cn); 15120 receivers.add(ri); 15121 } 15122 } else { 15123 receivers.add(ri); 15124 } 15125 } 15126 } 15127 } 15128 } catch (RemoteException ex) { 15129 // pm is in same process, this will never happen. 15130 } 15131 return receivers; 15132 } 15133 15134 private final int broadcastIntentLocked(ProcessRecord callerApp, 15135 String callerPackage, Intent intent, String resolvedType, 15136 IIntentReceiver resultTo, int resultCode, String resultData, 15137 Bundle map, String requiredPermission, int appOp, 15138 boolean ordered, boolean sticky, int callingPid, int callingUid, 15139 int userId) { 15140 intent = new Intent(intent); 15141 15142 // By default broadcasts do not go to stopped apps. 15143 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15144 15145 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15146 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15147 + " ordered=" + ordered + " userid=" + userId); 15148 if ((resultTo != null) && !ordered) { 15149 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15150 } 15151 15152 userId = handleIncomingUser(callingPid, callingUid, userId, 15153 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15154 15155 // Make sure that the user who is receiving this broadcast is started. 15156 // If not, we will just skip it. 15157 15158 15159 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15160 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15161 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15162 Slog.w(TAG, "Skipping broadcast of " + intent 15163 + ": user " + userId + " is stopped"); 15164 return ActivityManager.BROADCAST_SUCCESS; 15165 } 15166 } 15167 15168 /* 15169 * Prevent non-system code (defined here to be non-persistent 15170 * processes) from sending protected broadcasts. 15171 */ 15172 int callingAppId = UserHandle.getAppId(callingUid); 15173 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15174 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15175 || callingAppId == Process.NFC_UID || callingUid == 0) { 15176 // Always okay. 15177 } else if (callerApp == null || !callerApp.persistent) { 15178 try { 15179 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15180 intent.getAction())) { 15181 String msg = "Permission Denial: not allowed to send broadcast " 15182 + intent.getAction() + " from pid=" 15183 + callingPid + ", uid=" + callingUid; 15184 Slog.w(TAG, msg); 15185 throw new SecurityException(msg); 15186 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15187 // Special case for compatibility: we don't want apps to send this, 15188 // but historically it has not been protected and apps may be using it 15189 // to poke their own app widget. So, instead of making it protected, 15190 // just limit it to the caller. 15191 if (callerApp == null) { 15192 String msg = "Permission Denial: not allowed to send broadcast " 15193 + intent.getAction() + " from unknown caller."; 15194 Slog.w(TAG, msg); 15195 throw new SecurityException(msg); 15196 } else if (intent.getComponent() != null) { 15197 // They are good enough to send to an explicit component... verify 15198 // it is being sent to the calling app. 15199 if (!intent.getComponent().getPackageName().equals( 15200 callerApp.info.packageName)) { 15201 String msg = "Permission Denial: not allowed to send broadcast " 15202 + intent.getAction() + " to " 15203 + intent.getComponent().getPackageName() + " from " 15204 + callerApp.info.packageName; 15205 Slog.w(TAG, msg); 15206 throw new SecurityException(msg); 15207 } 15208 } else { 15209 // Limit broadcast to their own package. 15210 intent.setPackage(callerApp.info.packageName); 15211 } 15212 } 15213 } catch (RemoteException e) { 15214 Slog.w(TAG, "Remote exception", e); 15215 return ActivityManager.BROADCAST_SUCCESS; 15216 } 15217 } 15218 15219 // Handle special intents: if this broadcast is from the package 15220 // manager about a package being removed, we need to remove all of 15221 // its activities from the history stack. 15222 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15223 intent.getAction()); 15224 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15225 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15226 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15227 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15228 || uidRemoved) { 15229 if (checkComponentPermission( 15230 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15231 callingPid, callingUid, -1, true) 15232 == PackageManager.PERMISSION_GRANTED) { 15233 if (uidRemoved) { 15234 final Bundle intentExtras = intent.getExtras(); 15235 final int uid = intentExtras != null 15236 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15237 if (uid >= 0) { 15238 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15239 synchronized (bs) { 15240 bs.removeUidStatsLocked(uid); 15241 } 15242 mAppOpsService.uidRemoved(uid); 15243 } 15244 } else { 15245 // If resources are unavailable just force stop all 15246 // those packages and flush the attribute cache as well. 15247 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15248 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15249 if (list != null && (list.length > 0)) { 15250 for (String pkg : list) { 15251 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15252 "storage unmount"); 15253 } 15254 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15255 sendPackageBroadcastLocked( 15256 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15257 } 15258 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15259 intent.getAction())) { 15260 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15261 } else { 15262 Uri data = intent.getData(); 15263 String ssp; 15264 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15265 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15266 intent.getAction()); 15267 boolean fullUninstall = removed && 15268 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15269 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15270 forceStopPackageLocked(ssp, UserHandle.getAppId( 15271 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15272 false, fullUninstall, userId, 15273 removed ? "pkg removed" : "pkg changed"); 15274 } 15275 if (removed) { 15276 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15277 new String[] {ssp}, userId); 15278 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15279 mAppOpsService.packageRemoved( 15280 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15281 15282 // Remove all permissions granted from/to this package 15283 removeUriPermissionsForPackageLocked(ssp, userId, true); 15284 } 15285 } 15286 } 15287 } 15288 } 15289 } else { 15290 String msg = "Permission Denial: " + intent.getAction() 15291 + " broadcast from " + callerPackage + " (pid=" + callingPid 15292 + ", uid=" + callingUid + ")" 15293 + " requires " 15294 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15295 Slog.w(TAG, msg); 15296 throw new SecurityException(msg); 15297 } 15298 15299 // Special case for adding a package: by default turn on compatibility 15300 // mode. 15301 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15302 Uri data = intent.getData(); 15303 String ssp; 15304 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15305 mCompatModePackages.handlePackageAddedLocked(ssp, 15306 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15307 } 15308 } 15309 15310 /* 15311 * If this is the time zone changed action, queue up a message that will reset the timezone 15312 * of all currently running processes. This message will get queued up before the broadcast 15313 * happens. 15314 */ 15315 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15316 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15317 } 15318 15319 /* 15320 * If the user set the time, let all running processes know. 15321 */ 15322 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15323 final int is24Hour = intent.getBooleanExtra( 15324 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15325 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15326 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15327 synchronized (stats) { 15328 stats.noteCurrentTimeChangedLocked(); 15329 } 15330 } 15331 15332 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15333 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15334 } 15335 15336 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15337 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15338 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15339 } 15340 15341 // Add to the sticky list if requested. 15342 if (sticky) { 15343 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15344 callingPid, callingUid) 15345 != PackageManager.PERMISSION_GRANTED) { 15346 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15347 + callingPid + ", uid=" + callingUid 15348 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15349 Slog.w(TAG, msg); 15350 throw new SecurityException(msg); 15351 } 15352 if (requiredPermission != null) { 15353 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15354 + " and enforce permission " + requiredPermission); 15355 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15356 } 15357 if (intent.getComponent() != null) { 15358 throw new SecurityException( 15359 "Sticky broadcasts can't target a specific component"); 15360 } 15361 // We use userId directly here, since the "all" target is maintained 15362 // as a separate set of sticky broadcasts. 15363 if (userId != UserHandle.USER_ALL) { 15364 // But first, if this is not a broadcast to all users, then 15365 // make sure it doesn't conflict with an existing broadcast to 15366 // all users. 15367 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15368 UserHandle.USER_ALL); 15369 if (stickies != null) { 15370 ArrayList<Intent> list = stickies.get(intent.getAction()); 15371 if (list != null) { 15372 int N = list.size(); 15373 int i; 15374 for (i=0; i<N; i++) { 15375 if (intent.filterEquals(list.get(i))) { 15376 throw new IllegalArgumentException( 15377 "Sticky broadcast " + intent + " for user " 15378 + userId + " conflicts with existing global broadcast"); 15379 } 15380 } 15381 } 15382 } 15383 } 15384 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15385 if (stickies == null) { 15386 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15387 mStickyBroadcasts.put(userId, stickies); 15388 } 15389 ArrayList<Intent> list = stickies.get(intent.getAction()); 15390 if (list == null) { 15391 list = new ArrayList<Intent>(); 15392 stickies.put(intent.getAction(), list); 15393 } 15394 int N = list.size(); 15395 int i; 15396 for (i=0; i<N; i++) { 15397 if (intent.filterEquals(list.get(i))) { 15398 // This sticky already exists, replace it. 15399 list.set(i, new Intent(intent)); 15400 break; 15401 } 15402 } 15403 if (i >= N) { 15404 list.add(new Intent(intent)); 15405 } 15406 } 15407 15408 int[] users; 15409 if (userId == UserHandle.USER_ALL) { 15410 // Caller wants broadcast to go to all started users. 15411 users = mStartedUserArray; 15412 } else { 15413 // Caller wants broadcast to go to one specific user. 15414 users = new int[] {userId}; 15415 } 15416 15417 // Figure out who all will receive this broadcast. 15418 List receivers = null; 15419 List<BroadcastFilter> registeredReceivers = null; 15420 // Need to resolve the intent to interested receivers... 15421 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15422 == 0) { 15423 receivers = collectReceiverComponents(intent, resolvedType, users); 15424 } 15425 if (intent.getComponent() == null) { 15426 registeredReceivers = mReceiverResolver.queryIntent(intent, 15427 resolvedType, false, userId); 15428 } 15429 15430 final boolean replacePending = 15431 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15432 15433 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15434 + " replacePending=" + replacePending); 15435 15436 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15437 if (!ordered && NR > 0) { 15438 // If we are not serializing this broadcast, then send the 15439 // registered receivers separately so they don't wait for the 15440 // components to be launched. 15441 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15442 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15443 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15444 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15445 ordered, sticky, false, userId); 15446 if (DEBUG_BROADCAST) Slog.v( 15447 TAG, "Enqueueing parallel broadcast " + r); 15448 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15449 if (!replaced) { 15450 queue.enqueueParallelBroadcastLocked(r); 15451 queue.scheduleBroadcastsLocked(); 15452 } 15453 registeredReceivers = null; 15454 NR = 0; 15455 } 15456 15457 // Merge into one list. 15458 int ir = 0; 15459 if (receivers != null) { 15460 // A special case for PACKAGE_ADDED: do not allow the package 15461 // being added to see this broadcast. This prevents them from 15462 // using this as a back door to get run as soon as they are 15463 // installed. Maybe in the future we want to have a special install 15464 // broadcast or such for apps, but we'd like to deliberately make 15465 // this decision. 15466 String skipPackages[] = null; 15467 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15468 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15469 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15470 Uri data = intent.getData(); 15471 if (data != null) { 15472 String pkgName = data.getSchemeSpecificPart(); 15473 if (pkgName != null) { 15474 skipPackages = new String[] { pkgName }; 15475 } 15476 } 15477 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15478 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15479 } 15480 if (skipPackages != null && (skipPackages.length > 0)) { 15481 for (String skipPackage : skipPackages) { 15482 if (skipPackage != null) { 15483 int NT = receivers.size(); 15484 for (int it=0; it<NT; it++) { 15485 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15486 if (curt.activityInfo.packageName.equals(skipPackage)) { 15487 receivers.remove(it); 15488 it--; 15489 NT--; 15490 } 15491 } 15492 } 15493 } 15494 } 15495 15496 int NT = receivers != null ? receivers.size() : 0; 15497 int it = 0; 15498 ResolveInfo curt = null; 15499 BroadcastFilter curr = null; 15500 while (it < NT && ir < NR) { 15501 if (curt == null) { 15502 curt = (ResolveInfo)receivers.get(it); 15503 } 15504 if (curr == null) { 15505 curr = registeredReceivers.get(ir); 15506 } 15507 if (curr.getPriority() >= curt.priority) { 15508 // Insert this broadcast record into the final list. 15509 receivers.add(it, curr); 15510 ir++; 15511 curr = null; 15512 it++; 15513 NT++; 15514 } else { 15515 // Skip to the next ResolveInfo in the final list. 15516 it++; 15517 curt = null; 15518 } 15519 } 15520 } 15521 while (ir < NR) { 15522 if (receivers == null) { 15523 receivers = new ArrayList(); 15524 } 15525 receivers.add(registeredReceivers.get(ir)); 15526 ir++; 15527 } 15528 15529 if ((receivers != null && receivers.size() > 0) 15530 || resultTo != null) { 15531 BroadcastQueue queue = broadcastQueueForIntent(intent); 15532 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15533 callerPackage, callingPid, callingUid, resolvedType, 15534 requiredPermission, appOp, receivers, resultTo, resultCode, 15535 resultData, map, ordered, sticky, false, userId); 15536 if (DEBUG_BROADCAST) Slog.v( 15537 TAG, "Enqueueing ordered broadcast " + r 15538 + ": prev had " + queue.mOrderedBroadcasts.size()); 15539 if (DEBUG_BROADCAST) { 15540 int seq = r.intent.getIntExtra("seq", -1); 15541 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15542 } 15543 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15544 if (!replaced) { 15545 queue.enqueueOrderedBroadcastLocked(r); 15546 queue.scheduleBroadcastsLocked(); 15547 } 15548 } 15549 15550 return ActivityManager.BROADCAST_SUCCESS; 15551 } 15552 15553 final Intent verifyBroadcastLocked(Intent intent) { 15554 // Refuse possible leaked file descriptors 15555 if (intent != null && intent.hasFileDescriptors() == true) { 15556 throw new IllegalArgumentException("File descriptors passed in Intent"); 15557 } 15558 15559 int flags = intent.getFlags(); 15560 15561 if (!mProcessesReady) { 15562 // if the caller really truly claims to know what they're doing, go 15563 // ahead and allow the broadcast without launching any receivers 15564 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15565 intent = new Intent(intent); 15566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15567 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15568 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15569 + " before boot completion"); 15570 throw new IllegalStateException("Cannot broadcast before boot completed"); 15571 } 15572 } 15573 15574 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15575 throw new IllegalArgumentException( 15576 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15577 } 15578 15579 return intent; 15580 } 15581 15582 public final int broadcastIntent(IApplicationThread caller, 15583 Intent intent, String resolvedType, IIntentReceiver resultTo, 15584 int resultCode, String resultData, Bundle map, 15585 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15586 enforceNotIsolatedCaller("broadcastIntent"); 15587 synchronized(this) { 15588 intent = verifyBroadcastLocked(intent); 15589 15590 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15591 final int callingPid = Binder.getCallingPid(); 15592 final int callingUid = Binder.getCallingUid(); 15593 final long origId = Binder.clearCallingIdentity(); 15594 int res = broadcastIntentLocked(callerApp, 15595 callerApp != null ? callerApp.info.packageName : null, 15596 intent, resolvedType, resultTo, 15597 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15598 callingPid, callingUid, userId); 15599 Binder.restoreCallingIdentity(origId); 15600 return res; 15601 } 15602 } 15603 15604 int broadcastIntentInPackage(String packageName, int uid, 15605 Intent intent, String resolvedType, IIntentReceiver resultTo, 15606 int resultCode, String resultData, Bundle map, 15607 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15608 synchronized(this) { 15609 intent = verifyBroadcastLocked(intent); 15610 15611 final long origId = Binder.clearCallingIdentity(); 15612 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15613 resultTo, resultCode, resultData, map, requiredPermission, 15614 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15615 Binder.restoreCallingIdentity(origId); 15616 return res; 15617 } 15618 } 15619 15620 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15621 // Refuse possible leaked file descriptors 15622 if (intent != null && intent.hasFileDescriptors() == true) { 15623 throw new IllegalArgumentException("File descriptors passed in Intent"); 15624 } 15625 15626 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15627 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15628 15629 synchronized(this) { 15630 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15631 != PackageManager.PERMISSION_GRANTED) { 15632 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15633 + Binder.getCallingPid() 15634 + ", uid=" + Binder.getCallingUid() 15635 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15636 Slog.w(TAG, msg); 15637 throw new SecurityException(msg); 15638 } 15639 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15640 if (stickies != null) { 15641 ArrayList<Intent> list = stickies.get(intent.getAction()); 15642 if (list != null) { 15643 int N = list.size(); 15644 int i; 15645 for (i=0; i<N; i++) { 15646 if (intent.filterEquals(list.get(i))) { 15647 list.remove(i); 15648 break; 15649 } 15650 } 15651 if (list.size() <= 0) { 15652 stickies.remove(intent.getAction()); 15653 } 15654 } 15655 if (stickies.size() <= 0) { 15656 mStickyBroadcasts.remove(userId); 15657 } 15658 } 15659 } 15660 } 15661 15662 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15663 String resultData, Bundle resultExtras, boolean resultAbort) { 15664 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15665 if (r == null) { 15666 Slog.w(TAG, "finishReceiver called but not found on queue"); 15667 return false; 15668 } 15669 15670 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15671 } 15672 15673 void backgroundServicesFinishedLocked(int userId) { 15674 for (BroadcastQueue queue : mBroadcastQueues) { 15675 queue.backgroundServicesFinishedLocked(userId); 15676 } 15677 } 15678 15679 public void finishReceiver(IBinder who, int resultCode, String resultData, 15680 Bundle resultExtras, boolean resultAbort) { 15681 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15682 15683 // Refuse possible leaked file descriptors 15684 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15685 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15686 } 15687 15688 final long origId = Binder.clearCallingIdentity(); 15689 try { 15690 boolean doNext = false; 15691 BroadcastRecord r; 15692 15693 synchronized(this) { 15694 r = broadcastRecordForReceiverLocked(who); 15695 if (r != null) { 15696 doNext = r.queue.finishReceiverLocked(r, resultCode, 15697 resultData, resultExtras, resultAbort, true); 15698 } 15699 } 15700 15701 if (doNext) { 15702 r.queue.processNextBroadcast(false); 15703 } 15704 trimApplications(); 15705 } finally { 15706 Binder.restoreCallingIdentity(origId); 15707 } 15708 } 15709 15710 // ========================================================= 15711 // INSTRUMENTATION 15712 // ========================================================= 15713 15714 public boolean startInstrumentation(ComponentName className, 15715 String profileFile, int flags, Bundle arguments, 15716 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15717 int userId, String abiOverride) { 15718 enforceNotIsolatedCaller("startInstrumentation"); 15719 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15720 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15721 // Refuse possible leaked file descriptors 15722 if (arguments != null && arguments.hasFileDescriptors()) { 15723 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15724 } 15725 15726 synchronized(this) { 15727 InstrumentationInfo ii = null; 15728 ApplicationInfo ai = null; 15729 try { 15730 ii = mContext.getPackageManager().getInstrumentationInfo( 15731 className, STOCK_PM_FLAGS); 15732 ai = AppGlobals.getPackageManager().getApplicationInfo( 15733 ii.targetPackage, STOCK_PM_FLAGS, userId); 15734 } catch (PackageManager.NameNotFoundException e) { 15735 } catch (RemoteException e) { 15736 } 15737 if (ii == null) { 15738 reportStartInstrumentationFailure(watcher, className, 15739 "Unable to find instrumentation info for: " + className); 15740 return false; 15741 } 15742 if (ai == null) { 15743 reportStartInstrumentationFailure(watcher, className, 15744 "Unable to find instrumentation target package: " + ii.targetPackage); 15745 return false; 15746 } 15747 15748 int match = mContext.getPackageManager().checkSignatures( 15749 ii.targetPackage, ii.packageName); 15750 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15751 String msg = "Permission Denial: starting instrumentation " 15752 + className + " from pid=" 15753 + Binder.getCallingPid() 15754 + ", uid=" + Binder.getCallingPid() 15755 + " not allowed because package " + ii.packageName 15756 + " does not have a signature matching the target " 15757 + ii.targetPackage; 15758 reportStartInstrumentationFailure(watcher, className, msg); 15759 throw new SecurityException(msg); 15760 } 15761 15762 final long origId = Binder.clearCallingIdentity(); 15763 // Instrumentation can kill and relaunch even persistent processes 15764 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15765 "start instr"); 15766 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15767 app.instrumentationClass = className; 15768 app.instrumentationInfo = ai; 15769 app.instrumentationProfileFile = profileFile; 15770 app.instrumentationArguments = arguments; 15771 app.instrumentationWatcher = watcher; 15772 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15773 app.instrumentationResultClass = className; 15774 Binder.restoreCallingIdentity(origId); 15775 } 15776 15777 return true; 15778 } 15779 15780 /** 15781 * Report errors that occur while attempting to start Instrumentation. Always writes the 15782 * error to the logs, but if somebody is watching, send the report there too. This enables 15783 * the "am" command to report errors with more information. 15784 * 15785 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15786 * @param cn The component name of the instrumentation. 15787 * @param report The error report. 15788 */ 15789 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15790 ComponentName cn, String report) { 15791 Slog.w(TAG, report); 15792 try { 15793 if (watcher != null) { 15794 Bundle results = new Bundle(); 15795 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15796 results.putString("Error", report); 15797 watcher.instrumentationStatus(cn, -1, results); 15798 } 15799 } catch (RemoteException e) { 15800 Slog.w(TAG, e); 15801 } 15802 } 15803 15804 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15805 if (app.instrumentationWatcher != null) { 15806 try { 15807 // NOTE: IInstrumentationWatcher *must* be oneway here 15808 app.instrumentationWatcher.instrumentationFinished( 15809 app.instrumentationClass, 15810 resultCode, 15811 results); 15812 } catch (RemoteException e) { 15813 } 15814 } 15815 if (app.instrumentationUiAutomationConnection != null) { 15816 try { 15817 app.instrumentationUiAutomationConnection.shutdown(); 15818 } catch (RemoteException re) { 15819 /* ignore */ 15820 } 15821 // Only a UiAutomation can set this flag and now that 15822 // it is finished we make sure it is reset to its default. 15823 mUserIsMonkey = false; 15824 } 15825 app.instrumentationWatcher = null; 15826 app.instrumentationUiAutomationConnection = null; 15827 app.instrumentationClass = null; 15828 app.instrumentationInfo = null; 15829 app.instrumentationProfileFile = null; 15830 app.instrumentationArguments = null; 15831 15832 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15833 "finished inst"); 15834 } 15835 15836 public void finishInstrumentation(IApplicationThread target, 15837 int resultCode, Bundle results) { 15838 int userId = UserHandle.getCallingUserId(); 15839 // Refuse possible leaked file descriptors 15840 if (results != null && results.hasFileDescriptors()) { 15841 throw new IllegalArgumentException("File descriptors passed in Intent"); 15842 } 15843 15844 synchronized(this) { 15845 ProcessRecord app = getRecordForAppLocked(target); 15846 if (app == null) { 15847 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15848 return; 15849 } 15850 final long origId = Binder.clearCallingIdentity(); 15851 finishInstrumentationLocked(app, resultCode, results); 15852 Binder.restoreCallingIdentity(origId); 15853 } 15854 } 15855 15856 // ========================================================= 15857 // CONFIGURATION 15858 // ========================================================= 15859 15860 public ConfigurationInfo getDeviceConfigurationInfo() { 15861 ConfigurationInfo config = new ConfigurationInfo(); 15862 synchronized (this) { 15863 config.reqTouchScreen = mConfiguration.touchscreen; 15864 config.reqKeyboardType = mConfiguration.keyboard; 15865 config.reqNavigation = mConfiguration.navigation; 15866 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15867 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15868 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15869 } 15870 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15871 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15872 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15873 } 15874 config.reqGlEsVersion = GL_ES_VERSION; 15875 } 15876 return config; 15877 } 15878 15879 ActivityStack getFocusedStack() { 15880 return mStackSupervisor.getFocusedStack(); 15881 } 15882 15883 public Configuration getConfiguration() { 15884 Configuration ci; 15885 synchronized(this) { 15886 ci = new Configuration(mConfiguration); 15887 } 15888 return ci; 15889 } 15890 15891 public void updatePersistentConfiguration(Configuration values) { 15892 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15893 "updateConfiguration()"); 15894 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15895 "updateConfiguration()"); 15896 if (values == null) { 15897 throw new NullPointerException("Configuration must not be null"); 15898 } 15899 15900 synchronized(this) { 15901 final long origId = Binder.clearCallingIdentity(); 15902 updateConfigurationLocked(values, null, true, false); 15903 Binder.restoreCallingIdentity(origId); 15904 } 15905 } 15906 15907 public void updateConfiguration(Configuration values) { 15908 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15909 "updateConfiguration()"); 15910 15911 synchronized(this) { 15912 if (values == null && mWindowManager != null) { 15913 // sentinel: fetch the current configuration from the window manager 15914 values = mWindowManager.computeNewConfiguration(); 15915 } 15916 15917 if (mWindowManager != null) { 15918 mProcessList.applyDisplaySize(mWindowManager); 15919 } 15920 15921 final long origId = Binder.clearCallingIdentity(); 15922 if (values != null) { 15923 Settings.System.clearConfiguration(values); 15924 } 15925 updateConfigurationLocked(values, null, false, false); 15926 Binder.restoreCallingIdentity(origId); 15927 } 15928 } 15929 15930 /** 15931 * Do either or both things: (1) change the current configuration, and (2) 15932 * make sure the given activity is running with the (now) current 15933 * configuration. Returns true if the activity has been left running, or 15934 * false if <var>starting</var> is being destroyed to match the new 15935 * configuration. 15936 * @param persistent TODO 15937 */ 15938 boolean updateConfigurationLocked(Configuration values, 15939 ActivityRecord starting, boolean persistent, boolean initLocale) { 15940 int changes = 0; 15941 15942 if (values != null) { 15943 Configuration newConfig = new Configuration(mConfiguration); 15944 changes = newConfig.updateFrom(values); 15945 if (changes != 0) { 15946 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15947 Slog.i(TAG, "Updating configuration to: " + values); 15948 } 15949 15950 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15951 15952 if (values.locale != null && !initLocale) { 15953 saveLocaleLocked(values.locale, 15954 !values.locale.equals(mConfiguration.locale), 15955 values.userSetLocale); 15956 } 15957 15958 mConfigurationSeq++; 15959 if (mConfigurationSeq <= 0) { 15960 mConfigurationSeq = 1; 15961 } 15962 newConfig.seq = mConfigurationSeq; 15963 mConfiguration = newConfig; 15964 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15965 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15966 //mUsageStatsService.noteStartConfig(newConfig); 15967 15968 final Configuration configCopy = new Configuration(mConfiguration); 15969 15970 // TODO: If our config changes, should we auto dismiss any currently 15971 // showing dialogs? 15972 mShowDialogs = shouldShowDialogs(newConfig); 15973 15974 AttributeCache ac = AttributeCache.instance(); 15975 if (ac != null) { 15976 ac.updateConfiguration(configCopy); 15977 } 15978 15979 // Make sure all resources in our process are updated 15980 // right now, so that anyone who is going to retrieve 15981 // resource values after we return will be sure to get 15982 // the new ones. This is especially important during 15983 // boot, where the first config change needs to guarantee 15984 // all resources have that config before following boot 15985 // code is executed. 15986 mSystemThread.applyConfigurationToResources(configCopy); 15987 15988 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15989 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15990 msg.obj = new Configuration(configCopy); 15991 mHandler.sendMessage(msg); 15992 } 15993 15994 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15995 ProcessRecord app = mLruProcesses.get(i); 15996 try { 15997 if (app.thread != null) { 15998 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15999 + app.processName + " new config " + mConfiguration); 16000 app.thread.scheduleConfigurationChanged(configCopy); 16001 } 16002 } catch (Exception e) { 16003 } 16004 } 16005 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16006 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16007 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16008 | Intent.FLAG_RECEIVER_FOREGROUND); 16009 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16010 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16011 Process.SYSTEM_UID, UserHandle.USER_ALL); 16012 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16013 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16014 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16015 broadcastIntentLocked(null, null, intent, 16016 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16017 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16018 } 16019 } 16020 } 16021 16022 boolean kept = true; 16023 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16024 // mainStack is null during startup. 16025 if (mainStack != null) { 16026 if (changes != 0 && starting == null) { 16027 // If the configuration changed, and the caller is not already 16028 // in the process of starting an activity, then find the top 16029 // activity to check if its configuration needs to change. 16030 starting = mainStack.topRunningActivityLocked(null); 16031 } 16032 16033 if (starting != null) { 16034 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16035 // And we need to make sure at this point that all other activities 16036 // are made visible with the correct configuration. 16037 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16038 } 16039 } 16040 16041 if (values != null && mWindowManager != null) { 16042 mWindowManager.setNewConfiguration(mConfiguration); 16043 } 16044 16045 return kept; 16046 } 16047 16048 /** 16049 * Decide based on the configuration whether we should shouw the ANR, 16050 * crash, etc dialogs. The idea is that if there is no affordnace to 16051 * press the on-screen buttons, we shouldn't show the dialog. 16052 * 16053 * A thought: SystemUI might also want to get told about this, the Power 16054 * dialog / global actions also might want different behaviors. 16055 */ 16056 private static final boolean shouldShowDialogs(Configuration config) { 16057 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16058 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16059 } 16060 16061 /** 16062 * Save the locale. You must be inside a synchronized (this) block. 16063 */ 16064 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16065 if(isDiff) { 16066 SystemProperties.set("user.language", l.getLanguage()); 16067 SystemProperties.set("user.region", l.getCountry()); 16068 } 16069 16070 if(isPersist) { 16071 SystemProperties.set("persist.sys.language", l.getLanguage()); 16072 SystemProperties.set("persist.sys.country", l.getCountry()); 16073 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16074 } 16075 } 16076 16077 @Override 16078 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16079 synchronized (this) { 16080 ActivityRecord srec = ActivityRecord.forToken(token); 16081 if (srec.task != null && srec.task.stack != null) { 16082 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16083 } 16084 } 16085 return false; 16086 } 16087 16088 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16089 Intent resultData) { 16090 16091 synchronized (this) { 16092 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16093 if (stack != null) { 16094 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16095 } 16096 return false; 16097 } 16098 } 16099 16100 public int getLaunchedFromUid(IBinder activityToken) { 16101 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16102 if (srec == null) { 16103 return -1; 16104 } 16105 return srec.launchedFromUid; 16106 } 16107 16108 public String getLaunchedFromPackage(IBinder activityToken) { 16109 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16110 if (srec == null) { 16111 return null; 16112 } 16113 return srec.launchedFromPackage; 16114 } 16115 16116 // ========================================================= 16117 // LIFETIME MANAGEMENT 16118 // ========================================================= 16119 16120 // Returns which broadcast queue the app is the current [or imminent] receiver 16121 // on, or 'null' if the app is not an active broadcast recipient. 16122 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16123 BroadcastRecord r = app.curReceiver; 16124 if (r != null) { 16125 return r.queue; 16126 } 16127 16128 // It's not the current receiver, but it might be starting up to become one 16129 synchronized (this) { 16130 for (BroadcastQueue queue : mBroadcastQueues) { 16131 r = queue.mPendingBroadcast; 16132 if (r != null && r.curApp == app) { 16133 // found it; report which queue it's in 16134 return queue; 16135 } 16136 } 16137 } 16138 16139 return null; 16140 } 16141 16142 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16143 boolean doingAll, long now) { 16144 if (mAdjSeq == app.adjSeq) { 16145 // This adjustment has already been computed. 16146 return app.curRawAdj; 16147 } 16148 16149 if (app.thread == null) { 16150 app.adjSeq = mAdjSeq; 16151 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16152 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16153 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16154 } 16155 16156 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16157 app.adjSource = null; 16158 app.adjTarget = null; 16159 app.empty = false; 16160 app.cached = false; 16161 16162 final int activitiesSize = app.activities.size(); 16163 16164 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16165 // The max adjustment doesn't allow this app to be anything 16166 // below foreground, so it is not worth doing work for it. 16167 app.adjType = "fixed"; 16168 app.adjSeq = mAdjSeq; 16169 app.curRawAdj = app.maxAdj; 16170 app.foregroundActivities = false; 16171 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16172 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16173 // System processes can do UI, and when they do we want to have 16174 // them trim their memory after the user leaves the UI. To 16175 // facilitate this, here we need to determine whether or not it 16176 // is currently showing UI. 16177 app.systemNoUi = true; 16178 if (app == TOP_APP) { 16179 app.systemNoUi = false; 16180 } else if (activitiesSize > 0) { 16181 for (int j = 0; j < activitiesSize; j++) { 16182 final ActivityRecord r = app.activities.get(j); 16183 if (r.visible) { 16184 app.systemNoUi = false; 16185 } 16186 } 16187 } 16188 if (!app.systemNoUi) { 16189 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16190 } 16191 return (app.curAdj=app.maxAdj); 16192 } 16193 16194 app.systemNoUi = false; 16195 16196 // Determine the importance of the process, starting with most 16197 // important to least, and assign an appropriate OOM adjustment. 16198 int adj; 16199 int schedGroup; 16200 int procState; 16201 boolean foregroundActivities = false; 16202 BroadcastQueue queue; 16203 if (app == TOP_APP) { 16204 // The last app on the list is the foreground app. 16205 adj = ProcessList.FOREGROUND_APP_ADJ; 16206 schedGroup = Process.THREAD_GROUP_DEFAULT; 16207 app.adjType = "top-activity"; 16208 foregroundActivities = true; 16209 procState = ActivityManager.PROCESS_STATE_TOP; 16210 } else if (app.instrumentationClass != null) { 16211 // Don't want to kill running instrumentation. 16212 adj = ProcessList.FOREGROUND_APP_ADJ; 16213 schedGroup = Process.THREAD_GROUP_DEFAULT; 16214 app.adjType = "instrumentation"; 16215 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16216 } else if ((queue = isReceivingBroadcast(app)) != null) { 16217 // An app that is currently receiving a broadcast also 16218 // counts as being in the foreground for OOM killer purposes. 16219 // It's placed in a sched group based on the nature of the 16220 // broadcast as reflected by which queue it's active in. 16221 adj = ProcessList.FOREGROUND_APP_ADJ; 16222 schedGroup = (queue == mFgBroadcastQueue) 16223 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16224 app.adjType = "broadcast"; 16225 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16226 } else if (app.executingServices.size() > 0) { 16227 // An app that is currently executing a service callback also 16228 // counts as being in the foreground. 16229 adj = ProcessList.FOREGROUND_APP_ADJ; 16230 schedGroup = app.execServicesFg ? 16231 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16232 app.adjType = "exec-service"; 16233 procState = ActivityManager.PROCESS_STATE_SERVICE; 16234 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16235 } else { 16236 // As far as we know the process is empty. We may change our mind later. 16237 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16238 // At this point we don't actually know the adjustment. Use the cached adj 16239 // value that the caller wants us to. 16240 adj = cachedAdj; 16241 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16242 app.cached = true; 16243 app.empty = true; 16244 app.adjType = "cch-empty"; 16245 } 16246 16247 // Examine all activities if not already foreground. 16248 if (!foregroundActivities && activitiesSize > 0) { 16249 for (int j = 0; j < activitiesSize; j++) { 16250 final ActivityRecord r = app.activities.get(j); 16251 if (r.app != app) { 16252 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16253 + app + "?!?"); 16254 continue; 16255 } 16256 if (r.visible) { 16257 // App has a visible activity; only upgrade adjustment. 16258 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16259 adj = ProcessList.VISIBLE_APP_ADJ; 16260 app.adjType = "visible"; 16261 } 16262 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16263 procState = ActivityManager.PROCESS_STATE_TOP; 16264 } 16265 schedGroup = Process.THREAD_GROUP_DEFAULT; 16266 app.cached = false; 16267 app.empty = false; 16268 foregroundActivities = true; 16269 break; 16270 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16271 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16272 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16273 app.adjType = "pausing"; 16274 } 16275 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16276 procState = ActivityManager.PROCESS_STATE_TOP; 16277 } 16278 schedGroup = Process.THREAD_GROUP_DEFAULT; 16279 app.cached = false; 16280 app.empty = false; 16281 foregroundActivities = true; 16282 } else if (r.state == ActivityState.STOPPING) { 16283 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16284 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16285 app.adjType = "stopping"; 16286 } 16287 // For the process state, we will at this point consider the 16288 // process to be cached. It will be cached either as an activity 16289 // or empty depending on whether the activity is finishing. We do 16290 // this so that we can treat the process as cached for purposes of 16291 // memory trimming (determing current memory level, trim command to 16292 // send to process) since there can be an arbitrary number of stopping 16293 // processes and they should soon all go into the cached state. 16294 if (!r.finishing) { 16295 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16296 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16297 } 16298 } 16299 app.cached = false; 16300 app.empty = false; 16301 foregroundActivities = true; 16302 } else { 16303 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16304 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16305 app.adjType = "cch-act"; 16306 } 16307 } 16308 } 16309 } 16310 16311 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16312 if (app.foregroundServices) { 16313 // The user is aware of this app, so make it visible. 16314 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16315 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16316 app.cached = false; 16317 app.adjType = "fg-service"; 16318 schedGroup = Process.THREAD_GROUP_DEFAULT; 16319 } else if (app.forcingToForeground != null) { 16320 // The user is aware of this app, so make it visible. 16321 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16322 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16323 app.cached = false; 16324 app.adjType = "force-fg"; 16325 app.adjSource = app.forcingToForeground; 16326 schedGroup = Process.THREAD_GROUP_DEFAULT; 16327 } 16328 } 16329 16330 if (app == mHeavyWeightProcess) { 16331 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16332 // We don't want to kill the current heavy-weight process. 16333 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16334 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16335 app.cached = false; 16336 app.adjType = "heavy"; 16337 } 16338 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16339 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16340 } 16341 } 16342 16343 if (app == mHomeProcess) { 16344 if (adj > ProcessList.HOME_APP_ADJ) { 16345 // This process is hosting what we currently consider to be the 16346 // home app, so we don't want to let it go into the background. 16347 adj = ProcessList.HOME_APP_ADJ; 16348 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16349 app.cached = false; 16350 app.adjType = "home"; 16351 } 16352 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16353 procState = ActivityManager.PROCESS_STATE_HOME; 16354 } 16355 } 16356 16357 if (app == mPreviousProcess && app.activities.size() > 0) { 16358 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16359 // This was the previous process that showed UI to the user. 16360 // We want to try to keep it around more aggressively, to give 16361 // a good experience around switching between two apps. 16362 adj = ProcessList.PREVIOUS_APP_ADJ; 16363 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16364 app.cached = false; 16365 app.adjType = "previous"; 16366 } 16367 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16368 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16369 } 16370 } 16371 16372 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16373 + " reason=" + app.adjType); 16374 16375 // By default, we use the computed adjustment. It may be changed if 16376 // there are applications dependent on our services or providers, but 16377 // this gives us a baseline and makes sure we don't get into an 16378 // infinite recursion. 16379 app.adjSeq = mAdjSeq; 16380 app.curRawAdj = adj; 16381 app.hasStartedServices = false; 16382 16383 if (mBackupTarget != null && app == mBackupTarget.app) { 16384 // If possible we want to avoid killing apps while they're being backed up 16385 if (adj > ProcessList.BACKUP_APP_ADJ) { 16386 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16387 adj = ProcessList.BACKUP_APP_ADJ; 16388 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16389 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16390 } 16391 app.adjType = "backup"; 16392 app.cached = false; 16393 } 16394 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16395 procState = ActivityManager.PROCESS_STATE_BACKUP; 16396 } 16397 } 16398 16399 boolean mayBeTop = false; 16400 16401 for (int is = app.services.size()-1; 16402 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16403 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16404 || procState > ActivityManager.PROCESS_STATE_TOP); 16405 is--) { 16406 ServiceRecord s = app.services.valueAt(is); 16407 if (s.startRequested) { 16408 app.hasStartedServices = true; 16409 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16410 procState = ActivityManager.PROCESS_STATE_SERVICE; 16411 } 16412 if (app.hasShownUi && app != mHomeProcess) { 16413 // If this process has shown some UI, let it immediately 16414 // go to the LRU list because it may be pretty heavy with 16415 // UI stuff. We'll tag it with a label just to help 16416 // debug and understand what is going on. 16417 if (adj > ProcessList.SERVICE_ADJ) { 16418 app.adjType = "cch-started-ui-services"; 16419 } 16420 } else { 16421 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16422 // This service has seen some activity within 16423 // recent memory, so we will keep its process ahead 16424 // of the background processes. 16425 if (adj > ProcessList.SERVICE_ADJ) { 16426 adj = ProcessList.SERVICE_ADJ; 16427 app.adjType = "started-services"; 16428 app.cached = false; 16429 } 16430 } 16431 // If we have let the service slide into the background 16432 // state, still have some text describing what it is doing 16433 // even though the service no longer has an impact. 16434 if (adj > ProcessList.SERVICE_ADJ) { 16435 app.adjType = "cch-started-services"; 16436 } 16437 } 16438 } 16439 for (int conni = s.connections.size()-1; 16440 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16441 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16442 || procState > ActivityManager.PROCESS_STATE_TOP); 16443 conni--) { 16444 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16445 for (int i = 0; 16446 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16447 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16448 || procState > ActivityManager.PROCESS_STATE_TOP); 16449 i++) { 16450 // XXX should compute this based on the max of 16451 // all connected clients. 16452 ConnectionRecord cr = clist.get(i); 16453 if (cr.binding.client == app) { 16454 // Binding to ourself is not interesting. 16455 continue; 16456 } 16457 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16458 ProcessRecord client = cr.binding.client; 16459 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16460 TOP_APP, doingAll, now); 16461 int clientProcState = client.curProcState; 16462 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16463 // If the other app is cached for any reason, for purposes here 16464 // we are going to consider it empty. The specific cached state 16465 // doesn't propagate except under certain conditions. 16466 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16467 } 16468 String adjType = null; 16469 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16470 // Not doing bind OOM management, so treat 16471 // this guy more like a started service. 16472 if (app.hasShownUi && app != mHomeProcess) { 16473 // If this process has shown some UI, let it immediately 16474 // go to the LRU list because it may be pretty heavy with 16475 // UI stuff. We'll tag it with a label just to help 16476 // debug and understand what is going on. 16477 if (adj > clientAdj) { 16478 adjType = "cch-bound-ui-services"; 16479 } 16480 app.cached = false; 16481 clientAdj = adj; 16482 clientProcState = procState; 16483 } else { 16484 if (now >= (s.lastActivity 16485 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16486 // This service has not seen activity within 16487 // recent memory, so allow it to drop to the 16488 // LRU list if there is no other reason to keep 16489 // it around. We'll also tag it with a label just 16490 // to help debug and undertand what is going on. 16491 if (adj > clientAdj) { 16492 adjType = "cch-bound-services"; 16493 } 16494 clientAdj = adj; 16495 } 16496 } 16497 } 16498 if (adj > clientAdj) { 16499 // If this process has recently shown UI, and 16500 // the process that is binding to it is less 16501 // important than being visible, then we don't 16502 // care about the binding as much as we care 16503 // about letting this process get into the LRU 16504 // list to be killed and restarted if needed for 16505 // memory. 16506 if (app.hasShownUi && app != mHomeProcess 16507 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16508 adjType = "cch-bound-ui-services"; 16509 } else { 16510 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16511 |Context.BIND_IMPORTANT)) != 0) { 16512 adj = clientAdj; 16513 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16514 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16515 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16516 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16517 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16518 adj = clientAdj; 16519 } else { 16520 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16521 adj = ProcessList.VISIBLE_APP_ADJ; 16522 } 16523 } 16524 if (!client.cached) { 16525 app.cached = false; 16526 } 16527 adjType = "service"; 16528 } 16529 } 16530 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16531 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16532 schedGroup = Process.THREAD_GROUP_DEFAULT; 16533 } 16534 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16535 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16536 // Special handling of clients who are in the top state. 16537 // We *may* want to consider this process to be in the 16538 // top state as well, but only if there is not another 16539 // reason for it to be running. Being on the top is a 16540 // special state, meaning you are specifically running 16541 // for the current top app. If the process is already 16542 // running in the background for some other reason, it 16543 // is more important to continue considering it to be 16544 // in the background state. 16545 mayBeTop = true; 16546 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16547 } else { 16548 // Special handling for above-top states (persistent 16549 // processes). These should not bring the current process 16550 // into the top state, since they are not on top. Instead 16551 // give them the best state after that. 16552 clientProcState = 16553 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16554 } 16555 } 16556 } else { 16557 if (clientProcState < 16558 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16559 clientProcState = 16560 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16561 } 16562 } 16563 if (procState > clientProcState) { 16564 procState = clientProcState; 16565 } 16566 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16567 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16568 app.pendingUiClean = true; 16569 } 16570 if (adjType != null) { 16571 app.adjType = adjType; 16572 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16573 .REASON_SERVICE_IN_USE; 16574 app.adjSource = cr.binding.client; 16575 app.adjSourceProcState = clientProcState; 16576 app.adjTarget = s.name; 16577 } 16578 } 16579 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16580 app.treatLikeActivity = true; 16581 } 16582 final ActivityRecord a = cr.activity; 16583 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16584 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16585 (a.visible || a.state == ActivityState.RESUMED 16586 || a.state == ActivityState.PAUSING)) { 16587 adj = ProcessList.FOREGROUND_APP_ADJ; 16588 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16589 schedGroup = Process.THREAD_GROUP_DEFAULT; 16590 } 16591 app.cached = false; 16592 app.adjType = "service"; 16593 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16594 .REASON_SERVICE_IN_USE; 16595 app.adjSource = a; 16596 app.adjSourceProcState = procState; 16597 app.adjTarget = s.name; 16598 } 16599 } 16600 } 16601 } 16602 } 16603 16604 for (int provi = app.pubProviders.size()-1; 16605 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16606 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16607 || procState > ActivityManager.PROCESS_STATE_TOP); 16608 provi--) { 16609 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16610 for (int i = cpr.connections.size()-1; 16611 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16612 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16613 || procState > ActivityManager.PROCESS_STATE_TOP); 16614 i--) { 16615 ContentProviderConnection conn = cpr.connections.get(i); 16616 ProcessRecord client = conn.client; 16617 if (client == app) { 16618 // Being our own client is not interesting. 16619 continue; 16620 } 16621 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16622 int clientProcState = client.curProcState; 16623 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16624 // If the other app is cached for any reason, for purposes here 16625 // we are going to consider it empty. 16626 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16627 } 16628 if (adj > clientAdj) { 16629 if (app.hasShownUi && app != mHomeProcess 16630 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16631 app.adjType = "cch-ui-provider"; 16632 } else { 16633 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16634 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16635 app.adjType = "provider"; 16636 } 16637 app.cached &= client.cached; 16638 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16639 .REASON_PROVIDER_IN_USE; 16640 app.adjSource = client; 16641 app.adjSourceProcState = clientProcState; 16642 app.adjTarget = cpr.name; 16643 } 16644 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16645 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16646 // Special handling of clients who are in the top state. 16647 // We *may* want to consider this process to be in the 16648 // top state as well, but only if there is not another 16649 // reason for it to be running. Being on the top is a 16650 // special state, meaning you are specifically running 16651 // for the current top app. If the process is already 16652 // running in the background for some other reason, it 16653 // is more important to continue considering it to be 16654 // in the background state. 16655 mayBeTop = true; 16656 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16657 } else { 16658 // Special handling for above-top states (persistent 16659 // processes). These should not bring the current process 16660 // into the top state, since they are not on top. Instead 16661 // give them the best state after that. 16662 clientProcState = 16663 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16664 } 16665 } 16666 if (procState > clientProcState) { 16667 procState = clientProcState; 16668 } 16669 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16670 schedGroup = Process.THREAD_GROUP_DEFAULT; 16671 } 16672 } 16673 // If the provider has external (non-framework) process 16674 // dependencies, ensure that its adjustment is at least 16675 // FOREGROUND_APP_ADJ. 16676 if (cpr.hasExternalProcessHandles()) { 16677 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16678 adj = ProcessList.FOREGROUND_APP_ADJ; 16679 schedGroup = Process.THREAD_GROUP_DEFAULT; 16680 app.cached = false; 16681 app.adjType = "provider"; 16682 app.adjTarget = cpr.name; 16683 } 16684 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16685 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16686 } 16687 } 16688 } 16689 16690 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16691 // A client of one of our services or providers is in the top state. We 16692 // *may* want to be in the top state, but not if we are already running in 16693 // the background for some other reason. For the decision here, we are going 16694 // to pick out a few specific states that we want to remain in when a client 16695 // is top (states that tend to be longer-term) and otherwise allow it to go 16696 // to the top state. 16697 switch (procState) { 16698 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16699 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16700 case ActivityManager.PROCESS_STATE_SERVICE: 16701 // These all are longer-term states, so pull them up to the top 16702 // of the background states, but not all the way to the top state. 16703 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16704 break; 16705 default: 16706 // Otherwise, top is a better choice, so take it. 16707 procState = ActivityManager.PROCESS_STATE_TOP; 16708 break; 16709 } 16710 } 16711 16712 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16713 if (app.hasClientActivities) { 16714 // This is a cached process, but with client activities. Mark it so. 16715 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16716 app.adjType = "cch-client-act"; 16717 } else if (app.treatLikeActivity) { 16718 // This is a cached process, but somebody wants us to treat it like it has 16719 // an activity, okay! 16720 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16721 app.adjType = "cch-as-act"; 16722 } 16723 } 16724 16725 if (adj == ProcessList.SERVICE_ADJ) { 16726 if (doingAll) { 16727 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16728 mNewNumServiceProcs++; 16729 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16730 if (!app.serviceb) { 16731 // This service isn't far enough down on the LRU list to 16732 // normally be a B service, but if we are low on RAM and it 16733 // is large we want to force it down since we would prefer to 16734 // keep launcher over it. 16735 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16736 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16737 app.serviceHighRam = true; 16738 app.serviceb = true; 16739 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16740 } else { 16741 mNewNumAServiceProcs++; 16742 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16743 } 16744 } else { 16745 app.serviceHighRam = false; 16746 } 16747 } 16748 if (app.serviceb) { 16749 adj = ProcessList.SERVICE_B_ADJ; 16750 } 16751 } 16752 16753 app.curRawAdj = adj; 16754 16755 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16756 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16757 if (adj > app.maxAdj) { 16758 adj = app.maxAdj; 16759 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16760 schedGroup = Process.THREAD_GROUP_DEFAULT; 16761 } 16762 } 16763 16764 // Do final modification to adj. Everything we do between here and applying 16765 // the final setAdj must be done in this function, because we will also use 16766 // it when computing the final cached adj later. Note that we don't need to 16767 // worry about this for max adj above, since max adj will always be used to 16768 // keep it out of the cached vaues. 16769 app.curAdj = app.modifyRawOomAdj(adj); 16770 app.curSchedGroup = schedGroup; 16771 app.curProcState = procState; 16772 app.foregroundActivities = foregroundActivities; 16773 16774 return app.curRawAdj; 16775 } 16776 16777 /** 16778 * Schedule PSS collection of a process. 16779 */ 16780 void requestPssLocked(ProcessRecord proc, int procState) { 16781 if (mPendingPssProcesses.contains(proc)) { 16782 return; 16783 } 16784 if (mPendingPssProcesses.size() == 0) { 16785 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16786 } 16787 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16788 proc.pssProcState = procState; 16789 mPendingPssProcesses.add(proc); 16790 } 16791 16792 /** 16793 * Schedule PSS collection of all processes. 16794 */ 16795 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16796 if (!always) { 16797 if (now < (mLastFullPssTime + 16798 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16799 return; 16800 } 16801 } 16802 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16803 mLastFullPssTime = now; 16804 mFullPssPending = true; 16805 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16806 mPendingPssProcesses.clear(); 16807 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16808 ProcessRecord app = mLruProcesses.get(i); 16809 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16810 app.pssProcState = app.setProcState; 16811 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16812 isSleeping(), now); 16813 mPendingPssProcesses.add(app); 16814 } 16815 } 16816 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16817 } 16818 16819 /** 16820 * Ask a given process to GC right now. 16821 */ 16822 final void performAppGcLocked(ProcessRecord app) { 16823 try { 16824 app.lastRequestedGc = SystemClock.uptimeMillis(); 16825 if (app.thread != null) { 16826 if (app.reportLowMemory) { 16827 app.reportLowMemory = false; 16828 app.thread.scheduleLowMemory(); 16829 } else { 16830 app.thread.processInBackground(); 16831 } 16832 } 16833 } catch (Exception e) { 16834 // whatever. 16835 } 16836 } 16837 16838 /** 16839 * Returns true if things are idle enough to perform GCs. 16840 */ 16841 private final boolean canGcNowLocked() { 16842 boolean processingBroadcasts = false; 16843 for (BroadcastQueue q : mBroadcastQueues) { 16844 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16845 processingBroadcasts = true; 16846 } 16847 } 16848 return !processingBroadcasts 16849 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16850 } 16851 16852 /** 16853 * Perform GCs on all processes that are waiting for it, but only 16854 * if things are idle. 16855 */ 16856 final void performAppGcsLocked() { 16857 final int N = mProcessesToGc.size(); 16858 if (N <= 0) { 16859 return; 16860 } 16861 if (canGcNowLocked()) { 16862 while (mProcessesToGc.size() > 0) { 16863 ProcessRecord proc = mProcessesToGc.remove(0); 16864 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16865 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16866 <= SystemClock.uptimeMillis()) { 16867 // To avoid spamming the system, we will GC processes one 16868 // at a time, waiting a few seconds between each. 16869 performAppGcLocked(proc); 16870 scheduleAppGcsLocked(); 16871 return; 16872 } else { 16873 // It hasn't been long enough since we last GCed this 16874 // process... put it in the list to wait for its time. 16875 addProcessToGcListLocked(proc); 16876 break; 16877 } 16878 } 16879 } 16880 16881 scheduleAppGcsLocked(); 16882 } 16883 } 16884 16885 /** 16886 * If all looks good, perform GCs on all processes waiting for them. 16887 */ 16888 final void performAppGcsIfAppropriateLocked() { 16889 if (canGcNowLocked()) { 16890 performAppGcsLocked(); 16891 return; 16892 } 16893 // Still not idle, wait some more. 16894 scheduleAppGcsLocked(); 16895 } 16896 16897 /** 16898 * Schedule the execution of all pending app GCs. 16899 */ 16900 final void scheduleAppGcsLocked() { 16901 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16902 16903 if (mProcessesToGc.size() > 0) { 16904 // Schedule a GC for the time to the next process. 16905 ProcessRecord proc = mProcessesToGc.get(0); 16906 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16907 16908 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16909 long now = SystemClock.uptimeMillis(); 16910 if (when < (now+GC_TIMEOUT)) { 16911 when = now + GC_TIMEOUT; 16912 } 16913 mHandler.sendMessageAtTime(msg, when); 16914 } 16915 } 16916 16917 /** 16918 * Add a process to the array of processes waiting to be GCed. Keeps the 16919 * list in sorted order by the last GC time. The process can't already be 16920 * on the list. 16921 */ 16922 final void addProcessToGcListLocked(ProcessRecord proc) { 16923 boolean added = false; 16924 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16925 if (mProcessesToGc.get(i).lastRequestedGc < 16926 proc.lastRequestedGc) { 16927 added = true; 16928 mProcessesToGc.add(i+1, proc); 16929 break; 16930 } 16931 } 16932 if (!added) { 16933 mProcessesToGc.add(0, proc); 16934 } 16935 } 16936 16937 /** 16938 * Set up to ask a process to GC itself. This will either do it 16939 * immediately, or put it on the list of processes to gc the next 16940 * time things are idle. 16941 */ 16942 final void scheduleAppGcLocked(ProcessRecord app) { 16943 long now = SystemClock.uptimeMillis(); 16944 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16945 return; 16946 } 16947 if (!mProcessesToGc.contains(app)) { 16948 addProcessToGcListLocked(app); 16949 scheduleAppGcsLocked(); 16950 } 16951 } 16952 16953 final void checkExcessivePowerUsageLocked(boolean doKills) { 16954 updateCpuStatsNow(); 16955 16956 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16957 boolean doWakeKills = doKills; 16958 boolean doCpuKills = doKills; 16959 if (mLastPowerCheckRealtime == 0) { 16960 doWakeKills = false; 16961 } 16962 if (mLastPowerCheckUptime == 0) { 16963 doCpuKills = false; 16964 } 16965 if (stats.isScreenOn()) { 16966 doWakeKills = false; 16967 } 16968 final long curRealtime = SystemClock.elapsedRealtime(); 16969 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16970 final long curUptime = SystemClock.uptimeMillis(); 16971 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16972 mLastPowerCheckRealtime = curRealtime; 16973 mLastPowerCheckUptime = curUptime; 16974 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16975 doWakeKills = false; 16976 } 16977 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16978 doCpuKills = false; 16979 } 16980 int i = mLruProcesses.size(); 16981 while (i > 0) { 16982 i--; 16983 ProcessRecord app = mLruProcesses.get(i); 16984 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16985 long wtime; 16986 synchronized (stats) { 16987 wtime = stats.getProcessWakeTime(app.info.uid, 16988 app.pid, curRealtime); 16989 } 16990 long wtimeUsed = wtime - app.lastWakeTime; 16991 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16992 if (DEBUG_POWER) { 16993 StringBuilder sb = new StringBuilder(128); 16994 sb.append("Wake for "); 16995 app.toShortString(sb); 16996 sb.append(": over "); 16997 TimeUtils.formatDuration(realtimeSince, sb); 16998 sb.append(" used "); 16999 TimeUtils.formatDuration(wtimeUsed, sb); 17000 sb.append(" ("); 17001 sb.append((wtimeUsed*100)/realtimeSince); 17002 sb.append("%)"); 17003 Slog.i(TAG, sb.toString()); 17004 sb.setLength(0); 17005 sb.append("CPU for "); 17006 app.toShortString(sb); 17007 sb.append(": over "); 17008 TimeUtils.formatDuration(uptimeSince, sb); 17009 sb.append(" used "); 17010 TimeUtils.formatDuration(cputimeUsed, sb); 17011 sb.append(" ("); 17012 sb.append((cputimeUsed*100)/uptimeSince); 17013 sb.append("%)"); 17014 Slog.i(TAG, sb.toString()); 17015 } 17016 // If a process has held a wake lock for more 17017 // than 50% of the time during this period, 17018 // that sounds bad. Kill! 17019 if (doWakeKills && realtimeSince > 0 17020 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17021 synchronized (stats) { 17022 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17023 realtimeSince, wtimeUsed); 17024 } 17025 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17026 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17027 } else if (doCpuKills && uptimeSince > 0 17028 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17029 synchronized (stats) { 17030 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17031 uptimeSince, cputimeUsed); 17032 } 17033 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17034 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17035 } else { 17036 app.lastWakeTime = wtime; 17037 app.lastCpuTime = app.curCpuTime; 17038 } 17039 } 17040 } 17041 } 17042 17043 private final boolean applyOomAdjLocked(ProcessRecord app, 17044 ProcessRecord TOP_APP, boolean doingAll, long now) { 17045 boolean success = true; 17046 17047 if (app.curRawAdj != app.setRawAdj) { 17048 app.setRawAdj = app.curRawAdj; 17049 } 17050 17051 int changes = 0; 17052 17053 if (app.curAdj != app.setAdj) { 17054 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17055 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17056 TAG, "Set " + app.pid + " " + app.processName + 17057 " adj " + app.curAdj + ": " + app.adjType); 17058 app.setAdj = app.curAdj; 17059 } 17060 17061 if (app.setSchedGroup != app.curSchedGroup) { 17062 app.setSchedGroup = app.curSchedGroup; 17063 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17064 "Setting process group of " + app.processName 17065 + " to " + app.curSchedGroup); 17066 if (app.waitingToKill != null && 17067 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17068 app.kill(app.waitingToKill, true); 17069 success = false; 17070 } else { 17071 if (true) { 17072 long oldId = Binder.clearCallingIdentity(); 17073 try { 17074 Process.setProcessGroup(app.pid, app.curSchedGroup); 17075 } catch (Exception e) { 17076 Slog.w(TAG, "Failed setting process group of " + app.pid 17077 + " to " + app.curSchedGroup); 17078 e.printStackTrace(); 17079 } finally { 17080 Binder.restoreCallingIdentity(oldId); 17081 } 17082 } else { 17083 if (app.thread != null) { 17084 try { 17085 app.thread.setSchedulingGroup(app.curSchedGroup); 17086 } catch (RemoteException e) { 17087 } 17088 } 17089 } 17090 Process.setSwappiness(app.pid, 17091 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17092 } 17093 } 17094 if (app.repForegroundActivities != app.foregroundActivities) { 17095 app.repForegroundActivities = app.foregroundActivities; 17096 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17097 } 17098 if (app.repProcState != app.curProcState) { 17099 app.repProcState = app.curProcState; 17100 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17101 if (app.thread != null) { 17102 try { 17103 if (false) { 17104 //RuntimeException h = new RuntimeException("here"); 17105 Slog.i(TAG, "Sending new process state " + app.repProcState 17106 + " to " + app /*, h*/); 17107 } 17108 app.thread.setProcessState(app.repProcState); 17109 } catch (RemoteException e) { 17110 } 17111 } 17112 } 17113 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17114 app.setProcState)) { 17115 app.lastStateTime = now; 17116 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17117 isSleeping(), now); 17118 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17119 + ProcessList.makeProcStateString(app.setProcState) + " to " 17120 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17121 + (app.nextPssTime-now) + ": " + app); 17122 } else { 17123 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17124 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17125 requestPssLocked(app, app.setProcState); 17126 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17127 isSleeping(), now); 17128 } else if (false && DEBUG_PSS) { 17129 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17130 } 17131 } 17132 if (app.setProcState != app.curProcState) { 17133 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17134 "Proc state change of " + app.processName 17135 + " to " + app.curProcState); 17136 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17137 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17138 if (setImportant && !curImportant) { 17139 // This app is no longer something we consider important enough to allow to 17140 // use arbitrary amounts of battery power. Note 17141 // its current wake lock time to later know to kill it if 17142 // it is not behaving well. 17143 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17144 synchronized (stats) { 17145 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17146 app.pid, SystemClock.elapsedRealtime()); 17147 } 17148 app.lastCpuTime = app.curCpuTime; 17149 17150 } 17151 app.setProcState = app.curProcState; 17152 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17153 app.notCachedSinceIdle = false; 17154 } 17155 if (!doingAll) { 17156 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17157 } else { 17158 app.procStateChanged = true; 17159 } 17160 } 17161 17162 if (changes != 0) { 17163 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17164 int i = mPendingProcessChanges.size()-1; 17165 ProcessChangeItem item = null; 17166 while (i >= 0) { 17167 item = mPendingProcessChanges.get(i); 17168 if (item.pid == app.pid) { 17169 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17170 break; 17171 } 17172 i--; 17173 } 17174 if (i < 0) { 17175 // No existing item in pending changes; need a new one. 17176 final int NA = mAvailProcessChanges.size(); 17177 if (NA > 0) { 17178 item = mAvailProcessChanges.remove(NA-1); 17179 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17180 } else { 17181 item = new ProcessChangeItem(); 17182 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17183 } 17184 item.changes = 0; 17185 item.pid = app.pid; 17186 item.uid = app.info.uid; 17187 if (mPendingProcessChanges.size() == 0) { 17188 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17189 "*** Enqueueing dispatch processes changed!"); 17190 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17191 } 17192 mPendingProcessChanges.add(item); 17193 } 17194 item.changes |= changes; 17195 item.processState = app.repProcState; 17196 item.foregroundActivities = app.repForegroundActivities; 17197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17198 + Integer.toHexString(System.identityHashCode(item)) 17199 + " " + app.toShortString() + ": changes=" + item.changes 17200 + " procState=" + item.processState 17201 + " foreground=" + item.foregroundActivities 17202 + " type=" + app.adjType + " source=" + app.adjSource 17203 + " target=" + app.adjTarget); 17204 } 17205 17206 return success; 17207 } 17208 17209 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17210 if (proc.thread != null) { 17211 if (proc.baseProcessTracker != null) { 17212 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17213 } 17214 if (proc.repProcState >= 0) { 17215 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17216 proc.repProcState); 17217 } 17218 } 17219 } 17220 17221 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17222 ProcessRecord TOP_APP, boolean doingAll, long now) { 17223 if (app.thread == null) { 17224 return false; 17225 } 17226 17227 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17228 17229 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17230 } 17231 17232 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17233 boolean oomAdj) { 17234 if (isForeground != proc.foregroundServices) { 17235 proc.foregroundServices = isForeground; 17236 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17237 proc.info.uid); 17238 if (isForeground) { 17239 if (curProcs == null) { 17240 curProcs = new ArrayList<ProcessRecord>(); 17241 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17242 } 17243 if (!curProcs.contains(proc)) { 17244 curProcs.add(proc); 17245 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17246 proc.info.packageName, proc.info.uid); 17247 } 17248 } else { 17249 if (curProcs != null) { 17250 if (curProcs.remove(proc)) { 17251 mBatteryStatsService.noteEvent( 17252 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17253 proc.info.packageName, proc.info.uid); 17254 if (curProcs.size() <= 0) { 17255 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17256 } 17257 } 17258 } 17259 } 17260 if (oomAdj) { 17261 updateOomAdjLocked(); 17262 } 17263 } 17264 } 17265 17266 private final ActivityRecord resumedAppLocked() { 17267 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17268 String pkg; 17269 int uid; 17270 if (act != null) { 17271 pkg = act.packageName; 17272 uid = act.info.applicationInfo.uid; 17273 } else { 17274 pkg = null; 17275 uid = -1; 17276 } 17277 // Has the UID or resumed package name changed? 17278 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17279 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17280 if (mCurResumedPackage != null) { 17281 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17282 mCurResumedPackage, mCurResumedUid); 17283 } 17284 mCurResumedPackage = pkg; 17285 mCurResumedUid = uid; 17286 if (mCurResumedPackage != null) { 17287 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17288 mCurResumedPackage, mCurResumedUid); 17289 } 17290 } 17291 return act; 17292 } 17293 17294 final boolean updateOomAdjLocked(ProcessRecord app) { 17295 final ActivityRecord TOP_ACT = resumedAppLocked(); 17296 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17297 final boolean wasCached = app.cached; 17298 17299 mAdjSeq++; 17300 17301 // This is the desired cached adjusment we want to tell it to use. 17302 // If our app is currently cached, we know it, and that is it. Otherwise, 17303 // we don't know it yet, and it needs to now be cached we will then 17304 // need to do a complete oom adj. 17305 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17306 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17307 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17308 SystemClock.uptimeMillis()); 17309 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17310 // Changed to/from cached state, so apps after it in the LRU 17311 // list may also be changed. 17312 updateOomAdjLocked(); 17313 } 17314 return success; 17315 } 17316 17317 final void updateOomAdjLocked() { 17318 final ActivityRecord TOP_ACT = resumedAppLocked(); 17319 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17320 final long now = SystemClock.uptimeMillis(); 17321 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17322 final int N = mLruProcesses.size(); 17323 17324 if (false) { 17325 RuntimeException e = new RuntimeException(); 17326 e.fillInStackTrace(); 17327 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17328 } 17329 17330 mAdjSeq++; 17331 mNewNumServiceProcs = 0; 17332 mNewNumAServiceProcs = 0; 17333 17334 final int emptyProcessLimit; 17335 final int cachedProcessLimit; 17336 if (mProcessLimit <= 0) { 17337 emptyProcessLimit = cachedProcessLimit = 0; 17338 } else if (mProcessLimit == 1) { 17339 emptyProcessLimit = 1; 17340 cachedProcessLimit = 0; 17341 } else { 17342 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17343 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17344 } 17345 17346 // Let's determine how many processes we have running vs. 17347 // how many slots we have for background processes; we may want 17348 // to put multiple processes in a slot of there are enough of 17349 // them. 17350 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17351 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17352 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17353 if (numEmptyProcs > cachedProcessLimit) { 17354 // If there are more empty processes than our limit on cached 17355 // processes, then use the cached process limit for the factor. 17356 // This ensures that the really old empty processes get pushed 17357 // down to the bottom, so if we are running low on memory we will 17358 // have a better chance at keeping around more cached processes 17359 // instead of a gazillion empty processes. 17360 numEmptyProcs = cachedProcessLimit; 17361 } 17362 int emptyFactor = numEmptyProcs/numSlots; 17363 if (emptyFactor < 1) emptyFactor = 1; 17364 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17365 if (cachedFactor < 1) cachedFactor = 1; 17366 int stepCached = 0; 17367 int stepEmpty = 0; 17368 int numCached = 0; 17369 int numEmpty = 0; 17370 int numTrimming = 0; 17371 17372 mNumNonCachedProcs = 0; 17373 mNumCachedHiddenProcs = 0; 17374 17375 // First update the OOM adjustment for each of the 17376 // application processes based on their current state. 17377 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17378 int nextCachedAdj = curCachedAdj+1; 17379 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17380 int nextEmptyAdj = curEmptyAdj+2; 17381 for (int i=N-1; i>=0; i--) { 17382 ProcessRecord app = mLruProcesses.get(i); 17383 if (!app.killedByAm && app.thread != null) { 17384 app.procStateChanged = false; 17385 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17386 17387 // If we haven't yet assigned the final cached adj 17388 // to the process, do that now. 17389 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17390 switch (app.curProcState) { 17391 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17392 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17393 // This process is a cached process holding activities... 17394 // assign it the next cached value for that type, and then 17395 // step that cached level. 17396 app.curRawAdj = curCachedAdj; 17397 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17398 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17399 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17400 + ")"); 17401 if (curCachedAdj != nextCachedAdj) { 17402 stepCached++; 17403 if (stepCached >= cachedFactor) { 17404 stepCached = 0; 17405 curCachedAdj = nextCachedAdj; 17406 nextCachedAdj += 2; 17407 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17408 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17409 } 17410 } 17411 } 17412 break; 17413 default: 17414 // For everything else, assign next empty cached process 17415 // level and bump that up. Note that this means that 17416 // long-running services that have dropped down to the 17417 // cached level will be treated as empty (since their process 17418 // state is still as a service), which is what we want. 17419 app.curRawAdj = curEmptyAdj; 17420 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17421 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17422 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17423 + ")"); 17424 if (curEmptyAdj != nextEmptyAdj) { 17425 stepEmpty++; 17426 if (stepEmpty >= emptyFactor) { 17427 stepEmpty = 0; 17428 curEmptyAdj = nextEmptyAdj; 17429 nextEmptyAdj += 2; 17430 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17431 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17432 } 17433 } 17434 } 17435 break; 17436 } 17437 } 17438 17439 applyOomAdjLocked(app, TOP_APP, true, now); 17440 17441 // Count the number of process types. 17442 switch (app.curProcState) { 17443 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17444 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17445 mNumCachedHiddenProcs++; 17446 numCached++; 17447 if (numCached > cachedProcessLimit) { 17448 app.kill("cached #" + numCached, true); 17449 } 17450 break; 17451 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17452 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17453 && app.lastActivityTime < oldTime) { 17454 app.kill("empty for " 17455 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17456 / 1000) + "s", true); 17457 } else { 17458 numEmpty++; 17459 if (numEmpty > emptyProcessLimit) { 17460 app.kill("empty #" + numEmpty, true); 17461 } 17462 } 17463 break; 17464 default: 17465 mNumNonCachedProcs++; 17466 break; 17467 } 17468 17469 if (app.isolated && app.services.size() <= 0) { 17470 // If this is an isolated process, and there are no 17471 // services running in it, then the process is no longer 17472 // needed. We agressively kill these because we can by 17473 // definition not re-use the same process again, and it is 17474 // good to avoid having whatever code was running in them 17475 // left sitting around after no longer needed. 17476 app.kill("isolated not needed", true); 17477 } 17478 17479 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17480 && !app.killedByAm) { 17481 numTrimming++; 17482 } 17483 } 17484 } 17485 17486 mNumServiceProcs = mNewNumServiceProcs; 17487 17488 // Now determine the memory trimming level of background processes. 17489 // Unfortunately we need to start at the back of the list to do this 17490 // properly. We only do this if the number of background apps we 17491 // are managing to keep around is less than half the maximum we desire; 17492 // if we are keeping a good number around, we'll let them use whatever 17493 // memory they want. 17494 final int numCachedAndEmpty = numCached + numEmpty; 17495 int memFactor; 17496 if (numCached <= ProcessList.TRIM_CACHED_APPS 17497 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17498 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17499 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17500 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17501 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17502 } else { 17503 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17504 } 17505 } else { 17506 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17507 } 17508 // We always allow the memory level to go up (better). We only allow it to go 17509 // down if we are in a state where that is allowed, *and* the total number of processes 17510 // has gone down since last time. 17511 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17512 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17513 + " last=" + mLastNumProcesses); 17514 if (memFactor > mLastMemoryLevel) { 17515 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17516 memFactor = mLastMemoryLevel; 17517 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17518 } 17519 } 17520 mLastMemoryLevel = memFactor; 17521 mLastNumProcesses = mLruProcesses.size(); 17522 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17523 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17524 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17525 if (mLowRamStartTime == 0) { 17526 mLowRamStartTime = now; 17527 } 17528 int step = 0; 17529 int fgTrimLevel; 17530 switch (memFactor) { 17531 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17532 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17533 break; 17534 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17535 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17536 break; 17537 default: 17538 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17539 break; 17540 } 17541 int factor = numTrimming/3; 17542 int minFactor = 2; 17543 if (mHomeProcess != null) minFactor++; 17544 if (mPreviousProcess != null) minFactor++; 17545 if (factor < minFactor) factor = minFactor; 17546 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17547 for (int i=N-1; i>=0; i--) { 17548 ProcessRecord app = mLruProcesses.get(i); 17549 if (allChanged || app.procStateChanged) { 17550 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17551 app.procStateChanged = false; 17552 } 17553 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17554 && !app.killedByAm) { 17555 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17556 try { 17557 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17558 "Trimming memory of " + app.processName 17559 + " to " + curLevel); 17560 app.thread.scheduleTrimMemory(curLevel); 17561 } catch (RemoteException e) { 17562 } 17563 if (false) { 17564 // For now we won't do this; our memory trimming seems 17565 // to be good enough at this point that destroying 17566 // activities causes more harm than good. 17567 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17568 && app != mHomeProcess && app != mPreviousProcess) { 17569 // Need to do this on its own message because the stack may not 17570 // be in a consistent state at this point. 17571 // For these apps we will also finish their activities 17572 // to help them free memory. 17573 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17574 } 17575 } 17576 } 17577 app.trimMemoryLevel = curLevel; 17578 step++; 17579 if (step >= factor) { 17580 step = 0; 17581 switch (curLevel) { 17582 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17583 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17584 break; 17585 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17586 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17587 break; 17588 } 17589 } 17590 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17591 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17592 && app.thread != null) { 17593 try { 17594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17595 "Trimming memory of heavy-weight " + app.processName 17596 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17597 app.thread.scheduleTrimMemory( 17598 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17599 } catch (RemoteException e) { 17600 } 17601 } 17602 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17603 } else { 17604 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17605 || app.systemNoUi) && app.pendingUiClean) { 17606 // If this application is now in the background and it 17607 // had done UI, then give it the special trim level to 17608 // have it free UI resources. 17609 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17610 if (app.trimMemoryLevel < level && app.thread != null) { 17611 try { 17612 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17613 "Trimming memory of bg-ui " + app.processName 17614 + " to " + level); 17615 app.thread.scheduleTrimMemory(level); 17616 } catch (RemoteException e) { 17617 } 17618 } 17619 app.pendingUiClean = false; 17620 } 17621 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17622 try { 17623 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17624 "Trimming memory of fg " + app.processName 17625 + " to " + fgTrimLevel); 17626 app.thread.scheduleTrimMemory(fgTrimLevel); 17627 } catch (RemoteException e) { 17628 } 17629 } 17630 app.trimMemoryLevel = fgTrimLevel; 17631 } 17632 } 17633 } else { 17634 if (mLowRamStartTime != 0) { 17635 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17636 mLowRamStartTime = 0; 17637 } 17638 for (int i=N-1; i>=0; i--) { 17639 ProcessRecord app = mLruProcesses.get(i); 17640 if (allChanged || app.procStateChanged) { 17641 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17642 app.procStateChanged = false; 17643 } 17644 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17645 || app.systemNoUi) && app.pendingUiClean) { 17646 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17647 && app.thread != null) { 17648 try { 17649 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17650 "Trimming memory of ui hidden " + app.processName 17651 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17652 app.thread.scheduleTrimMemory( 17653 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17654 } catch (RemoteException e) { 17655 } 17656 } 17657 app.pendingUiClean = false; 17658 } 17659 app.trimMemoryLevel = 0; 17660 } 17661 } 17662 17663 if (mAlwaysFinishActivities) { 17664 // Need to do this on its own message because the stack may not 17665 // be in a consistent state at this point. 17666 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17667 } 17668 17669 if (allChanged) { 17670 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17671 } 17672 17673 if (mProcessStats.shouldWriteNowLocked(now)) { 17674 mHandler.post(new Runnable() { 17675 @Override public void run() { 17676 synchronized (ActivityManagerService.this) { 17677 mProcessStats.writeStateAsyncLocked(); 17678 } 17679 } 17680 }); 17681 } 17682 17683 if (DEBUG_OOM_ADJ) { 17684 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17685 } 17686 } 17687 17688 final void trimApplications() { 17689 synchronized (this) { 17690 int i; 17691 17692 // First remove any unused application processes whose package 17693 // has been removed. 17694 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17695 final ProcessRecord app = mRemovedProcesses.get(i); 17696 if (app.activities.size() == 0 17697 && app.curReceiver == null && app.services.size() == 0) { 17698 Slog.i( 17699 TAG, "Exiting empty application process " 17700 + app.processName + " (" 17701 + (app.thread != null ? app.thread.asBinder() : null) 17702 + ")\n"); 17703 if (app.pid > 0 && app.pid != MY_PID) { 17704 app.kill("empty", false); 17705 } else { 17706 try { 17707 app.thread.scheduleExit(); 17708 } catch (Exception e) { 17709 // Ignore exceptions. 17710 } 17711 } 17712 cleanUpApplicationRecordLocked(app, false, true, -1); 17713 mRemovedProcesses.remove(i); 17714 17715 if (app.persistent) { 17716 addAppLocked(app.info, false, null /* ABI override */); 17717 } 17718 } 17719 } 17720 17721 // Now update the oom adj for all processes. 17722 updateOomAdjLocked(); 17723 } 17724 } 17725 17726 /** This method sends the specified signal to each of the persistent apps */ 17727 public void signalPersistentProcesses(int sig) throws RemoteException { 17728 if (sig != Process.SIGNAL_USR1) { 17729 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17730 } 17731 17732 synchronized (this) { 17733 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17734 != PackageManager.PERMISSION_GRANTED) { 17735 throw new SecurityException("Requires permission " 17736 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17737 } 17738 17739 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17740 ProcessRecord r = mLruProcesses.get(i); 17741 if (r.thread != null && r.persistent) { 17742 Process.sendSignal(r.pid, sig); 17743 } 17744 } 17745 } 17746 } 17747 17748 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17749 if (proc == null || proc == mProfileProc) { 17750 proc = mProfileProc; 17751 profileType = mProfileType; 17752 clearProfilerLocked(); 17753 } 17754 if (proc == null) { 17755 return; 17756 } 17757 try { 17758 proc.thread.profilerControl(false, null, profileType); 17759 } catch (RemoteException e) { 17760 throw new IllegalStateException("Process disappeared"); 17761 } 17762 } 17763 17764 private void clearProfilerLocked() { 17765 if (mProfileFd != null) { 17766 try { 17767 mProfileFd.close(); 17768 } catch (IOException e) { 17769 } 17770 } 17771 mProfileApp = null; 17772 mProfileProc = null; 17773 mProfileFile = null; 17774 mProfileType = 0; 17775 mAutoStopProfiler = false; 17776 mSamplingInterval = 0; 17777 } 17778 17779 public boolean profileControl(String process, int userId, boolean start, 17780 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17781 17782 try { 17783 synchronized (this) { 17784 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17785 // its own permission. 17786 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17787 != PackageManager.PERMISSION_GRANTED) { 17788 throw new SecurityException("Requires permission " 17789 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17790 } 17791 17792 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17793 throw new IllegalArgumentException("null profile info or fd"); 17794 } 17795 17796 ProcessRecord proc = null; 17797 if (process != null) { 17798 proc = findProcessLocked(process, userId, "profileControl"); 17799 } 17800 17801 if (start && (proc == null || proc.thread == null)) { 17802 throw new IllegalArgumentException("Unknown process: " + process); 17803 } 17804 17805 if (start) { 17806 stopProfilerLocked(null, 0); 17807 setProfileApp(proc.info, proc.processName, profilerInfo); 17808 mProfileProc = proc; 17809 mProfileType = profileType; 17810 ParcelFileDescriptor fd = profilerInfo.profileFd; 17811 try { 17812 fd = fd.dup(); 17813 } catch (IOException e) { 17814 fd = null; 17815 } 17816 profilerInfo.profileFd = fd; 17817 proc.thread.profilerControl(start, profilerInfo, profileType); 17818 fd = null; 17819 mProfileFd = null; 17820 } else { 17821 stopProfilerLocked(proc, profileType); 17822 if (profilerInfo != null && profilerInfo.profileFd != null) { 17823 try { 17824 profilerInfo.profileFd.close(); 17825 } catch (IOException e) { 17826 } 17827 } 17828 } 17829 17830 return true; 17831 } 17832 } catch (RemoteException e) { 17833 throw new IllegalStateException("Process disappeared"); 17834 } finally { 17835 if (profilerInfo != null && profilerInfo.profileFd != null) { 17836 try { 17837 profilerInfo.profileFd.close(); 17838 } catch (IOException e) { 17839 } 17840 } 17841 } 17842 } 17843 17844 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17845 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17846 userId, true, ALLOW_FULL_ONLY, callName, null); 17847 ProcessRecord proc = null; 17848 try { 17849 int pid = Integer.parseInt(process); 17850 synchronized (mPidsSelfLocked) { 17851 proc = mPidsSelfLocked.get(pid); 17852 } 17853 } catch (NumberFormatException e) { 17854 } 17855 17856 if (proc == null) { 17857 ArrayMap<String, SparseArray<ProcessRecord>> all 17858 = mProcessNames.getMap(); 17859 SparseArray<ProcessRecord> procs = all.get(process); 17860 if (procs != null && procs.size() > 0) { 17861 proc = procs.valueAt(0); 17862 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17863 for (int i=1; i<procs.size(); i++) { 17864 ProcessRecord thisProc = procs.valueAt(i); 17865 if (thisProc.userId == userId) { 17866 proc = thisProc; 17867 break; 17868 } 17869 } 17870 } 17871 } 17872 } 17873 17874 return proc; 17875 } 17876 17877 public boolean dumpHeap(String process, int userId, boolean managed, 17878 String path, ParcelFileDescriptor fd) throws RemoteException { 17879 17880 try { 17881 synchronized (this) { 17882 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17883 // its own permission (same as profileControl). 17884 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17885 != PackageManager.PERMISSION_GRANTED) { 17886 throw new SecurityException("Requires permission " 17887 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17888 } 17889 17890 if (fd == null) { 17891 throw new IllegalArgumentException("null fd"); 17892 } 17893 17894 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17895 if (proc == null || proc.thread == null) { 17896 throw new IllegalArgumentException("Unknown process: " + process); 17897 } 17898 17899 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17900 if (!isDebuggable) { 17901 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17902 throw new SecurityException("Process not debuggable: " + proc); 17903 } 17904 } 17905 17906 proc.thread.dumpHeap(managed, path, fd); 17907 fd = null; 17908 return true; 17909 } 17910 } catch (RemoteException e) { 17911 throw new IllegalStateException("Process disappeared"); 17912 } finally { 17913 if (fd != null) { 17914 try { 17915 fd.close(); 17916 } catch (IOException e) { 17917 } 17918 } 17919 } 17920 } 17921 17922 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17923 public void monitor() { 17924 synchronized (this) { } 17925 } 17926 17927 void onCoreSettingsChange(Bundle settings) { 17928 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17929 ProcessRecord processRecord = mLruProcesses.get(i); 17930 try { 17931 if (processRecord.thread != null) { 17932 processRecord.thread.setCoreSettings(settings); 17933 } 17934 } catch (RemoteException re) { 17935 /* ignore */ 17936 } 17937 } 17938 } 17939 17940 // Multi-user methods 17941 17942 /** 17943 * Start user, if its not already running, but don't bring it to foreground. 17944 */ 17945 @Override 17946 public boolean startUserInBackground(final int userId) { 17947 return startUser(userId, /* foreground */ false); 17948 } 17949 17950 /** 17951 * Start user, if its not already running, and bring it to foreground. 17952 */ 17953 boolean startUserInForeground(final int userId, Dialog dlg) { 17954 boolean result = startUser(userId, /* foreground */ true); 17955 dlg.dismiss(); 17956 return result; 17957 } 17958 17959 /** 17960 * Refreshes the list of users related to the current user when either a 17961 * user switch happens or when a new related user is started in the 17962 * background. 17963 */ 17964 private void updateCurrentProfileIdsLocked() { 17965 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17966 mCurrentUserId, false /* enabledOnly */); 17967 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17968 for (int i = 0; i < currentProfileIds.length; i++) { 17969 currentProfileIds[i] = profiles.get(i).id; 17970 } 17971 mCurrentProfileIds = currentProfileIds; 17972 17973 synchronized (mUserProfileGroupIdsSelfLocked) { 17974 mUserProfileGroupIdsSelfLocked.clear(); 17975 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17976 for (int i = 0; i < users.size(); i++) { 17977 UserInfo user = users.get(i); 17978 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17979 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17980 } 17981 } 17982 } 17983 } 17984 17985 private Set getProfileIdsLocked(int userId) { 17986 Set userIds = new HashSet<Integer>(); 17987 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17988 userId, false /* enabledOnly */); 17989 for (UserInfo user : profiles) { 17990 userIds.add(Integer.valueOf(user.id)); 17991 } 17992 return userIds; 17993 } 17994 17995 @Override 17996 public boolean switchUser(final int userId) { 17997 String userName; 17998 synchronized (this) { 17999 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18000 if (userInfo == null) { 18001 Slog.w(TAG, "No user info for user #" + userId); 18002 return false; 18003 } 18004 if (userInfo.isManagedProfile()) { 18005 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18006 return false; 18007 } 18008 userName = userInfo.name; 18009 mTargetUserId = userId; 18010 } 18011 mHandler.removeMessages(START_USER_SWITCH_MSG); 18012 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18013 return true; 18014 } 18015 18016 private void showUserSwitchDialog(int userId, String userName) { 18017 // The dialog will show and then initiate the user switch by calling startUserInForeground 18018 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18019 true /* above system */); 18020 d.show(); 18021 } 18022 18023 private boolean startUser(final int userId, final boolean foreground) { 18024 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18025 != PackageManager.PERMISSION_GRANTED) { 18026 String msg = "Permission Denial: switchUser() from pid=" 18027 + Binder.getCallingPid() 18028 + ", uid=" + Binder.getCallingUid() 18029 + " requires " + INTERACT_ACROSS_USERS_FULL; 18030 Slog.w(TAG, msg); 18031 throw new SecurityException(msg); 18032 } 18033 18034 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18035 18036 final long ident = Binder.clearCallingIdentity(); 18037 try { 18038 synchronized (this) { 18039 final int oldUserId = mCurrentUserId; 18040 if (oldUserId == userId) { 18041 return true; 18042 } 18043 18044 mStackSupervisor.setLockTaskModeLocked(null, false); 18045 18046 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18047 if (userInfo == null) { 18048 Slog.w(TAG, "No user info for user #" + userId); 18049 return false; 18050 } 18051 if (foreground && userInfo.isManagedProfile()) { 18052 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18053 return false; 18054 } 18055 18056 if (foreground) { 18057 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18058 R.anim.screen_user_enter); 18059 } 18060 18061 boolean needStart = false; 18062 18063 // If the user we are switching to is not currently started, then 18064 // we need to start it now. 18065 if (mStartedUsers.get(userId) == null) { 18066 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18067 updateStartedUserArrayLocked(); 18068 needStart = true; 18069 } 18070 18071 final Integer userIdInt = Integer.valueOf(userId); 18072 mUserLru.remove(userIdInt); 18073 mUserLru.add(userIdInt); 18074 18075 if (foreground) { 18076 mCurrentUserId = userId; 18077 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18078 updateCurrentProfileIdsLocked(); 18079 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18080 // Once the internal notion of the active user has switched, we lock the device 18081 // with the option to show the user switcher on the keyguard. 18082 mWindowManager.lockNow(null); 18083 } else { 18084 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18085 updateCurrentProfileIdsLocked(); 18086 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18087 mUserLru.remove(currentUserIdInt); 18088 mUserLru.add(currentUserIdInt); 18089 } 18090 18091 final UserStartedState uss = mStartedUsers.get(userId); 18092 18093 // Make sure user is in the started state. If it is currently 18094 // stopping, we need to knock that off. 18095 if (uss.mState == UserStartedState.STATE_STOPPING) { 18096 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18097 // so we can just fairly silently bring the user back from 18098 // the almost-dead. 18099 uss.mState = UserStartedState.STATE_RUNNING; 18100 updateStartedUserArrayLocked(); 18101 needStart = true; 18102 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18103 // This means ACTION_SHUTDOWN has been sent, so we will 18104 // need to treat this as a new boot of the user. 18105 uss.mState = UserStartedState.STATE_BOOTING; 18106 updateStartedUserArrayLocked(); 18107 needStart = true; 18108 } 18109 18110 if (uss.mState == UserStartedState.STATE_BOOTING) { 18111 // Booting up a new user, need to tell system services about it. 18112 // Note that this is on the same handler as scheduling of broadcasts, 18113 // which is important because it needs to go first. 18114 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18115 } 18116 18117 if (foreground) { 18118 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18119 oldUserId)); 18120 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18121 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18122 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18123 oldUserId, userId, uss)); 18124 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18125 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18126 } 18127 18128 if (needStart) { 18129 // Send USER_STARTED broadcast 18130 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18131 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18132 | Intent.FLAG_RECEIVER_FOREGROUND); 18133 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18134 broadcastIntentLocked(null, null, intent, 18135 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18136 false, false, MY_PID, Process.SYSTEM_UID, userId); 18137 } 18138 18139 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18140 if (userId != UserHandle.USER_OWNER) { 18141 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18142 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18143 broadcastIntentLocked(null, null, intent, null, 18144 new IIntentReceiver.Stub() { 18145 public void performReceive(Intent intent, int resultCode, 18146 String data, Bundle extras, boolean ordered, 18147 boolean sticky, int sendingUser) { 18148 onUserInitialized(uss, foreground, oldUserId, userId); 18149 } 18150 }, 0, null, null, null, AppOpsManager.OP_NONE, 18151 true, false, MY_PID, Process.SYSTEM_UID, 18152 userId); 18153 uss.initializing = true; 18154 } else { 18155 getUserManagerLocked().makeInitialized(userInfo.id); 18156 } 18157 } 18158 18159 if (foreground) { 18160 if (!uss.initializing) { 18161 moveUserToForeground(uss, oldUserId, userId); 18162 } 18163 } else { 18164 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18165 } 18166 18167 if (needStart) { 18168 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18169 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18170 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18171 broadcastIntentLocked(null, null, intent, 18172 null, new IIntentReceiver.Stub() { 18173 @Override 18174 public void performReceive(Intent intent, int resultCode, String data, 18175 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18176 throws RemoteException { 18177 } 18178 }, 0, null, null, 18179 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18180 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18181 } 18182 } 18183 } finally { 18184 Binder.restoreCallingIdentity(ident); 18185 } 18186 18187 return true; 18188 } 18189 18190 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18191 long ident = Binder.clearCallingIdentity(); 18192 try { 18193 Intent intent; 18194 if (oldUserId >= 0) { 18195 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18196 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18197 int count = profiles.size(); 18198 for (int i = 0; i < count; i++) { 18199 int profileUserId = profiles.get(i).id; 18200 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18201 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18202 | Intent.FLAG_RECEIVER_FOREGROUND); 18203 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18204 broadcastIntentLocked(null, null, intent, 18205 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18206 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18207 } 18208 } 18209 if (newUserId >= 0) { 18210 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18211 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18212 int count = profiles.size(); 18213 for (int i = 0; i < count; i++) { 18214 int profileUserId = profiles.get(i).id; 18215 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18216 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18217 | Intent.FLAG_RECEIVER_FOREGROUND); 18218 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18219 broadcastIntentLocked(null, null, intent, 18220 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18221 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18222 } 18223 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18224 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18225 | Intent.FLAG_RECEIVER_FOREGROUND); 18226 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18227 broadcastIntentLocked(null, null, intent, 18228 null, null, 0, null, null, 18229 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18230 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18231 } 18232 } finally { 18233 Binder.restoreCallingIdentity(ident); 18234 } 18235 } 18236 18237 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18238 final int newUserId) { 18239 final int N = mUserSwitchObservers.beginBroadcast(); 18240 if (N > 0) { 18241 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18242 int mCount = 0; 18243 @Override 18244 public void sendResult(Bundle data) throws RemoteException { 18245 synchronized (ActivityManagerService.this) { 18246 if (mCurUserSwitchCallback == this) { 18247 mCount++; 18248 if (mCount == N) { 18249 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18250 } 18251 } 18252 } 18253 } 18254 }; 18255 synchronized (this) { 18256 uss.switching = true; 18257 mCurUserSwitchCallback = callback; 18258 } 18259 for (int i=0; i<N; i++) { 18260 try { 18261 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18262 newUserId, callback); 18263 } catch (RemoteException e) { 18264 } 18265 } 18266 } else { 18267 synchronized (this) { 18268 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18269 } 18270 } 18271 mUserSwitchObservers.finishBroadcast(); 18272 } 18273 18274 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18275 synchronized (this) { 18276 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18277 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18278 } 18279 } 18280 18281 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18282 mCurUserSwitchCallback = null; 18283 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18284 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18285 oldUserId, newUserId, uss)); 18286 } 18287 18288 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18289 synchronized (this) { 18290 if (foreground) { 18291 moveUserToForeground(uss, oldUserId, newUserId); 18292 } 18293 } 18294 18295 completeSwitchAndInitalize(uss, newUserId, true, false); 18296 } 18297 18298 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18299 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18300 if (homeInFront) { 18301 startHomeActivityLocked(newUserId); 18302 } else { 18303 mStackSupervisor.resumeTopActivitiesLocked(); 18304 } 18305 EventLogTags.writeAmSwitchUser(newUserId); 18306 getUserManagerLocked().userForeground(newUserId); 18307 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18308 } 18309 18310 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18311 completeSwitchAndInitalize(uss, newUserId, false, true); 18312 } 18313 18314 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18315 boolean clearInitializing, boolean clearSwitching) { 18316 boolean unfrozen = false; 18317 synchronized (this) { 18318 if (clearInitializing) { 18319 uss.initializing = false; 18320 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18321 } 18322 if (clearSwitching) { 18323 uss.switching = false; 18324 } 18325 if (!uss.switching && !uss.initializing) { 18326 mWindowManager.stopFreezingScreen(); 18327 unfrozen = true; 18328 } 18329 } 18330 if (unfrozen) { 18331 final int N = mUserSwitchObservers.beginBroadcast(); 18332 for (int i=0; i<N; i++) { 18333 try { 18334 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18335 } catch (RemoteException e) { 18336 } 18337 } 18338 mUserSwitchObservers.finishBroadcast(); 18339 } 18340 } 18341 18342 void scheduleStartProfilesLocked() { 18343 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18344 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18345 DateUtils.SECOND_IN_MILLIS); 18346 } 18347 } 18348 18349 void startProfilesLocked() { 18350 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18351 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18352 mCurrentUserId, false /* enabledOnly */); 18353 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18354 for (UserInfo user : profiles) { 18355 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18356 && user.id != mCurrentUserId) { 18357 toStart.add(user); 18358 } 18359 } 18360 final int n = toStart.size(); 18361 int i = 0; 18362 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18363 startUserInBackground(toStart.get(i).id); 18364 } 18365 if (i < n) { 18366 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18367 } 18368 } 18369 18370 void finishUserBoot(UserStartedState uss) { 18371 synchronized (this) { 18372 if (uss.mState == UserStartedState.STATE_BOOTING 18373 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18374 uss.mState = UserStartedState.STATE_RUNNING; 18375 final int userId = uss.mHandle.getIdentifier(); 18376 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18377 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18378 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18379 broadcastIntentLocked(null, null, intent, 18380 null, null, 0, null, null, 18381 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18382 true, false, MY_PID, Process.SYSTEM_UID, userId); 18383 } 18384 } 18385 } 18386 18387 void finishUserSwitch(UserStartedState uss) { 18388 synchronized (this) { 18389 finishUserBoot(uss); 18390 18391 startProfilesLocked(); 18392 18393 int num = mUserLru.size(); 18394 int i = 0; 18395 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18396 Integer oldUserId = mUserLru.get(i); 18397 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18398 if (oldUss == null) { 18399 // Shouldn't happen, but be sane if it does. 18400 mUserLru.remove(i); 18401 num--; 18402 continue; 18403 } 18404 if (oldUss.mState == UserStartedState.STATE_STOPPING 18405 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18406 // This user is already stopping, doesn't count. 18407 num--; 18408 i++; 18409 continue; 18410 } 18411 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18412 // Owner and current can't be stopped, but count as running. 18413 i++; 18414 continue; 18415 } 18416 // This is a user to be stopped. 18417 stopUserLocked(oldUserId, null); 18418 num--; 18419 i++; 18420 } 18421 } 18422 } 18423 18424 @Override 18425 public int stopUser(final int userId, final IStopUserCallback callback) { 18426 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18427 != PackageManager.PERMISSION_GRANTED) { 18428 String msg = "Permission Denial: switchUser() from pid=" 18429 + Binder.getCallingPid() 18430 + ", uid=" + Binder.getCallingUid() 18431 + " requires " + INTERACT_ACROSS_USERS_FULL; 18432 Slog.w(TAG, msg); 18433 throw new SecurityException(msg); 18434 } 18435 if (userId <= 0) { 18436 throw new IllegalArgumentException("Can't stop primary user " + userId); 18437 } 18438 synchronized (this) { 18439 return stopUserLocked(userId, callback); 18440 } 18441 } 18442 18443 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18444 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18445 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18446 return ActivityManager.USER_OP_IS_CURRENT; 18447 } 18448 18449 final UserStartedState uss = mStartedUsers.get(userId); 18450 if (uss == null) { 18451 // User is not started, nothing to do... but we do need to 18452 // callback if requested. 18453 if (callback != null) { 18454 mHandler.post(new Runnable() { 18455 @Override 18456 public void run() { 18457 try { 18458 callback.userStopped(userId); 18459 } catch (RemoteException e) { 18460 } 18461 } 18462 }); 18463 } 18464 return ActivityManager.USER_OP_SUCCESS; 18465 } 18466 18467 if (callback != null) { 18468 uss.mStopCallbacks.add(callback); 18469 } 18470 18471 if (uss.mState != UserStartedState.STATE_STOPPING 18472 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18473 uss.mState = UserStartedState.STATE_STOPPING; 18474 updateStartedUserArrayLocked(); 18475 18476 long ident = Binder.clearCallingIdentity(); 18477 try { 18478 // We are going to broadcast ACTION_USER_STOPPING and then 18479 // once that is done send a final ACTION_SHUTDOWN and then 18480 // stop the user. 18481 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18482 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18483 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18484 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18485 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18486 // This is the result receiver for the final shutdown broadcast. 18487 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18488 @Override 18489 public void performReceive(Intent intent, int resultCode, String data, 18490 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18491 finishUserStop(uss); 18492 } 18493 }; 18494 // This is the result receiver for the initial stopping broadcast. 18495 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18496 @Override 18497 public void performReceive(Intent intent, int resultCode, String data, 18498 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18499 // On to the next. 18500 synchronized (ActivityManagerService.this) { 18501 if (uss.mState != UserStartedState.STATE_STOPPING) { 18502 // Whoops, we are being started back up. Abort, abort! 18503 return; 18504 } 18505 uss.mState = UserStartedState.STATE_SHUTDOWN; 18506 } 18507 mBatteryStatsService.noteEvent( 18508 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18509 Integer.toString(userId), userId); 18510 mSystemServiceManager.stopUser(userId); 18511 broadcastIntentLocked(null, null, shutdownIntent, 18512 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18513 true, false, MY_PID, Process.SYSTEM_UID, userId); 18514 } 18515 }; 18516 // Kick things off. 18517 broadcastIntentLocked(null, null, stoppingIntent, 18518 null, stoppingReceiver, 0, null, null, 18519 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18520 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18521 } finally { 18522 Binder.restoreCallingIdentity(ident); 18523 } 18524 } 18525 18526 return ActivityManager.USER_OP_SUCCESS; 18527 } 18528 18529 void finishUserStop(UserStartedState uss) { 18530 final int userId = uss.mHandle.getIdentifier(); 18531 boolean stopped; 18532 ArrayList<IStopUserCallback> callbacks; 18533 synchronized (this) { 18534 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18535 if (mStartedUsers.get(userId) != uss) { 18536 stopped = false; 18537 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18538 stopped = false; 18539 } else { 18540 stopped = true; 18541 // User can no longer run. 18542 mStartedUsers.remove(userId); 18543 mUserLru.remove(Integer.valueOf(userId)); 18544 updateStartedUserArrayLocked(); 18545 18546 // Clean up all state and processes associated with the user. 18547 // Kill all the processes for the user. 18548 forceStopUserLocked(userId, "finish user"); 18549 } 18550 18551 // Explicitly remove the old information in mRecentTasks. 18552 removeRecentTasksForUserLocked(userId); 18553 } 18554 18555 for (int i=0; i<callbacks.size(); i++) { 18556 try { 18557 if (stopped) callbacks.get(i).userStopped(userId); 18558 else callbacks.get(i).userStopAborted(userId); 18559 } catch (RemoteException e) { 18560 } 18561 } 18562 18563 if (stopped) { 18564 mSystemServiceManager.cleanupUser(userId); 18565 synchronized (this) { 18566 mStackSupervisor.removeUserLocked(userId); 18567 } 18568 } 18569 } 18570 18571 @Override 18572 public UserInfo getCurrentUser() { 18573 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18574 != PackageManager.PERMISSION_GRANTED) && ( 18575 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18576 != PackageManager.PERMISSION_GRANTED)) { 18577 String msg = "Permission Denial: getCurrentUser() from pid=" 18578 + Binder.getCallingPid() 18579 + ", uid=" + Binder.getCallingUid() 18580 + " requires " + INTERACT_ACROSS_USERS; 18581 Slog.w(TAG, msg); 18582 throw new SecurityException(msg); 18583 } 18584 synchronized (this) { 18585 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18586 return getUserManagerLocked().getUserInfo(userId); 18587 } 18588 } 18589 18590 int getCurrentUserIdLocked() { 18591 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18592 } 18593 18594 @Override 18595 public boolean isUserRunning(int userId, boolean orStopped) { 18596 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18597 != PackageManager.PERMISSION_GRANTED) { 18598 String msg = "Permission Denial: isUserRunning() from pid=" 18599 + Binder.getCallingPid() 18600 + ", uid=" + Binder.getCallingUid() 18601 + " requires " + INTERACT_ACROSS_USERS; 18602 Slog.w(TAG, msg); 18603 throw new SecurityException(msg); 18604 } 18605 synchronized (this) { 18606 return isUserRunningLocked(userId, orStopped); 18607 } 18608 } 18609 18610 boolean isUserRunningLocked(int userId, boolean orStopped) { 18611 UserStartedState state = mStartedUsers.get(userId); 18612 if (state == null) { 18613 return false; 18614 } 18615 if (orStopped) { 18616 return true; 18617 } 18618 return state.mState != UserStartedState.STATE_STOPPING 18619 && state.mState != UserStartedState.STATE_SHUTDOWN; 18620 } 18621 18622 @Override 18623 public int[] getRunningUserIds() { 18624 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18625 != PackageManager.PERMISSION_GRANTED) { 18626 String msg = "Permission Denial: isUserRunning() from pid=" 18627 + Binder.getCallingPid() 18628 + ", uid=" + Binder.getCallingUid() 18629 + " requires " + INTERACT_ACROSS_USERS; 18630 Slog.w(TAG, msg); 18631 throw new SecurityException(msg); 18632 } 18633 synchronized (this) { 18634 return mStartedUserArray; 18635 } 18636 } 18637 18638 private void updateStartedUserArrayLocked() { 18639 int num = 0; 18640 for (int i=0; i<mStartedUsers.size(); i++) { 18641 UserStartedState uss = mStartedUsers.valueAt(i); 18642 // This list does not include stopping users. 18643 if (uss.mState != UserStartedState.STATE_STOPPING 18644 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18645 num++; 18646 } 18647 } 18648 mStartedUserArray = new int[num]; 18649 num = 0; 18650 for (int i=0; i<mStartedUsers.size(); i++) { 18651 UserStartedState uss = mStartedUsers.valueAt(i); 18652 if (uss.mState != UserStartedState.STATE_STOPPING 18653 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18654 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18655 num++; 18656 } 18657 } 18658 } 18659 18660 @Override 18661 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18662 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18663 != PackageManager.PERMISSION_GRANTED) { 18664 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18665 + Binder.getCallingPid() 18666 + ", uid=" + Binder.getCallingUid() 18667 + " requires " + INTERACT_ACROSS_USERS_FULL; 18668 Slog.w(TAG, msg); 18669 throw new SecurityException(msg); 18670 } 18671 18672 mUserSwitchObservers.register(observer); 18673 } 18674 18675 @Override 18676 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18677 mUserSwitchObservers.unregister(observer); 18678 } 18679 18680 private boolean userExists(int userId) { 18681 if (userId == 0) { 18682 return true; 18683 } 18684 UserManagerService ums = getUserManagerLocked(); 18685 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18686 } 18687 18688 int[] getUsersLocked() { 18689 UserManagerService ums = getUserManagerLocked(); 18690 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18691 } 18692 18693 UserManagerService getUserManagerLocked() { 18694 if (mUserManager == null) { 18695 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18696 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18697 } 18698 return mUserManager; 18699 } 18700 18701 private int applyUserId(int uid, int userId) { 18702 return UserHandle.getUid(userId, uid); 18703 } 18704 18705 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18706 if (info == null) return null; 18707 ApplicationInfo newInfo = new ApplicationInfo(info); 18708 newInfo.uid = applyUserId(info.uid, userId); 18709 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18710 + info.packageName; 18711 return newInfo; 18712 } 18713 18714 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18715 if (aInfo == null 18716 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18717 return aInfo; 18718 } 18719 18720 ActivityInfo info = new ActivityInfo(aInfo); 18721 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18722 return info; 18723 } 18724 18725 private final class LocalService extends ActivityManagerInternal { 18726 @Override 18727 public void goingToSleep() { 18728 ActivityManagerService.this.goingToSleep(); 18729 } 18730 18731 @Override 18732 public void wakingUp() { 18733 ActivityManagerService.this.wakingUp(); 18734 } 18735 18736 @Override 18737 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18738 String processName, String abiOverride, int uid, Runnable crashHandler) { 18739 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18740 processName, abiOverride, uid, crashHandler); 18741 } 18742 } 18743 18744 /** 18745 * An implementation of IAppTask, that allows an app to manage its own tasks via 18746 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18747 * only the process that calls getAppTasks() can call the AppTask methods. 18748 */ 18749 class AppTaskImpl extends IAppTask.Stub { 18750 private int mTaskId; 18751 private int mCallingUid; 18752 18753 public AppTaskImpl(int taskId, int callingUid) { 18754 mTaskId = taskId; 18755 mCallingUid = callingUid; 18756 } 18757 18758 private void checkCaller() { 18759 if (mCallingUid != Binder.getCallingUid()) { 18760 throw new SecurityException("Caller " + mCallingUid 18761 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18762 } 18763 } 18764 18765 @Override 18766 public void finishAndRemoveTask() { 18767 checkCaller(); 18768 18769 synchronized (ActivityManagerService.this) { 18770 long origId = Binder.clearCallingIdentity(); 18771 try { 18772 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18773 if (tr == null) { 18774 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18775 } 18776 // Only kill the process if we are not a new document 18777 int flags = tr.getBaseIntent().getFlags(); 18778 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18779 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18780 removeTaskByIdLocked(mTaskId, 18781 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18782 } finally { 18783 Binder.restoreCallingIdentity(origId); 18784 } 18785 } 18786 } 18787 18788 @Override 18789 public ActivityManager.RecentTaskInfo getTaskInfo() { 18790 checkCaller(); 18791 18792 synchronized (ActivityManagerService.this) { 18793 long origId = Binder.clearCallingIdentity(); 18794 try { 18795 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18796 if (tr == null) { 18797 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18798 } 18799 return createRecentTaskInfoFromTaskRecord(tr); 18800 } finally { 18801 Binder.restoreCallingIdentity(origId); 18802 } 18803 } 18804 } 18805 18806 @Override 18807 public void moveToFront() { 18808 checkCaller(); 18809 18810 final TaskRecord tr; 18811 synchronized (ActivityManagerService.this) { 18812 tr = recentTaskForIdLocked(mTaskId); 18813 if (tr == null) { 18814 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18815 } 18816 if (tr.getRootActivity() != null) { 18817 long origId = Binder.clearCallingIdentity(); 18818 try { 18819 moveTaskToFrontLocked(tr.taskId, 0, null); 18820 return; 18821 } finally { 18822 Binder.restoreCallingIdentity(origId); 18823 } 18824 } 18825 } 18826 18827 startActivityFromRecentsInner(tr.taskId, null); 18828 } 18829 18830 @Override 18831 public int startActivity(IBinder whoThread, String callingPackage, 18832 Intent intent, String resolvedType, Bundle options) { 18833 checkCaller(); 18834 18835 int callingUser = UserHandle.getCallingUserId(); 18836 TaskRecord tr; 18837 IApplicationThread appThread; 18838 synchronized (ActivityManagerService.this) { 18839 tr = recentTaskForIdLocked(mTaskId); 18840 if (tr == null) { 18841 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18842 } 18843 appThread = ApplicationThreadNative.asInterface(whoThread); 18844 if (appThread == null) { 18845 throw new IllegalArgumentException("Bad app thread " + appThread); 18846 } 18847 } 18848 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18849 resolvedType, null, null, null, null, 0, 0, null, null, 18850 null, options, callingUser, null, tr); 18851 } 18852 18853 @Override 18854 public void setExcludeFromRecents(boolean exclude) { 18855 checkCaller(); 18856 18857 synchronized (ActivityManagerService.this) { 18858 long origId = Binder.clearCallingIdentity(); 18859 try { 18860 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18861 if (tr == null) { 18862 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18863 } 18864 Intent intent = tr.getBaseIntent(); 18865 if (exclude) { 18866 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18867 } else { 18868 intent.setFlags(intent.getFlags() 18869 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18870 } 18871 } finally { 18872 Binder.restoreCallingIdentity(origId); 18873 } 18874 } 18875 } 18876 } 18877} 18878