ActivityManagerService.java revision 8cd28b57ed732656d002d97879e15c5695b54fff
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mWaitingUpdate = false; 893 boolean mDidUpdate = false; 894 boolean mOnBattery = false; 895 boolean mLaunchWarningShown = false; 896 897 Context mContext; 898 899 int mFactoryTest; 900 901 boolean mCheckedForSetup; 902 903 /** 904 * The time at which we will allow normal application switches again, 905 * after a call to {@link #stopAppSwitches()}. 906 */ 907 long mAppSwitchesAllowedTime; 908 909 /** 910 * This is set to true after the first switch after mAppSwitchesAllowedTime 911 * is set; any switches after that will clear the time. 912 */ 913 boolean mDidAppSwitch; 914 915 /** 916 * Last time (in realtime) at which we checked for power usage. 917 */ 918 long mLastPowerCheckRealtime; 919 920 /** 921 * Last time (in uptime) at which we checked for power usage. 922 */ 923 long mLastPowerCheckUptime; 924 925 /** 926 * Set while we are wanting to sleep, to prevent any 927 * activities from being started/resumed. 928 */ 929 private boolean mSleeping = false; 930 931 /** 932 * Set while we are running a voice interaction. This overrides 933 * sleeping while it is active. 934 */ 935 private boolean mRunningVoice = false; 936 937 /** 938 * State of external calls telling us if the device is asleep. 939 */ 940 private boolean mWentToSleep = false; 941 942 /** 943 * State of external call telling us if the lock screen is shown. 944 */ 945 private boolean mLockScreenShown = false; 946 947 /** 948 * Set if we are shutting down the system, similar to sleeping. 949 */ 950 boolean mShuttingDown = false; 951 952 /** 953 * Current sequence id for oom_adj computation traversal. 954 */ 955 int mAdjSeq = 0; 956 957 /** 958 * Current sequence id for process LRU updating. 959 */ 960 int mLruSeq = 0; 961 962 /** 963 * Keep track of the non-cached/empty process we last found, to help 964 * determine how to distribute cached/empty processes next time. 965 */ 966 int mNumNonCachedProcs = 0; 967 968 /** 969 * Keep track of the number of cached hidden procs, to balance oom adj 970 * distribution between those and empty procs. 971 */ 972 int mNumCachedHiddenProcs = 0; 973 974 /** 975 * Keep track of the number of service processes we last found, to 976 * determine on the next iteration which should be B services. 977 */ 978 int mNumServiceProcs = 0; 979 int mNewNumAServiceProcs = 0; 980 int mNewNumServiceProcs = 0; 981 982 /** 983 * Allow the current computed overall memory level of the system to go down? 984 * This is set to false when we are killing processes for reasons other than 985 * memory management, so that the now smaller process list will not be taken as 986 * an indication that memory is tighter. 987 */ 988 boolean mAllowLowerMemLevel = false; 989 990 /** 991 * The last computed memory level, for holding when we are in a state that 992 * processes are going away for other reasons. 993 */ 994 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 995 996 /** 997 * The last total number of process we have, to determine if changes actually look 998 * like a shrinking number of process due to lower RAM. 999 */ 1000 int mLastNumProcesses; 1001 1002 /** 1003 * The uptime of the last time we performed idle maintenance. 1004 */ 1005 long mLastIdleTime = SystemClock.uptimeMillis(); 1006 1007 /** 1008 * Total time spent with RAM that has been added in the past since the last idle time. 1009 */ 1010 long mLowRamTimeSinceLastIdle = 0; 1011 1012 /** 1013 * If RAM is currently low, when that horrible situation started. 1014 */ 1015 long mLowRamStartTime = 0; 1016 1017 /** 1018 * For reporting to battery stats the current top application. 1019 */ 1020 private String mCurResumedPackage = null; 1021 private int mCurResumedUid = -1; 1022 1023 /** 1024 * For reporting to battery stats the apps currently running foreground 1025 * service. The ProcessMap is package/uid tuples; each of these contain 1026 * an array of the currently foreground processes. 1027 */ 1028 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1029 = new ProcessMap<ArrayList<ProcessRecord>>(); 1030 1031 /** 1032 * This is set if we had to do a delayed dexopt of an app before launching 1033 * it, to increase the ANR timeouts in that case. 1034 */ 1035 boolean mDidDexOpt; 1036 1037 /** 1038 * Set if the systemServer made a call to enterSafeMode. 1039 */ 1040 boolean mSafeMode; 1041 1042 String mDebugApp = null; 1043 boolean mWaitForDebugger = false; 1044 boolean mDebugTransient = false; 1045 String mOrigDebugApp = null; 1046 boolean mOrigWaitForDebugger = false; 1047 boolean mAlwaysFinishActivities = false; 1048 IActivityController mController = null; 1049 String mProfileApp = null; 1050 ProcessRecord mProfileProc = null; 1051 String mProfileFile; 1052 ParcelFileDescriptor mProfileFd; 1053 int mSamplingInterval = 0; 1054 boolean mAutoStopProfiler = false; 1055 int mProfileType = 0; 1056 String mOpenGlTraceApp = null; 1057 1058 static class ProcessChangeItem { 1059 static final int CHANGE_ACTIVITIES = 1<<0; 1060 static final int CHANGE_PROCESS_STATE = 1<<1; 1061 int changes; 1062 int uid; 1063 int pid; 1064 int processState; 1065 boolean foregroundActivities; 1066 } 1067 1068 final RemoteCallbackList<IProcessObserver> mProcessObservers 1069 = new RemoteCallbackList<IProcessObserver>(); 1070 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1071 1072 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1075 = new ArrayList<ProcessChangeItem>(); 1076 1077 /** 1078 * Runtime CPU use collection thread. This object's lock is used to 1079 * protect all related state. 1080 */ 1081 final Thread mProcessCpuThread; 1082 1083 /** 1084 * Used to collect process stats when showing not responding dialog. 1085 * Protected by mProcessCpuThread. 1086 */ 1087 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1088 MONITOR_THREAD_CPU_USAGE); 1089 final AtomicLong mLastCpuTime = new AtomicLong(0); 1090 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1091 1092 long mLastWriteTime = 0; 1093 1094 /** 1095 * Used to retain an update lock when the foreground activity is in 1096 * immersive mode. 1097 */ 1098 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1099 1100 /** 1101 * Set to true after the system has finished booting. 1102 */ 1103 boolean mBooted = false; 1104 1105 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1106 int mProcessLimitOverride = -1; 1107 1108 WindowManagerService mWindowManager; 1109 1110 final ActivityThread mSystemThread; 1111 1112 // Holds the current foreground user's id 1113 int mCurrentUserId = 0; 1114 // Holds the target user's id during a user switch 1115 int mTargetUserId = UserHandle.USER_NULL; 1116 // If there are multiple profiles for the current user, their ids are here 1117 // Currently only the primary user can have managed profiles 1118 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1119 1120 /** 1121 * Mapping from each known user ID to the profile group ID it is associated with. 1122 */ 1123 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1124 1125 private UserManagerService mUserManager; 1126 1127 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1128 final ProcessRecord mApp; 1129 final int mPid; 1130 final IApplicationThread mAppThread; 1131 1132 AppDeathRecipient(ProcessRecord app, int pid, 1133 IApplicationThread thread) { 1134 if (localLOGV) Slog.v( 1135 TAG, "New death recipient " + this 1136 + " for thread " + thread.asBinder()); 1137 mApp = app; 1138 mPid = pid; 1139 mAppThread = thread; 1140 } 1141 1142 @Override 1143 public void binderDied() { 1144 if (localLOGV) Slog.v( 1145 TAG, "Death received in " + this 1146 + " for thread " + mAppThread.asBinder()); 1147 synchronized(ActivityManagerService.this) { 1148 appDiedLocked(mApp, mPid, mAppThread); 1149 } 1150 } 1151 } 1152 1153 static final int SHOW_ERROR_MSG = 1; 1154 static final int SHOW_NOT_RESPONDING_MSG = 2; 1155 static final int SHOW_FACTORY_ERROR_MSG = 3; 1156 static final int UPDATE_CONFIGURATION_MSG = 4; 1157 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1158 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1159 static final int SERVICE_TIMEOUT_MSG = 12; 1160 static final int UPDATE_TIME_ZONE = 13; 1161 static final int SHOW_UID_ERROR_MSG = 14; 1162 static final int IM_FEELING_LUCKY_MSG = 15; 1163 static final int PROC_START_TIMEOUT_MSG = 20; 1164 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1165 static final int KILL_APPLICATION_MSG = 22; 1166 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1167 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1168 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1169 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1170 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1171 static final int CLEAR_DNS_CACHE_MSG = 28; 1172 static final int UPDATE_HTTP_PROXY_MSG = 29; 1173 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1174 static final int DISPATCH_PROCESSES_CHANGED = 31; 1175 static final int DISPATCH_PROCESS_DIED = 32; 1176 static final int REPORT_MEM_USAGE_MSG = 33; 1177 static final int REPORT_USER_SWITCH_MSG = 34; 1178 static final int CONTINUE_USER_SWITCH_MSG = 35; 1179 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1180 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1181 static final int PERSIST_URI_GRANTS_MSG = 38; 1182 static final int REQUEST_ALL_PSS_MSG = 39; 1183 static final int START_PROFILES_MSG = 40; 1184 static final int UPDATE_TIME = 41; 1185 static final int SYSTEM_USER_START_MSG = 42; 1186 static final int SYSTEM_USER_CURRENT_MSG = 43; 1187 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1188 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1189 static final int START_USER_SWITCH_MSG = 46; 1190 1191 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1192 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1193 static final int FIRST_COMPAT_MODE_MSG = 300; 1194 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1195 1196 AlertDialog mUidAlert; 1197 CompatModeDialog mCompatModeDialog; 1198 long mLastMemUsageReportTime = 0; 1199 1200 private LockToAppRequestDialog mLockToAppRequest; 1201 1202 /** 1203 * Flag whether the current user is a "monkey", i.e. whether 1204 * the UI is driven by a UI automation tool. 1205 */ 1206 private boolean mUserIsMonkey; 1207 1208 /** Flag whether the device has a Recents UI */ 1209 boolean mHasRecents; 1210 1211 /** The dimensions of the thumbnails in the Recents UI. */ 1212 int mThumbnailWidth; 1213 int mThumbnailHeight; 1214 1215 final ServiceThread mHandlerThread; 1216 final MainHandler mHandler; 1217 1218 final class MainHandler extends Handler { 1219 public MainHandler(Looper looper) { 1220 super(looper, null, true); 1221 } 1222 1223 @Override 1224 public void handleMessage(Message msg) { 1225 switch (msg.what) { 1226 case SHOW_ERROR_MSG: { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1229 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1230 synchronized (ActivityManagerService.this) { 1231 ProcessRecord proc = (ProcessRecord)data.get("app"); 1232 AppErrorResult res = (AppErrorResult) data.get("result"); 1233 if (proc != null && proc.crashDialog != null) { 1234 Slog.e(TAG, "App already has crash dialog: " + proc); 1235 if (res != null) { 1236 res.set(0); 1237 } 1238 return; 1239 } 1240 boolean isBackground = (UserHandle.getAppId(proc.uid) 1241 >= Process.FIRST_APPLICATION_UID 1242 && proc.pid != MY_PID); 1243 for (int userId : mCurrentProfileIds) { 1244 isBackground &= (proc.userId != userId); 1245 } 1246 if (isBackground && !showBackground) { 1247 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1248 if (res != null) { 1249 res.set(0); 1250 } 1251 return; 1252 } 1253 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1254 Dialog d = new AppErrorDialog(mContext, 1255 ActivityManagerService.this, res, proc); 1256 d.show(); 1257 proc.crashDialog = d; 1258 } else { 1259 // The device is asleep, so just pretend that the user 1260 // saw a crash dialog and hit "force quit". 1261 if (res != null) { 1262 res.set(0); 1263 } 1264 } 1265 } 1266 1267 ensureBootCompleted(); 1268 } break; 1269 case SHOW_NOT_RESPONDING_MSG: { 1270 synchronized (ActivityManagerService.this) { 1271 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1272 ProcessRecord proc = (ProcessRecord)data.get("app"); 1273 if (proc != null && proc.anrDialog != null) { 1274 Slog.e(TAG, "App already has anr dialog: " + proc); 1275 return; 1276 } 1277 1278 Intent intent = new Intent("android.intent.action.ANR"); 1279 if (!mProcessesReady) { 1280 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1281 | Intent.FLAG_RECEIVER_FOREGROUND); 1282 } 1283 broadcastIntentLocked(null, null, intent, 1284 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1285 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1286 1287 if (mShowDialogs) { 1288 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1289 mContext, proc, (ActivityRecord)data.get("activity"), 1290 msg.arg1 != 0); 1291 d.show(); 1292 proc.anrDialog = d; 1293 } else { 1294 // Just kill the app if there is no dialog to be shown. 1295 killAppAtUsersRequest(proc, null); 1296 } 1297 } 1298 1299 ensureBootCompleted(); 1300 } break; 1301 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1302 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1303 synchronized (ActivityManagerService.this) { 1304 ProcessRecord proc = (ProcessRecord) data.get("app"); 1305 if (proc == null) { 1306 Slog.e(TAG, "App not found when showing strict mode dialog."); 1307 break; 1308 } 1309 if (proc.crashDialog != null) { 1310 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1311 return; 1312 } 1313 AppErrorResult res = (AppErrorResult) data.get("result"); 1314 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1315 Dialog d = new StrictModeViolationDialog(mContext, 1316 ActivityManagerService.this, res, proc); 1317 d.show(); 1318 proc.crashDialog = d; 1319 } else { 1320 // The device is asleep, so just pretend that the user 1321 // saw a crash dialog and hit "force quit". 1322 res.set(0); 1323 } 1324 } 1325 ensureBootCompleted(); 1326 } break; 1327 case SHOW_FACTORY_ERROR_MSG: { 1328 Dialog d = new FactoryErrorDialog( 1329 mContext, msg.getData().getCharSequence("msg")); 1330 d.show(); 1331 ensureBootCompleted(); 1332 } break; 1333 case UPDATE_CONFIGURATION_MSG: { 1334 final ContentResolver resolver = mContext.getContentResolver(); 1335 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1336 } break; 1337 case GC_BACKGROUND_PROCESSES_MSG: { 1338 synchronized (ActivityManagerService.this) { 1339 performAppGcsIfAppropriateLocked(); 1340 } 1341 } break; 1342 case WAIT_FOR_DEBUGGER_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 ProcessRecord app = (ProcessRecord)msg.obj; 1345 if (msg.arg1 != 0) { 1346 if (!app.waitedForDebugger) { 1347 Dialog d = new AppWaitingForDebuggerDialog( 1348 ActivityManagerService.this, 1349 mContext, app); 1350 app.waitDialog = d; 1351 app.waitedForDebugger = true; 1352 d.show(); 1353 } 1354 } else { 1355 if (app.waitDialog != null) { 1356 app.waitDialog.dismiss(); 1357 app.waitDialog = null; 1358 } 1359 } 1360 } 1361 } break; 1362 case SERVICE_TIMEOUT_MSG: { 1363 if (mDidDexOpt) { 1364 mDidDexOpt = false; 1365 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1366 nmsg.obj = msg.obj; 1367 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1368 return; 1369 } 1370 mServices.serviceTimeout((ProcessRecord)msg.obj); 1371 } break; 1372 case UPDATE_TIME_ZONE: { 1373 synchronized (ActivityManagerService.this) { 1374 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1375 ProcessRecord r = mLruProcesses.get(i); 1376 if (r.thread != null) { 1377 try { 1378 r.thread.updateTimeZone(); 1379 } catch (RemoteException ex) { 1380 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1381 } 1382 } 1383 } 1384 } 1385 } break; 1386 case CLEAR_DNS_CACHE_MSG: { 1387 synchronized (ActivityManagerService.this) { 1388 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1389 ProcessRecord r = mLruProcesses.get(i); 1390 if (r.thread != null) { 1391 try { 1392 r.thread.clearDnsCache(); 1393 } catch (RemoteException ex) { 1394 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1395 } 1396 } 1397 } 1398 } 1399 } break; 1400 case UPDATE_HTTP_PROXY_MSG: { 1401 ProxyInfo proxy = (ProxyInfo)msg.obj; 1402 String host = ""; 1403 String port = ""; 1404 String exclList = ""; 1405 Uri pacFileUrl = Uri.EMPTY; 1406 if (proxy != null) { 1407 host = proxy.getHost(); 1408 port = Integer.toString(proxy.getPort()); 1409 exclList = proxy.getExclusionListAsString(); 1410 pacFileUrl = proxy.getPacFileUrl(); 1411 } 1412 synchronized (ActivityManagerService.this) { 1413 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1414 ProcessRecord r = mLruProcesses.get(i); 1415 if (r.thread != null) { 1416 try { 1417 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1418 } catch (RemoteException ex) { 1419 Slog.w(TAG, "Failed to update http proxy for: " + 1420 r.info.processName); 1421 } 1422 } 1423 } 1424 } 1425 } break; 1426 case SHOW_UID_ERROR_MSG: { 1427 String title = "System UIDs Inconsistent"; 1428 String text = "UIDs on the system are inconsistent, you need to wipe your" 1429 + " data partition or your device will be unstable."; 1430 Log.e(TAG, title + ": " + text); 1431 if (mShowDialogs) { 1432 // XXX This is a temporary dialog, no need to localize. 1433 AlertDialog d = new BaseErrorDialog(mContext); 1434 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1435 d.setCancelable(false); 1436 d.setTitle(title); 1437 d.setMessage(text); 1438 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1439 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1440 mUidAlert = d; 1441 d.show(); 1442 } 1443 } break; 1444 case IM_FEELING_LUCKY_MSG: { 1445 if (mUidAlert != null) { 1446 mUidAlert.dismiss(); 1447 mUidAlert = null; 1448 } 1449 } break; 1450 case PROC_START_TIMEOUT_MSG: { 1451 if (mDidDexOpt) { 1452 mDidDexOpt = false; 1453 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1454 nmsg.obj = msg.obj; 1455 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1456 return; 1457 } 1458 ProcessRecord app = (ProcessRecord)msg.obj; 1459 synchronized (ActivityManagerService.this) { 1460 processStartTimedOutLocked(app); 1461 } 1462 } break; 1463 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1464 synchronized (ActivityManagerService.this) { 1465 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1466 } 1467 } break; 1468 case KILL_APPLICATION_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 int appid = msg.arg1; 1471 boolean restart = (msg.arg2 == 1); 1472 Bundle bundle = (Bundle)msg.obj; 1473 String pkg = bundle.getString("pkg"); 1474 String reason = bundle.getString("reason"); 1475 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1476 false, UserHandle.USER_ALL, reason); 1477 } 1478 } break; 1479 case FINALIZE_PENDING_INTENT_MSG: { 1480 ((PendingIntentRecord)msg.obj).completeFinalize(); 1481 } break; 1482 case POST_HEAVY_NOTIFICATION_MSG: { 1483 INotificationManager inm = NotificationManager.getService(); 1484 if (inm == null) { 1485 return; 1486 } 1487 1488 ActivityRecord root = (ActivityRecord)msg.obj; 1489 ProcessRecord process = root.app; 1490 if (process == null) { 1491 return; 1492 } 1493 1494 try { 1495 Context context = mContext.createPackageContext(process.info.packageName, 0); 1496 String text = mContext.getString(R.string.heavy_weight_notification, 1497 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1498 Notification notification = new Notification(); 1499 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1500 notification.when = 0; 1501 notification.flags = Notification.FLAG_ONGOING_EVENT; 1502 notification.tickerText = text; 1503 notification.defaults = 0; // please be quiet 1504 notification.sound = null; 1505 notification.vibrate = null; 1506 notification.color = mContext.getResources().getColor( 1507 com.android.internal.R.color.system_notification_accent_color); 1508 notification.setLatestEventInfo(context, text, 1509 mContext.getText(R.string.heavy_weight_notification_detail), 1510 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1511 PendingIntent.FLAG_CANCEL_CURRENT, null, 1512 new UserHandle(root.userId))); 1513 1514 try { 1515 int[] outId = new int[1]; 1516 inm.enqueueNotificationWithTag("android", "android", null, 1517 R.string.heavy_weight_notification, 1518 notification, outId, root.userId); 1519 } catch (RuntimeException e) { 1520 Slog.w(ActivityManagerService.TAG, 1521 "Error showing notification for heavy-weight app", e); 1522 } catch (RemoteException e) { 1523 } 1524 } catch (NameNotFoundException e) { 1525 Slog.w(TAG, "Unable to create context for heavy notification", e); 1526 } 1527 } break; 1528 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1529 INotificationManager inm = NotificationManager.getService(); 1530 if (inm == null) { 1531 return; 1532 } 1533 try { 1534 inm.cancelNotificationWithTag("android", null, 1535 R.string.heavy_weight_notification, msg.arg1); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error canceling notification for service", e); 1539 } catch (RemoteException e) { 1540 } 1541 } break; 1542 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1543 synchronized (ActivityManagerService.this) { 1544 checkExcessivePowerUsageLocked(true); 1545 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1546 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1547 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1548 } 1549 } break; 1550 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1551 synchronized (ActivityManagerService.this) { 1552 ActivityRecord ar = (ActivityRecord)msg.obj; 1553 if (mCompatModeDialog != null) { 1554 if (mCompatModeDialog.mAppInfo.packageName.equals( 1555 ar.info.applicationInfo.packageName)) { 1556 return; 1557 } 1558 mCompatModeDialog.dismiss(); 1559 mCompatModeDialog = null; 1560 } 1561 if (ar != null && false) { 1562 if (mCompatModePackages.getPackageAskCompatModeLocked( 1563 ar.packageName)) { 1564 int mode = mCompatModePackages.computeCompatModeLocked( 1565 ar.info.applicationInfo); 1566 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1567 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1568 mCompatModeDialog = new CompatModeDialog( 1569 ActivityManagerService.this, mContext, 1570 ar.info.applicationInfo); 1571 mCompatModeDialog.show(); 1572 } 1573 } 1574 } 1575 } 1576 break; 1577 } 1578 case DISPATCH_PROCESSES_CHANGED: { 1579 dispatchProcessesChanged(); 1580 break; 1581 } 1582 case DISPATCH_PROCESS_DIED: { 1583 final int pid = msg.arg1; 1584 final int uid = msg.arg2; 1585 dispatchProcessDied(pid, uid); 1586 break; 1587 } 1588 case REPORT_MEM_USAGE_MSG: { 1589 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1590 Thread thread = new Thread() { 1591 @Override public void run() { 1592 final SparseArray<ProcessMemInfo> infoMap 1593 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1594 for (int i=0, N=memInfos.size(); i<N; i++) { 1595 ProcessMemInfo mi = memInfos.get(i); 1596 infoMap.put(mi.pid, mi); 1597 } 1598 updateCpuStatsNow(); 1599 synchronized (mProcessCpuThread) { 1600 final int N = mProcessCpuTracker.countStats(); 1601 for (int i=0; i<N; i++) { 1602 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1603 if (st.vsize > 0) { 1604 long pss = Debug.getPss(st.pid, null); 1605 if (pss > 0) { 1606 if (infoMap.indexOfKey(st.pid) < 0) { 1607 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1608 ProcessList.NATIVE_ADJ, -1, "native", null); 1609 mi.pss = pss; 1610 memInfos.add(mi); 1611 } 1612 } 1613 } 1614 } 1615 } 1616 1617 long totalPss = 0; 1618 for (int i=0, N=memInfos.size(); i<N; i++) { 1619 ProcessMemInfo mi = memInfos.get(i); 1620 if (mi.pss == 0) { 1621 mi.pss = Debug.getPss(mi.pid, null); 1622 } 1623 totalPss += mi.pss; 1624 } 1625 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1626 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1627 if (lhs.oomAdj != rhs.oomAdj) { 1628 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1629 } 1630 if (lhs.pss != rhs.pss) { 1631 return lhs.pss < rhs.pss ? 1 : -1; 1632 } 1633 return 0; 1634 } 1635 }); 1636 1637 StringBuilder tag = new StringBuilder(128); 1638 StringBuilder stack = new StringBuilder(128); 1639 tag.append("Low on memory -- "); 1640 appendMemBucket(tag, totalPss, "total", false); 1641 appendMemBucket(stack, totalPss, "total", true); 1642 1643 StringBuilder logBuilder = new StringBuilder(1024); 1644 logBuilder.append("Low on memory:\n"); 1645 1646 boolean firstLine = true; 1647 int lastOomAdj = Integer.MIN_VALUE; 1648 for (int i=0, N=memInfos.size(); i<N; i++) { 1649 ProcessMemInfo mi = memInfos.get(i); 1650 1651 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1652 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1653 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1654 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1655 if (lastOomAdj != mi.oomAdj) { 1656 lastOomAdj = mi.oomAdj; 1657 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1658 tag.append(" / "); 1659 } 1660 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1661 if (firstLine) { 1662 stack.append(":"); 1663 firstLine = false; 1664 } 1665 stack.append("\n\t at "); 1666 } else { 1667 stack.append("$"); 1668 } 1669 } else { 1670 tag.append(" "); 1671 stack.append("$"); 1672 } 1673 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1674 appendMemBucket(tag, mi.pss, mi.name, false); 1675 } 1676 appendMemBucket(stack, mi.pss, mi.name, true); 1677 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1678 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1679 stack.append("("); 1680 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1681 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1682 stack.append(DUMP_MEM_OOM_LABEL[k]); 1683 stack.append(":"); 1684 stack.append(DUMP_MEM_OOM_ADJ[k]); 1685 } 1686 } 1687 stack.append(")"); 1688 } 1689 } 1690 1691 logBuilder.append(" "); 1692 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1693 logBuilder.append(' '); 1694 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1695 logBuilder.append(' '); 1696 ProcessList.appendRamKb(logBuilder, mi.pss); 1697 logBuilder.append(" kB: "); 1698 logBuilder.append(mi.name); 1699 logBuilder.append(" ("); 1700 logBuilder.append(mi.pid); 1701 logBuilder.append(") "); 1702 logBuilder.append(mi.adjType); 1703 logBuilder.append('\n'); 1704 if (mi.adjReason != null) { 1705 logBuilder.append(" "); 1706 logBuilder.append(mi.adjReason); 1707 logBuilder.append('\n'); 1708 } 1709 } 1710 1711 logBuilder.append(" "); 1712 ProcessList.appendRamKb(logBuilder, totalPss); 1713 logBuilder.append(" kB: TOTAL\n"); 1714 1715 long[] infos = new long[Debug.MEMINFO_COUNT]; 1716 Debug.getMemInfo(infos); 1717 logBuilder.append(" MemInfo: "); 1718 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1719 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1720 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1721 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1722 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1723 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1724 logBuilder.append(" ZRAM: "); 1725 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1726 logBuilder.append(" kB RAM, "); 1727 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1728 logBuilder.append(" kB swap total, "); 1729 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1730 logBuilder.append(" kB swap free\n"); 1731 } 1732 Slog.i(TAG, logBuilder.toString()); 1733 1734 StringBuilder dropBuilder = new StringBuilder(1024); 1735 /* 1736 StringWriter oomSw = new StringWriter(); 1737 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1738 StringWriter catSw = new StringWriter(); 1739 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1740 String[] emptyArgs = new String[] { }; 1741 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1742 oomPw.flush(); 1743 String oomString = oomSw.toString(); 1744 */ 1745 dropBuilder.append(stack); 1746 dropBuilder.append('\n'); 1747 dropBuilder.append('\n'); 1748 dropBuilder.append(logBuilder); 1749 dropBuilder.append('\n'); 1750 /* 1751 dropBuilder.append(oomString); 1752 dropBuilder.append('\n'); 1753 */ 1754 StringWriter catSw = new StringWriter(); 1755 synchronized (ActivityManagerService.this) { 1756 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1757 String[] emptyArgs = new String[] { }; 1758 catPw.println(); 1759 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1760 catPw.println(); 1761 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1762 false, false, null); 1763 catPw.println(); 1764 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1765 catPw.flush(); 1766 } 1767 dropBuilder.append(catSw.toString()); 1768 addErrorToDropBox("lowmem", null, "system_server", null, 1769 null, tag.toString(), dropBuilder.toString(), null, null); 1770 //Slog.i(TAG, "Sent to dropbox:"); 1771 //Slog.i(TAG, dropBuilder.toString()); 1772 synchronized (ActivityManagerService.this) { 1773 long now = SystemClock.uptimeMillis(); 1774 if (mLastMemUsageReportTime < now) { 1775 mLastMemUsageReportTime = now; 1776 } 1777 } 1778 } 1779 }; 1780 thread.start(); 1781 break; 1782 } 1783 case START_USER_SWITCH_MSG: { 1784 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1785 break; 1786 } 1787 case REPORT_USER_SWITCH_MSG: { 1788 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1789 break; 1790 } 1791 case CONTINUE_USER_SWITCH_MSG: { 1792 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1793 break; 1794 } 1795 case USER_SWITCH_TIMEOUT_MSG: { 1796 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1797 break; 1798 } 1799 case IMMERSIVE_MODE_LOCK_MSG: { 1800 final boolean nextState = (msg.arg1 != 0); 1801 if (mUpdateLock.isHeld() != nextState) { 1802 if (DEBUG_IMMERSIVE) { 1803 final ActivityRecord r = (ActivityRecord) msg.obj; 1804 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1805 } 1806 if (nextState) { 1807 mUpdateLock.acquire(); 1808 } else { 1809 mUpdateLock.release(); 1810 } 1811 } 1812 break; 1813 } 1814 case PERSIST_URI_GRANTS_MSG: { 1815 writeGrantedUriPermissions(); 1816 break; 1817 } 1818 case REQUEST_ALL_PSS_MSG: { 1819 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1820 break; 1821 } 1822 case START_PROFILES_MSG: { 1823 synchronized (ActivityManagerService.this) { 1824 startProfilesLocked(); 1825 } 1826 break; 1827 } 1828 case UPDATE_TIME: { 1829 synchronized (ActivityManagerService.this) { 1830 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1831 ProcessRecord r = mLruProcesses.get(i); 1832 if (r.thread != null) { 1833 try { 1834 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1835 } catch (RemoteException ex) { 1836 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1837 } 1838 } 1839 } 1840 } 1841 break; 1842 } 1843 case SYSTEM_USER_START_MSG: { 1844 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1845 Integer.toString(msg.arg1), msg.arg1); 1846 mSystemServiceManager.startUser(msg.arg1); 1847 break; 1848 } 1849 case SYSTEM_USER_CURRENT_MSG: { 1850 mBatteryStatsService.noteEvent( 1851 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1852 Integer.toString(msg.arg2), msg.arg2); 1853 mBatteryStatsService.noteEvent( 1854 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1855 Integer.toString(msg.arg1), msg.arg1); 1856 mSystemServiceManager.switchUser(msg.arg1); 1857 mLockToAppRequest.clearPrompt(); 1858 break; 1859 } 1860 case ENTER_ANIMATION_COMPLETE_MSG: { 1861 synchronized (ActivityManagerService.this) { 1862 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1863 if (r != null && r.app != null && r.app.thread != null) { 1864 try { 1865 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1866 } catch (RemoteException e) { 1867 } 1868 } 1869 } 1870 break; 1871 } 1872 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1873 enableScreenAfterBoot(); 1874 break; 1875 } 1876 } 1877 } 1878 }; 1879 1880 static final int COLLECT_PSS_BG_MSG = 1; 1881 1882 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1883 @Override 1884 public void handleMessage(Message msg) { 1885 switch (msg.what) { 1886 case COLLECT_PSS_BG_MSG: { 1887 long start = SystemClock.uptimeMillis(); 1888 MemInfoReader memInfo = null; 1889 synchronized (ActivityManagerService.this) { 1890 if (mFullPssPending) { 1891 mFullPssPending = false; 1892 memInfo = new MemInfoReader(); 1893 } 1894 } 1895 if (memInfo != null) { 1896 updateCpuStatsNow(); 1897 long nativeTotalPss = 0; 1898 synchronized (mProcessCpuThread) { 1899 final int N = mProcessCpuTracker.countStats(); 1900 for (int j=0; j<N; j++) { 1901 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1902 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1903 // This is definitely an application process; skip it. 1904 continue; 1905 } 1906 synchronized (mPidsSelfLocked) { 1907 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1908 // This is one of our own processes; skip it. 1909 continue; 1910 } 1911 } 1912 nativeTotalPss += Debug.getPss(st.pid, null); 1913 } 1914 } 1915 memInfo.readMemInfo(); 1916 synchronized (this) { 1917 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1918 + (SystemClock.uptimeMillis()-start) + "ms"); 1919 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1920 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1921 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1922 +memInfo.getSlabSizeKb(), 1923 nativeTotalPss); 1924 } 1925 } 1926 1927 int i=0, num=0; 1928 long[] tmp = new long[1]; 1929 do { 1930 ProcessRecord proc; 1931 int procState; 1932 int pid; 1933 synchronized (ActivityManagerService.this) { 1934 if (i >= mPendingPssProcesses.size()) { 1935 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1936 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1937 mPendingPssProcesses.clear(); 1938 return; 1939 } 1940 proc = mPendingPssProcesses.get(i); 1941 procState = proc.pssProcState; 1942 if (proc.thread != null && procState == proc.setProcState) { 1943 pid = proc.pid; 1944 } else { 1945 proc = null; 1946 pid = 0; 1947 } 1948 i++; 1949 } 1950 if (proc != null) { 1951 long pss = Debug.getPss(pid, tmp); 1952 synchronized (ActivityManagerService.this) { 1953 if (proc.thread != null && proc.setProcState == procState 1954 && proc.pid == pid) { 1955 num++; 1956 proc.lastPssTime = SystemClock.uptimeMillis(); 1957 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1958 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1959 + ": " + pss + " lastPss=" + proc.lastPss 1960 + " state=" + ProcessList.makeProcStateString(procState)); 1961 if (proc.initialIdlePss == 0) { 1962 proc.initialIdlePss = pss; 1963 } 1964 proc.lastPss = pss; 1965 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1966 proc.lastCachedPss = pss; 1967 } 1968 } 1969 } 1970 } 1971 } while (true); 1972 } 1973 } 1974 } 1975 }; 1976 1977 /** 1978 * Monitor for package changes and update our internal state. 1979 */ 1980 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1981 @Override 1982 public void onPackageRemoved(String packageName, int uid) { 1983 // Remove all tasks with activities in the specified package from the list of recent tasks 1984 synchronized (ActivityManagerService.this) { 1985 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1986 TaskRecord tr = mRecentTasks.get(i); 1987 ComponentName cn = tr.intent.getComponent(); 1988 if (cn != null && cn.getPackageName().equals(packageName)) { 1989 // If the package name matches, remove the task and kill the process 1990 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1991 } 1992 } 1993 } 1994 } 1995 1996 @Override 1997 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1998 onPackageModified(packageName); 1999 return true; 2000 } 2001 2002 @Override 2003 public void onPackageModified(String packageName) { 2004 final PackageManager pm = mContext.getPackageManager(); 2005 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2006 new ArrayList<Pair<Intent, Integer>>(); 2007 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2008 // Copy the list of recent tasks so that we don't hold onto the lock on 2009 // ActivityManagerService for long periods while checking if components exist. 2010 synchronized (ActivityManagerService.this) { 2011 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2012 TaskRecord tr = mRecentTasks.get(i); 2013 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2014 } 2015 } 2016 // Check the recent tasks and filter out all tasks with components that no longer exist. 2017 Intent tmpI = new Intent(); 2018 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2019 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2020 ComponentName cn = p.first.getComponent(); 2021 if (cn != null && cn.getPackageName().equals(packageName)) { 2022 try { 2023 // Add the task to the list to remove if the component no longer exists 2024 tmpI.setComponent(cn); 2025 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2026 tasksToRemove.add(p.second); 2027 } 2028 } catch (Exception e) {} 2029 } 2030 } 2031 // Prune all the tasks with removed components from the list of recent tasks 2032 synchronized (ActivityManagerService.this) { 2033 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2034 // Remove the task but don't kill the process (since other components in that 2035 // package may still be running and in the background) 2036 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2037 } 2038 } 2039 } 2040 2041 @Override 2042 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2043 // Force stop the specified packages 2044 if (packages != null) { 2045 for (String pkg : packages) { 2046 synchronized (ActivityManagerService.this) { 2047 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2048 "finished booting")) { 2049 return true; 2050 } 2051 } 2052 } 2053 } 2054 return false; 2055 } 2056 }; 2057 2058 public void setSystemProcess() { 2059 try { 2060 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2061 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2062 ServiceManager.addService("meminfo", new MemBinder(this)); 2063 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2064 ServiceManager.addService("dbinfo", new DbBinder(this)); 2065 if (MONITOR_CPU_USAGE) { 2066 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2067 } 2068 ServiceManager.addService("permission", new PermissionController(this)); 2069 2070 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2071 "android", STOCK_PM_FLAGS); 2072 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2073 2074 synchronized (this) { 2075 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2076 app.persistent = true; 2077 app.pid = MY_PID; 2078 app.maxAdj = ProcessList.SYSTEM_ADJ; 2079 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2080 mProcessNames.put(app.processName, app.uid, app); 2081 synchronized (mPidsSelfLocked) { 2082 mPidsSelfLocked.put(app.pid, app); 2083 } 2084 updateLruProcessLocked(app, false, null); 2085 updateOomAdjLocked(); 2086 } 2087 } catch (PackageManager.NameNotFoundException e) { 2088 throw new RuntimeException( 2089 "Unable to find android system package", e); 2090 } 2091 } 2092 2093 public void setWindowManager(WindowManagerService wm) { 2094 mWindowManager = wm; 2095 mStackSupervisor.setWindowManager(wm); 2096 } 2097 2098 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2099 mUsageStatsService = usageStatsManager; 2100 } 2101 2102 public void startObservingNativeCrashes() { 2103 final NativeCrashListener ncl = new NativeCrashListener(this); 2104 ncl.start(); 2105 } 2106 2107 public IAppOpsService getAppOpsService() { 2108 return mAppOpsService; 2109 } 2110 2111 static class MemBinder extends Binder { 2112 ActivityManagerService mActivityManagerService; 2113 MemBinder(ActivityManagerService activityManagerService) { 2114 mActivityManagerService = activityManagerService; 2115 } 2116 2117 @Override 2118 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2119 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2120 != PackageManager.PERMISSION_GRANTED) { 2121 pw.println("Permission Denial: can't dump meminfo from from pid=" 2122 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2123 + " without permission " + android.Manifest.permission.DUMP); 2124 return; 2125 } 2126 2127 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2128 } 2129 } 2130 2131 static class GraphicsBinder extends Binder { 2132 ActivityManagerService mActivityManagerService; 2133 GraphicsBinder(ActivityManagerService activityManagerService) { 2134 mActivityManagerService = activityManagerService; 2135 } 2136 2137 @Override 2138 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2139 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2140 != PackageManager.PERMISSION_GRANTED) { 2141 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2142 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2143 + " without permission " + android.Manifest.permission.DUMP); 2144 return; 2145 } 2146 2147 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2148 } 2149 } 2150 2151 static class DbBinder extends Binder { 2152 ActivityManagerService mActivityManagerService; 2153 DbBinder(ActivityManagerService activityManagerService) { 2154 mActivityManagerService = activityManagerService; 2155 } 2156 2157 @Override 2158 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2159 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2160 != PackageManager.PERMISSION_GRANTED) { 2161 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2162 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2163 + " without permission " + android.Manifest.permission.DUMP); 2164 return; 2165 } 2166 2167 mActivityManagerService.dumpDbInfo(fd, pw, args); 2168 } 2169 } 2170 2171 static class CpuBinder extends Binder { 2172 ActivityManagerService mActivityManagerService; 2173 CpuBinder(ActivityManagerService activityManagerService) { 2174 mActivityManagerService = activityManagerService; 2175 } 2176 2177 @Override 2178 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2179 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2180 != PackageManager.PERMISSION_GRANTED) { 2181 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2182 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2183 + " without permission " + android.Manifest.permission.DUMP); 2184 return; 2185 } 2186 2187 synchronized (mActivityManagerService.mProcessCpuThread) { 2188 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2189 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2190 SystemClock.uptimeMillis())); 2191 } 2192 } 2193 } 2194 2195 public static final class Lifecycle extends SystemService { 2196 private final ActivityManagerService mService; 2197 2198 public Lifecycle(Context context) { 2199 super(context); 2200 mService = new ActivityManagerService(context); 2201 } 2202 2203 @Override 2204 public void onStart() { 2205 mService.start(); 2206 } 2207 2208 public ActivityManagerService getService() { 2209 return mService; 2210 } 2211 } 2212 2213 // Note: This method is invoked on the main thread but may need to attach various 2214 // handlers to other threads. So take care to be explicit about the looper. 2215 public ActivityManagerService(Context systemContext) { 2216 mContext = systemContext; 2217 mFactoryTest = FactoryTest.getMode(); 2218 mSystemThread = ActivityThread.currentActivityThread(); 2219 2220 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2221 2222 mHandlerThread = new ServiceThread(TAG, 2223 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2224 mHandlerThread.start(); 2225 mHandler = new MainHandler(mHandlerThread.getLooper()); 2226 2227 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2228 "foreground", BROADCAST_FG_TIMEOUT, false); 2229 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2230 "background", BROADCAST_BG_TIMEOUT, true); 2231 mBroadcastQueues[0] = mFgBroadcastQueue; 2232 mBroadcastQueues[1] = mBgBroadcastQueue; 2233 2234 mServices = new ActiveServices(this); 2235 mProviderMap = new ProviderMap(this); 2236 2237 // TODO: Move creation of battery stats service outside of activity manager service. 2238 File dataDir = Environment.getDataDirectory(); 2239 File systemDir = new File(dataDir, "system"); 2240 systemDir.mkdirs(); 2241 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2242 mBatteryStatsService.getActiveStatistics().readLocked(); 2243 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2244 mOnBattery = DEBUG_POWER ? true 2245 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2246 mBatteryStatsService.getActiveStatistics().setCallback(this); 2247 2248 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2249 2250 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2251 2252 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2253 2254 // User 0 is the first and only user that runs at boot. 2255 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2256 mUserLru.add(Integer.valueOf(0)); 2257 updateStartedUserArrayLocked(); 2258 2259 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2260 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2261 2262 mConfiguration.setToDefaults(); 2263 mConfiguration.setLocale(Locale.getDefault()); 2264 2265 mConfigurationSeq = mConfiguration.seq = 1; 2266 mProcessCpuTracker.init(); 2267 2268 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2269 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2270 mStackSupervisor = new ActivityStackSupervisor(this); 2271 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2272 2273 mProcessCpuThread = new Thread("CpuTracker") { 2274 @Override 2275 public void run() { 2276 while (true) { 2277 try { 2278 try { 2279 synchronized(this) { 2280 final long now = SystemClock.uptimeMillis(); 2281 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2282 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2283 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2284 // + ", write delay=" + nextWriteDelay); 2285 if (nextWriteDelay < nextCpuDelay) { 2286 nextCpuDelay = nextWriteDelay; 2287 } 2288 if (nextCpuDelay > 0) { 2289 mProcessCpuMutexFree.set(true); 2290 this.wait(nextCpuDelay); 2291 } 2292 } 2293 } catch (InterruptedException e) { 2294 } 2295 updateCpuStatsNow(); 2296 } catch (Exception e) { 2297 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2298 } 2299 } 2300 } 2301 }; 2302 2303 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2304 2305 Watchdog.getInstance().addMonitor(this); 2306 Watchdog.getInstance().addThread(mHandler); 2307 } 2308 2309 public void setSystemServiceManager(SystemServiceManager mgr) { 2310 mSystemServiceManager = mgr; 2311 } 2312 2313 private void start() { 2314 Process.removeAllProcessGroups(); 2315 mProcessCpuThread.start(); 2316 2317 mBatteryStatsService.publish(mContext); 2318 mAppOpsService.publish(mContext); 2319 Slog.d("AppOps", "AppOpsService published"); 2320 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2321 } 2322 2323 public void initPowerManagement() { 2324 mStackSupervisor.initPowerManagement(); 2325 mBatteryStatsService.initPowerManagement(); 2326 } 2327 2328 @Override 2329 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2330 throws RemoteException { 2331 if (code == SYSPROPS_TRANSACTION) { 2332 // We need to tell all apps about the system property change. 2333 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2334 synchronized(this) { 2335 final int NP = mProcessNames.getMap().size(); 2336 for (int ip=0; ip<NP; ip++) { 2337 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2338 final int NA = apps.size(); 2339 for (int ia=0; ia<NA; ia++) { 2340 ProcessRecord app = apps.valueAt(ia); 2341 if (app.thread != null) { 2342 procs.add(app.thread.asBinder()); 2343 } 2344 } 2345 } 2346 } 2347 2348 int N = procs.size(); 2349 for (int i=0; i<N; i++) { 2350 Parcel data2 = Parcel.obtain(); 2351 try { 2352 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2353 } catch (RemoteException e) { 2354 } 2355 data2.recycle(); 2356 } 2357 } 2358 try { 2359 return super.onTransact(code, data, reply, flags); 2360 } catch (RuntimeException e) { 2361 // The activity manager only throws security exceptions, so let's 2362 // log all others. 2363 if (!(e instanceof SecurityException)) { 2364 Slog.wtf(TAG, "Activity Manager Crash", e); 2365 } 2366 throw e; 2367 } 2368 } 2369 2370 void updateCpuStats() { 2371 final long now = SystemClock.uptimeMillis(); 2372 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2373 return; 2374 } 2375 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2376 synchronized (mProcessCpuThread) { 2377 mProcessCpuThread.notify(); 2378 } 2379 } 2380 } 2381 2382 void updateCpuStatsNow() { 2383 synchronized (mProcessCpuThread) { 2384 mProcessCpuMutexFree.set(false); 2385 final long now = SystemClock.uptimeMillis(); 2386 boolean haveNewCpuStats = false; 2387 2388 if (MONITOR_CPU_USAGE && 2389 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2390 mLastCpuTime.set(now); 2391 haveNewCpuStats = true; 2392 mProcessCpuTracker.update(); 2393 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2394 //Slog.i(TAG, "Total CPU usage: " 2395 // + mProcessCpu.getTotalCpuPercent() + "%"); 2396 2397 // Slog the cpu usage if the property is set. 2398 if ("true".equals(SystemProperties.get("events.cpu"))) { 2399 int user = mProcessCpuTracker.getLastUserTime(); 2400 int system = mProcessCpuTracker.getLastSystemTime(); 2401 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2402 int irq = mProcessCpuTracker.getLastIrqTime(); 2403 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2404 int idle = mProcessCpuTracker.getLastIdleTime(); 2405 2406 int total = user + system + iowait + irq + softIrq + idle; 2407 if (total == 0) total = 1; 2408 2409 EventLog.writeEvent(EventLogTags.CPU, 2410 ((user+system+iowait+irq+softIrq) * 100) / total, 2411 (user * 100) / total, 2412 (system * 100) / total, 2413 (iowait * 100) / total, 2414 (irq * 100) / total, 2415 (softIrq * 100) / total); 2416 } 2417 } 2418 2419 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2420 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2421 synchronized(bstats) { 2422 synchronized(mPidsSelfLocked) { 2423 if (haveNewCpuStats) { 2424 if (mOnBattery) { 2425 int perc = bstats.startAddingCpuLocked(); 2426 int totalUTime = 0; 2427 int totalSTime = 0; 2428 final int N = mProcessCpuTracker.countStats(); 2429 for (int i=0; i<N; i++) { 2430 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2431 if (!st.working) { 2432 continue; 2433 } 2434 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2435 int otherUTime = (st.rel_utime*perc)/100; 2436 int otherSTime = (st.rel_stime*perc)/100; 2437 totalUTime += otherUTime; 2438 totalSTime += otherSTime; 2439 if (pr != null) { 2440 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2441 if (ps == null || !ps.isActive()) { 2442 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2443 pr.info.uid, pr.processName); 2444 } 2445 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2446 st.rel_stime-otherSTime); 2447 ps.addSpeedStepTimes(cpuSpeedTimes); 2448 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2449 } else { 2450 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2451 if (ps == null || !ps.isActive()) { 2452 st.batteryStats = ps = bstats.getProcessStatsLocked( 2453 bstats.mapUid(st.uid), st.name); 2454 } 2455 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2456 st.rel_stime-otherSTime); 2457 ps.addSpeedStepTimes(cpuSpeedTimes); 2458 } 2459 } 2460 bstats.finishAddingCpuLocked(perc, totalUTime, 2461 totalSTime, cpuSpeedTimes); 2462 } 2463 } 2464 } 2465 2466 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2467 mLastWriteTime = now; 2468 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2469 } 2470 } 2471 } 2472 } 2473 2474 @Override 2475 public void batteryNeedsCpuUpdate() { 2476 updateCpuStatsNow(); 2477 } 2478 2479 @Override 2480 public void batteryPowerChanged(boolean onBattery) { 2481 // When plugging in, update the CPU stats first before changing 2482 // the plug state. 2483 updateCpuStatsNow(); 2484 synchronized (this) { 2485 synchronized(mPidsSelfLocked) { 2486 mOnBattery = DEBUG_POWER ? true : onBattery; 2487 } 2488 } 2489 } 2490 2491 /** 2492 * Initialize the application bind args. These are passed to each 2493 * process when the bindApplication() IPC is sent to the process. They're 2494 * lazily setup to make sure the services are running when they're asked for. 2495 */ 2496 private HashMap<String, IBinder> getCommonServicesLocked() { 2497 if (mAppBindArgs == null) { 2498 mAppBindArgs = new HashMap<String, IBinder>(); 2499 2500 // Setup the application init args 2501 mAppBindArgs.put("package", ServiceManager.getService("package")); 2502 mAppBindArgs.put("window", ServiceManager.getService("window")); 2503 mAppBindArgs.put(Context.ALARM_SERVICE, 2504 ServiceManager.getService(Context.ALARM_SERVICE)); 2505 } 2506 return mAppBindArgs; 2507 } 2508 2509 final void setFocusedActivityLocked(ActivityRecord r) { 2510 if (mFocusedActivity != r) { 2511 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2512 mFocusedActivity = r; 2513 if (r.task != null && r.task.voiceInteractor != null) { 2514 startRunningVoiceLocked(); 2515 } else { 2516 finishRunningVoiceLocked(); 2517 } 2518 mStackSupervisor.setFocusedStack(r); 2519 if (r != null) { 2520 mWindowManager.setFocusedApp(r.appToken, true); 2521 } 2522 applyUpdateLockStateLocked(r); 2523 } 2524 } 2525 2526 final void clearFocusedActivity(ActivityRecord r) { 2527 if (mFocusedActivity == r) { 2528 mFocusedActivity = null; 2529 } 2530 } 2531 2532 @Override 2533 public void setFocusedStack(int stackId) { 2534 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2535 synchronized (ActivityManagerService.this) { 2536 ActivityStack stack = mStackSupervisor.getStack(stackId); 2537 if (stack != null) { 2538 ActivityRecord r = stack.topRunningActivityLocked(null); 2539 if (r != null) { 2540 setFocusedActivityLocked(r); 2541 } 2542 } 2543 } 2544 } 2545 2546 @Override 2547 public void notifyActivityDrawn(IBinder token) { 2548 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2549 synchronized (this) { 2550 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2551 if (r != null) { 2552 r.task.stack.notifyActivityDrawnLocked(r); 2553 } 2554 } 2555 } 2556 2557 final void applyUpdateLockStateLocked(ActivityRecord r) { 2558 // Modifications to the UpdateLock state are done on our handler, outside 2559 // the activity manager's locks. The new state is determined based on the 2560 // state *now* of the relevant activity record. The object is passed to 2561 // the handler solely for logging detail, not to be consulted/modified. 2562 final boolean nextState = r != null && r.immersive; 2563 mHandler.sendMessage( 2564 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2565 } 2566 2567 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2568 Message msg = Message.obtain(); 2569 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2570 msg.obj = r.task.askedCompatMode ? null : r; 2571 mHandler.sendMessage(msg); 2572 } 2573 2574 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2575 String what, Object obj, ProcessRecord srcApp) { 2576 app.lastActivityTime = now; 2577 2578 if (app.activities.size() > 0) { 2579 // Don't want to touch dependent processes that are hosting activities. 2580 return index; 2581 } 2582 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 if (lrui < 0) { 2585 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2586 + what + " " + obj + " from " + srcApp); 2587 return index; 2588 } 2589 2590 if (lrui >= index) { 2591 // Don't want to cause this to move dependent processes *back* in the 2592 // list as if they were less frequently used. 2593 return index; 2594 } 2595 2596 if (lrui >= mLruProcessActivityStart) { 2597 // Don't want to touch dependent processes that are hosting activities. 2598 return index; 2599 } 2600 2601 mLruProcesses.remove(lrui); 2602 if (index > 0) { 2603 index--; 2604 } 2605 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2606 + " in LRU list: " + app); 2607 mLruProcesses.add(index, app); 2608 return index; 2609 } 2610 2611 final void removeLruProcessLocked(ProcessRecord app) { 2612 int lrui = mLruProcesses.lastIndexOf(app); 2613 if (lrui >= 0) { 2614 if (lrui <= mLruProcessActivityStart) { 2615 mLruProcessActivityStart--; 2616 } 2617 if (lrui <= mLruProcessServiceStart) { 2618 mLruProcessServiceStart--; 2619 } 2620 mLruProcesses.remove(lrui); 2621 } 2622 } 2623 2624 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2625 ProcessRecord client) { 2626 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2627 || app.treatLikeActivity; 2628 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2629 if (!activityChange && hasActivity) { 2630 // The process has activities, so we are only allowing activity-based adjustments 2631 // to move it. It should be kept in the front of the list with other 2632 // processes that have activities, and we don't want those to change their 2633 // order except due to activity operations. 2634 return; 2635 } 2636 2637 mLruSeq++; 2638 final long now = SystemClock.uptimeMillis(); 2639 app.lastActivityTime = now; 2640 2641 // First a quick reject: if the app is already at the position we will 2642 // put it, then there is nothing to do. 2643 if (hasActivity) { 2644 final int N = mLruProcesses.size(); 2645 if (N > 0 && mLruProcesses.get(N-1) == app) { 2646 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2647 return; 2648 } 2649 } else { 2650 if (mLruProcessServiceStart > 0 2651 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2652 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2653 return; 2654 } 2655 } 2656 2657 int lrui = mLruProcesses.lastIndexOf(app); 2658 2659 if (app.persistent && lrui >= 0) { 2660 // We don't care about the position of persistent processes, as long as 2661 // they are in the list. 2662 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2663 return; 2664 } 2665 2666 /* In progress: compute new position first, so we can avoid doing work 2667 if the process is not actually going to move. Not yet working. 2668 int addIndex; 2669 int nextIndex; 2670 boolean inActivity = false, inService = false; 2671 if (hasActivity) { 2672 // Process has activities, put it at the very tipsy-top. 2673 addIndex = mLruProcesses.size(); 2674 nextIndex = mLruProcessServiceStart; 2675 inActivity = true; 2676 } else if (hasService) { 2677 // Process has services, put it at the top of the service list. 2678 addIndex = mLruProcessActivityStart; 2679 nextIndex = mLruProcessServiceStart; 2680 inActivity = true; 2681 inService = true; 2682 } else { 2683 // Process not otherwise of interest, it goes to the top of the non-service area. 2684 addIndex = mLruProcessServiceStart; 2685 if (client != null) { 2686 int clientIndex = mLruProcesses.lastIndexOf(client); 2687 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2688 + app); 2689 if (clientIndex >= 0 && addIndex > clientIndex) { 2690 addIndex = clientIndex; 2691 } 2692 } 2693 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2694 } 2695 2696 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2697 + mLruProcessActivityStart + "): " + app); 2698 */ 2699 2700 if (lrui >= 0) { 2701 if (lrui < mLruProcessActivityStart) { 2702 mLruProcessActivityStart--; 2703 } 2704 if (lrui < mLruProcessServiceStart) { 2705 mLruProcessServiceStart--; 2706 } 2707 /* 2708 if (addIndex > lrui) { 2709 addIndex--; 2710 } 2711 if (nextIndex > lrui) { 2712 nextIndex--; 2713 } 2714 */ 2715 mLruProcesses.remove(lrui); 2716 } 2717 2718 /* 2719 mLruProcesses.add(addIndex, app); 2720 if (inActivity) { 2721 mLruProcessActivityStart++; 2722 } 2723 if (inService) { 2724 mLruProcessActivityStart++; 2725 } 2726 */ 2727 2728 int nextIndex; 2729 if (hasActivity) { 2730 final int N = mLruProcesses.size(); 2731 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2732 // Process doesn't have activities, but has clients with 2733 // activities... move it up, but one below the top (the top 2734 // should always have a real activity). 2735 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2736 mLruProcesses.add(N-1, app); 2737 // To keep it from spamming the LRU list (by making a bunch of clients), 2738 // we will push down any other entries owned by the app. 2739 final int uid = app.info.uid; 2740 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2741 ProcessRecord subProc = mLruProcesses.get(i); 2742 if (subProc.info.uid == uid) { 2743 // We want to push this one down the list. If the process after 2744 // it is for the same uid, however, don't do so, because we don't 2745 // want them internally to be re-ordered. 2746 if (mLruProcesses.get(i-1).info.uid != uid) { 2747 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2748 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2749 ProcessRecord tmp = mLruProcesses.get(i); 2750 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2751 mLruProcesses.set(i-1, tmp); 2752 i--; 2753 } 2754 } else { 2755 // A gap, we can stop here. 2756 break; 2757 } 2758 } 2759 } else { 2760 // Process has activities, put it at the very tipsy-top. 2761 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2762 mLruProcesses.add(app); 2763 } 2764 nextIndex = mLruProcessServiceStart; 2765 } else if (hasService) { 2766 // Process has services, put it at the top of the service list. 2767 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2768 mLruProcesses.add(mLruProcessActivityStart, app); 2769 nextIndex = mLruProcessServiceStart; 2770 mLruProcessActivityStart++; 2771 } else { 2772 // Process not otherwise of interest, it goes to the top of the non-service area. 2773 int index = mLruProcessServiceStart; 2774 if (client != null) { 2775 // If there is a client, don't allow the process to be moved up higher 2776 // in the list than that client. 2777 int clientIndex = mLruProcesses.lastIndexOf(client); 2778 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2779 + " when updating " + app); 2780 if (clientIndex <= lrui) { 2781 // Don't allow the client index restriction to push it down farther in the 2782 // list than it already is. 2783 clientIndex = lrui; 2784 } 2785 if (clientIndex >= 0 && index > clientIndex) { 2786 index = clientIndex; 2787 } 2788 } 2789 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2790 mLruProcesses.add(index, app); 2791 nextIndex = index-1; 2792 mLruProcessActivityStart++; 2793 mLruProcessServiceStart++; 2794 } 2795 2796 // If the app is currently using a content provider or service, 2797 // bump those processes as well. 2798 for (int j=app.connections.size()-1; j>=0; j--) { 2799 ConnectionRecord cr = app.connections.valueAt(j); 2800 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2801 && cr.binding.service.app != null 2802 && cr.binding.service.app.lruSeq != mLruSeq 2803 && !cr.binding.service.app.persistent) { 2804 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2805 "service connection", cr, app); 2806 } 2807 } 2808 for (int j=app.conProviders.size()-1; j>=0; j--) { 2809 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2810 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2811 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2812 "provider reference", cpr, app); 2813 } 2814 } 2815 } 2816 2817 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2818 if (uid == Process.SYSTEM_UID) { 2819 // The system gets to run in any process. If there are multiple 2820 // processes with the same uid, just pick the first (this 2821 // should never happen). 2822 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2823 if (procs == null) return null; 2824 final int N = procs.size(); 2825 for (int i = 0; i < N; i++) { 2826 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2827 } 2828 } 2829 ProcessRecord proc = mProcessNames.get(processName, uid); 2830 if (false && proc != null && !keepIfLarge 2831 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2832 && proc.lastCachedPss >= 4000) { 2833 // Turn this condition on to cause killing to happen regularly, for testing. 2834 if (proc.baseProcessTracker != null) { 2835 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2836 } 2837 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2838 } else if (proc != null && !keepIfLarge 2839 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2840 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2841 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2842 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2843 if (proc.baseProcessTracker != null) { 2844 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2845 } 2846 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2847 } 2848 } 2849 return proc; 2850 } 2851 2852 void ensurePackageDexOpt(String packageName) { 2853 IPackageManager pm = AppGlobals.getPackageManager(); 2854 try { 2855 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2856 mDidDexOpt = true; 2857 } 2858 } catch (RemoteException e) { 2859 } 2860 } 2861 2862 boolean isNextTransitionForward() { 2863 int transit = mWindowManager.getPendingAppTransition(); 2864 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2865 || transit == AppTransition.TRANSIT_TASK_OPEN 2866 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2867 } 2868 2869 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2870 String processName, String abiOverride, int uid, Runnable crashHandler) { 2871 synchronized(this) { 2872 ApplicationInfo info = new ApplicationInfo(); 2873 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2874 // For isolated processes, the former contains the parent's uid and the latter the 2875 // actual uid of the isolated process. 2876 // In the special case introduced by this method (which is, starting an isolated 2877 // process directly from the SystemServer without an actual parent app process) the 2878 // closest thing to a parent's uid is SYSTEM_UID. 2879 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2880 // the |isolated| logic in the ProcessRecord constructor. 2881 info.uid = Process.SYSTEM_UID; 2882 info.processName = processName; 2883 info.className = entryPoint; 2884 info.packageName = "android"; 2885 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2886 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2887 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2888 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2889 crashHandler); 2890 return proc != null ? proc.pid : 0; 2891 } 2892 } 2893 2894 final ProcessRecord startProcessLocked(String processName, 2895 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2896 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2897 boolean isolated, boolean keepIfLarge) { 2898 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2899 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2900 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2901 null /* crashHandler */); 2902 } 2903 2904 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2905 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2906 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2907 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2908 long startTime = SystemClock.elapsedRealtime(); 2909 ProcessRecord app; 2910 if (!isolated) { 2911 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2912 checkTime(startTime, "startProcess: after getProcessRecord"); 2913 } else { 2914 // If this is an isolated process, it can't re-use an existing process. 2915 app = null; 2916 } 2917 // We don't have to do anything more if: 2918 // (1) There is an existing application record; and 2919 // (2) The caller doesn't think it is dead, OR there is no thread 2920 // object attached to it so we know it couldn't have crashed; and 2921 // (3) There is a pid assigned to it, so it is either starting or 2922 // already running. 2923 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2924 + " app=" + app + " knownToBeDead=" + knownToBeDead 2925 + " thread=" + (app != null ? app.thread : null) 2926 + " pid=" + (app != null ? app.pid : -1)); 2927 if (app != null && app.pid > 0) { 2928 if (!knownToBeDead || app.thread == null) { 2929 // We already have the app running, or are waiting for it to 2930 // come up (we have a pid but not yet its thread), so keep it. 2931 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2932 // If this is a new package in the process, add the package to the list 2933 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2934 checkTime(startTime, "startProcess: done, added package to proc"); 2935 return app; 2936 } 2937 2938 // An application record is attached to a previous process, 2939 // clean it up now. 2940 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2941 checkTime(startTime, "startProcess: bad proc running, killing"); 2942 Process.killProcessGroup(app.info.uid, app.pid); 2943 handleAppDiedLocked(app, true, true); 2944 checkTime(startTime, "startProcess: done killing old proc"); 2945 } 2946 2947 String hostingNameStr = hostingName != null 2948 ? hostingName.flattenToShortString() : null; 2949 2950 if (!isolated) { 2951 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2952 // If we are in the background, then check to see if this process 2953 // is bad. If so, we will just silently fail. 2954 if (mBadProcesses.get(info.processName, info.uid) != null) { 2955 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2956 + "/" + info.processName); 2957 return null; 2958 } 2959 } else { 2960 // When the user is explicitly starting a process, then clear its 2961 // crash count so that we won't make it bad until they see at 2962 // least one crash dialog again, and make the process good again 2963 // if it had been bad. 2964 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2965 + "/" + info.processName); 2966 mProcessCrashTimes.remove(info.processName, info.uid); 2967 if (mBadProcesses.get(info.processName, info.uid) != null) { 2968 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2969 UserHandle.getUserId(info.uid), info.uid, 2970 info.processName); 2971 mBadProcesses.remove(info.processName, info.uid); 2972 if (app != null) { 2973 app.bad = false; 2974 } 2975 } 2976 } 2977 } 2978 2979 if (app == null) { 2980 checkTime(startTime, "startProcess: creating new process record"); 2981 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2982 app.crashHandler = crashHandler; 2983 if (app == null) { 2984 Slog.w(TAG, "Failed making new process record for " 2985 + processName + "/" + info.uid + " isolated=" + isolated); 2986 return null; 2987 } 2988 mProcessNames.put(processName, app.uid, app); 2989 if (isolated) { 2990 mIsolatedProcesses.put(app.uid, app); 2991 } 2992 checkTime(startTime, "startProcess: done creating new process record"); 2993 } else { 2994 // If this is a new package in the process, add the package to the list 2995 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2996 checkTime(startTime, "startProcess: added package to existing proc"); 2997 } 2998 2999 // If the system is not ready yet, then hold off on starting this 3000 // process until it is. 3001 if (!mProcessesReady 3002 && !isAllowedWhileBooting(info) 3003 && !allowWhileBooting) { 3004 if (!mProcessesOnHold.contains(app)) { 3005 mProcessesOnHold.add(app); 3006 } 3007 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3008 checkTime(startTime, "startProcess: returning with proc on hold"); 3009 return app; 3010 } 3011 3012 checkTime(startTime, "startProcess: stepping in to startProcess"); 3013 startProcessLocked( 3014 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3015 checkTime(startTime, "startProcess: done starting proc!"); 3016 return (app.pid != 0) ? app : null; 3017 } 3018 3019 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3020 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3021 } 3022 3023 private final void startProcessLocked(ProcessRecord app, 3024 String hostingType, String hostingNameStr) { 3025 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3026 null /* entryPoint */, null /* entryPointArgs */); 3027 } 3028 3029 private final void startProcessLocked(ProcessRecord app, String hostingType, 3030 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3031 long startTime = SystemClock.elapsedRealtime(); 3032 if (app.pid > 0 && app.pid != MY_PID) { 3033 checkTime(startTime, "startProcess: removing from pids map"); 3034 synchronized (mPidsSelfLocked) { 3035 mPidsSelfLocked.remove(app.pid); 3036 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3037 } 3038 checkTime(startTime, "startProcess: done removing from pids map"); 3039 app.setPid(0); 3040 } 3041 3042 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3043 "startProcessLocked removing on hold: " + app); 3044 mProcessesOnHold.remove(app); 3045 3046 checkTime(startTime, "startProcess: starting to update cpu stats"); 3047 updateCpuStats(); 3048 checkTime(startTime, "startProcess: done updating cpu stats"); 3049 3050 try { 3051 int uid = app.uid; 3052 3053 int[] gids = null; 3054 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3055 if (!app.isolated) { 3056 int[] permGids = null; 3057 try { 3058 checkTime(startTime, "startProcess: getting gids from package manager"); 3059 final PackageManager pm = mContext.getPackageManager(); 3060 permGids = pm.getPackageGids(app.info.packageName); 3061 3062 if (Environment.isExternalStorageEmulated()) { 3063 checkTime(startTime, "startProcess: checking external storage perm"); 3064 if (pm.checkPermission( 3065 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3066 app.info.packageName) == PERMISSION_GRANTED) { 3067 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3068 } else { 3069 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3070 } 3071 } 3072 } catch (PackageManager.NameNotFoundException e) { 3073 Slog.w(TAG, "Unable to retrieve gids", e); 3074 } 3075 3076 /* 3077 * Add shared application and profile GIDs so applications can share some 3078 * resources like shared libraries and access user-wide resources 3079 */ 3080 if (permGids == null) { 3081 gids = new int[2]; 3082 } else { 3083 gids = new int[permGids.length + 2]; 3084 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3085 } 3086 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3087 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3088 } 3089 checkTime(startTime, "startProcess: building args"); 3090 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3091 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3092 && mTopComponent != null 3093 && app.processName.equals(mTopComponent.getPackageName())) { 3094 uid = 0; 3095 } 3096 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3097 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3098 uid = 0; 3099 } 3100 } 3101 int debugFlags = 0; 3102 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3103 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3104 // Also turn on CheckJNI for debuggable apps. It's quite 3105 // awkward to turn on otherwise. 3106 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3107 } 3108 // Run the app in safe mode if its manifest requests so or the 3109 // system is booted in safe mode. 3110 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3111 mSafeMode == true) { 3112 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3113 } 3114 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3115 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3116 } 3117 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3118 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3119 } 3120 if ("1".equals(SystemProperties.get("debug.assert"))) { 3121 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3122 } 3123 3124 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3125 if (requiredAbi == null) { 3126 requiredAbi = Build.SUPPORTED_ABIS[0]; 3127 } 3128 3129 String instructionSet = null; 3130 if (app.info.primaryCpuAbi != null) { 3131 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3132 } 3133 3134 // Start the process. It will either succeed and return a result containing 3135 // the PID of the new process, or else throw a RuntimeException. 3136 boolean isActivityProcess = (entryPoint == null); 3137 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3138 checkTime(startTime, "startProcess: asking zygote to start proc"); 3139 Process.ProcessStartResult startResult = Process.start(entryPoint, 3140 app.processName, uid, uid, gids, debugFlags, mountExternal, 3141 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3142 entryPointArgs); 3143 checkTime(startTime, "startProcess: returned from zygote!"); 3144 3145 if (app.isolated) { 3146 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3147 } 3148 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3149 checkTime(startTime, "startProcess: done updating battery stats"); 3150 3151 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3152 UserHandle.getUserId(uid), startResult.pid, uid, 3153 app.processName, hostingType, 3154 hostingNameStr != null ? hostingNameStr : ""); 3155 3156 if (app.persistent) { 3157 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3158 } 3159 3160 checkTime(startTime, "startProcess: building log message"); 3161 StringBuilder buf = mStringBuilder; 3162 buf.setLength(0); 3163 buf.append("Start proc "); 3164 buf.append(app.processName); 3165 if (!isActivityProcess) { 3166 buf.append(" ["); 3167 buf.append(entryPoint); 3168 buf.append("]"); 3169 } 3170 buf.append(" for "); 3171 buf.append(hostingType); 3172 if (hostingNameStr != null) { 3173 buf.append(" "); 3174 buf.append(hostingNameStr); 3175 } 3176 buf.append(": pid="); 3177 buf.append(startResult.pid); 3178 buf.append(" uid="); 3179 buf.append(uid); 3180 buf.append(" gids={"); 3181 if (gids != null) { 3182 for (int gi=0; gi<gids.length; gi++) { 3183 if (gi != 0) buf.append(", "); 3184 buf.append(gids[gi]); 3185 3186 } 3187 } 3188 buf.append("}"); 3189 if (requiredAbi != null) { 3190 buf.append(" abi="); 3191 buf.append(requiredAbi); 3192 } 3193 Slog.i(TAG, buf.toString()); 3194 app.setPid(startResult.pid); 3195 app.usingWrapper = startResult.usingWrapper; 3196 app.removed = false; 3197 app.killedByAm = false; 3198 checkTime(startTime, "startProcess: starting to update pids map"); 3199 synchronized (mPidsSelfLocked) { 3200 this.mPidsSelfLocked.put(startResult.pid, app); 3201 if (isActivityProcess) { 3202 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3203 msg.obj = app; 3204 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3205 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3206 } 3207 } 3208 checkTime(startTime, "startProcess: done updating pids map"); 3209 } catch (RuntimeException e) { 3210 // XXX do better error recovery. 3211 app.setPid(0); 3212 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3213 if (app.isolated) { 3214 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3215 } 3216 Slog.e(TAG, "Failure starting process " + app.processName, e); 3217 } 3218 } 3219 3220 void updateUsageStats(ActivityRecord component, boolean resumed) { 3221 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3222 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3223 if (resumed) { 3224 if (mUsageStatsService != null) { 3225 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3226 UsageEvents.Event.MOVE_TO_FOREGROUND); 3227 } 3228 synchronized (stats) { 3229 stats.noteActivityResumedLocked(component.app.uid); 3230 } 3231 } else { 3232 if (mUsageStatsService != null) { 3233 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3234 UsageEvents.Event.MOVE_TO_BACKGROUND); 3235 } 3236 synchronized (stats) { 3237 stats.noteActivityPausedLocked(component.app.uid); 3238 } 3239 } 3240 } 3241 3242 Intent getHomeIntent() { 3243 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3244 intent.setComponent(mTopComponent); 3245 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3246 intent.addCategory(Intent.CATEGORY_HOME); 3247 } 3248 return intent; 3249 } 3250 3251 boolean startHomeActivityLocked(int userId) { 3252 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3253 && mTopAction == null) { 3254 // We are running in factory test mode, but unable to find 3255 // the factory test app, so just sit around displaying the 3256 // error message and don't try to start anything. 3257 return false; 3258 } 3259 Intent intent = getHomeIntent(); 3260 ActivityInfo aInfo = 3261 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3262 if (aInfo != null) { 3263 intent.setComponent(new ComponentName( 3264 aInfo.applicationInfo.packageName, aInfo.name)); 3265 // Don't do this if the home app is currently being 3266 // instrumented. 3267 aInfo = new ActivityInfo(aInfo); 3268 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3269 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3270 aInfo.applicationInfo.uid, true); 3271 if (app == null || app.instrumentationClass == null) { 3272 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3273 mStackSupervisor.startHomeActivity(intent, aInfo); 3274 } 3275 } 3276 3277 return true; 3278 } 3279 3280 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3281 ActivityInfo ai = null; 3282 ComponentName comp = intent.getComponent(); 3283 try { 3284 if (comp != null) { 3285 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3286 } else { 3287 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3288 intent, 3289 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3290 flags, userId); 3291 3292 if (info != null) { 3293 ai = info.activityInfo; 3294 } 3295 } 3296 } catch (RemoteException e) { 3297 // ignore 3298 } 3299 3300 return ai; 3301 } 3302 3303 /** 3304 * Starts the "new version setup screen" if appropriate. 3305 */ 3306 void startSetupActivityLocked() { 3307 // Only do this once per boot. 3308 if (mCheckedForSetup) { 3309 return; 3310 } 3311 3312 // We will show this screen if the current one is a different 3313 // version than the last one shown, and we are not running in 3314 // low-level factory test mode. 3315 final ContentResolver resolver = mContext.getContentResolver(); 3316 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3317 Settings.Global.getInt(resolver, 3318 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3319 mCheckedForSetup = true; 3320 3321 // See if we should be showing the platform update setup UI. 3322 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3323 List<ResolveInfo> ris = mContext.getPackageManager() 3324 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3325 3326 // We don't allow third party apps to replace this. 3327 ResolveInfo ri = null; 3328 for (int i=0; ris != null && i<ris.size(); i++) { 3329 if ((ris.get(i).activityInfo.applicationInfo.flags 3330 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3331 ri = ris.get(i); 3332 break; 3333 } 3334 } 3335 3336 if (ri != null) { 3337 String vers = ri.activityInfo.metaData != null 3338 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3339 : null; 3340 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3341 vers = ri.activityInfo.applicationInfo.metaData.getString( 3342 Intent.METADATA_SETUP_VERSION); 3343 } 3344 String lastVers = Settings.Secure.getString( 3345 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3346 if (vers != null && !vers.equals(lastVers)) { 3347 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3348 intent.setComponent(new ComponentName( 3349 ri.activityInfo.packageName, ri.activityInfo.name)); 3350 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3351 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3352 null); 3353 } 3354 } 3355 } 3356 } 3357 3358 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3359 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3360 } 3361 3362 void enforceNotIsolatedCaller(String caller) { 3363 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3364 throw new SecurityException("Isolated process not allowed to call " + caller); 3365 } 3366 } 3367 3368 void enforceShellRestriction(String restriction, int userHandle) { 3369 if (Binder.getCallingUid() == Process.SHELL_UID) { 3370 if (userHandle < 0 3371 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3372 throw new SecurityException("Shell does not have permission to access user " 3373 + userHandle); 3374 } 3375 } 3376 } 3377 3378 @Override 3379 public int getFrontActivityScreenCompatMode() { 3380 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3381 synchronized (this) { 3382 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3383 } 3384 } 3385 3386 @Override 3387 public void setFrontActivityScreenCompatMode(int mode) { 3388 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3389 "setFrontActivityScreenCompatMode"); 3390 synchronized (this) { 3391 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3392 } 3393 } 3394 3395 @Override 3396 public int getPackageScreenCompatMode(String packageName) { 3397 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3398 synchronized (this) { 3399 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3400 } 3401 } 3402 3403 @Override 3404 public void setPackageScreenCompatMode(String packageName, int mode) { 3405 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3406 "setPackageScreenCompatMode"); 3407 synchronized (this) { 3408 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3409 } 3410 } 3411 3412 @Override 3413 public boolean getPackageAskScreenCompat(String packageName) { 3414 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3415 synchronized (this) { 3416 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3417 } 3418 } 3419 3420 @Override 3421 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3422 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3423 "setPackageAskScreenCompat"); 3424 synchronized (this) { 3425 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3426 } 3427 } 3428 3429 private void dispatchProcessesChanged() { 3430 int N; 3431 synchronized (this) { 3432 N = mPendingProcessChanges.size(); 3433 if (mActiveProcessChanges.length < N) { 3434 mActiveProcessChanges = new ProcessChangeItem[N]; 3435 } 3436 mPendingProcessChanges.toArray(mActiveProcessChanges); 3437 mAvailProcessChanges.addAll(mPendingProcessChanges); 3438 mPendingProcessChanges.clear(); 3439 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3440 } 3441 3442 int i = mProcessObservers.beginBroadcast(); 3443 while (i > 0) { 3444 i--; 3445 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3446 if (observer != null) { 3447 try { 3448 for (int j=0; j<N; j++) { 3449 ProcessChangeItem item = mActiveProcessChanges[j]; 3450 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3451 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3452 + item.pid + " uid=" + item.uid + ": " 3453 + item.foregroundActivities); 3454 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3455 item.foregroundActivities); 3456 } 3457 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3458 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3459 + item.pid + " uid=" + item.uid + ": " + item.processState); 3460 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3461 } 3462 } 3463 } catch (RemoteException e) { 3464 } 3465 } 3466 } 3467 mProcessObservers.finishBroadcast(); 3468 } 3469 3470 private void dispatchProcessDied(int pid, int uid) { 3471 int i = mProcessObservers.beginBroadcast(); 3472 while (i > 0) { 3473 i--; 3474 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3475 if (observer != null) { 3476 try { 3477 observer.onProcessDied(pid, uid); 3478 } catch (RemoteException e) { 3479 } 3480 } 3481 } 3482 mProcessObservers.finishBroadcast(); 3483 } 3484 3485 @Override 3486 public final int startActivity(IApplicationThread caller, String callingPackage, 3487 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3488 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3489 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3490 resultWho, requestCode, startFlags, profilerInfo, options, 3491 UserHandle.getCallingUserId()); 3492 } 3493 3494 @Override 3495 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3496 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3497 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3498 enforceNotIsolatedCaller("startActivity"); 3499 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3500 false, ALLOW_FULL_ONLY, "startActivity", null); 3501 // TODO: Switch to user app stacks here. 3502 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3503 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3504 profilerInfo, null, null, options, userId, null, null); 3505 } 3506 3507 @Override 3508 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3509 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3510 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3511 3512 // This is very dangerous -- it allows you to perform a start activity (including 3513 // permission grants) as any app that may launch one of your own activities. So 3514 // we will only allow this to be done from activities that are part of the core framework, 3515 // and then only when they are running as the system. 3516 final ActivityRecord sourceRecord; 3517 final int targetUid; 3518 final String targetPackage; 3519 synchronized (this) { 3520 if (resultTo == null) { 3521 throw new SecurityException("Must be called from an activity"); 3522 } 3523 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3524 if (sourceRecord == null) { 3525 throw new SecurityException("Called with bad activity token: " + resultTo); 3526 } 3527 if (!sourceRecord.info.packageName.equals("android")) { 3528 throw new SecurityException( 3529 "Must be called from an activity that is declared in the android package"); 3530 } 3531 if (sourceRecord.app == null) { 3532 throw new SecurityException("Called without a process attached to activity"); 3533 } 3534 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3535 // This is still okay, as long as this activity is running under the 3536 // uid of the original calling activity. 3537 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3538 throw new SecurityException( 3539 "Calling activity in uid " + sourceRecord.app.uid 3540 + " must be system uid or original calling uid " 3541 + sourceRecord.launchedFromUid); 3542 } 3543 } 3544 targetUid = sourceRecord.launchedFromUid; 3545 targetPackage = sourceRecord.launchedFromPackage; 3546 } 3547 3548 // TODO: Switch to user app stacks here. 3549 try { 3550 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3551 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3552 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3553 return ret; 3554 } catch (SecurityException e) { 3555 // XXX need to figure out how to propagate to original app. 3556 // A SecurityException here is generally actually a fault of the original 3557 // calling activity (such as a fairly granting permissions), so propagate it 3558 // back to them. 3559 /* 3560 StringBuilder msg = new StringBuilder(); 3561 msg.append("While launching"); 3562 msg.append(intent.toString()); 3563 msg.append(": "); 3564 msg.append(e.getMessage()); 3565 */ 3566 throw e; 3567 } 3568 } 3569 3570 @Override 3571 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3572 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3573 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3574 enforceNotIsolatedCaller("startActivityAndWait"); 3575 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3576 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3577 WaitResult res = new WaitResult(); 3578 // TODO: Switch to user app stacks here. 3579 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3580 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3581 options, userId, null, null); 3582 return res; 3583 } 3584 3585 @Override 3586 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3587 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3588 int startFlags, Configuration config, Bundle options, int userId) { 3589 enforceNotIsolatedCaller("startActivityWithConfig"); 3590 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3591 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3592 // TODO: Switch to user app stacks here. 3593 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3594 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3595 null, null, config, options, userId, null, null); 3596 return ret; 3597 } 3598 3599 @Override 3600 public int startActivityIntentSender(IApplicationThread caller, 3601 IntentSender intent, Intent fillInIntent, String resolvedType, 3602 IBinder resultTo, String resultWho, int requestCode, 3603 int flagsMask, int flagsValues, Bundle options) { 3604 enforceNotIsolatedCaller("startActivityIntentSender"); 3605 // Refuse possible leaked file descriptors 3606 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3607 throw new IllegalArgumentException("File descriptors passed in Intent"); 3608 } 3609 3610 IIntentSender sender = intent.getTarget(); 3611 if (!(sender instanceof PendingIntentRecord)) { 3612 throw new IllegalArgumentException("Bad PendingIntent object"); 3613 } 3614 3615 PendingIntentRecord pir = (PendingIntentRecord)sender; 3616 3617 synchronized (this) { 3618 // If this is coming from the currently resumed activity, it is 3619 // effectively saying that app switches are allowed at this point. 3620 final ActivityStack stack = getFocusedStack(); 3621 if (stack.mResumedActivity != null && 3622 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3623 mAppSwitchesAllowedTime = 0; 3624 } 3625 } 3626 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3627 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3628 return ret; 3629 } 3630 3631 @Override 3632 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3633 Intent intent, String resolvedType, IVoiceInteractionSession session, 3634 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3635 Bundle options, int userId) { 3636 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3637 != PackageManager.PERMISSION_GRANTED) { 3638 String msg = "Permission Denial: startVoiceActivity() from pid=" 3639 + Binder.getCallingPid() 3640 + ", uid=" + Binder.getCallingUid() 3641 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3642 Slog.w(TAG, msg); 3643 throw new SecurityException(msg); 3644 } 3645 if (session == null || interactor == null) { 3646 throw new NullPointerException("null session or interactor"); 3647 } 3648 userId = handleIncomingUser(callingPid, callingUid, userId, 3649 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3650 // TODO: Switch to user app stacks here. 3651 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3652 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3653 null, options, userId, null, null); 3654 } 3655 3656 @Override 3657 public boolean startNextMatchingActivity(IBinder callingActivity, 3658 Intent intent, Bundle options) { 3659 // Refuse possible leaked file descriptors 3660 if (intent != null && intent.hasFileDescriptors() == true) { 3661 throw new IllegalArgumentException("File descriptors passed in Intent"); 3662 } 3663 3664 synchronized (this) { 3665 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3666 if (r == null) { 3667 ActivityOptions.abort(options); 3668 return false; 3669 } 3670 if (r.app == null || r.app.thread == null) { 3671 // The caller is not running... d'oh! 3672 ActivityOptions.abort(options); 3673 return false; 3674 } 3675 intent = new Intent(intent); 3676 // The caller is not allowed to change the data. 3677 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3678 // And we are resetting to find the next component... 3679 intent.setComponent(null); 3680 3681 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3682 3683 ActivityInfo aInfo = null; 3684 try { 3685 List<ResolveInfo> resolves = 3686 AppGlobals.getPackageManager().queryIntentActivities( 3687 intent, r.resolvedType, 3688 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3689 UserHandle.getCallingUserId()); 3690 3691 // Look for the original activity in the list... 3692 final int N = resolves != null ? resolves.size() : 0; 3693 for (int i=0; i<N; i++) { 3694 ResolveInfo rInfo = resolves.get(i); 3695 if (rInfo.activityInfo.packageName.equals(r.packageName) 3696 && rInfo.activityInfo.name.equals(r.info.name)) { 3697 // We found the current one... the next matching is 3698 // after it. 3699 i++; 3700 if (i<N) { 3701 aInfo = resolves.get(i).activityInfo; 3702 } 3703 if (debug) { 3704 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3705 + "/" + r.info.name); 3706 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3707 + "/" + aInfo.name); 3708 } 3709 break; 3710 } 3711 } 3712 } catch (RemoteException e) { 3713 } 3714 3715 if (aInfo == null) { 3716 // Nobody who is next! 3717 ActivityOptions.abort(options); 3718 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3719 return false; 3720 } 3721 3722 intent.setComponent(new ComponentName( 3723 aInfo.applicationInfo.packageName, aInfo.name)); 3724 intent.setFlags(intent.getFlags()&~( 3725 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3726 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3727 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3728 Intent.FLAG_ACTIVITY_NEW_TASK)); 3729 3730 // Okay now we need to start the new activity, replacing the 3731 // currently running activity. This is a little tricky because 3732 // we want to start the new one as if the current one is finished, 3733 // but not finish the current one first so that there is no flicker. 3734 // And thus... 3735 final boolean wasFinishing = r.finishing; 3736 r.finishing = true; 3737 3738 // Propagate reply information over to the new activity. 3739 final ActivityRecord resultTo = r.resultTo; 3740 final String resultWho = r.resultWho; 3741 final int requestCode = r.requestCode; 3742 r.resultTo = null; 3743 if (resultTo != null) { 3744 resultTo.removeResultsLocked(r, resultWho, requestCode); 3745 } 3746 3747 final long origId = Binder.clearCallingIdentity(); 3748 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3749 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3750 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3751 options, false, null, null, null); 3752 Binder.restoreCallingIdentity(origId); 3753 3754 r.finishing = wasFinishing; 3755 if (res != ActivityManager.START_SUCCESS) { 3756 return false; 3757 } 3758 return true; 3759 } 3760 } 3761 3762 @Override 3763 public final int startActivityFromRecents(int taskId, Bundle options) { 3764 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3765 String msg = "Permission Denial: startActivityFromRecents called without " + 3766 START_TASKS_FROM_RECENTS; 3767 Slog.w(TAG, msg); 3768 throw new SecurityException(msg); 3769 } 3770 return startActivityFromRecentsInner(taskId, options); 3771 } 3772 3773 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3774 final TaskRecord task; 3775 final int callingUid; 3776 final String callingPackage; 3777 final Intent intent; 3778 final int userId; 3779 synchronized (this) { 3780 task = recentTaskForIdLocked(taskId); 3781 if (task == null) { 3782 throw new IllegalArgumentException("Task " + taskId + " not found."); 3783 } 3784 callingUid = task.mCallingUid; 3785 callingPackage = task.mCallingPackage; 3786 intent = task.intent; 3787 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3788 userId = task.userId; 3789 } 3790 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3791 options, userId, null, task); 3792 } 3793 3794 final int startActivityInPackage(int uid, String callingPackage, 3795 Intent intent, String resolvedType, IBinder resultTo, 3796 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3797 IActivityContainer container, TaskRecord inTask) { 3798 3799 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3800 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3801 3802 // TODO: Switch to user app stacks here. 3803 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3804 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3805 null, null, null, options, userId, container, inTask); 3806 return ret; 3807 } 3808 3809 @Override 3810 public final int startActivities(IApplicationThread caller, String callingPackage, 3811 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3812 int userId) { 3813 enforceNotIsolatedCaller("startActivities"); 3814 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3815 false, ALLOW_FULL_ONLY, "startActivity", null); 3816 // TODO: Switch to user app stacks here. 3817 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3818 resolvedTypes, resultTo, options, userId); 3819 return ret; 3820 } 3821 3822 final int startActivitiesInPackage(int uid, String callingPackage, 3823 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3824 Bundle options, int userId) { 3825 3826 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3827 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3828 // TODO: Switch to user app stacks here. 3829 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3830 resultTo, options, userId); 3831 return ret; 3832 } 3833 3834 //explicitly remove thd old information in mRecentTasks when removing existing user. 3835 private void removeRecentTasksForUserLocked(int userId) { 3836 if(userId <= 0) { 3837 Slog.i(TAG, "Can't remove recent task on user " + userId); 3838 return; 3839 } 3840 3841 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3842 TaskRecord tr = mRecentTasks.get(i); 3843 if (tr.userId == userId) { 3844 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3845 + " when finishing user" + userId); 3846 mRecentTasks.remove(i); 3847 tr.removedFromRecents(mTaskPersister); 3848 } 3849 } 3850 3851 // Remove tasks from persistent storage. 3852 mTaskPersister.wakeup(null, true); 3853 } 3854 3855 /** 3856 * Update the recent tasks lists: make sure tasks should still be here (their 3857 * applications / activities still exist), update their availability, fixup ordering 3858 * of affiliations. 3859 */ 3860 void cleanupRecentTasksLocked(int userId) { 3861 if (mRecentTasks == null) { 3862 // Happens when called from the packagemanager broadcast before boot. 3863 return; 3864 } 3865 3866 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3867 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3868 final IPackageManager pm = AppGlobals.getPackageManager(); 3869 final ActivityInfo dummyAct = new ActivityInfo(); 3870 final ApplicationInfo dummyApp = new ApplicationInfo(); 3871 3872 int N = mRecentTasks.size(); 3873 3874 int[] users = userId == UserHandle.USER_ALL 3875 ? getUsersLocked() : new int[] { userId }; 3876 for (int user : users) { 3877 for (int i = 0; i < N; i++) { 3878 TaskRecord task = mRecentTasks.get(i); 3879 if (task.userId != user) { 3880 // Only look at tasks for the user ID of interest. 3881 continue; 3882 } 3883 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3884 // This situation is broken, and we should just get rid of it now. 3885 mRecentTasks.remove(i); 3886 task.removedFromRecents(mTaskPersister); 3887 i--; 3888 N--; 3889 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3890 continue; 3891 } 3892 // Check whether this activity is currently available. 3893 if (task.realActivity != null) { 3894 ActivityInfo ai = availActCache.get(task.realActivity); 3895 if (ai == null) { 3896 try { 3897 ai = pm.getActivityInfo(task.realActivity, 3898 PackageManager.GET_UNINSTALLED_PACKAGES 3899 | PackageManager.GET_DISABLED_COMPONENTS, user); 3900 } catch (RemoteException e) { 3901 // Will never happen. 3902 continue; 3903 } 3904 if (ai == null) { 3905 ai = dummyAct; 3906 } 3907 availActCache.put(task.realActivity, ai); 3908 } 3909 if (ai == dummyAct) { 3910 // This could be either because the activity no longer exists, or the 3911 // app is temporarily gone. For the former we want to remove the recents 3912 // entry; for the latter we want to mark it as unavailable. 3913 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3914 if (app == null) { 3915 try { 3916 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3917 PackageManager.GET_UNINSTALLED_PACKAGES 3918 | PackageManager.GET_DISABLED_COMPONENTS, user); 3919 } catch (RemoteException e) { 3920 // Will never happen. 3921 continue; 3922 } 3923 if (app == null) { 3924 app = dummyApp; 3925 } 3926 availAppCache.put(task.realActivity.getPackageName(), app); 3927 } 3928 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3929 // Doesn't exist any more! Good-bye. 3930 mRecentTasks.remove(i); 3931 task.removedFromRecents(mTaskPersister); 3932 i--; 3933 N--; 3934 Slog.w(TAG, "Removing no longer valid recent: " + task); 3935 continue; 3936 } else { 3937 // Otherwise just not available for now. 3938 if (task.isAvailable) { 3939 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3940 + task); 3941 } 3942 task.isAvailable = false; 3943 } 3944 } else { 3945 if (!ai.enabled || !ai.applicationInfo.enabled 3946 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3947 if (task.isAvailable) { 3948 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3949 + task + " (enabled=" + ai.enabled + "/" 3950 + ai.applicationInfo.enabled + " flags=" 3951 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3952 } 3953 task.isAvailable = false; 3954 } else { 3955 if (!task.isAvailable) { 3956 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3957 + task); 3958 } 3959 task.isAvailable = true; 3960 } 3961 } 3962 } 3963 } 3964 } 3965 3966 // Verify the affiliate chain for each task. 3967 for (int i = 0; i < N; ) { 3968 TaskRecord task = mRecentTasks.remove(i); 3969 if (mTmpRecents.contains(task)) { 3970 continue; 3971 } 3972 int affiliatedTaskId = task.mAffiliatedTaskId; 3973 while (true) { 3974 TaskRecord next = task.mNextAffiliate; 3975 if (next == null) { 3976 break; 3977 } 3978 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3979 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3980 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3981 task.setNextAffiliate(null); 3982 if (next.mPrevAffiliate == task) { 3983 next.setPrevAffiliate(null); 3984 } 3985 break; 3986 } 3987 if (next.mPrevAffiliate != task) { 3988 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3989 next.mPrevAffiliate + " task=" + task); 3990 next.setPrevAffiliate(null); 3991 task.setNextAffiliate(null); 3992 break; 3993 } 3994 if (!mRecentTasks.contains(next)) { 3995 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3996 task.setNextAffiliate(null); 3997 // We know that next.mPrevAffiliate is always task, from above, so clear 3998 // its previous affiliate. 3999 next.setPrevAffiliate(null); 4000 break; 4001 } 4002 task = next; 4003 } 4004 // task is now the end of the list 4005 do { 4006 mRecentTasks.remove(task); 4007 mRecentTasks.add(i++, task); 4008 mTmpRecents.add(task); 4009 task.inRecents = true; 4010 } while ((task = task.mPrevAffiliate) != null); 4011 } 4012 mTmpRecents.clear(); 4013 // mRecentTasks is now in sorted, affiliated order. 4014 } 4015 4016 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4017 int N = mRecentTasks.size(); 4018 TaskRecord top = task; 4019 int topIndex = taskIndex; 4020 while (top.mNextAffiliate != null && topIndex > 0) { 4021 top = top.mNextAffiliate; 4022 topIndex--; 4023 } 4024 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4025 + topIndex + " from intial " + taskIndex); 4026 // Find the end of the chain, doing a sanity check along the way. 4027 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4028 int endIndex = topIndex; 4029 TaskRecord prev = top; 4030 while (endIndex < N) { 4031 TaskRecord cur = mRecentTasks.get(endIndex); 4032 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4033 + endIndex + " " + cur); 4034 if (cur == top) { 4035 // Verify start of the chain. 4036 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4037 Slog.wtf(TAG, "Bad chain @" + endIndex 4038 + ": first task has next affiliate: " + prev); 4039 sane = false; 4040 break; 4041 } 4042 } else { 4043 // Verify middle of the chain's next points back to the one before. 4044 if (cur.mNextAffiliate != prev 4045 || cur.mNextAffiliateTaskId != prev.taskId) { 4046 Slog.wtf(TAG, "Bad chain @" + endIndex 4047 + ": middle task " + cur + " @" + endIndex 4048 + " has bad next affiliate " 4049 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4050 + ", expected " + prev); 4051 sane = false; 4052 break; 4053 } 4054 } 4055 if (cur.mPrevAffiliateTaskId == -1) { 4056 // Chain ends here. 4057 if (cur.mPrevAffiliate != null) { 4058 Slog.wtf(TAG, "Bad chain @" + endIndex 4059 + ": last task " + cur + " has previous affiliate " 4060 + cur.mPrevAffiliate); 4061 sane = false; 4062 } 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4064 break; 4065 } else { 4066 // Verify middle of the chain's prev points to a valid item. 4067 if (cur.mPrevAffiliate == null) { 4068 Slog.wtf(TAG, "Bad chain @" + endIndex 4069 + ": task " + cur + " has previous affiliate " 4070 + cur.mPrevAffiliate + " but should be id " 4071 + cur.mPrevAffiliate); 4072 sane = false; 4073 break; 4074 } 4075 } 4076 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4077 Slog.wtf(TAG, "Bad chain @" + endIndex 4078 + ": task " + cur + " has affiliated id " 4079 + cur.mAffiliatedTaskId + " but should be " 4080 + task.mAffiliatedTaskId); 4081 sane = false; 4082 break; 4083 } 4084 prev = cur; 4085 endIndex++; 4086 if (endIndex >= N) { 4087 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4088 + ": last task " + prev); 4089 sane = false; 4090 break; 4091 } 4092 } 4093 if (sane) { 4094 if (endIndex < taskIndex) { 4095 Slog.wtf(TAG, "Bad chain @" + endIndex 4096 + ": did not extend to task " + task + " @" + taskIndex); 4097 sane = false; 4098 } 4099 } 4100 if (sane) { 4101 // All looks good, we can just move all of the affiliated tasks 4102 // to the top. 4103 for (int i=topIndex; i<=endIndex; i++) { 4104 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4105 + " from " + i + " to " + (i-topIndex)); 4106 TaskRecord cur = mRecentTasks.remove(i); 4107 mRecentTasks.add(i-topIndex, cur); 4108 } 4109 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4110 + " to " + endIndex); 4111 return true; 4112 } 4113 4114 // Whoops, couldn't do it. 4115 return false; 4116 } 4117 4118 final void addRecentTaskLocked(TaskRecord task) { 4119 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4120 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4121 4122 int N = mRecentTasks.size(); 4123 // Quick case: check if the top-most recent task is the same. 4124 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4125 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4126 return; 4127 } 4128 // Another quick case: check if this is part of a set of affiliated 4129 // tasks that are at the top. 4130 if (isAffiliated && N > 0 && task.inRecents 4131 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4133 + " at top when adding " + task); 4134 return; 4135 } 4136 // Another quick case: never add voice sessions. 4137 if (task.voiceSession != null) { 4138 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4139 return; 4140 } 4141 4142 boolean needAffiliationFix = false; 4143 4144 // Slightly less quick case: the task is already in recents, so all we need 4145 // to do is move it. 4146 if (task.inRecents) { 4147 int taskIndex = mRecentTasks.indexOf(task); 4148 if (taskIndex >= 0) { 4149 if (!isAffiliated) { 4150 // Simple case: this is not an affiliated task, so we just move it to the front. 4151 mRecentTasks.remove(taskIndex); 4152 mRecentTasks.add(0, task); 4153 notifyTaskPersisterLocked(task, false); 4154 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4155 + " from " + taskIndex); 4156 return; 4157 } else { 4158 // More complicated: need to keep all affiliated tasks together. 4159 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4160 // All went well. 4161 return; 4162 } 4163 4164 // Uh oh... something bad in the affiliation chain, try to rebuild 4165 // everything and then go through our general path of adding a new task. 4166 needAffiliationFix = true; 4167 } 4168 } else { 4169 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4170 needAffiliationFix = true; 4171 } 4172 } 4173 4174 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4175 trimRecentsForTask(task, true); 4176 4177 N = mRecentTasks.size(); 4178 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4179 final TaskRecord tr = mRecentTasks.remove(N - 1); 4180 tr.removedFromRecents(mTaskPersister); 4181 N--; 4182 } 4183 task.inRecents = true; 4184 if (!isAffiliated || needAffiliationFix) { 4185 // If this is a simple non-affiliated task, or we had some failure trying to 4186 // handle it as part of an affilated task, then just place it at the top. 4187 mRecentTasks.add(0, task); 4188 } else if (isAffiliated) { 4189 // If this is a new affiliated task, then move all of the affiliated tasks 4190 // to the front and insert this new one. 4191 TaskRecord other = task.mNextAffiliate; 4192 if (other == null) { 4193 other = task.mPrevAffiliate; 4194 } 4195 if (other != null) { 4196 int otherIndex = mRecentTasks.indexOf(other); 4197 if (otherIndex >= 0) { 4198 // Insert new task at appropriate location. 4199 int taskIndex; 4200 if (other == task.mNextAffiliate) { 4201 // We found the index of our next affiliation, which is who is 4202 // before us in the list, so add after that point. 4203 taskIndex = otherIndex+1; 4204 } else { 4205 // We found the index of our previous affiliation, which is who is 4206 // after us in the list, so add at their position. 4207 taskIndex = otherIndex; 4208 } 4209 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4210 + taskIndex + ": " + task); 4211 mRecentTasks.add(taskIndex, task); 4212 4213 // Now move everything to the front. 4214 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4215 // All went well. 4216 return; 4217 } 4218 4219 // Uh oh... something bad in the affiliation chain, try to rebuild 4220 // everything and then go through our general path of adding a new task. 4221 needAffiliationFix = true; 4222 } else { 4223 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4224 + other); 4225 needAffiliationFix = true; 4226 } 4227 } else { 4228 if (DEBUG_RECENTS) Slog.d(TAG, 4229 "addRecent: adding affiliated task without next/prev:" + task); 4230 needAffiliationFix = true; 4231 } 4232 } 4233 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4234 4235 if (needAffiliationFix) { 4236 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4237 cleanupRecentTasksLocked(task.userId); 4238 } 4239 } 4240 4241 /** 4242 * If needed, remove oldest existing entries in recents that are for the same kind 4243 * of task as the given one. 4244 */ 4245 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4246 int N = mRecentTasks.size(); 4247 final Intent intent = task.intent; 4248 final boolean document = intent != null && intent.isDocument(); 4249 4250 int maxRecents = task.maxRecents - 1; 4251 for (int i=0; i<N; i++) { 4252 final TaskRecord tr = mRecentTasks.get(i); 4253 if (task != tr) { 4254 if (task.userId != tr.userId) { 4255 continue; 4256 } 4257 if (i > MAX_RECENT_BITMAPS) { 4258 tr.freeLastThumbnail(); 4259 } 4260 final Intent trIntent = tr.intent; 4261 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4262 (intent == null || !intent.filterEquals(trIntent))) { 4263 continue; 4264 } 4265 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4266 if (document && trIsDocument) { 4267 // These are the same document activity (not necessarily the same doc). 4268 if (maxRecents > 0) { 4269 --maxRecents; 4270 continue; 4271 } 4272 // Hit the maximum number of documents for this task. Fall through 4273 // and remove this document from recents. 4274 } else if (document || trIsDocument) { 4275 // Only one of these is a document. Not the droid we're looking for. 4276 continue; 4277 } 4278 } 4279 4280 if (!doTrim) { 4281 // If the caller is not actually asking for a trim, just tell them we reached 4282 // a point where the trim would happen. 4283 return i; 4284 } 4285 4286 // Either task and tr are the same or, their affinities match or their intents match 4287 // and neither of them is a document, or they are documents using the same activity 4288 // and their maxRecents has been reached. 4289 tr.disposeThumbnail(); 4290 mRecentTasks.remove(i); 4291 if (task != tr) { 4292 tr.removedFromRecents(mTaskPersister); 4293 } 4294 i--; 4295 N--; 4296 if (task.intent == null) { 4297 // If the new recent task we are adding is not fully 4298 // specified, then replace it with the existing recent task. 4299 task = tr; 4300 } 4301 notifyTaskPersisterLocked(tr, false); 4302 } 4303 4304 return -1; 4305 } 4306 4307 @Override 4308 public void reportActivityFullyDrawn(IBinder token) { 4309 synchronized (this) { 4310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4311 if (r == null) { 4312 return; 4313 } 4314 r.reportFullyDrawnLocked(); 4315 } 4316 } 4317 4318 @Override 4319 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4320 synchronized (this) { 4321 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4322 if (r == null) { 4323 return; 4324 } 4325 final long origId = Binder.clearCallingIdentity(); 4326 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4327 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4328 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4329 if (config != null) { 4330 r.frozenBeforeDestroy = true; 4331 if (!updateConfigurationLocked(config, r, false, false)) { 4332 mStackSupervisor.resumeTopActivitiesLocked(); 4333 } 4334 } 4335 Binder.restoreCallingIdentity(origId); 4336 } 4337 } 4338 4339 @Override 4340 public int getRequestedOrientation(IBinder token) { 4341 synchronized (this) { 4342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4343 if (r == null) { 4344 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4345 } 4346 return mWindowManager.getAppOrientation(r.appToken); 4347 } 4348 } 4349 4350 /** 4351 * This is the internal entry point for handling Activity.finish(). 4352 * 4353 * @param token The Binder token referencing the Activity we want to finish. 4354 * @param resultCode Result code, if any, from this Activity. 4355 * @param resultData Result data (Intent), if any, from this Activity. 4356 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4357 * the root Activity in the task. 4358 * 4359 * @return Returns true if the activity successfully finished, or false if it is still running. 4360 */ 4361 @Override 4362 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4363 boolean finishTask) { 4364 // Refuse possible leaked file descriptors 4365 if (resultData != null && resultData.hasFileDescriptors() == true) { 4366 throw new IllegalArgumentException("File descriptors passed in Intent"); 4367 } 4368 4369 synchronized(this) { 4370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4371 if (r == null) { 4372 return true; 4373 } 4374 // Keep track of the root activity of the task before we finish it 4375 TaskRecord tr = r.task; 4376 ActivityRecord rootR = tr.getRootActivity(); 4377 // Do not allow task to finish in Lock Task mode. 4378 if (tr == mStackSupervisor.mLockTaskModeTask) { 4379 if (rootR == r) { 4380 mStackSupervisor.showLockTaskToast(); 4381 return false; 4382 } 4383 } 4384 if (mController != null) { 4385 // Find the first activity that is not finishing. 4386 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4387 if (next != null) { 4388 // ask watcher if this is allowed 4389 boolean resumeOK = true; 4390 try { 4391 resumeOK = mController.activityResuming(next.packageName); 4392 } catch (RemoteException e) { 4393 mController = null; 4394 Watchdog.getInstance().setActivityController(null); 4395 } 4396 4397 if (!resumeOK) { 4398 return false; 4399 } 4400 } 4401 } 4402 final long origId = Binder.clearCallingIdentity(); 4403 try { 4404 boolean res; 4405 if (finishTask && r == rootR) { 4406 // If requested, remove the task that is associated to this activity only if it 4407 // was the root activity in the task. The result code and data is ignored because 4408 // we don't support returning them across task boundaries. 4409 res = removeTaskByIdLocked(tr.taskId, 0); 4410 } else { 4411 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4412 resultData, "app-request", true); 4413 } 4414 return res; 4415 } finally { 4416 Binder.restoreCallingIdentity(origId); 4417 } 4418 } 4419 } 4420 4421 @Override 4422 public final void finishHeavyWeightApp() { 4423 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4424 != PackageManager.PERMISSION_GRANTED) { 4425 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4426 + Binder.getCallingPid() 4427 + ", uid=" + Binder.getCallingUid() 4428 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4429 Slog.w(TAG, msg); 4430 throw new SecurityException(msg); 4431 } 4432 4433 synchronized(this) { 4434 if (mHeavyWeightProcess == null) { 4435 return; 4436 } 4437 4438 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4439 mHeavyWeightProcess.activities); 4440 for (int i=0; i<activities.size(); i++) { 4441 ActivityRecord r = activities.get(i); 4442 if (!r.finishing) { 4443 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4444 null, "finish-heavy", true); 4445 } 4446 } 4447 4448 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4449 mHeavyWeightProcess.userId, 0)); 4450 mHeavyWeightProcess = null; 4451 } 4452 } 4453 4454 @Override 4455 public void crashApplication(int uid, int initialPid, String packageName, 4456 String message) { 4457 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4458 != PackageManager.PERMISSION_GRANTED) { 4459 String msg = "Permission Denial: crashApplication() from pid=" 4460 + Binder.getCallingPid() 4461 + ", uid=" + Binder.getCallingUid() 4462 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4463 Slog.w(TAG, msg); 4464 throw new SecurityException(msg); 4465 } 4466 4467 synchronized(this) { 4468 ProcessRecord proc = null; 4469 4470 // Figure out which process to kill. We don't trust that initialPid 4471 // still has any relation to current pids, so must scan through the 4472 // list. 4473 synchronized (mPidsSelfLocked) { 4474 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4475 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4476 if (p.uid != uid) { 4477 continue; 4478 } 4479 if (p.pid == initialPid) { 4480 proc = p; 4481 break; 4482 } 4483 if (p.pkgList.containsKey(packageName)) { 4484 proc = p; 4485 } 4486 } 4487 } 4488 4489 if (proc == null) { 4490 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4491 + " initialPid=" + initialPid 4492 + " packageName=" + packageName); 4493 return; 4494 } 4495 4496 if (proc.thread != null) { 4497 if (proc.pid == Process.myPid()) { 4498 Log.w(TAG, "crashApplication: trying to crash self!"); 4499 return; 4500 } 4501 long ident = Binder.clearCallingIdentity(); 4502 try { 4503 proc.thread.scheduleCrash(message); 4504 } catch (RemoteException e) { 4505 } 4506 Binder.restoreCallingIdentity(ident); 4507 } 4508 } 4509 } 4510 4511 @Override 4512 public final void finishSubActivity(IBinder token, String resultWho, 4513 int requestCode) { 4514 synchronized(this) { 4515 final long origId = Binder.clearCallingIdentity(); 4516 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4517 if (r != null) { 4518 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4519 } 4520 Binder.restoreCallingIdentity(origId); 4521 } 4522 } 4523 4524 @Override 4525 public boolean finishActivityAffinity(IBinder token) { 4526 synchronized(this) { 4527 final long origId = Binder.clearCallingIdentity(); 4528 try { 4529 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4530 4531 ActivityRecord rootR = r.task.getRootActivity(); 4532 // Do not allow task to finish in Lock Task mode. 4533 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4534 if (rootR == r) { 4535 mStackSupervisor.showLockTaskToast(); 4536 return false; 4537 } 4538 } 4539 boolean res = false; 4540 if (r != null) { 4541 res = r.task.stack.finishActivityAffinityLocked(r); 4542 } 4543 return res; 4544 } finally { 4545 Binder.restoreCallingIdentity(origId); 4546 } 4547 } 4548 } 4549 4550 @Override 4551 public void finishVoiceTask(IVoiceInteractionSession session) { 4552 synchronized(this) { 4553 final long origId = Binder.clearCallingIdentity(); 4554 try { 4555 mStackSupervisor.finishVoiceTask(session); 4556 } finally { 4557 Binder.restoreCallingIdentity(origId); 4558 } 4559 } 4560 4561 } 4562 4563 @Override 4564 public boolean releaseActivityInstance(IBinder token) { 4565 synchronized(this) { 4566 final long origId = Binder.clearCallingIdentity(); 4567 try { 4568 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4569 if (r.task == null || r.task.stack == null) { 4570 return false; 4571 } 4572 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4573 } finally { 4574 Binder.restoreCallingIdentity(origId); 4575 } 4576 } 4577 } 4578 4579 @Override 4580 public void releaseSomeActivities(IApplicationThread appInt) { 4581 synchronized(this) { 4582 final long origId = Binder.clearCallingIdentity(); 4583 try { 4584 ProcessRecord app = getRecordForAppLocked(appInt); 4585 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4586 } finally { 4587 Binder.restoreCallingIdentity(origId); 4588 } 4589 } 4590 } 4591 4592 @Override 4593 public boolean willActivityBeVisible(IBinder token) { 4594 synchronized(this) { 4595 ActivityStack stack = ActivityRecord.getStackLocked(token); 4596 if (stack != null) { 4597 return stack.willActivityBeVisibleLocked(token); 4598 } 4599 return false; 4600 } 4601 } 4602 4603 @Override 4604 public void overridePendingTransition(IBinder token, String packageName, 4605 int enterAnim, int exitAnim) { 4606 synchronized(this) { 4607 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4608 if (self == null) { 4609 return; 4610 } 4611 4612 final long origId = Binder.clearCallingIdentity(); 4613 4614 if (self.state == ActivityState.RESUMED 4615 || self.state == ActivityState.PAUSING) { 4616 mWindowManager.overridePendingAppTransition(packageName, 4617 enterAnim, exitAnim, null); 4618 } 4619 4620 Binder.restoreCallingIdentity(origId); 4621 } 4622 } 4623 4624 /** 4625 * Main function for removing an existing process from the activity manager 4626 * as a result of that process going away. Clears out all connections 4627 * to the process. 4628 */ 4629 private final void handleAppDiedLocked(ProcessRecord app, 4630 boolean restarting, boolean allowRestart) { 4631 int pid = app.pid; 4632 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4633 if (!restarting) { 4634 removeLruProcessLocked(app); 4635 if (pid > 0) { 4636 ProcessList.remove(pid); 4637 } 4638 } 4639 4640 if (mProfileProc == app) { 4641 clearProfilerLocked(); 4642 } 4643 4644 // Remove this application's activities from active lists. 4645 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4646 4647 app.activities.clear(); 4648 4649 if (app.instrumentationClass != null) { 4650 Slog.w(TAG, "Crash of app " + app.processName 4651 + " running instrumentation " + app.instrumentationClass); 4652 Bundle info = new Bundle(); 4653 info.putString("shortMsg", "Process crashed."); 4654 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4655 } 4656 4657 if (!restarting) { 4658 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4659 // If there was nothing to resume, and we are not already 4660 // restarting this process, but there is a visible activity that 4661 // is hosted by the process... then make sure all visible 4662 // activities are running, taking care of restarting this 4663 // process. 4664 if (hasVisibleActivities) { 4665 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4666 } 4667 } 4668 } 4669 } 4670 4671 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4672 IBinder threadBinder = thread.asBinder(); 4673 // Find the application record. 4674 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4675 ProcessRecord rec = mLruProcesses.get(i); 4676 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4677 return i; 4678 } 4679 } 4680 return -1; 4681 } 4682 4683 final ProcessRecord getRecordForAppLocked( 4684 IApplicationThread thread) { 4685 if (thread == null) { 4686 return null; 4687 } 4688 4689 int appIndex = getLRURecordIndexForAppLocked(thread); 4690 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4691 } 4692 4693 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4694 // If there are no longer any background processes running, 4695 // and the app that died was not running instrumentation, 4696 // then tell everyone we are now low on memory. 4697 boolean haveBg = false; 4698 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4699 ProcessRecord rec = mLruProcesses.get(i); 4700 if (rec.thread != null 4701 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4702 haveBg = true; 4703 break; 4704 } 4705 } 4706 4707 if (!haveBg) { 4708 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4709 if (doReport) { 4710 long now = SystemClock.uptimeMillis(); 4711 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4712 doReport = false; 4713 } else { 4714 mLastMemUsageReportTime = now; 4715 } 4716 } 4717 final ArrayList<ProcessMemInfo> memInfos 4718 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4719 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4720 long now = SystemClock.uptimeMillis(); 4721 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4722 ProcessRecord rec = mLruProcesses.get(i); 4723 if (rec == dyingProc || rec.thread == null) { 4724 continue; 4725 } 4726 if (doReport) { 4727 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4728 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4729 } 4730 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4731 // The low memory report is overriding any current 4732 // state for a GC request. Make sure to do 4733 // heavy/important/visible/foreground processes first. 4734 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4735 rec.lastRequestedGc = 0; 4736 } else { 4737 rec.lastRequestedGc = rec.lastLowMemory; 4738 } 4739 rec.reportLowMemory = true; 4740 rec.lastLowMemory = now; 4741 mProcessesToGc.remove(rec); 4742 addProcessToGcListLocked(rec); 4743 } 4744 } 4745 if (doReport) { 4746 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4747 mHandler.sendMessage(msg); 4748 } 4749 scheduleAppGcsLocked(); 4750 } 4751 } 4752 4753 final void appDiedLocked(ProcessRecord app) { 4754 appDiedLocked(app, app.pid, app.thread); 4755 } 4756 4757 final void appDiedLocked(ProcessRecord app, int pid, 4758 IApplicationThread thread) { 4759 4760 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4761 synchronized (stats) { 4762 stats.noteProcessDiedLocked(app.info.uid, pid); 4763 } 4764 4765 Process.killProcessGroup(app.info.uid, pid); 4766 4767 // Clean up already done if the process has been re-started. 4768 if (app.pid == pid && app.thread != null && 4769 app.thread.asBinder() == thread.asBinder()) { 4770 boolean doLowMem = app.instrumentationClass == null; 4771 boolean doOomAdj = doLowMem; 4772 if (!app.killedByAm) { 4773 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4774 + ") has died."); 4775 mAllowLowerMemLevel = true; 4776 } else { 4777 // Note that we always want to do oom adj to update our state with the 4778 // new number of procs. 4779 mAllowLowerMemLevel = false; 4780 doLowMem = false; 4781 } 4782 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4783 if (DEBUG_CLEANUP) Slog.v( 4784 TAG, "Dying app: " + app + ", pid: " + pid 4785 + ", thread: " + thread.asBinder()); 4786 handleAppDiedLocked(app, false, true); 4787 4788 if (doOomAdj) { 4789 updateOomAdjLocked(); 4790 } 4791 if (doLowMem) { 4792 doLowMemReportIfNeededLocked(app); 4793 } 4794 } else if (app.pid != pid) { 4795 // A new process has already been started. 4796 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4797 + ") has died and restarted (pid " + app.pid + ")."); 4798 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4799 } else if (DEBUG_PROCESSES) { 4800 Slog.d(TAG, "Received spurious death notification for thread " 4801 + thread.asBinder()); 4802 } 4803 } 4804 4805 /** 4806 * If a stack trace dump file is configured, dump process stack traces. 4807 * @param clearTraces causes the dump file to be erased prior to the new 4808 * traces being written, if true; when false, the new traces will be 4809 * appended to any existing file content. 4810 * @param firstPids of dalvik VM processes to dump stack traces for first 4811 * @param lastPids of dalvik VM processes to dump stack traces for last 4812 * @param nativeProcs optional list of native process names to dump stack crawls 4813 * @return file containing stack traces, or null if no dump file is configured 4814 */ 4815 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4816 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4818 if (tracesPath == null || tracesPath.length() == 0) { 4819 return null; 4820 } 4821 4822 File tracesFile = new File(tracesPath); 4823 try { 4824 File tracesDir = tracesFile.getParentFile(); 4825 if (!tracesDir.exists()) { 4826 tracesFile.mkdirs(); 4827 if (!SELinux.restorecon(tracesDir)) { 4828 return null; 4829 } 4830 } 4831 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4832 4833 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4834 tracesFile.createNewFile(); 4835 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4836 } catch (IOException e) { 4837 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4838 return null; 4839 } 4840 4841 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4842 return tracesFile; 4843 } 4844 4845 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4846 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4847 // Use a FileObserver to detect when traces finish writing. 4848 // The order of traces is considered important to maintain for legibility. 4849 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4850 @Override 4851 public synchronized void onEvent(int event, String path) { notify(); } 4852 }; 4853 4854 try { 4855 observer.startWatching(); 4856 4857 // First collect all of the stacks of the most important pids. 4858 if (firstPids != null) { 4859 try { 4860 int num = firstPids.size(); 4861 for (int i = 0; i < num; i++) { 4862 synchronized (observer) { 4863 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4864 observer.wait(200); // Wait for write-close, give up after 200msec 4865 } 4866 } 4867 } catch (InterruptedException e) { 4868 Log.wtf(TAG, e); 4869 } 4870 } 4871 4872 // Next collect the stacks of the native pids 4873 if (nativeProcs != null) { 4874 int[] pids = Process.getPidsForCommands(nativeProcs); 4875 if (pids != null) { 4876 for (int pid : pids) { 4877 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4878 } 4879 } 4880 } 4881 4882 // Lastly, measure CPU usage. 4883 if (processCpuTracker != null) { 4884 processCpuTracker.init(); 4885 System.gc(); 4886 processCpuTracker.update(); 4887 try { 4888 synchronized (processCpuTracker) { 4889 processCpuTracker.wait(500); // measure over 1/2 second. 4890 } 4891 } catch (InterruptedException e) { 4892 } 4893 processCpuTracker.update(); 4894 4895 // We'll take the stack crawls of just the top apps using CPU. 4896 final int N = processCpuTracker.countWorkingStats(); 4897 int numProcs = 0; 4898 for (int i=0; i<N && numProcs<5; i++) { 4899 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4900 if (lastPids.indexOfKey(stats.pid) >= 0) { 4901 numProcs++; 4902 try { 4903 synchronized (observer) { 4904 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4905 observer.wait(200); // Wait for write-close, give up after 200msec 4906 } 4907 } catch (InterruptedException e) { 4908 Log.wtf(TAG, e); 4909 } 4910 4911 } 4912 } 4913 } 4914 } finally { 4915 observer.stopWatching(); 4916 } 4917 } 4918 4919 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4920 if (true || IS_USER_BUILD) { 4921 return; 4922 } 4923 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4924 if (tracesPath == null || tracesPath.length() == 0) { 4925 return; 4926 } 4927 4928 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4929 StrictMode.allowThreadDiskWrites(); 4930 try { 4931 final File tracesFile = new File(tracesPath); 4932 final File tracesDir = tracesFile.getParentFile(); 4933 final File tracesTmp = new File(tracesDir, "__tmp__"); 4934 try { 4935 if (!tracesDir.exists()) { 4936 tracesFile.mkdirs(); 4937 if (!SELinux.restorecon(tracesDir.getPath())) { 4938 return; 4939 } 4940 } 4941 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4942 4943 if (tracesFile.exists()) { 4944 tracesTmp.delete(); 4945 tracesFile.renameTo(tracesTmp); 4946 } 4947 StringBuilder sb = new StringBuilder(); 4948 Time tobj = new Time(); 4949 tobj.set(System.currentTimeMillis()); 4950 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4951 sb.append(": "); 4952 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4953 sb.append(" since "); 4954 sb.append(msg); 4955 FileOutputStream fos = new FileOutputStream(tracesFile); 4956 fos.write(sb.toString().getBytes()); 4957 if (app == null) { 4958 fos.write("\n*** No application process!".getBytes()); 4959 } 4960 fos.close(); 4961 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4962 } catch (IOException e) { 4963 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4964 return; 4965 } 4966 4967 if (app != null) { 4968 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4969 firstPids.add(app.pid); 4970 dumpStackTraces(tracesPath, firstPids, null, null, null); 4971 } 4972 4973 File lastTracesFile = null; 4974 File curTracesFile = null; 4975 for (int i=9; i>=0; i--) { 4976 String name = String.format(Locale.US, "slow%02d.txt", i); 4977 curTracesFile = new File(tracesDir, name); 4978 if (curTracesFile.exists()) { 4979 if (lastTracesFile != null) { 4980 curTracesFile.renameTo(lastTracesFile); 4981 } else { 4982 curTracesFile.delete(); 4983 } 4984 } 4985 lastTracesFile = curTracesFile; 4986 } 4987 tracesFile.renameTo(curTracesFile); 4988 if (tracesTmp.exists()) { 4989 tracesTmp.renameTo(tracesFile); 4990 } 4991 } finally { 4992 StrictMode.setThreadPolicy(oldPolicy); 4993 } 4994 } 4995 4996 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4997 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4998 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4999 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5000 5001 if (mController != null) { 5002 try { 5003 // 0 == continue, -1 = kill process immediately 5004 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5005 if (res < 0 && app.pid != MY_PID) { 5006 app.kill("anr", true); 5007 } 5008 } catch (RemoteException e) { 5009 mController = null; 5010 Watchdog.getInstance().setActivityController(null); 5011 } 5012 } 5013 5014 long anrTime = SystemClock.uptimeMillis(); 5015 if (MONITOR_CPU_USAGE) { 5016 updateCpuStatsNow(); 5017 } 5018 5019 synchronized (this) { 5020 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5021 if (mShuttingDown) { 5022 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5023 return; 5024 } else if (app.notResponding) { 5025 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5026 return; 5027 } else if (app.crashing) { 5028 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5029 return; 5030 } 5031 5032 // In case we come through here for the same app before completing 5033 // this one, mark as anring now so we will bail out. 5034 app.notResponding = true; 5035 5036 // Log the ANR to the event log. 5037 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5038 app.processName, app.info.flags, annotation); 5039 5040 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5041 firstPids.add(app.pid); 5042 5043 int parentPid = app.pid; 5044 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5045 if (parentPid != app.pid) firstPids.add(parentPid); 5046 5047 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5048 5049 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5050 ProcessRecord r = mLruProcesses.get(i); 5051 if (r != null && r.thread != null) { 5052 int pid = r.pid; 5053 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5054 if (r.persistent) { 5055 firstPids.add(pid); 5056 } else { 5057 lastPids.put(pid, Boolean.TRUE); 5058 } 5059 } 5060 } 5061 } 5062 } 5063 5064 // Log the ANR to the main log. 5065 StringBuilder info = new StringBuilder(); 5066 info.setLength(0); 5067 info.append("ANR in ").append(app.processName); 5068 if (activity != null && activity.shortComponentName != null) { 5069 info.append(" (").append(activity.shortComponentName).append(")"); 5070 } 5071 info.append("\n"); 5072 info.append("PID: ").append(app.pid).append("\n"); 5073 if (annotation != null) { 5074 info.append("Reason: ").append(annotation).append("\n"); 5075 } 5076 if (parent != null && parent != activity) { 5077 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5078 } 5079 5080 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5081 5082 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5083 NATIVE_STACKS_OF_INTEREST); 5084 5085 String cpuInfo = null; 5086 if (MONITOR_CPU_USAGE) { 5087 updateCpuStatsNow(); 5088 synchronized (mProcessCpuThread) { 5089 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5090 } 5091 info.append(processCpuTracker.printCurrentLoad()); 5092 info.append(cpuInfo); 5093 } 5094 5095 info.append(processCpuTracker.printCurrentState(anrTime)); 5096 5097 Slog.e(TAG, info.toString()); 5098 if (tracesFile == null) { 5099 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5100 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5101 } 5102 5103 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5104 cpuInfo, tracesFile, null); 5105 5106 if (mController != null) { 5107 try { 5108 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5109 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5110 if (res != 0) { 5111 if (res < 0 && app.pid != MY_PID) { 5112 app.kill("anr", true); 5113 } else { 5114 synchronized (this) { 5115 mServices.scheduleServiceTimeoutLocked(app); 5116 } 5117 } 5118 return; 5119 } 5120 } catch (RemoteException e) { 5121 mController = null; 5122 Watchdog.getInstance().setActivityController(null); 5123 } 5124 } 5125 5126 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5127 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5128 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5129 5130 synchronized (this) { 5131 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5132 app.kill("bg anr", true); 5133 return; 5134 } 5135 5136 // Set the app's notResponding state, and look up the errorReportReceiver 5137 makeAppNotRespondingLocked(app, 5138 activity != null ? activity.shortComponentName : null, 5139 annotation != null ? "ANR " + annotation : "ANR", 5140 info.toString()); 5141 5142 // Bring up the infamous App Not Responding dialog 5143 Message msg = Message.obtain(); 5144 HashMap<String, Object> map = new HashMap<String, Object>(); 5145 msg.what = SHOW_NOT_RESPONDING_MSG; 5146 msg.obj = map; 5147 msg.arg1 = aboveSystem ? 1 : 0; 5148 map.put("app", app); 5149 if (activity != null) { 5150 map.put("activity", activity); 5151 } 5152 5153 mHandler.sendMessage(msg); 5154 } 5155 } 5156 5157 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5158 if (!mLaunchWarningShown) { 5159 mLaunchWarningShown = true; 5160 mHandler.post(new Runnable() { 5161 @Override 5162 public void run() { 5163 synchronized (ActivityManagerService.this) { 5164 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5165 d.show(); 5166 mHandler.postDelayed(new Runnable() { 5167 @Override 5168 public void run() { 5169 synchronized (ActivityManagerService.this) { 5170 d.dismiss(); 5171 mLaunchWarningShown = false; 5172 } 5173 } 5174 }, 4000); 5175 } 5176 } 5177 }); 5178 } 5179 } 5180 5181 @Override 5182 public boolean clearApplicationUserData(final String packageName, 5183 final IPackageDataObserver observer, int userId) { 5184 enforceNotIsolatedCaller("clearApplicationUserData"); 5185 int uid = Binder.getCallingUid(); 5186 int pid = Binder.getCallingPid(); 5187 userId = handleIncomingUser(pid, uid, 5188 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5189 long callingId = Binder.clearCallingIdentity(); 5190 try { 5191 IPackageManager pm = AppGlobals.getPackageManager(); 5192 int pkgUid = -1; 5193 synchronized(this) { 5194 try { 5195 pkgUid = pm.getPackageUid(packageName, userId); 5196 } catch (RemoteException e) { 5197 } 5198 if (pkgUid == -1) { 5199 Slog.w(TAG, "Invalid packageName: " + packageName); 5200 if (observer != null) { 5201 try { 5202 observer.onRemoveCompleted(packageName, false); 5203 } catch (RemoteException e) { 5204 Slog.i(TAG, "Observer no longer exists."); 5205 } 5206 } 5207 return false; 5208 } 5209 if (uid == pkgUid || checkComponentPermission( 5210 android.Manifest.permission.CLEAR_APP_USER_DATA, 5211 pid, uid, -1, true) 5212 == PackageManager.PERMISSION_GRANTED) { 5213 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5214 } else { 5215 throw new SecurityException("PID " + pid + " does not have permission " 5216 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5217 + " of package " + packageName); 5218 } 5219 5220 // Remove all tasks match the cleared application package and user 5221 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5222 final TaskRecord tr = mRecentTasks.get(i); 5223 final String taskPackageName = 5224 tr.getBaseIntent().getComponent().getPackageName(); 5225 if (tr.userId != userId) continue; 5226 if (!taskPackageName.equals(packageName)) continue; 5227 removeTaskByIdLocked(tr.taskId, 0); 5228 } 5229 } 5230 5231 try { 5232 // Clear application user data 5233 pm.clearApplicationUserData(packageName, observer, userId); 5234 5235 synchronized(this) { 5236 // Remove all permissions granted from/to this package 5237 removeUriPermissionsForPackageLocked(packageName, userId, true); 5238 } 5239 5240 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5241 Uri.fromParts("package", packageName, null)); 5242 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5243 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5244 null, null, 0, null, null, null, false, false, userId); 5245 } catch (RemoteException e) { 5246 } 5247 } finally { 5248 Binder.restoreCallingIdentity(callingId); 5249 } 5250 return true; 5251 } 5252 5253 @Override 5254 public void killBackgroundProcesses(final String packageName, int userId) { 5255 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5256 != PackageManager.PERMISSION_GRANTED && 5257 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5258 != PackageManager.PERMISSION_GRANTED) { 5259 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5260 + Binder.getCallingPid() 5261 + ", uid=" + Binder.getCallingUid() 5262 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5263 Slog.w(TAG, msg); 5264 throw new SecurityException(msg); 5265 } 5266 5267 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5268 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5269 long callingId = Binder.clearCallingIdentity(); 5270 try { 5271 IPackageManager pm = AppGlobals.getPackageManager(); 5272 synchronized(this) { 5273 int appId = -1; 5274 try { 5275 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5276 } catch (RemoteException e) { 5277 } 5278 if (appId == -1) { 5279 Slog.w(TAG, "Invalid packageName: " + packageName); 5280 return; 5281 } 5282 killPackageProcessesLocked(packageName, appId, userId, 5283 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5284 } 5285 } finally { 5286 Binder.restoreCallingIdentity(callingId); 5287 } 5288 } 5289 5290 @Override 5291 public void killAllBackgroundProcesses() { 5292 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5293 != PackageManager.PERMISSION_GRANTED) { 5294 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5295 + Binder.getCallingPid() 5296 + ", uid=" + Binder.getCallingUid() 5297 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5298 Slog.w(TAG, msg); 5299 throw new SecurityException(msg); 5300 } 5301 5302 long callingId = Binder.clearCallingIdentity(); 5303 try { 5304 synchronized(this) { 5305 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5306 final int NP = mProcessNames.getMap().size(); 5307 for (int ip=0; ip<NP; ip++) { 5308 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5309 final int NA = apps.size(); 5310 for (int ia=0; ia<NA; ia++) { 5311 ProcessRecord app = apps.valueAt(ia); 5312 if (app.persistent) { 5313 // we don't kill persistent processes 5314 continue; 5315 } 5316 if (app.removed) { 5317 procs.add(app); 5318 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5319 app.removed = true; 5320 procs.add(app); 5321 } 5322 } 5323 } 5324 5325 int N = procs.size(); 5326 for (int i=0; i<N; i++) { 5327 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5328 } 5329 mAllowLowerMemLevel = true; 5330 updateOomAdjLocked(); 5331 doLowMemReportIfNeededLocked(null); 5332 } 5333 } finally { 5334 Binder.restoreCallingIdentity(callingId); 5335 } 5336 } 5337 5338 @Override 5339 public void forceStopPackage(final String packageName, int userId) { 5340 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5341 != PackageManager.PERMISSION_GRANTED) { 5342 String msg = "Permission Denial: forceStopPackage() from pid=" 5343 + Binder.getCallingPid() 5344 + ", uid=" + Binder.getCallingUid() 5345 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5346 Slog.w(TAG, msg); 5347 throw new SecurityException(msg); 5348 } 5349 final int callingPid = Binder.getCallingPid(); 5350 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5351 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5352 long callingId = Binder.clearCallingIdentity(); 5353 try { 5354 IPackageManager pm = AppGlobals.getPackageManager(); 5355 synchronized(this) { 5356 int[] users = userId == UserHandle.USER_ALL 5357 ? getUsersLocked() : new int[] { userId }; 5358 for (int user : users) { 5359 int pkgUid = -1; 5360 try { 5361 pkgUid = pm.getPackageUid(packageName, user); 5362 } catch (RemoteException e) { 5363 } 5364 if (pkgUid == -1) { 5365 Slog.w(TAG, "Invalid packageName: " + packageName); 5366 continue; 5367 } 5368 try { 5369 pm.setPackageStoppedState(packageName, true, user); 5370 } catch (RemoteException e) { 5371 } catch (IllegalArgumentException e) { 5372 Slog.w(TAG, "Failed trying to unstop package " 5373 + packageName + ": " + e); 5374 } 5375 if (isUserRunningLocked(user, false)) { 5376 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5377 } 5378 } 5379 } 5380 } finally { 5381 Binder.restoreCallingIdentity(callingId); 5382 } 5383 } 5384 5385 @Override 5386 public void addPackageDependency(String packageName) { 5387 synchronized (this) { 5388 int callingPid = Binder.getCallingPid(); 5389 if (callingPid == Process.myPid()) { 5390 // Yeah, um, no. 5391 Slog.w(TAG, "Can't addPackageDependency on system process"); 5392 return; 5393 } 5394 ProcessRecord proc; 5395 synchronized (mPidsSelfLocked) { 5396 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5397 } 5398 if (proc != null) { 5399 if (proc.pkgDeps == null) { 5400 proc.pkgDeps = new ArraySet<String>(1); 5401 } 5402 proc.pkgDeps.add(packageName); 5403 } 5404 } 5405 } 5406 5407 /* 5408 * The pkg name and app id have to be specified. 5409 */ 5410 @Override 5411 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5412 if (pkg == null) { 5413 return; 5414 } 5415 // Make sure the uid is valid. 5416 if (appid < 0) { 5417 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5418 return; 5419 } 5420 int callerUid = Binder.getCallingUid(); 5421 // Only the system server can kill an application 5422 if (callerUid == Process.SYSTEM_UID) { 5423 // Post an aysnc message to kill the application 5424 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5425 msg.arg1 = appid; 5426 msg.arg2 = 0; 5427 Bundle bundle = new Bundle(); 5428 bundle.putString("pkg", pkg); 5429 bundle.putString("reason", reason); 5430 msg.obj = bundle; 5431 mHandler.sendMessage(msg); 5432 } else { 5433 throw new SecurityException(callerUid + " cannot kill pkg: " + 5434 pkg); 5435 } 5436 } 5437 5438 @Override 5439 public void closeSystemDialogs(String reason) { 5440 enforceNotIsolatedCaller("closeSystemDialogs"); 5441 5442 final int pid = Binder.getCallingPid(); 5443 final int uid = Binder.getCallingUid(); 5444 final long origId = Binder.clearCallingIdentity(); 5445 try { 5446 synchronized (this) { 5447 // Only allow this from foreground processes, so that background 5448 // applications can't abuse it to prevent system UI from being shown. 5449 if (uid >= Process.FIRST_APPLICATION_UID) { 5450 ProcessRecord proc; 5451 synchronized (mPidsSelfLocked) { 5452 proc = mPidsSelfLocked.get(pid); 5453 } 5454 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5455 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5456 + " from background process " + proc); 5457 return; 5458 } 5459 } 5460 closeSystemDialogsLocked(reason); 5461 } 5462 } finally { 5463 Binder.restoreCallingIdentity(origId); 5464 } 5465 } 5466 5467 void closeSystemDialogsLocked(String reason) { 5468 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5469 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5470 | Intent.FLAG_RECEIVER_FOREGROUND); 5471 if (reason != null) { 5472 intent.putExtra("reason", reason); 5473 } 5474 mWindowManager.closeSystemDialogs(reason); 5475 5476 mStackSupervisor.closeSystemDialogsLocked(); 5477 5478 broadcastIntentLocked(null, null, intent, null, 5479 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5480 Process.SYSTEM_UID, UserHandle.USER_ALL); 5481 } 5482 5483 @Override 5484 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5485 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5486 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5487 for (int i=pids.length-1; i>=0; i--) { 5488 ProcessRecord proc; 5489 int oomAdj; 5490 synchronized (this) { 5491 synchronized (mPidsSelfLocked) { 5492 proc = mPidsSelfLocked.get(pids[i]); 5493 oomAdj = proc != null ? proc.setAdj : 0; 5494 } 5495 } 5496 infos[i] = new Debug.MemoryInfo(); 5497 Debug.getMemoryInfo(pids[i], infos[i]); 5498 if (proc != null) { 5499 synchronized (this) { 5500 if (proc.thread != null && proc.setAdj == oomAdj) { 5501 // Record this for posterity if the process has been stable. 5502 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5503 infos[i].getTotalUss(), false, proc.pkgList); 5504 } 5505 } 5506 } 5507 } 5508 return infos; 5509 } 5510 5511 @Override 5512 public long[] getProcessPss(int[] pids) { 5513 enforceNotIsolatedCaller("getProcessPss"); 5514 long[] pss = new long[pids.length]; 5515 for (int i=pids.length-1; i>=0; i--) { 5516 ProcessRecord proc; 5517 int oomAdj; 5518 synchronized (this) { 5519 synchronized (mPidsSelfLocked) { 5520 proc = mPidsSelfLocked.get(pids[i]); 5521 oomAdj = proc != null ? proc.setAdj : 0; 5522 } 5523 } 5524 long[] tmpUss = new long[1]; 5525 pss[i] = Debug.getPss(pids[i], tmpUss); 5526 if (proc != null) { 5527 synchronized (this) { 5528 if (proc.thread != null && proc.setAdj == oomAdj) { 5529 // Record this for posterity if the process has been stable. 5530 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5531 } 5532 } 5533 } 5534 } 5535 return pss; 5536 } 5537 5538 @Override 5539 public void killApplicationProcess(String processName, int uid) { 5540 if (processName == null) { 5541 return; 5542 } 5543 5544 int callerUid = Binder.getCallingUid(); 5545 // Only the system server can kill an application 5546 if (callerUid == Process.SYSTEM_UID) { 5547 synchronized (this) { 5548 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5549 if (app != null && app.thread != null) { 5550 try { 5551 app.thread.scheduleSuicide(); 5552 } catch (RemoteException e) { 5553 // If the other end already died, then our work here is done. 5554 } 5555 } else { 5556 Slog.w(TAG, "Process/uid not found attempting kill of " 5557 + processName + " / " + uid); 5558 } 5559 } 5560 } else { 5561 throw new SecurityException(callerUid + " cannot kill app process: " + 5562 processName); 5563 } 5564 } 5565 5566 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5567 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5568 false, true, false, false, UserHandle.getUserId(uid), reason); 5569 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5570 Uri.fromParts("package", packageName, null)); 5571 if (!mProcessesReady) { 5572 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5573 | Intent.FLAG_RECEIVER_FOREGROUND); 5574 } 5575 intent.putExtra(Intent.EXTRA_UID, uid); 5576 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5577 broadcastIntentLocked(null, null, intent, 5578 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5579 false, false, 5580 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5581 } 5582 5583 private void forceStopUserLocked(int userId, String reason) { 5584 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5585 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5587 | Intent.FLAG_RECEIVER_FOREGROUND); 5588 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5589 broadcastIntentLocked(null, null, intent, 5590 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5591 false, false, 5592 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5593 } 5594 5595 private final boolean killPackageProcessesLocked(String packageName, int appId, 5596 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5597 boolean doit, boolean evenPersistent, String reason) { 5598 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5599 5600 // Remove all processes this package may have touched: all with the 5601 // same UID (except for the system or root user), and all whose name 5602 // matches the package name. 5603 final int NP = mProcessNames.getMap().size(); 5604 for (int ip=0; ip<NP; ip++) { 5605 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5606 final int NA = apps.size(); 5607 for (int ia=0; ia<NA; ia++) { 5608 ProcessRecord app = apps.valueAt(ia); 5609 if (app.persistent && !evenPersistent) { 5610 // we don't kill persistent processes 5611 continue; 5612 } 5613 if (app.removed) { 5614 if (doit) { 5615 procs.add(app); 5616 } 5617 continue; 5618 } 5619 5620 // Skip process if it doesn't meet our oom adj requirement. 5621 if (app.setAdj < minOomAdj) { 5622 continue; 5623 } 5624 5625 // If no package is specified, we call all processes under the 5626 // give user id. 5627 if (packageName == null) { 5628 if (app.userId != userId) { 5629 continue; 5630 } 5631 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5632 continue; 5633 } 5634 // Package has been specified, we want to hit all processes 5635 // that match it. We need to qualify this by the processes 5636 // that are running under the specified app and user ID. 5637 } else { 5638 final boolean isDep = app.pkgDeps != null 5639 && app.pkgDeps.contains(packageName); 5640 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5641 continue; 5642 } 5643 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5644 continue; 5645 } 5646 if (!app.pkgList.containsKey(packageName) && !isDep) { 5647 continue; 5648 } 5649 } 5650 5651 // Process has passed all conditions, kill it! 5652 if (!doit) { 5653 return true; 5654 } 5655 app.removed = true; 5656 procs.add(app); 5657 } 5658 } 5659 5660 int N = procs.size(); 5661 for (int i=0; i<N; i++) { 5662 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5663 } 5664 updateOomAdjLocked(); 5665 return N > 0; 5666 } 5667 5668 private final boolean forceStopPackageLocked(String name, int appId, 5669 boolean callerWillRestart, boolean purgeCache, boolean doit, 5670 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5671 int i; 5672 int N; 5673 5674 if (userId == UserHandle.USER_ALL && name == null) { 5675 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5676 } 5677 5678 if (appId < 0 && name != null) { 5679 try { 5680 appId = UserHandle.getAppId( 5681 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5682 } catch (RemoteException e) { 5683 } 5684 } 5685 5686 if (doit) { 5687 if (name != null) { 5688 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5689 + " user=" + userId + ": " + reason); 5690 } else { 5691 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5692 } 5693 5694 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5695 for (int ip=pmap.size()-1; ip>=0; ip--) { 5696 SparseArray<Long> ba = pmap.valueAt(ip); 5697 for (i=ba.size()-1; i>=0; i--) { 5698 boolean remove = false; 5699 final int entUid = ba.keyAt(i); 5700 if (name != null) { 5701 if (userId == UserHandle.USER_ALL) { 5702 if (UserHandle.getAppId(entUid) == appId) { 5703 remove = true; 5704 } 5705 } else { 5706 if (entUid == UserHandle.getUid(userId, appId)) { 5707 remove = true; 5708 } 5709 } 5710 } else if (UserHandle.getUserId(entUid) == userId) { 5711 remove = true; 5712 } 5713 if (remove) { 5714 ba.removeAt(i); 5715 } 5716 } 5717 if (ba.size() == 0) { 5718 pmap.removeAt(ip); 5719 } 5720 } 5721 } 5722 5723 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5724 -100, callerWillRestart, true, doit, evenPersistent, 5725 name == null ? ("stop user " + userId) : ("stop " + name)); 5726 5727 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5728 if (!doit) { 5729 return true; 5730 } 5731 didSomething = true; 5732 } 5733 5734 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5735 if (!doit) { 5736 return true; 5737 } 5738 didSomething = true; 5739 } 5740 5741 if (name == null) { 5742 // Remove all sticky broadcasts from this user. 5743 mStickyBroadcasts.remove(userId); 5744 } 5745 5746 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5747 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5748 userId, providers)) { 5749 if (!doit) { 5750 return true; 5751 } 5752 didSomething = true; 5753 } 5754 N = providers.size(); 5755 for (i=0; i<N; i++) { 5756 removeDyingProviderLocked(null, providers.get(i), true); 5757 } 5758 5759 // Remove transient permissions granted from/to this package/user 5760 removeUriPermissionsForPackageLocked(name, userId, false); 5761 5762 if (name == null || uninstalling) { 5763 // Remove pending intents. For now we only do this when force 5764 // stopping users, because we have some problems when doing this 5765 // for packages -- app widgets are not currently cleaned up for 5766 // such packages, so they can be left with bad pending intents. 5767 if (mIntentSenderRecords.size() > 0) { 5768 Iterator<WeakReference<PendingIntentRecord>> it 5769 = mIntentSenderRecords.values().iterator(); 5770 while (it.hasNext()) { 5771 WeakReference<PendingIntentRecord> wpir = it.next(); 5772 if (wpir == null) { 5773 it.remove(); 5774 continue; 5775 } 5776 PendingIntentRecord pir = wpir.get(); 5777 if (pir == null) { 5778 it.remove(); 5779 continue; 5780 } 5781 if (name == null) { 5782 // Stopping user, remove all objects for the user. 5783 if (pir.key.userId != userId) { 5784 // Not the same user, skip it. 5785 continue; 5786 } 5787 } else { 5788 if (UserHandle.getAppId(pir.uid) != appId) { 5789 // Different app id, skip it. 5790 continue; 5791 } 5792 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5793 // Different user, skip it. 5794 continue; 5795 } 5796 if (!pir.key.packageName.equals(name)) { 5797 // Different package, skip it. 5798 continue; 5799 } 5800 } 5801 if (!doit) { 5802 return true; 5803 } 5804 didSomething = true; 5805 it.remove(); 5806 pir.canceled = true; 5807 if (pir.key.activity != null) { 5808 pir.key.activity.pendingResults.remove(pir.ref); 5809 } 5810 } 5811 } 5812 } 5813 5814 if (doit) { 5815 if (purgeCache && name != null) { 5816 AttributeCache ac = AttributeCache.instance(); 5817 if (ac != null) { 5818 ac.removePackage(name); 5819 } 5820 } 5821 if (mBooted) { 5822 mStackSupervisor.resumeTopActivitiesLocked(); 5823 mStackSupervisor.scheduleIdleLocked(); 5824 } 5825 } 5826 5827 return didSomething; 5828 } 5829 5830 private final boolean removeProcessLocked(ProcessRecord app, 5831 boolean callerWillRestart, boolean allowRestart, String reason) { 5832 final String name = app.processName; 5833 final int uid = app.uid; 5834 if (DEBUG_PROCESSES) Slog.d( 5835 TAG, "Force removing proc " + app.toShortString() + " (" + name 5836 + "/" + uid + ")"); 5837 5838 mProcessNames.remove(name, uid); 5839 mIsolatedProcesses.remove(app.uid); 5840 if (mHeavyWeightProcess == app) { 5841 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5842 mHeavyWeightProcess.userId, 0)); 5843 mHeavyWeightProcess = null; 5844 } 5845 boolean needRestart = false; 5846 if (app.pid > 0 && app.pid != MY_PID) { 5847 int pid = app.pid; 5848 synchronized (mPidsSelfLocked) { 5849 mPidsSelfLocked.remove(pid); 5850 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5851 } 5852 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5853 if (app.isolated) { 5854 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5855 } 5856 app.kill(reason, true); 5857 handleAppDiedLocked(app, true, allowRestart); 5858 removeLruProcessLocked(app); 5859 5860 if (app.persistent && !app.isolated) { 5861 if (!callerWillRestart) { 5862 addAppLocked(app.info, false, null /* ABI override */); 5863 } else { 5864 needRestart = true; 5865 } 5866 } 5867 } else { 5868 mRemovedProcesses.add(app); 5869 } 5870 5871 return needRestart; 5872 } 5873 5874 private final void processStartTimedOutLocked(ProcessRecord app) { 5875 final int pid = app.pid; 5876 boolean gone = false; 5877 synchronized (mPidsSelfLocked) { 5878 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5879 if (knownApp != null && knownApp.thread == null) { 5880 mPidsSelfLocked.remove(pid); 5881 gone = true; 5882 } 5883 } 5884 5885 if (gone) { 5886 Slog.w(TAG, "Process " + app + " failed to attach"); 5887 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5888 pid, app.uid, app.processName); 5889 mProcessNames.remove(app.processName, app.uid); 5890 mIsolatedProcesses.remove(app.uid); 5891 if (mHeavyWeightProcess == app) { 5892 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5893 mHeavyWeightProcess.userId, 0)); 5894 mHeavyWeightProcess = null; 5895 } 5896 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5897 if (app.isolated) { 5898 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5899 } 5900 // Take care of any launching providers waiting for this process. 5901 checkAppInLaunchingProvidersLocked(app, true); 5902 // Take care of any services that are waiting for the process. 5903 mServices.processStartTimedOutLocked(app); 5904 app.kill("start timeout", true); 5905 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5906 Slog.w(TAG, "Unattached app died before backup, skipping"); 5907 try { 5908 IBackupManager bm = IBackupManager.Stub.asInterface( 5909 ServiceManager.getService(Context.BACKUP_SERVICE)); 5910 bm.agentDisconnected(app.info.packageName); 5911 } catch (RemoteException e) { 5912 // Can't happen; the backup manager is local 5913 } 5914 } 5915 if (isPendingBroadcastProcessLocked(pid)) { 5916 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5917 skipPendingBroadcastLocked(pid); 5918 } 5919 } else { 5920 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5921 } 5922 } 5923 5924 private final boolean attachApplicationLocked(IApplicationThread thread, 5925 int pid) { 5926 5927 // Find the application record that is being attached... either via 5928 // the pid if we are running in multiple processes, or just pull the 5929 // next app record if we are emulating process with anonymous threads. 5930 ProcessRecord app; 5931 if (pid != MY_PID && pid >= 0) { 5932 synchronized (mPidsSelfLocked) { 5933 app = mPidsSelfLocked.get(pid); 5934 } 5935 } else { 5936 app = null; 5937 } 5938 5939 if (app == null) { 5940 Slog.w(TAG, "No pending application record for pid " + pid 5941 + " (IApplicationThread " + thread + "); dropping process"); 5942 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5943 if (pid > 0 && pid != MY_PID) { 5944 Process.killProcessQuiet(pid); 5945 //TODO: Process.killProcessGroup(app.info.uid, pid); 5946 } else { 5947 try { 5948 thread.scheduleExit(); 5949 } catch (Exception e) { 5950 // Ignore exceptions. 5951 } 5952 } 5953 return false; 5954 } 5955 5956 // If this application record is still attached to a previous 5957 // process, clean it up now. 5958 if (app.thread != null) { 5959 handleAppDiedLocked(app, true, true); 5960 } 5961 5962 // Tell the process all about itself. 5963 5964 if (localLOGV) Slog.v( 5965 TAG, "Binding process pid " + pid + " to record " + app); 5966 5967 final String processName = app.processName; 5968 try { 5969 AppDeathRecipient adr = new AppDeathRecipient( 5970 app, pid, thread); 5971 thread.asBinder().linkToDeath(adr, 0); 5972 app.deathRecipient = adr; 5973 } catch (RemoteException e) { 5974 app.resetPackageList(mProcessStats); 5975 startProcessLocked(app, "link fail", processName); 5976 return false; 5977 } 5978 5979 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5980 5981 app.makeActive(thread, mProcessStats); 5982 app.curAdj = app.setAdj = -100; 5983 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5984 app.forcingToForeground = null; 5985 updateProcessForegroundLocked(app, false, false); 5986 app.hasShownUi = false; 5987 app.debugging = false; 5988 app.cached = false; 5989 5990 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5991 5992 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5993 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5994 5995 if (!normalMode) { 5996 Slog.i(TAG, "Launching preboot mode app: " + app); 5997 } 5998 5999 if (localLOGV) Slog.v( 6000 TAG, "New app record " + app 6001 + " thread=" + thread.asBinder() + " pid=" + pid); 6002 try { 6003 int testMode = IApplicationThread.DEBUG_OFF; 6004 if (mDebugApp != null && mDebugApp.equals(processName)) { 6005 testMode = mWaitForDebugger 6006 ? IApplicationThread.DEBUG_WAIT 6007 : IApplicationThread.DEBUG_ON; 6008 app.debugging = true; 6009 if (mDebugTransient) { 6010 mDebugApp = mOrigDebugApp; 6011 mWaitForDebugger = mOrigWaitForDebugger; 6012 } 6013 } 6014 String profileFile = app.instrumentationProfileFile; 6015 ParcelFileDescriptor profileFd = null; 6016 int samplingInterval = 0; 6017 boolean profileAutoStop = false; 6018 if (mProfileApp != null && mProfileApp.equals(processName)) { 6019 mProfileProc = app; 6020 profileFile = mProfileFile; 6021 profileFd = mProfileFd; 6022 samplingInterval = mSamplingInterval; 6023 profileAutoStop = mAutoStopProfiler; 6024 } 6025 boolean enableOpenGlTrace = false; 6026 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6027 enableOpenGlTrace = true; 6028 mOpenGlTraceApp = null; 6029 } 6030 6031 // If the app is being launched for restore or full backup, set it up specially 6032 boolean isRestrictedBackupMode = false; 6033 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6034 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6035 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6036 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6037 } 6038 6039 ensurePackageDexOpt(app.instrumentationInfo != null 6040 ? app.instrumentationInfo.packageName 6041 : app.info.packageName); 6042 if (app.instrumentationClass != null) { 6043 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6044 } 6045 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6046 + processName + " with config " + mConfiguration); 6047 ApplicationInfo appInfo = app.instrumentationInfo != null 6048 ? app.instrumentationInfo : app.info; 6049 app.compat = compatibilityInfoForPackageLocked(appInfo); 6050 if (profileFd != null) { 6051 profileFd = profileFd.dup(); 6052 } 6053 ProfilerInfo profilerInfo = profileFile == null ? null 6054 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6055 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6056 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6057 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6058 isRestrictedBackupMode || !normalMode, app.persistent, 6059 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6060 mCoreSettingsObserver.getCoreSettingsLocked()); 6061 updateLruProcessLocked(app, false, null); 6062 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6063 } catch (Exception e) { 6064 // todo: Yikes! What should we do? For now we will try to 6065 // start another process, but that could easily get us in 6066 // an infinite loop of restarting processes... 6067 Slog.w(TAG, "Exception thrown during bind!", e); 6068 6069 app.resetPackageList(mProcessStats); 6070 app.unlinkDeathRecipient(); 6071 startProcessLocked(app, "bind fail", processName); 6072 return false; 6073 } 6074 6075 // Remove this record from the list of starting applications. 6076 mPersistentStartingProcesses.remove(app); 6077 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6078 "Attach application locked removing on hold: " + app); 6079 mProcessesOnHold.remove(app); 6080 6081 boolean badApp = false; 6082 boolean didSomething = false; 6083 6084 // See if the top visible activity is waiting to run in this process... 6085 if (normalMode) { 6086 try { 6087 if (mStackSupervisor.attachApplicationLocked(app)) { 6088 didSomething = true; 6089 } 6090 } catch (Exception e) { 6091 badApp = true; 6092 } 6093 } 6094 6095 // Find any services that should be running in this process... 6096 if (!badApp) { 6097 try { 6098 didSomething |= mServices.attachApplicationLocked(app, processName); 6099 } catch (Exception e) { 6100 badApp = true; 6101 } 6102 } 6103 6104 // Check if a next-broadcast receiver is in this process... 6105 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6106 try { 6107 didSomething |= sendPendingBroadcastsLocked(app); 6108 } catch (Exception e) { 6109 // If the app died trying to launch the receiver we declare it 'bad' 6110 badApp = true; 6111 } 6112 } 6113 6114 // Check whether the next backup agent is in this process... 6115 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6116 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6117 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6118 try { 6119 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6120 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6121 mBackupTarget.backupMode); 6122 } catch (Exception e) { 6123 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6124 e.printStackTrace(); 6125 } 6126 } 6127 6128 if (badApp) { 6129 // todo: Also need to kill application to deal with all 6130 // kinds of exceptions. 6131 handleAppDiedLocked(app, false, true); 6132 return false; 6133 } 6134 6135 if (!didSomething) { 6136 updateOomAdjLocked(); 6137 } 6138 6139 return true; 6140 } 6141 6142 @Override 6143 public final void attachApplication(IApplicationThread thread) { 6144 synchronized (this) { 6145 int callingPid = Binder.getCallingPid(); 6146 final long origId = Binder.clearCallingIdentity(); 6147 attachApplicationLocked(thread, callingPid); 6148 Binder.restoreCallingIdentity(origId); 6149 } 6150 } 6151 6152 @Override 6153 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6154 final long origId = Binder.clearCallingIdentity(); 6155 synchronized (this) { 6156 ActivityStack stack = ActivityRecord.getStackLocked(token); 6157 if (stack != null) { 6158 ActivityRecord r = 6159 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6160 if (stopProfiling) { 6161 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6162 try { 6163 mProfileFd.close(); 6164 } catch (IOException e) { 6165 } 6166 clearProfilerLocked(); 6167 } 6168 } 6169 } 6170 } 6171 Binder.restoreCallingIdentity(origId); 6172 } 6173 6174 void postEnableScreenAfterBootLocked() { 6175 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6176 } 6177 6178 void enableScreenAfterBoot() { 6179 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6180 SystemClock.uptimeMillis()); 6181 mWindowManager.enableScreenAfterBoot(); 6182 6183 synchronized (this) { 6184 updateEventDispatchingLocked(); 6185 } 6186 } 6187 6188 @Override 6189 public void showBootMessage(final CharSequence msg, final boolean always) { 6190 enforceNotIsolatedCaller("showBootMessage"); 6191 mWindowManager.showBootMessage(msg, always); 6192 } 6193 6194 @Override 6195 public void keyguardWaitingForActivityDrawn() { 6196 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6197 final long token = Binder.clearCallingIdentity(); 6198 try { 6199 synchronized (this) { 6200 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6201 mWindowManager.keyguardWaitingForActivityDrawn(); 6202 } 6203 } finally { 6204 Binder.restoreCallingIdentity(token); 6205 } 6206 } 6207 6208 final void finishBooting() { 6209 // Register receivers to handle package update events 6210 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6211 6212 // Let system services know. 6213 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6214 6215 synchronized (this) { 6216 // Ensure that any processes we had put on hold are now started 6217 // up. 6218 final int NP = mProcessesOnHold.size(); 6219 if (NP > 0) { 6220 ArrayList<ProcessRecord> procs = 6221 new ArrayList<ProcessRecord>(mProcessesOnHold); 6222 for (int ip=0; ip<NP; ip++) { 6223 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6224 + procs.get(ip)); 6225 startProcessLocked(procs.get(ip), "on-hold", null); 6226 } 6227 } 6228 6229 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6230 // Start looking for apps that are abusing wake locks. 6231 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6232 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6233 // Tell anyone interested that we are done booting! 6234 SystemProperties.set("sys.boot_completed", "1"); 6235 SystemProperties.set("dev.bootcomplete", "1"); 6236 for (int i=0; i<mStartedUsers.size(); i++) { 6237 UserStartedState uss = mStartedUsers.valueAt(i); 6238 if (uss.mState == UserStartedState.STATE_BOOTING) { 6239 uss.mState = UserStartedState.STATE_RUNNING; 6240 final int userId = mStartedUsers.keyAt(i); 6241 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6242 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6243 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6244 broadcastIntentLocked(null, null, intent, null, 6245 new IIntentReceiver.Stub() { 6246 @Override 6247 public void performReceive(Intent intent, int resultCode, 6248 String data, Bundle extras, boolean ordered, 6249 boolean sticky, int sendingUser) { 6250 synchronized (ActivityManagerService.this) { 6251 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6252 true, false); 6253 } 6254 } 6255 }, 6256 0, null, null, 6257 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6258 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6259 userId); 6260 } 6261 } 6262 scheduleStartProfilesLocked(); 6263 } 6264 } 6265 } 6266 6267 final void ensureBootCompleted() { 6268 boolean booting; 6269 boolean enableScreen; 6270 synchronized (this) { 6271 booting = mBooting; 6272 mBooting = false; 6273 enableScreen = !mBooted; 6274 mBooted = true; 6275 } 6276 6277 if (booting) { 6278 finishBooting(); 6279 } 6280 6281 if (enableScreen) { 6282 enableScreenAfterBoot(); 6283 } 6284 } 6285 6286 @Override 6287 public final void activityResumed(IBinder token) { 6288 final long origId = Binder.clearCallingIdentity(); 6289 synchronized(this) { 6290 ActivityStack stack = ActivityRecord.getStackLocked(token); 6291 if (stack != null) { 6292 ActivityRecord.activityResumedLocked(token); 6293 } 6294 } 6295 Binder.restoreCallingIdentity(origId); 6296 } 6297 6298 @Override 6299 public final void activityPaused(IBinder token) { 6300 final long origId = Binder.clearCallingIdentity(); 6301 synchronized(this) { 6302 ActivityStack stack = ActivityRecord.getStackLocked(token); 6303 if (stack != null) { 6304 stack.activityPausedLocked(token, false); 6305 } 6306 } 6307 Binder.restoreCallingIdentity(origId); 6308 } 6309 6310 @Override 6311 public final void activityStopped(IBinder token, Bundle icicle, 6312 PersistableBundle persistentState, CharSequence description) { 6313 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6314 6315 // Refuse possible leaked file descriptors 6316 if (icicle != null && icicle.hasFileDescriptors()) { 6317 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6318 } 6319 6320 final long origId = Binder.clearCallingIdentity(); 6321 6322 synchronized (this) { 6323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6324 if (r != null) { 6325 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6326 } 6327 } 6328 6329 trimApplications(); 6330 6331 Binder.restoreCallingIdentity(origId); 6332 } 6333 6334 @Override 6335 public final void activityDestroyed(IBinder token) { 6336 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6337 synchronized (this) { 6338 ActivityStack stack = ActivityRecord.getStackLocked(token); 6339 if (stack != null) { 6340 stack.activityDestroyedLocked(token); 6341 } 6342 } 6343 } 6344 6345 @Override 6346 public final void backgroundResourcesReleased(IBinder token) { 6347 final long origId = Binder.clearCallingIdentity(); 6348 try { 6349 synchronized (this) { 6350 ActivityStack stack = ActivityRecord.getStackLocked(token); 6351 if (stack != null) { 6352 stack.backgroundResourcesReleased(token); 6353 } 6354 } 6355 } finally { 6356 Binder.restoreCallingIdentity(origId); 6357 } 6358 } 6359 6360 @Override 6361 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6362 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6363 } 6364 6365 @Override 6366 public final void notifyEnterAnimationComplete(IBinder token) { 6367 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6368 } 6369 6370 @Override 6371 public String getCallingPackage(IBinder token) { 6372 synchronized (this) { 6373 ActivityRecord r = getCallingRecordLocked(token); 6374 return r != null ? r.info.packageName : null; 6375 } 6376 } 6377 6378 @Override 6379 public ComponentName getCallingActivity(IBinder token) { 6380 synchronized (this) { 6381 ActivityRecord r = getCallingRecordLocked(token); 6382 return r != null ? r.intent.getComponent() : null; 6383 } 6384 } 6385 6386 private ActivityRecord getCallingRecordLocked(IBinder token) { 6387 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6388 if (r == null) { 6389 return null; 6390 } 6391 return r.resultTo; 6392 } 6393 6394 @Override 6395 public ComponentName getActivityClassForToken(IBinder token) { 6396 synchronized(this) { 6397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6398 if (r == null) { 6399 return null; 6400 } 6401 return r.intent.getComponent(); 6402 } 6403 } 6404 6405 @Override 6406 public String getPackageForToken(IBinder token) { 6407 synchronized(this) { 6408 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6409 if (r == null) { 6410 return null; 6411 } 6412 return r.packageName; 6413 } 6414 } 6415 6416 @Override 6417 public IIntentSender getIntentSender(int type, 6418 String packageName, IBinder token, String resultWho, 6419 int requestCode, Intent[] intents, String[] resolvedTypes, 6420 int flags, Bundle options, int userId) { 6421 enforceNotIsolatedCaller("getIntentSender"); 6422 // Refuse possible leaked file descriptors 6423 if (intents != null) { 6424 if (intents.length < 1) { 6425 throw new IllegalArgumentException("Intents array length must be >= 1"); 6426 } 6427 for (int i=0; i<intents.length; i++) { 6428 Intent intent = intents[i]; 6429 if (intent != null) { 6430 if (intent.hasFileDescriptors()) { 6431 throw new IllegalArgumentException("File descriptors passed in Intent"); 6432 } 6433 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6434 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6435 throw new IllegalArgumentException( 6436 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6437 } 6438 intents[i] = new Intent(intent); 6439 } 6440 } 6441 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6442 throw new IllegalArgumentException( 6443 "Intent array length does not match resolvedTypes length"); 6444 } 6445 } 6446 if (options != null) { 6447 if (options.hasFileDescriptors()) { 6448 throw new IllegalArgumentException("File descriptors passed in options"); 6449 } 6450 } 6451 6452 synchronized(this) { 6453 int callingUid = Binder.getCallingUid(); 6454 int origUserId = userId; 6455 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6456 type == ActivityManager.INTENT_SENDER_BROADCAST, 6457 ALLOW_NON_FULL, "getIntentSender", null); 6458 if (origUserId == UserHandle.USER_CURRENT) { 6459 // We don't want to evaluate this until the pending intent is 6460 // actually executed. However, we do want to always do the 6461 // security checking for it above. 6462 userId = UserHandle.USER_CURRENT; 6463 } 6464 try { 6465 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6466 int uid = AppGlobals.getPackageManager() 6467 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6468 if (!UserHandle.isSameApp(callingUid, uid)) { 6469 String msg = "Permission Denial: getIntentSender() from pid=" 6470 + Binder.getCallingPid() 6471 + ", uid=" + Binder.getCallingUid() 6472 + ", (need uid=" + uid + ")" 6473 + " is not allowed to send as package " + packageName; 6474 Slog.w(TAG, msg); 6475 throw new SecurityException(msg); 6476 } 6477 } 6478 6479 return getIntentSenderLocked(type, packageName, callingUid, userId, 6480 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6481 6482 } catch (RemoteException e) { 6483 throw new SecurityException(e); 6484 } 6485 } 6486 } 6487 6488 IIntentSender getIntentSenderLocked(int type, String packageName, 6489 int callingUid, int userId, IBinder token, String resultWho, 6490 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6491 Bundle options) { 6492 if (DEBUG_MU) 6493 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6494 ActivityRecord activity = null; 6495 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6496 activity = ActivityRecord.isInStackLocked(token); 6497 if (activity == null) { 6498 return null; 6499 } 6500 if (activity.finishing) { 6501 return null; 6502 } 6503 } 6504 6505 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6506 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6507 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6508 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6509 |PendingIntent.FLAG_UPDATE_CURRENT); 6510 6511 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6512 type, packageName, activity, resultWho, 6513 requestCode, intents, resolvedTypes, flags, options, userId); 6514 WeakReference<PendingIntentRecord> ref; 6515 ref = mIntentSenderRecords.get(key); 6516 PendingIntentRecord rec = ref != null ? ref.get() : null; 6517 if (rec != null) { 6518 if (!cancelCurrent) { 6519 if (updateCurrent) { 6520 if (rec.key.requestIntent != null) { 6521 rec.key.requestIntent.replaceExtras(intents != null ? 6522 intents[intents.length - 1] : null); 6523 } 6524 if (intents != null) { 6525 intents[intents.length-1] = rec.key.requestIntent; 6526 rec.key.allIntents = intents; 6527 rec.key.allResolvedTypes = resolvedTypes; 6528 } else { 6529 rec.key.allIntents = null; 6530 rec.key.allResolvedTypes = null; 6531 } 6532 } 6533 return rec; 6534 } 6535 rec.canceled = true; 6536 mIntentSenderRecords.remove(key); 6537 } 6538 if (noCreate) { 6539 return rec; 6540 } 6541 rec = new PendingIntentRecord(this, key, callingUid); 6542 mIntentSenderRecords.put(key, rec.ref); 6543 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6544 if (activity.pendingResults == null) { 6545 activity.pendingResults 6546 = new HashSet<WeakReference<PendingIntentRecord>>(); 6547 } 6548 activity.pendingResults.add(rec.ref); 6549 } 6550 return rec; 6551 } 6552 6553 @Override 6554 public void cancelIntentSender(IIntentSender sender) { 6555 if (!(sender instanceof PendingIntentRecord)) { 6556 return; 6557 } 6558 synchronized(this) { 6559 PendingIntentRecord rec = (PendingIntentRecord)sender; 6560 try { 6561 int uid = AppGlobals.getPackageManager() 6562 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6563 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6564 String msg = "Permission Denial: cancelIntentSender() from pid=" 6565 + Binder.getCallingPid() 6566 + ", uid=" + Binder.getCallingUid() 6567 + " is not allowed to cancel packges " 6568 + rec.key.packageName; 6569 Slog.w(TAG, msg); 6570 throw new SecurityException(msg); 6571 } 6572 } catch (RemoteException e) { 6573 throw new SecurityException(e); 6574 } 6575 cancelIntentSenderLocked(rec, true); 6576 } 6577 } 6578 6579 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6580 rec.canceled = true; 6581 mIntentSenderRecords.remove(rec.key); 6582 if (cleanActivity && rec.key.activity != null) { 6583 rec.key.activity.pendingResults.remove(rec.ref); 6584 } 6585 } 6586 6587 @Override 6588 public String getPackageForIntentSender(IIntentSender pendingResult) { 6589 if (!(pendingResult instanceof PendingIntentRecord)) { 6590 return null; 6591 } 6592 try { 6593 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6594 return res.key.packageName; 6595 } catch (ClassCastException e) { 6596 } 6597 return null; 6598 } 6599 6600 @Override 6601 public int getUidForIntentSender(IIntentSender sender) { 6602 if (sender instanceof PendingIntentRecord) { 6603 try { 6604 PendingIntentRecord res = (PendingIntentRecord)sender; 6605 return res.uid; 6606 } catch (ClassCastException e) { 6607 } 6608 } 6609 return -1; 6610 } 6611 6612 @Override 6613 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6614 if (!(pendingResult instanceof PendingIntentRecord)) { 6615 return false; 6616 } 6617 try { 6618 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6619 if (res.key.allIntents == null) { 6620 return false; 6621 } 6622 for (int i=0; i<res.key.allIntents.length; i++) { 6623 Intent intent = res.key.allIntents[i]; 6624 if (intent.getPackage() != null && intent.getComponent() != null) { 6625 return false; 6626 } 6627 } 6628 return true; 6629 } catch (ClassCastException e) { 6630 } 6631 return false; 6632 } 6633 6634 @Override 6635 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6636 if (!(pendingResult instanceof PendingIntentRecord)) { 6637 return false; 6638 } 6639 try { 6640 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6641 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6642 return true; 6643 } 6644 return false; 6645 } catch (ClassCastException e) { 6646 } 6647 return false; 6648 } 6649 6650 @Override 6651 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6652 if (!(pendingResult instanceof PendingIntentRecord)) { 6653 return null; 6654 } 6655 try { 6656 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6657 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6658 } catch (ClassCastException e) { 6659 } 6660 return null; 6661 } 6662 6663 @Override 6664 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6665 if (!(pendingResult instanceof PendingIntentRecord)) { 6666 return null; 6667 } 6668 try { 6669 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6670 Intent intent = res.key.requestIntent; 6671 if (intent != null) { 6672 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6673 || res.lastTagPrefix.equals(prefix))) { 6674 return res.lastTag; 6675 } 6676 res.lastTagPrefix = prefix; 6677 StringBuilder sb = new StringBuilder(128); 6678 if (prefix != null) { 6679 sb.append(prefix); 6680 } 6681 if (intent.getAction() != null) { 6682 sb.append(intent.getAction()); 6683 } else if (intent.getComponent() != null) { 6684 intent.getComponent().appendShortString(sb); 6685 } else { 6686 sb.append("?"); 6687 } 6688 return res.lastTag = sb.toString(); 6689 } 6690 } catch (ClassCastException e) { 6691 } 6692 return null; 6693 } 6694 6695 @Override 6696 public void setProcessLimit(int max) { 6697 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6698 "setProcessLimit()"); 6699 synchronized (this) { 6700 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6701 mProcessLimitOverride = max; 6702 } 6703 trimApplications(); 6704 } 6705 6706 @Override 6707 public int getProcessLimit() { 6708 synchronized (this) { 6709 return mProcessLimitOverride; 6710 } 6711 } 6712 6713 void foregroundTokenDied(ForegroundToken token) { 6714 synchronized (ActivityManagerService.this) { 6715 synchronized (mPidsSelfLocked) { 6716 ForegroundToken cur 6717 = mForegroundProcesses.get(token.pid); 6718 if (cur != token) { 6719 return; 6720 } 6721 mForegroundProcesses.remove(token.pid); 6722 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6723 if (pr == null) { 6724 return; 6725 } 6726 pr.forcingToForeground = null; 6727 updateProcessForegroundLocked(pr, false, false); 6728 } 6729 updateOomAdjLocked(); 6730 } 6731 } 6732 6733 @Override 6734 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6735 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6736 "setProcessForeground()"); 6737 synchronized(this) { 6738 boolean changed = false; 6739 6740 synchronized (mPidsSelfLocked) { 6741 ProcessRecord pr = mPidsSelfLocked.get(pid); 6742 if (pr == null && isForeground) { 6743 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6744 return; 6745 } 6746 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6747 if (oldToken != null) { 6748 oldToken.token.unlinkToDeath(oldToken, 0); 6749 mForegroundProcesses.remove(pid); 6750 if (pr != null) { 6751 pr.forcingToForeground = null; 6752 } 6753 changed = true; 6754 } 6755 if (isForeground && token != null) { 6756 ForegroundToken newToken = new ForegroundToken() { 6757 @Override 6758 public void binderDied() { 6759 foregroundTokenDied(this); 6760 } 6761 }; 6762 newToken.pid = pid; 6763 newToken.token = token; 6764 try { 6765 token.linkToDeath(newToken, 0); 6766 mForegroundProcesses.put(pid, newToken); 6767 pr.forcingToForeground = token; 6768 changed = true; 6769 } catch (RemoteException e) { 6770 // If the process died while doing this, we will later 6771 // do the cleanup with the process death link. 6772 } 6773 } 6774 } 6775 6776 if (changed) { 6777 updateOomAdjLocked(); 6778 } 6779 } 6780 } 6781 6782 // ========================================================= 6783 // PERMISSIONS 6784 // ========================================================= 6785 6786 static class PermissionController extends IPermissionController.Stub { 6787 ActivityManagerService mActivityManagerService; 6788 PermissionController(ActivityManagerService activityManagerService) { 6789 mActivityManagerService = activityManagerService; 6790 } 6791 6792 @Override 6793 public boolean checkPermission(String permission, int pid, int uid) { 6794 return mActivityManagerService.checkPermission(permission, pid, 6795 uid) == PackageManager.PERMISSION_GRANTED; 6796 } 6797 } 6798 6799 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6800 @Override 6801 public int checkComponentPermission(String permission, int pid, int uid, 6802 int owningUid, boolean exported) { 6803 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6804 owningUid, exported); 6805 } 6806 6807 @Override 6808 public Object getAMSLock() { 6809 return ActivityManagerService.this; 6810 } 6811 } 6812 6813 /** 6814 * This can be called with or without the global lock held. 6815 */ 6816 int checkComponentPermission(String permission, int pid, int uid, 6817 int owningUid, boolean exported) { 6818 // We might be performing an operation on behalf of an indirect binder 6819 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6820 // client identity accordingly before proceeding. 6821 Identity tlsIdentity = sCallerIdentity.get(); 6822 if (tlsIdentity != null) { 6823 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6824 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6825 uid = tlsIdentity.uid; 6826 pid = tlsIdentity.pid; 6827 } 6828 6829 if (pid == MY_PID) { 6830 return PackageManager.PERMISSION_GRANTED; 6831 } 6832 6833 return ActivityManager.checkComponentPermission(permission, uid, 6834 owningUid, exported); 6835 } 6836 6837 /** 6838 * As the only public entry point for permissions checking, this method 6839 * can enforce the semantic that requesting a check on a null global 6840 * permission is automatically denied. (Internally a null permission 6841 * string is used when calling {@link #checkComponentPermission} in cases 6842 * when only uid-based security is needed.) 6843 * 6844 * This can be called with or without the global lock held. 6845 */ 6846 @Override 6847 public int checkPermission(String permission, int pid, int uid) { 6848 if (permission == null) { 6849 return PackageManager.PERMISSION_DENIED; 6850 } 6851 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6852 } 6853 6854 /** 6855 * Binder IPC calls go through the public entry point. 6856 * This can be called with or without the global lock held. 6857 */ 6858 int checkCallingPermission(String permission) { 6859 return checkPermission(permission, 6860 Binder.getCallingPid(), 6861 UserHandle.getAppId(Binder.getCallingUid())); 6862 } 6863 6864 /** 6865 * This can be called with or without the global lock held. 6866 */ 6867 void enforceCallingPermission(String permission, String func) { 6868 if (checkCallingPermission(permission) 6869 == PackageManager.PERMISSION_GRANTED) { 6870 return; 6871 } 6872 6873 String msg = "Permission Denial: " + func + " from pid=" 6874 + Binder.getCallingPid() 6875 + ", uid=" + Binder.getCallingUid() 6876 + " requires " + permission; 6877 Slog.w(TAG, msg); 6878 throw new SecurityException(msg); 6879 } 6880 6881 /** 6882 * Determine if UID is holding permissions required to access {@link Uri} in 6883 * the given {@link ProviderInfo}. Final permission checking is always done 6884 * in {@link ContentProvider}. 6885 */ 6886 private final boolean checkHoldingPermissionsLocked( 6887 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6888 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6889 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6890 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6891 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6892 != PERMISSION_GRANTED) { 6893 return false; 6894 } 6895 } 6896 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6897 } 6898 6899 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6900 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6901 if (pi.applicationInfo.uid == uid) { 6902 return true; 6903 } else if (!pi.exported) { 6904 return false; 6905 } 6906 6907 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6908 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6909 try { 6910 // check if target holds top-level <provider> permissions 6911 if (!readMet && pi.readPermission != null && considerUidPermissions 6912 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6913 readMet = true; 6914 } 6915 if (!writeMet && pi.writePermission != null && considerUidPermissions 6916 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6917 writeMet = true; 6918 } 6919 6920 // track if unprotected read/write is allowed; any denied 6921 // <path-permission> below removes this ability 6922 boolean allowDefaultRead = pi.readPermission == null; 6923 boolean allowDefaultWrite = pi.writePermission == null; 6924 6925 // check if target holds any <path-permission> that match uri 6926 final PathPermission[] pps = pi.pathPermissions; 6927 if (pps != null) { 6928 final String path = grantUri.uri.getPath(); 6929 int i = pps.length; 6930 while (i > 0 && (!readMet || !writeMet)) { 6931 i--; 6932 PathPermission pp = pps[i]; 6933 if (pp.match(path)) { 6934 if (!readMet) { 6935 final String pprperm = pp.getReadPermission(); 6936 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6937 + pprperm + " for " + pp.getPath() 6938 + ": match=" + pp.match(path) 6939 + " check=" + pm.checkUidPermission(pprperm, uid)); 6940 if (pprperm != null) { 6941 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6942 == PERMISSION_GRANTED) { 6943 readMet = true; 6944 } else { 6945 allowDefaultRead = false; 6946 } 6947 } 6948 } 6949 if (!writeMet) { 6950 final String ppwperm = pp.getWritePermission(); 6951 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6952 + ppwperm + " for " + pp.getPath() 6953 + ": match=" + pp.match(path) 6954 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6955 if (ppwperm != null) { 6956 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6957 == PERMISSION_GRANTED) { 6958 writeMet = true; 6959 } else { 6960 allowDefaultWrite = false; 6961 } 6962 } 6963 } 6964 } 6965 } 6966 } 6967 6968 // grant unprotected <provider> read/write, if not blocked by 6969 // <path-permission> above 6970 if (allowDefaultRead) readMet = true; 6971 if (allowDefaultWrite) writeMet = true; 6972 6973 } catch (RemoteException e) { 6974 return false; 6975 } 6976 6977 return readMet && writeMet; 6978 } 6979 6980 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6981 ProviderInfo pi = null; 6982 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6983 if (cpr != null) { 6984 pi = cpr.info; 6985 } else { 6986 try { 6987 pi = AppGlobals.getPackageManager().resolveContentProvider( 6988 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6989 } catch (RemoteException ex) { 6990 } 6991 } 6992 return pi; 6993 } 6994 6995 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6996 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6997 if (targetUris != null) { 6998 return targetUris.get(grantUri); 6999 } 7000 return null; 7001 } 7002 7003 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7004 String targetPkg, int targetUid, GrantUri grantUri) { 7005 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7006 if (targetUris == null) { 7007 targetUris = Maps.newArrayMap(); 7008 mGrantedUriPermissions.put(targetUid, targetUris); 7009 } 7010 7011 UriPermission perm = targetUris.get(grantUri); 7012 if (perm == null) { 7013 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7014 targetUris.put(grantUri, perm); 7015 } 7016 7017 return perm; 7018 } 7019 7020 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7021 final int modeFlags) { 7022 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7023 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7024 : UriPermission.STRENGTH_OWNED; 7025 7026 // Root gets to do everything. 7027 if (uid == 0) { 7028 return true; 7029 } 7030 7031 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7032 if (perms == null) return false; 7033 7034 // First look for exact match 7035 final UriPermission exactPerm = perms.get(grantUri); 7036 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7037 return true; 7038 } 7039 7040 // No exact match, look for prefixes 7041 final int N = perms.size(); 7042 for (int i = 0; i < N; i++) { 7043 final UriPermission perm = perms.valueAt(i); 7044 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7045 && perm.getStrength(modeFlags) >= minStrength) { 7046 return true; 7047 } 7048 } 7049 7050 return false; 7051 } 7052 7053 /** 7054 * @param uri This uri must NOT contain an embedded userId. 7055 * @param userId The userId in which the uri is to be resolved. 7056 */ 7057 @Override 7058 public int checkUriPermission(Uri uri, int pid, int uid, 7059 final int modeFlags, int userId) { 7060 enforceNotIsolatedCaller("checkUriPermission"); 7061 7062 // Another redirected-binder-call permissions check as in 7063 // {@link checkComponentPermission}. 7064 Identity tlsIdentity = sCallerIdentity.get(); 7065 if (tlsIdentity != null) { 7066 uid = tlsIdentity.uid; 7067 pid = tlsIdentity.pid; 7068 } 7069 7070 // Our own process gets to do everything. 7071 if (pid == MY_PID) { 7072 return PackageManager.PERMISSION_GRANTED; 7073 } 7074 synchronized (this) { 7075 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7076 ? PackageManager.PERMISSION_GRANTED 7077 : PackageManager.PERMISSION_DENIED; 7078 } 7079 } 7080 7081 /** 7082 * Check if the targetPkg can be granted permission to access uri by 7083 * the callingUid using the given modeFlags. Throws a security exception 7084 * if callingUid is not allowed to do this. Returns the uid of the target 7085 * if the URI permission grant should be performed; returns -1 if it is not 7086 * needed (for example targetPkg already has permission to access the URI). 7087 * If you already know the uid of the target, you can supply it in 7088 * lastTargetUid else set that to -1. 7089 */ 7090 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7091 final int modeFlags, int lastTargetUid) { 7092 if (!Intent.isAccessUriMode(modeFlags)) { 7093 return -1; 7094 } 7095 7096 if (targetPkg != null) { 7097 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7098 "Checking grant " + targetPkg + " permission to " + grantUri); 7099 } 7100 7101 final IPackageManager pm = AppGlobals.getPackageManager(); 7102 7103 // If this is not a content: uri, we can't do anything with it. 7104 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7105 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7106 "Can't grant URI permission for non-content URI: " + grantUri); 7107 return -1; 7108 } 7109 7110 final String authority = grantUri.uri.getAuthority(); 7111 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7112 if (pi == null) { 7113 Slog.w(TAG, "No content provider found for permission check: " + 7114 grantUri.uri.toSafeString()); 7115 return -1; 7116 } 7117 7118 int targetUid = lastTargetUid; 7119 if (targetUid < 0 && targetPkg != null) { 7120 try { 7121 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7122 if (targetUid < 0) { 7123 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7124 "Can't grant URI permission no uid for: " + targetPkg); 7125 return -1; 7126 } 7127 } catch (RemoteException ex) { 7128 return -1; 7129 } 7130 } 7131 7132 if (targetUid >= 0) { 7133 // First... does the target actually need this permission? 7134 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7135 // No need to grant the target this permission. 7136 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7137 "Target " + targetPkg + " already has full permission to " + grantUri); 7138 return -1; 7139 } 7140 } else { 7141 // First... there is no target package, so can anyone access it? 7142 boolean allowed = pi.exported; 7143 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7144 if (pi.readPermission != null) { 7145 allowed = false; 7146 } 7147 } 7148 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7149 if (pi.writePermission != null) { 7150 allowed = false; 7151 } 7152 } 7153 if (allowed) { 7154 return -1; 7155 } 7156 } 7157 7158 /* There is a special cross user grant if: 7159 * - The target is on another user. 7160 * - Apps on the current user can access the uri without any uid permissions. 7161 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7162 * grant uri permissions. 7163 */ 7164 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7165 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7166 modeFlags, false /*without considering the uid permissions*/); 7167 7168 // Second... is the provider allowing granting of URI permissions? 7169 if (!specialCrossUserGrant) { 7170 if (!pi.grantUriPermissions) { 7171 throw new SecurityException("Provider " + pi.packageName 7172 + "/" + pi.name 7173 + " does not allow granting of Uri permissions (uri " 7174 + grantUri + ")"); 7175 } 7176 if (pi.uriPermissionPatterns != null) { 7177 final int N = pi.uriPermissionPatterns.length; 7178 boolean allowed = false; 7179 for (int i=0; i<N; i++) { 7180 if (pi.uriPermissionPatterns[i] != null 7181 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7182 allowed = true; 7183 break; 7184 } 7185 } 7186 if (!allowed) { 7187 throw new SecurityException("Provider " + pi.packageName 7188 + "/" + pi.name 7189 + " does not allow granting of permission to path of Uri " 7190 + grantUri); 7191 } 7192 } 7193 } 7194 7195 // Third... does the caller itself have permission to access 7196 // this uri? 7197 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7198 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7199 // Require they hold a strong enough Uri permission 7200 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7201 throw new SecurityException("Uid " + callingUid 7202 + " does not have permission to uri " + grantUri); 7203 } 7204 } 7205 } 7206 return targetUid; 7207 } 7208 7209 /** 7210 * @param uri This uri must NOT contain an embedded userId. 7211 * @param userId The userId in which the uri is to be resolved. 7212 */ 7213 @Override 7214 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7215 final int modeFlags, int userId) { 7216 enforceNotIsolatedCaller("checkGrantUriPermission"); 7217 synchronized(this) { 7218 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7219 new GrantUri(userId, uri, false), modeFlags, -1); 7220 } 7221 } 7222 7223 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7224 final int modeFlags, UriPermissionOwner owner) { 7225 if (!Intent.isAccessUriMode(modeFlags)) { 7226 return; 7227 } 7228 7229 // So here we are: the caller has the assumed permission 7230 // to the uri, and the target doesn't. Let's now give this to 7231 // the target. 7232 7233 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7234 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7235 7236 final String authority = grantUri.uri.getAuthority(); 7237 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7238 if (pi == null) { 7239 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7240 return; 7241 } 7242 7243 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7244 grantUri.prefix = true; 7245 } 7246 final UriPermission perm = findOrCreateUriPermissionLocked( 7247 pi.packageName, targetPkg, targetUid, grantUri); 7248 perm.grantModes(modeFlags, owner); 7249 } 7250 7251 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7252 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7253 if (targetPkg == null) { 7254 throw new NullPointerException("targetPkg"); 7255 } 7256 int targetUid; 7257 final IPackageManager pm = AppGlobals.getPackageManager(); 7258 try { 7259 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7260 } catch (RemoteException ex) { 7261 return; 7262 } 7263 7264 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7265 targetUid); 7266 if (targetUid < 0) { 7267 return; 7268 } 7269 7270 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7271 owner); 7272 } 7273 7274 static class NeededUriGrants extends ArrayList<GrantUri> { 7275 final String targetPkg; 7276 final int targetUid; 7277 final int flags; 7278 7279 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7280 this.targetPkg = targetPkg; 7281 this.targetUid = targetUid; 7282 this.flags = flags; 7283 } 7284 } 7285 7286 /** 7287 * Like checkGrantUriPermissionLocked, but takes an Intent. 7288 */ 7289 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7290 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7291 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7292 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7293 + " clip=" + (intent != null ? intent.getClipData() : null) 7294 + " from " + intent + "; flags=0x" 7295 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7296 7297 if (targetPkg == null) { 7298 throw new NullPointerException("targetPkg"); 7299 } 7300 7301 if (intent == null) { 7302 return null; 7303 } 7304 Uri data = intent.getData(); 7305 ClipData clip = intent.getClipData(); 7306 if (data == null && clip == null) { 7307 return null; 7308 } 7309 // Default userId for uris in the intent (if they don't specify it themselves) 7310 int contentUserHint = intent.getContentUserHint(); 7311 if (contentUserHint == UserHandle.USER_CURRENT) { 7312 contentUserHint = UserHandle.getUserId(callingUid); 7313 } 7314 final IPackageManager pm = AppGlobals.getPackageManager(); 7315 int targetUid; 7316 if (needed != null) { 7317 targetUid = needed.targetUid; 7318 } else { 7319 try { 7320 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7321 } catch (RemoteException ex) { 7322 return null; 7323 } 7324 if (targetUid < 0) { 7325 if (DEBUG_URI_PERMISSION) { 7326 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7327 + " on user " + targetUserId); 7328 } 7329 return null; 7330 } 7331 } 7332 if (data != null) { 7333 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7334 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7335 targetUid); 7336 if (targetUid > 0) { 7337 if (needed == null) { 7338 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7339 } 7340 needed.add(grantUri); 7341 } 7342 } 7343 if (clip != null) { 7344 for (int i=0; i<clip.getItemCount(); i++) { 7345 Uri uri = clip.getItemAt(i).getUri(); 7346 if (uri != null) { 7347 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7348 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7349 targetUid); 7350 if (targetUid > 0) { 7351 if (needed == null) { 7352 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7353 } 7354 needed.add(grantUri); 7355 } 7356 } else { 7357 Intent clipIntent = clip.getItemAt(i).getIntent(); 7358 if (clipIntent != null) { 7359 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7360 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7361 if (newNeeded != null) { 7362 needed = newNeeded; 7363 } 7364 } 7365 } 7366 } 7367 } 7368 7369 return needed; 7370 } 7371 7372 /** 7373 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7374 */ 7375 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7376 UriPermissionOwner owner) { 7377 if (needed != null) { 7378 for (int i=0; i<needed.size(); i++) { 7379 GrantUri grantUri = needed.get(i); 7380 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7381 grantUri, needed.flags, owner); 7382 } 7383 } 7384 } 7385 7386 void grantUriPermissionFromIntentLocked(int callingUid, 7387 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7388 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7389 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7390 if (needed == null) { 7391 return; 7392 } 7393 7394 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7395 } 7396 7397 /** 7398 * @param uri This uri must NOT contain an embedded userId. 7399 * @param userId The userId in which the uri is to be resolved. 7400 */ 7401 @Override 7402 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7403 final int modeFlags, int userId) { 7404 enforceNotIsolatedCaller("grantUriPermission"); 7405 GrantUri grantUri = new GrantUri(userId, uri, false); 7406 synchronized(this) { 7407 final ProcessRecord r = getRecordForAppLocked(caller); 7408 if (r == null) { 7409 throw new SecurityException("Unable to find app for caller " 7410 + caller 7411 + " when granting permission to uri " + grantUri); 7412 } 7413 if (targetPkg == null) { 7414 throw new IllegalArgumentException("null target"); 7415 } 7416 if (grantUri == null) { 7417 throw new IllegalArgumentException("null uri"); 7418 } 7419 7420 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7421 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7422 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7423 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7424 7425 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7426 UserHandle.getUserId(r.uid)); 7427 } 7428 } 7429 7430 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7431 if (perm.modeFlags == 0) { 7432 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7433 perm.targetUid); 7434 if (perms != null) { 7435 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7436 "Removing " + perm.targetUid + " permission to " + perm.uri); 7437 7438 perms.remove(perm.uri); 7439 if (perms.isEmpty()) { 7440 mGrantedUriPermissions.remove(perm.targetUid); 7441 } 7442 } 7443 } 7444 } 7445 7446 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7448 7449 final IPackageManager pm = AppGlobals.getPackageManager(); 7450 final String authority = grantUri.uri.getAuthority(); 7451 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7452 if (pi == null) { 7453 Slog.w(TAG, "No content provider found for permission revoke: " 7454 + grantUri.toSafeString()); 7455 return; 7456 } 7457 7458 // Does the caller have this permission on the URI? 7459 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7460 // Right now, if you are not the original owner of the permission, 7461 // you are not allowed to revoke it. 7462 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7463 throw new SecurityException("Uid " + callingUid 7464 + " does not have permission to uri " + grantUri); 7465 //} 7466 } 7467 7468 boolean persistChanged = false; 7469 7470 // Go through all of the permissions and remove any that match. 7471 int N = mGrantedUriPermissions.size(); 7472 for (int i = 0; i < N; i++) { 7473 final int targetUid = mGrantedUriPermissions.keyAt(i); 7474 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7475 7476 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7477 final UriPermission perm = it.next(); 7478 if (perm.uri.sourceUserId == grantUri.sourceUserId 7479 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7480 if (DEBUG_URI_PERMISSION) 7481 Slog.v(TAG, 7482 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7483 persistChanged |= perm.revokeModes( 7484 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7485 if (perm.modeFlags == 0) { 7486 it.remove(); 7487 } 7488 } 7489 } 7490 7491 if (perms.isEmpty()) { 7492 mGrantedUriPermissions.remove(targetUid); 7493 N--; 7494 i--; 7495 } 7496 } 7497 7498 if (persistChanged) { 7499 schedulePersistUriGrants(); 7500 } 7501 } 7502 7503 /** 7504 * @param uri This uri must NOT contain an embedded userId. 7505 * @param userId The userId in which the uri is to be resolved. 7506 */ 7507 @Override 7508 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7509 int userId) { 7510 enforceNotIsolatedCaller("revokeUriPermission"); 7511 synchronized(this) { 7512 final ProcessRecord r = getRecordForAppLocked(caller); 7513 if (r == null) { 7514 throw new SecurityException("Unable to find app for caller " 7515 + caller 7516 + " when revoking permission to uri " + uri); 7517 } 7518 if (uri == null) { 7519 Slog.w(TAG, "revokeUriPermission: null uri"); 7520 return; 7521 } 7522 7523 if (!Intent.isAccessUriMode(modeFlags)) { 7524 return; 7525 } 7526 7527 final IPackageManager pm = AppGlobals.getPackageManager(); 7528 final String authority = uri.getAuthority(); 7529 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7530 if (pi == null) { 7531 Slog.w(TAG, "No content provider found for permission revoke: " 7532 + uri.toSafeString()); 7533 return; 7534 } 7535 7536 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7537 } 7538 } 7539 7540 /** 7541 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7542 * given package. 7543 * 7544 * @param packageName Package name to match, or {@code null} to apply to all 7545 * packages. 7546 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7547 * to all users. 7548 * @param persistable If persistable grants should be removed. 7549 */ 7550 private void removeUriPermissionsForPackageLocked( 7551 String packageName, int userHandle, boolean persistable) { 7552 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7553 throw new IllegalArgumentException("Must narrow by either package or user"); 7554 } 7555 7556 boolean persistChanged = false; 7557 7558 int N = mGrantedUriPermissions.size(); 7559 for (int i = 0; i < N; i++) { 7560 final int targetUid = mGrantedUriPermissions.keyAt(i); 7561 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7562 7563 // Only inspect grants matching user 7564 if (userHandle == UserHandle.USER_ALL 7565 || userHandle == UserHandle.getUserId(targetUid)) { 7566 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7567 final UriPermission perm = it.next(); 7568 7569 // Only inspect grants matching package 7570 if (packageName == null || perm.sourcePkg.equals(packageName) 7571 || perm.targetPkg.equals(packageName)) { 7572 persistChanged |= perm.revokeModes( 7573 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7574 7575 // Only remove when no modes remain; any persisted grants 7576 // will keep this alive. 7577 if (perm.modeFlags == 0) { 7578 it.remove(); 7579 } 7580 } 7581 } 7582 7583 if (perms.isEmpty()) { 7584 mGrantedUriPermissions.remove(targetUid); 7585 N--; 7586 i--; 7587 } 7588 } 7589 } 7590 7591 if (persistChanged) { 7592 schedulePersistUriGrants(); 7593 } 7594 } 7595 7596 @Override 7597 public IBinder newUriPermissionOwner(String name) { 7598 enforceNotIsolatedCaller("newUriPermissionOwner"); 7599 synchronized(this) { 7600 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7601 return owner.getExternalTokenLocked(); 7602 } 7603 } 7604 7605 /** 7606 * @param uri This uri must NOT contain an embedded userId. 7607 * @param sourceUserId The userId in which the uri is to be resolved. 7608 * @param targetUserId The userId of the app that receives the grant. 7609 */ 7610 @Override 7611 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7612 final int modeFlags, int sourceUserId, int targetUserId) { 7613 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7614 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7615 synchronized(this) { 7616 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7617 if (owner == null) { 7618 throw new IllegalArgumentException("Unknown owner: " + token); 7619 } 7620 if (fromUid != Binder.getCallingUid()) { 7621 if (Binder.getCallingUid() != Process.myUid()) { 7622 // Only system code can grant URI permissions on behalf 7623 // of other users. 7624 throw new SecurityException("nice try"); 7625 } 7626 } 7627 if (targetPkg == null) { 7628 throw new IllegalArgumentException("null target"); 7629 } 7630 if (uri == null) { 7631 throw new IllegalArgumentException("null uri"); 7632 } 7633 7634 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7635 modeFlags, owner, targetUserId); 7636 } 7637 } 7638 7639 /** 7640 * @param uri This uri must NOT contain an embedded userId. 7641 * @param userId The userId in which the uri is to be resolved. 7642 */ 7643 @Override 7644 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7645 synchronized(this) { 7646 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7647 if (owner == null) { 7648 throw new IllegalArgumentException("Unknown owner: " + token); 7649 } 7650 7651 if (uri == null) { 7652 owner.removeUriPermissionsLocked(mode); 7653 } else { 7654 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7655 } 7656 } 7657 } 7658 7659 private void schedulePersistUriGrants() { 7660 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7661 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7662 10 * DateUtils.SECOND_IN_MILLIS); 7663 } 7664 } 7665 7666 private void writeGrantedUriPermissions() { 7667 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7668 7669 // Snapshot permissions so we can persist without lock 7670 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7671 synchronized (this) { 7672 final int size = mGrantedUriPermissions.size(); 7673 for (int i = 0; i < size; i++) { 7674 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7675 for (UriPermission perm : perms.values()) { 7676 if (perm.persistedModeFlags != 0) { 7677 persist.add(perm.snapshot()); 7678 } 7679 } 7680 } 7681 } 7682 7683 FileOutputStream fos = null; 7684 try { 7685 fos = mGrantFile.startWrite(); 7686 7687 XmlSerializer out = new FastXmlSerializer(); 7688 out.setOutput(fos, "utf-8"); 7689 out.startDocument(null, true); 7690 out.startTag(null, TAG_URI_GRANTS); 7691 for (UriPermission.Snapshot perm : persist) { 7692 out.startTag(null, TAG_URI_GRANT); 7693 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7694 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7695 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7696 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7697 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7698 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7699 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7700 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7701 out.endTag(null, TAG_URI_GRANT); 7702 } 7703 out.endTag(null, TAG_URI_GRANTS); 7704 out.endDocument(); 7705 7706 mGrantFile.finishWrite(fos); 7707 } catch (IOException e) { 7708 if (fos != null) { 7709 mGrantFile.failWrite(fos); 7710 } 7711 } 7712 } 7713 7714 private void readGrantedUriPermissionsLocked() { 7715 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7716 7717 final long now = System.currentTimeMillis(); 7718 7719 FileInputStream fis = null; 7720 try { 7721 fis = mGrantFile.openRead(); 7722 final XmlPullParser in = Xml.newPullParser(); 7723 in.setInput(fis, null); 7724 7725 int type; 7726 while ((type = in.next()) != END_DOCUMENT) { 7727 final String tag = in.getName(); 7728 if (type == START_TAG) { 7729 if (TAG_URI_GRANT.equals(tag)) { 7730 final int sourceUserId; 7731 final int targetUserId; 7732 final int userHandle = readIntAttribute(in, 7733 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7734 if (userHandle != UserHandle.USER_NULL) { 7735 // For backwards compatibility. 7736 sourceUserId = userHandle; 7737 targetUserId = userHandle; 7738 } else { 7739 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7740 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7741 } 7742 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7743 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7744 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7745 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7746 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7747 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7748 7749 // Sanity check that provider still belongs to source package 7750 final ProviderInfo pi = getProviderInfoLocked( 7751 uri.getAuthority(), sourceUserId); 7752 if (pi != null && sourcePkg.equals(pi.packageName)) { 7753 int targetUid = -1; 7754 try { 7755 targetUid = AppGlobals.getPackageManager() 7756 .getPackageUid(targetPkg, targetUserId); 7757 } catch (RemoteException e) { 7758 } 7759 if (targetUid != -1) { 7760 final UriPermission perm = findOrCreateUriPermissionLocked( 7761 sourcePkg, targetPkg, targetUid, 7762 new GrantUri(sourceUserId, uri, prefix)); 7763 perm.initPersistedModes(modeFlags, createdTime); 7764 } 7765 } else { 7766 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7767 + " but instead found " + pi); 7768 } 7769 } 7770 } 7771 } 7772 } catch (FileNotFoundException e) { 7773 // Missing grants is okay 7774 } catch (IOException e) { 7775 Log.wtf(TAG, "Failed reading Uri grants", e); 7776 } catch (XmlPullParserException e) { 7777 Log.wtf(TAG, "Failed reading Uri grants", e); 7778 } finally { 7779 IoUtils.closeQuietly(fis); 7780 } 7781 } 7782 7783 /** 7784 * @param uri This uri must NOT contain an embedded userId. 7785 * @param userId The userId in which the uri is to be resolved. 7786 */ 7787 @Override 7788 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7789 enforceNotIsolatedCaller("takePersistableUriPermission"); 7790 7791 Preconditions.checkFlagsArgument(modeFlags, 7792 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7793 7794 synchronized (this) { 7795 final int callingUid = Binder.getCallingUid(); 7796 boolean persistChanged = false; 7797 GrantUri grantUri = new GrantUri(userId, uri, false); 7798 7799 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7800 new GrantUri(userId, uri, false)); 7801 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7802 new GrantUri(userId, uri, true)); 7803 7804 final boolean exactValid = (exactPerm != null) 7805 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7806 final boolean prefixValid = (prefixPerm != null) 7807 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7808 7809 if (!(exactValid || prefixValid)) { 7810 throw new SecurityException("No persistable permission grants found for UID " 7811 + callingUid + " and Uri " + grantUri.toSafeString()); 7812 } 7813 7814 if (exactValid) { 7815 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7816 } 7817 if (prefixValid) { 7818 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7819 } 7820 7821 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7822 7823 if (persistChanged) { 7824 schedulePersistUriGrants(); 7825 } 7826 } 7827 } 7828 7829 /** 7830 * @param uri This uri must NOT contain an embedded userId. 7831 * @param userId The userId in which the uri is to be resolved. 7832 */ 7833 @Override 7834 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7835 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7836 7837 Preconditions.checkFlagsArgument(modeFlags, 7838 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7839 7840 synchronized (this) { 7841 final int callingUid = Binder.getCallingUid(); 7842 boolean persistChanged = false; 7843 7844 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7845 new GrantUri(userId, uri, false)); 7846 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7847 new GrantUri(userId, uri, true)); 7848 if (exactPerm == null && prefixPerm == null) { 7849 throw new SecurityException("No permission grants found for UID " + callingUid 7850 + " and Uri " + uri.toSafeString()); 7851 } 7852 7853 if (exactPerm != null) { 7854 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7855 removeUriPermissionIfNeededLocked(exactPerm); 7856 } 7857 if (prefixPerm != null) { 7858 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7859 removeUriPermissionIfNeededLocked(prefixPerm); 7860 } 7861 7862 if (persistChanged) { 7863 schedulePersistUriGrants(); 7864 } 7865 } 7866 } 7867 7868 /** 7869 * Prune any older {@link UriPermission} for the given UID until outstanding 7870 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7871 * 7872 * @return if any mutations occured that require persisting. 7873 */ 7874 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7875 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7876 if (perms == null) return false; 7877 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7878 7879 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7880 for (UriPermission perm : perms.values()) { 7881 if (perm.persistedModeFlags != 0) { 7882 persisted.add(perm); 7883 } 7884 } 7885 7886 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7887 if (trimCount <= 0) return false; 7888 7889 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7890 for (int i = 0; i < trimCount; i++) { 7891 final UriPermission perm = persisted.get(i); 7892 7893 if (DEBUG_URI_PERMISSION) { 7894 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7895 } 7896 7897 perm.releasePersistableModes(~0); 7898 removeUriPermissionIfNeededLocked(perm); 7899 } 7900 7901 return true; 7902 } 7903 7904 @Override 7905 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7906 String packageName, boolean incoming) { 7907 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7908 Preconditions.checkNotNull(packageName, "packageName"); 7909 7910 final int callingUid = Binder.getCallingUid(); 7911 final IPackageManager pm = AppGlobals.getPackageManager(); 7912 try { 7913 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7914 if (packageUid != callingUid) { 7915 throw new SecurityException( 7916 "Package " + packageName + " does not belong to calling UID " + callingUid); 7917 } 7918 } catch (RemoteException e) { 7919 throw new SecurityException("Failed to verify package name ownership"); 7920 } 7921 7922 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7923 synchronized (this) { 7924 if (incoming) { 7925 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7926 callingUid); 7927 if (perms == null) { 7928 Slog.w(TAG, "No permission grants found for " + packageName); 7929 } else { 7930 for (UriPermission perm : perms.values()) { 7931 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7932 result.add(perm.buildPersistedPublicApiObject()); 7933 } 7934 } 7935 } 7936 } else { 7937 final int size = mGrantedUriPermissions.size(); 7938 for (int i = 0; i < size; i++) { 7939 final ArrayMap<GrantUri, UriPermission> perms = 7940 mGrantedUriPermissions.valueAt(i); 7941 for (UriPermission perm : perms.values()) { 7942 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7943 result.add(perm.buildPersistedPublicApiObject()); 7944 } 7945 } 7946 } 7947 } 7948 } 7949 return new ParceledListSlice<android.content.UriPermission>(result); 7950 } 7951 7952 @Override 7953 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7954 synchronized (this) { 7955 ProcessRecord app = 7956 who != null ? getRecordForAppLocked(who) : null; 7957 if (app == null) return; 7958 7959 Message msg = Message.obtain(); 7960 msg.what = WAIT_FOR_DEBUGGER_MSG; 7961 msg.obj = app; 7962 msg.arg1 = waiting ? 1 : 0; 7963 mHandler.sendMessage(msg); 7964 } 7965 } 7966 7967 @Override 7968 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7969 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7970 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7971 outInfo.availMem = Process.getFreeMemory(); 7972 outInfo.totalMem = Process.getTotalMemory(); 7973 outInfo.threshold = homeAppMem; 7974 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7975 outInfo.hiddenAppThreshold = cachedAppMem; 7976 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7977 ProcessList.SERVICE_ADJ); 7978 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7979 ProcessList.VISIBLE_APP_ADJ); 7980 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7981 ProcessList.FOREGROUND_APP_ADJ); 7982 } 7983 7984 // ========================================================= 7985 // TASK MANAGEMENT 7986 // ========================================================= 7987 7988 @Override 7989 public List<IAppTask> getAppTasks(String callingPackage) { 7990 int callingUid = Binder.getCallingUid(); 7991 long ident = Binder.clearCallingIdentity(); 7992 7993 synchronized(this) { 7994 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7995 try { 7996 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7997 7998 final int N = mRecentTasks.size(); 7999 for (int i = 0; i < N; i++) { 8000 TaskRecord tr = mRecentTasks.get(i); 8001 // Skip tasks that do not match the caller. We don't need to verify 8002 // callingPackage, because we are also limiting to callingUid and know 8003 // that will limit to the correct security sandbox. 8004 if (tr.effectiveUid != callingUid) { 8005 continue; 8006 } 8007 Intent intent = tr.getBaseIntent(); 8008 if (intent == null || 8009 !callingPackage.equals(intent.getComponent().getPackageName())) { 8010 continue; 8011 } 8012 ActivityManager.RecentTaskInfo taskInfo = 8013 createRecentTaskInfoFromTaskRecord(tr); 8014 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8015 list.add(taskImpl); 8016 } 8017 } finally { 8018 Binder.restoreCallingIdentity(ident); 8019 } 8020 return list; 8021 } 8022 } 8023 8024 @Override 8025 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8026 final int callingUid = Binder.getCallingUid(); 8027 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8028 8029 synchronized(this) { 8030 if (localLOGV) Slog.v( 8031 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8032 8033 final boolean allowed = checkCallingPermission( 8034 android.Manifest.permission.GET_TASKS) 8035 == PackageManager.PERMISSION_GRANTED; 8036 if (!allowed) { 8037 Slog.w(TAG, "getTasks: caller " + callingUid 8038 + " does not hold GET_TASKS; limiting output"); 8039 } 8040 8041 // TODO: Improve with MRU list from all ActivityStacks. 8042 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8043 } 8044 8045 return list; 8046 } 8047 8048 TaskRecord getMostRecentTask() { 8049 return mRecentTasks.get(0); 8050 } 8051 8052 /** 8053 * Creates a new RecentTaskInfo from a TaskRecord. 8054 */ 8055 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8056 // Update the task description to reflect any changes in the task stack 8057 tr.updateTaskDescription(); 8058 8059 // Compose the recent task info 8060 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8061 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8062 rti.persistentId = tr.taskId; 8063 rti.baseIntent = new Intent(tr.getBaseIntent()); 8064 rti.origActivity = tr.origActivity; 8065 rti.description = tr.lastDescription; 8066 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8067 rti.userId = tr.userId; 8068 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8069 rti.firstActiveTime = tr.firstActiveTime; 8070 rti.lastActiveTime = tr.lastActiveTime; 8071 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8072 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8073 return rti; 8074 } 8075 8076 @Override 8077 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8078 final int callingUid = Binder.getCallingUid(); 8079 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8080 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8081 8082 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8083 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8084 synchronized (this) { 8085 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8086 == PackageManager.PERMISSION_GRANTED; 8087 if (!allowed) { 8088 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8089 + " does not hold GET_TASKS; limiting output"); 8090 } 8091 final boolean detailed = checkCallingPermission( 8092 android.Manifest.permission.GET_DETAILED_TASKS) 8093 == PackageManager.PERMISSION_GRANTED; 8094 8095 final int N = mRecentTasks.size(); 8096 ArrayList<ActivityManager.RecentTaskInfo> res 8097 = new ArrayList<ActivityManager.RecentTaskInfo>( 8098 maxNum < N ? maxNum : N); 8099 8100 final Set<Integer> includedUsers; 8101 if (includeProfiles) { 8102 includedUsers = getProfileIdsLocked(userId); 8103 } else { 8104 includedUsers = new HashSet<Integer>(); 8105 } 8106 includedUsers.add(Integer.valueOf(userId)); 8107 8108 for (int i=0; i<N && maxNum > 0; i++) { 8109 TaskRecord tr = mRecentTasks.get(i); 8110 // Only add calling user or related users recent tasks 8111 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8112 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8113 continue; 8114 } 8115 8116 // Return the entry if desired by the caller. We always return 8117 // the first entry, because callers always expect this to be the 8118 // foreground app. We may filter others if the caller has 8119 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8120 // we should exclude the entry. 8121 8122 if (i == 0 8123 || withExcluded 8124 || (tr.intent == null) 8125 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8126 == 0)) { 8127 if (!allowed) { 8128 // If the caller doesn't have the GET_TASKS permission, then only 8129 // allow them to see a small subset of tasks -- their own and home. 8130 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8131 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8132 continue; 8133 } 8134 } 8135 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8136 if (tr.stack != null && tr.stack.isHomeStack()) { 8137 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8138 continue; 8139 } 8140 } 8141 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8142 // Don't include auto remove tasks that are finished or finishing. 8143 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8144 + tr); 8145 continue; 8146 } 8147 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8148 && !tr.isAvailable) { 8149 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8150 continue; 8151 } 8152 8153 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8154 if (!detailed) { 8155 rti.baseIntent.replaceExtras((Bundle)null); 8156 } 8157 8158 res.add(rti); 8159 maxNum--; 8160 } 8161 } 8162 return res; 8163 } 8164 } 8165 8166 private TaskRecord recentTaskForIdLocked(int id) { 8167 final int N = mRecentTasks.size(); 8168 for (int i=0; i<N; i++) { 8169 TaskRecord tr = mRecentTasks.get(i); 8170 if (tr.taskId == id) { 8171 return tr; 8172 } 8173 } 8174 return null; 8175 } 8176 8177 @Override 8178 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8179 synchronized (this) { 8180 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8181 "getTaskThumbnail()"); 8182 TaskRecord tr = recentTaskForIdLocked(id); 8183 if (tr != null) { 8184 return tr.getTaskThumbnailLocked(); 8185 } 8186 } 8187 return null; 8188 } 8189 8190 @Override 8191 public int addAppTask(IBinder activityToken, Intent intent, 8192 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8193 final int callingUid = Binder.getCallingUid(); 8194 final long callingIdent = Binder.clearCallingIdentity(); 8195 8196 try { 8197 synchronized (this) { 8198 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8199 if (r == null) { 8200 throw new IllegalArgumentException("Activity does not exist; token=" 8201 + activityToken); 8202 } 8203 ComponentName comp = intent.getComponent(); 8204 if (comp == null) { 8205 throw new IllegalArgumentException("Intent " + intent 8206 + " must specify explicit component"); 8207 } 8208 if (thumbnail.getWidth() != mThumbnailWidth 8209 || thumbnail.getHeight() != mThumbnailHeight) { 8210 throw new IllegalArgumentException("Bad thumbnail size: got " 8211 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8212 + mThumbnailWidth + "x" + mThumbnailHeight); 8213 } 8214 if (intent.getSelector() != null) { 8215 intent.setSelector(null); 8216 } 8217 if (intent.getSourceBounds() != null) { 8218 intent.setSourceBounds(null); 8219 } 8220 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8221 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8222 // The caller has added this as an auto-remove task... that makes no 8223 // sense, so turn off auto-remove. 8224 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8225 } 8226 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8227 // Must be a new task. 8228 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8229 } 8230 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8231 mLastAddedTaskActivity = null; 8232 } 8233 ActivityInfo ainfo = mLastAddedTaskActivity; 8234 if (ainfo == null) { 8235 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8236 comp, 0, UserHandle.getUserId(callingUid)); 8237 if (ainfo.applicationInfo.uid != callingUid) { 8238 throw new SecurityException( 8239 "Can't add task for another application: target uid=" 8240 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8241 } 8242 } 8243 8244 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8245 intent, description); 8246 8247 int trimIdx = trimRecentsForTask(task, false); 8248 if (trimIdx >= 0) { 8249 // If this would have caused a trim, then we'll abort because that 8250 // means it would be added at the end of the list but then just removed. 8251 return -1; 8252 } 8253 8254 final int N = mRecentTasks.size(); 8255 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8256 final TaskRecord tr = mRecentTasks.remove(N - 1); 8257 tr.removedFromRecents(mTaskPersister); 8258 } 8259 8260 task.inRecents = true; 8261 mRecentTasks.add(task); 8262 r.task.stack.addTask(task, false, false); 8263 8264 task.setLastThumbnail(thumbnail); 8265 task.freeLastThumbnail(); 8266 8267 return task.taskId; 8268 } 8269 } finally { 8270 Binder.restoreCallingIdentity(callingIdent); 8271 } 8272 } 8273 8274 @Override 8275 public Point getAppTaskThumbnailSize() { 8276 synchronized (this) { 8277 return new Point(mThumbnailWidth, mThumbnailHeight); 8278 } 8279 } 8280 8281 @Override 8282 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8283 synchronized (this) { 8284 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8285 if (r != null) { 8286 r.taskDescription = td; 8287 r.task.updateTaskDescription(); 8288 } 8289 } 8290 } 8291 8292 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8293 mRecentTasks.remove(tr); 8294 tr.removedFromRecents(mTaskPersister); 8295 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8296 Intent baseIntent = new Intent( 8297 tr.intent != null ? tr.intent : tr.affinityIntent); 8298 ComponentName component = baseIntent.getComponent(); 8299 if (component == null) { 8300 Slog.w(TAG, "Now component for base intent of task: " + tr); 8301 return; 8302 } 8303 8304 // Find any running services associated with this app. 8305 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8306 8307 if (killProcesses) { 8308 // Find any running processes associated with this app. 8309 final String pkg = component.getPackageName(); 8310 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8311 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8312 for (int i=0; i<pmap.size(); i++) { 8313 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8314 for (int j=0; j<uids.size(); j++) { 8315 ProcessRecord proc = uids.valueAt(j); 8316 if (proc.userId != tr.userId) { 8317 continue; 8318 } 8319 if (!proc.pkgList.containsKey(pkg)) { 8320 continue; 8321 } 8322 procs.add(proc); 8323 } 8324 } 8325 8326 // Kill the running processes. 8327 for (int i=0; i<procs.size(); i++) { 8328 ProcessRecord pr = procs.get(i); 8329 if (pr == mHomeProcess) { 8330 // Don't kill the home process along with tasks from the same package. 8331 continue; 8332 } 8333 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8334 pr.kill("remove task", true); 8335 } else { 8336 pr.waitingToKill = "remove task"; 8337 } 8338 } 8339 } 8340 } 8341 8342 /** 8343 * Removes the task with the specified task id. 8344 * 8345 * @param taskId Identifier of the task to be removed. 8346 * @param flags Additional operational flags. May be 0 or 8347 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8348 * @return Returns true if the given task was found and removed. 8349 */ 8350 private boolean removeTaskByIdLocked(int taskId, int flags) { 8351 TaskRecord tr = recentTaskForIdLocked(taskId); 8352 if (tr != null) { 8353 tr.removeTaskActivitiesLocked(); 8354 cleanUpRemovedTaskLocked(tr, flags); 8355 if (tr.isPersistable) { 8356 notifyTaskPersisterLocked(null, true); 8357 } 8358 return true; 8359 } 8360 return false; 8361 } 8362 8363 @Override 8364 public boolean removeTask(int taskId, int flags) { 8365 synchronized (this) { 8366 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8367 "removeTask()"); 8368 long ident = Binder.clearCallingIdentity(); 8369 try { 8370 return removeTaskByIdLocked(taskId, flags); 8371 } finally { 8372 Binder.restoreCallingIdentity(ident); 8373 } 8374 } 8375 } 8376 8377 /** 8378 * TODO: Add mController hook 8379 */ 8380 @Override 8381 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8382 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8383 "moveTaskToFront()"); 8384 8385 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8386 synchronized(this) { 8387 moveTaskToFrontLocked(taskId, flags, options); 8388 } 8389 } 8390 8391 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8392 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8393 Binder.getCallingUid(), "Task to front")) { 8394 ActivityOptions.abort(options); 8395 return; 8396 } 8397 final long origId = Binder.clearCallingIdentity(); 8398 try { 8399 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8400 if (task == null) { 8401 return; 8402 } 8403 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8404 mStackSupervisor.showLockTaskToast(); 8405 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8406 return; 8407 } 8408 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8409 if (prev != null && prev.isRecentsActivity()) { 8410 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8411 } 8412 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8413 } finally { 8414 Binder.restoreCallingIdentity(origId); 8415 } 8416 ActivityOptions.abort(options); 8417 } 8418 8419 @Override 8420 public void moveTaskToBack(int taskId) { 8421 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8422 "moveTaskToBack()"); 8423 8424 synchronized(this) { 8425 TaskRecord tr = recentTaskForIdLocked(taskId); 8426 if (tr != null) { 8427 if (tr == mStackSupervisor.mLockTaskModeTask) { 8428 mStackSupervisor.showLockTaskToast(); 8429 return; 8430 } 8431 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8432 ActivityStack stack = tr.stack; 8433 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8434 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8435 Binder.getCallingUid(), "Task to back")) { 8436 return; 8437 } 8438 } 8439 final long origId = Binder.clearCallingIdentity(); 8440 try { 8441 stack.moveTaskToBackLocked(taskId, null); 8442 } finally { 8443 Binder.restoreCallingIdentity(origId); 8444 } 8445 } 8446 } 8447 } 8448 8449 /** 8450 * Moves an activity, and all of the other activities within the same task, to the bottom 8451 * of the history stack. The activity's order within the task is unchanged. 8452 * 8453 * @param token A reference to the activity we wish to move 8454 * @param nonRoot If false then this only works if the activity is the root 8455 * of a task; if true it will work for any activity in a task. 8456 * @return Returns true if the move completed, false if not. 8457 */ 8458 @Override 8459 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8460 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8461 synchronized(this) { 8462 final long origId = Binder.clearCallingIdentity(); 8463 try { 8464 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8465 if (taskId >= 0) { 8466 if ((mStackSupervisor.mLockTaskModeTask != null) 8467 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8468 mStackSupervisor.showLockTaskToast(); 8469 return false; 8470 } 8471 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8472 } 8473 } finally { 8474 Binder.restoreCallingIdentity(origId); 8475 } 8476 } 8477 return false; 8478 } 8479 8480 @Override 8481 public void moveTaskBackwards(int task) { 8482 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8483 "moveTaskBackwards()"); 8484 8485 synchronized(this) { 8486 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8487 Binder.getCallingUid(), "Task backwards")) { 8488 return; 8489 } 8490 final long origId = Binder.clearCallingIdentity(); 8491 moveTaskBackwardsLocked(task); 8492 Binder.restoreCallingIdentity(origId); 8493 } 8494 } 8495 8496 private final void moveTaskBackwardsLocked(int task) { 8497 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8498 } 8499 8500 @Override 8501 public IBinder getHomeActivityToken() throws RemoteException { 8502 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8503 "getHomeActivityToken()"); 8504 synchronized (this) { 8505 return mStackSupervisor.getHomeActivityToken(); 8506 } 8507 } 8508 8509 @Override 8510 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8511 IActivityContainerCallback callback) throws RemoteException { 8512 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8513 "createActivityContainer()"); 8514 synchronized (this) { 8515 if (parentActivityToken == null) { 8516 throw new IllegalArgumentException("parent token must not be null"); 8517 } 8518 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8519 if (r == null) { 8520 return null; 8521 } 8522 if (callback == null) { 8523 throw new IllegalArgumentException("callback must not be null"); 8524 } 8525 return mStackSupervisor.createActivityContainer(r, callback); 8526 } 8527 } 8528 8529 @Override 8530 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8531 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8532 "deleteActivityContainer()"); 8533 synchronized (this) { 8534 mStackSupervisor.deleteActivityContainer(container); 8535 } 8536 } 8537 8538 @Override 8539 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8540 throws RemoteException { 8541 synchronized (this) { 8542 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8543 if (stack != null) { 8544 return stack.mActivityContainer; 8545 } 8546 return null; 8547 } 8548 } 8549 8550 @Override 8551 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8552 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8553 "moveTaskToStack()"); 8554 if (stackId == HOME_STACK_ID) { 8555 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8556 new RuntimeException("here").fillInStackTrace()); 8557 } 8558 synchronized (this) { 8559 long ident = Binder.clearCallingIdentity(); 8560 try { 8561 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8562 + stackId + " toTop=" + toTop); 8563 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8564 } finally { 8565 Binder.restoreCallingIdentity(ident); 8566 } 8567 } 8568 } 8569 8570 @Override 8571 public void resizeStack(int stackBoxId, Rect bounds) { 8572 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8573 "resizeStackBox()"); 8574 long ident = Binder.clearCallingIdentity(); 8575 try { 8576 mWindowManager.resizeStack(stackBoxId, bounds); 8577 } finally { 8578 Binder.restoreCallingIdentity(ident); 8579 } 8580 } 8581 8582 @Override 8583 public List<StackInfo> getAllStackInfos() { 8584 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8585 "getAllStackInfos()"); 8586 long ident = Binder.clearCallingIdentity(); 8587 try { 8588 synchronized (this) { 8589 return mStackSupervisor.getAllStackInfosLocked(); 8590 } 8591 } finally { 8592 Binder.restoreCallingIdentity(ident); 8593 } 8594 } 8595 8596 @Override 8597 public StackInfo getStackInfo(int stackId) { 8598 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8599 "getStackInfo()"); 8600 long ident = Binder.clearCallingIdentity(); 8601 try { 8602 synchronized (this) { 8603 return mStackSupervisor.getStackInfoLocked(stackId); 8604 } 8605 } finally { 8606 Binder.restoreCallingIdentity(ident); 8607 } 8608 } 8609 8610 @Override 8611 public boolean isInHomeStack(int taskId) { 8612 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8613 "getStackInfo()"); 8614 long ident = Binder.clearCallingIdentity(); 8615 try { 8616 synchronized (this) { 8617 TaskRecord tr = recentTaskForIdLocked(taskId); 8618 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8619 } 8620 } finally { 8621 Binder.restoreCallingIdentity(ident); 8622 } 8623 } 8624 8625 @Override 8626 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8627 synchronized(this) { 8628 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8629 } 8630 } 8631 8632 private boolean isLockTaskAuthorized(String pkg) { 8633 final DevicePolicyManager dpm = (DevicePolicyManager) 8634 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8635 try { 8636 int uid = mContext.getPackageManager().getPackageUid(pkg, 8637 Binder.getCallingUserHandle().getIdentifier()); 8638 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8639 } catch (NameNotFoundException e) { 8640 return false; 8641 } 8642 } 8643 8644 void startLockTaskMode(TaskRecord task) { 8645 final String pkg; 8646 synchronized (this) { 8647 pkg = task.intent.getComponent().getPackageName(); 8648 } 8649 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8650 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8651 final TaskRecord taskRecord = task; 8652 mHandler.post(new Runnable() { 8653 @Override 8654 public void run() { 8655 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8656 } 8657 }); 8658 return; 8659 } 8660 long ident = Binder.clearCallingIdentity(); 8661 try { 8662 synchronized (this) { 8663 // Since we lost lock on task, make sure it is still there. 8664 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8665 if (task != null) { 8666 if (!isSystemInitiated 8667 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8668 throw new IllegalArgumentException("Invalid task, not in foreground"); 8669 } 8670 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8671 } 8672 } 8673 } finally { 8674 Binder.restoreCallingIdentity(ident); 8675 } 8676 } 8677 8678 @Override 8679 public void startLockTaskMode(int taskId) { 8680 final TaskRecord task; 8681 long ident = Binder.clearCallingIdentity(); 8682 try { 8683 synchronized (this) { 8684 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8685 } 8686 } finally { 8687 Binder.restoreCallingIdentity(ident); 8688 } 8689 if (task != null) { 8690 startLockTaskMode(task); 8691 } 8692 } 8693 8694 @Override 8695 public void startLockTaskMode(IBinder token) { 8696 final TaskRecord task; 8697 long ident = Binder.clearCallingIdentity(); 8698 try { 8699 synchronized (this) { 8700 final ActivityRecord r = ActivityRecord.forToken(token); 8701 if (r == null) { 8702 return; 8703 } 8704 task = r.task; 8705 } 8706 } finally { 8707 Binder.restoreCallingIdentity(ident); 8708 } 8709 if (task != null) { 8710 startLockTaskMode(task); 8711 } 8712 } 8713 8714 @Override 8715 public void startLockTaskModeOnCurrent() throws RemoteException { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "startLockTaskModeOnCurrent"); 8718 ActivityRecord r = null; 8719 synchronized (this) { 8720 r = mStackSupervisor.topRunningActivityLocked(); 8721 } 8722 startLockTaskMode(r.task); 8723 } 8724 8725 @Override 8726 public void stopLockTaskMode() { 8727 // Verify that the user matches the package of the intent for the TaskRecord 8728 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8729 // and stopLockTaskMode. 8730 final int callingUid = Binder.getCallingUid(); 8731 if (callingUid != Process.SYSTEM_UID) { 8732 try { 8733 String pkg = 8734 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8735 int uid = mContext.getPackageManager().getPackageUid(pkg, 8736 Binder.getCallingUserHandle().getIdentifier()); 8737 if (uid != callingUid) { 8738 throw new SecurityException("Invalid uid, expected " + uid); 8739 } 8740 } catch (NameNotFoundException e) { 8741 Log.d(TAG, "stopLockTaskMode " + e); 8742 return; 8743 } 8744 } 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 Log.d(TAG, "stopLockTaskMode"); 8748 // Stop lock task 8749 synchronized (this) { 8750 mStackSupervisor.setLockTaskModeLocked(null, false); 8751 } 8752 } finally { 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 } 8756 8757 @Override 8758 public void stopLockTaskModeOnCurrent() throws RemoteException { 8759 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8760 "stopLockTaskModeOnCurrent"); 8761 long ident = Binder.clearCallingIdentity(); 8762 try { 8763 stopLockTaskMode(); 8764 } finally { 8765 Binder.restoreCallingIdentity(ident); 8766 } 8767 } 8768 8769 @Override 8770 public boolean isInLockTaskMode() { 8771 synchronized (this) { 8772 return mStackSupervisor.isInLockTaskMode(); 8773 } 8774 } 8775 8776 // ========================================================= 8777 // CONTENT PROVIDERS 8778 // ========================================================= 8779 8780 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8781 List<ProviderInfo> providers = null; 8782 try { 8783 providers = AppGlobals.getPackageManager(). 8784 queryContentProviders(app.processName, app.uid, 8785 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8786 } catch (RemoteException ex) { 8787 } 8788 if (DEBUG_MU) 8789 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8790 int userId = app.userId; 8791 if (providers != null) { 8792 int N = providers.size(); 8793 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8794 for (int i=0; i<N; i++) { 8795 ProviderInfo cpi = 8796 (ProviderInfo)providers.get(i); 8797 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8798 cpi.name, cpi.flags); 8799 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8800 // This is a singleton provider, but a user besides the 8801 // default user is asking to initialize a process it runs 8802 // in... well, no, it doesn't actually run in this process, 8803 // it runs in the process of the default user. Get rid of it. 8804 providers.remove(i); 8805 N--; 8806 i--; 8807 continue; 8808 } 8809 8810 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8811 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8812 if (cpr == null) { 8813 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8814 mProviderMap.putProviderByClass(comp, cpr); 8815 } 8816 if (DEBUG_MU) 8817 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8818 app.pubProviders.put(cpi.name, cpr); 8819 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8820 // Don't add this if it is a platform component that is marked 8821 // to run in multiple processes, because this is actually 8822 // part of the framework so doesn't make sense to track as a 8823 // separate apk in the process. 8824 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8825 mProcessStats); 8826 } 8827 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8828 } 8829 } 8830 return providers; 8831 } 8832 8833 /** 8834 * Check if {@link ProcessRecord} has a possible chance at accessing the 8835 * given {@link ProviderInfo}. Final permission checking is always done 8836 * in {@link ContentProvider}. 8837 */ 8838 private final String checkContentProviderPermissionLocked( 8839 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8840 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8841 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8842 boolean checkedGrants = false; 8843 if (checkUser) { 8844 // Looking for cross-user grants before enforcing the typical cross-users permissions 8845 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8846 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8847 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8848 return null; 8849 } 8850 checkedGrants = true; 8851 } 8852 userId = handleIncomingUser(callingPid, callingUid, userId, 8853 false, ALLOW_NON_FULL, 8854 "checkContentProviderPermissionLocked " + cpi.authority, null); 8855 if (userId != tmpTargetUserId) { 8856 // When we actually went to determine the final targer user ID, this ended 8857 // up different than our initial check for the authority. This is because 8858 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8859 // SELF. So we need to re-check the grants again. 8860 checkedGrants = false; 8861 } 8862 } 8863 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8864 cpi.applicationInfo.uid, cpi.exported) 8865 == PackageManager.PERMISSION_GRANTED) { 8866 return null; 8867 } 8868 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8869 cpi.applicationInfo.uid, cpi.exported) 8870 == PackageManager.PERMISSION_GRANTED) { 8871 return null; 8872 } 8873 8874 PathPermission[] pps = cpi.pathPermissions; 8875 if (pps != null) { 8876 int i = pps.length; 8877 while (i > 0) { 8878 i--; 8879 PathPermission pp = pps[i]; 8880 String pprperm = pp.getReadPermission(); 8881 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8882 cpi.applicationInfo.uid, cpi.exported) 8883 == PackageManager.PERMISSION_GRANTED) { 8884 return null; 8885 } 8886 String ppwperm = pp.getWritePermission(); 8887 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8888 cpi.applicationInfo.uid, cpi.exported) 8889 == PackageManager.PERMISSION_GRANTED) { 8890 return null; 8891 } 8892 } 8893 } 8894 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8895 return null; 8896 } 8897 8898 String msg; 8899 if (!cpi.exported) { 8900 msg = "Permission Denial: opening provider " + cpi.name 8901 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8902 + ", uid=" + callingUid + ") that is not exported from uid " 8903 + cpi.applicationInfo.uid; 8904 } else { 8905 msg = "Permission Denial: opening provider " + cpi.name 8906 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8907 + ", uid=" + callingUid + ") requires " 8908 + cpi.readPermission + " or " + cpi.writePermission; 8909 } 8910 Slog.w(TAG, msg); 8911 return msg; 8912 } 8913 8914 /** 8915 * Returns if the ContentProvider has granted a uri to callingUid 8916 */ 8917 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8918 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8919 if (perms != null) { 8920 for (int i=perms.size()-1; i>=0; i--) { 8921 GrantUri grantUri = perms.keyAt(i); 8922 if (grantUri.sourceUserId == userId || !checkUser) { 8923 if (matchesProvider(grantUri.uri, cpi)) { 8924 return true; 8925 } 8926 } 8927 } 8928 } 8929 return false; 8930 } 8931 8932 /** 8933 * Returns true if the uri authority is one of the authorities specified in the provider. 8934 */ 8935 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8936 String uriAuth = uri.getAuthority(); 8937 String cpiAuth = cpi.authority; 8938 if (cpiAuth.indexOf(';') == -1) { 8939 return cpiAuth.equals(uriAuth); 8940 } 8941 String[] cpiAuths = cpiAuth.split(";"); 8942 int length = cpiAuths.length; 8943 for (int i = 0; i < length; i++) { 8944 if (cpiAuths[i].equals(uriAuth)) return true; 8945 } 8946 return false; 8947 } 8948 8949 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8950 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8951 if (r != null) { 8952 for (int i=0; i<r.conProviders.size(); i++) { 8953 ContentProviderConnection conn = r.conProviders.get(i); 8954 if (conn.provider == cpr) { 8955 if (DEBUG_PROVIDER) Slog.v(TAG, 8956 "Adding provider requested by " 8957 + r.processName + " from process " 8958 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8959 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8960 if (stable) { 8961 conn.stableCount++; 8962 conn.numStableIncs++; 8963 } else { 8964 conn.unstableCount++; 8965 conn.numUnstableIncs++; 8966 } 8967 return conn; 8968 } 8969 } 8970 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8971 if (stable) { 8972 conn.stableCount = 1; 8973 conn.numStableIncs = 1; 8974 } else { 8975 conn.unstableCount = 1; 8976 conn.numUnstableIncs = 1; 8977 } 8978 cpr.connections.add(conn); 8979 r.conProviders.add(conn); 8980 return conn; 8981 } 8982 cpr.addExternalProcessHandleLocked(externalProcessToken); 8983 return null; 8984 } 8985 8986 boolean decProviderCountLocked(ContentProviderConnection conn, 8987 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8988 if (conn != null) { 8989 cpr = conn.provider; 8990 if (DEBUG_PROVIDER) Slog.v(TAG, 8991 "Removing provider requested by " 8992 + conn.client.processName + " from process " 8993 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8994 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8995 if (stable) { 8996 conn.stableCount--; 8997 } else { 8998 conn.unstableCount--; 8999 } 9000 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9001 cpr.connections.remove(conn); 9002 conn.client.conProviders.remove(conn); 9003 return true; 9004 } 9005 return false; 9006 } 9007 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9008 return false; 9009 } 9010 9011 private void checkTime(long startTime, String where) { 9012 long now = SystemClock.elapsedRealtime(); 9013 if ((now-startTime) > 1000) { 9014 // If we are taking more than a second, log about it. 9015 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9016 } 9017 } 9018 9019 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9020 String name, IBinder token, boolean stable, int userId) { 9021 ContentProviderRecord cpr; 9022 ContentProviderConnection conn = null; 9023 ProviderInfo cpi = null; 9024 9025 synchronized(this) { 9026 long startTime = SystemClock.elapsedRealtime(); 9027 9028 ProcessRecord r = null; 9029 if (caller != null) { 9030 r = getRecordForAppLocked(caller); 9031 if (r == null) { 9032 throw new SecurityException( 9033 "Unable to find app for caller " + caller 9034 + " (pid=" + Binder.getCallingPid() 9035 + ") when getting content provider " + name); 9036 } 9037 } 9038 9039 boolean checkCrossUser = true; 9040 9041 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9042 9043 // First check if this content provider has been published... 9044 cpr = mProviderMap.getProviderByName(name, userId); 9045 // If that didn't work, check if it exists for user 0 and then 9046 // verify that it's a singleton provider before using it. 9047 if (cpr == null && userId != UserHandle.USER_OWNER) { 9048 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9049 if (cpr != null) { 9050 cpi = cpr.info; 9051 if (isSingleton(cpi.processName, cpi.applicationInfo, 9052 cpi.name, cpi.flags) 9053 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9054 userId = UserHandle.USER_OWNER; 9055 checkCrossUser = false; 9056 } else { 9057 cpr = null; 9058 cpi = null; 9059 } 9060 } 9061 } 9062 9063 boolean providerRunning = cpr != null; 9064 if (providerRunning) { 9065 cpi = cpr.info; 9066 String msg; 9067 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9068 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9069 != null) { 9070 throw new SecurityException(msg); 9071 } 9072 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9073 9074 if (r != null && cpr.canRunHere(r)) { 9075 // This provider has been published or is in the process 9076 // of being published... but it is also allowed to run 9077 // in the caller's process, so don't make a connection 9078 // and just let the caller instantiate its own instance. 9079 ContentProviderHolder holder = cpr.newHolder(null); 9080 // don't give caller the provider object, it needs 9081 // to make its own. 9082 holder.provider = null; 9083 return holder; 9084 } 9085 9086 final long origId = Binder.clearCallingIdentity(); 9087 9088 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9089 9090 // In this case the provider instance already exists, so we can 9091 // return it right away. 9092 conn = incProviderCountLocked(r, cpr, token, stable); 9093 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9094 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9095 // If this is a perceptible app accessing the provider, 9096 // make sure to count it as being accessed and thus 9097 // back up on the LRU list. This is good because 9098 // content providers are often expensive to start. 9099 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9100 updateLruProcessLocked(cpr.proc, false, null); 9101 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9102 } 9103 } 9104 9105 if (cpr.proc != null) { 9106 if (false) { 9107 if (cpr.name.flattenToShortString().equals( 9108 "com.android.providers.calendar/.CalendarProvider2")) { 9109 Slog.v(TAG, "****************** KILLING " 9110 + cpr.name.flattenToShortString()); 9111 Process.killProcess(cpr.proc.pid); 9112 } 9113 } 9114 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9115 boolean success = updateOomAdjLocked(cpr.proc); 9116 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9117 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9118 // NOTE: there is still a race here where a signal could be 9119 // pending on the process even though we managed to update its 9120 // adj level. Not sure what to do about this, but at least 9121 // the race is now smaller. 9122 if (!success) { 9123 // Uh oh... it looks like the provider's process 9124 // has been killed on us. We need to wait for a new 9125 // process to be started, and make sure its death 9126 // doesn't kill our process. 9127 Slog.i(TAG, 9128 "Existing provider " + cpr.name.flattenToShortString() 9129 + " is crashing; detaching " + r); 9130 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9131 checkTime(startTime, "getContentProviderImpl: before appDied"); 9132 appDiedLocked(cpr.proc); 9133 checkTime(startTime, "getContentProviderImpl: after appDied"); 9134 if (!lastRef) { 9135 // This wasn't the last ref our process had on 9136 // the provider... we have now been killed, bail. 9137 return null; 9138 } 9139 providerRunning = false; 9140 conn = null; 9141 } 9142 } 9143 9144 Binder.restoreCallingIdentity(origId); 9145 } 9146 9147 boolean singleton; 9148 if (!providerRunning) { 9149 try { 9150 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9151 cpi = AppGlobals.getPackageManager(). 9152 resolveContentProvider(name, 9153 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9154 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9155 } catch (RemoteException ex) { 9156 } 9157 if (cpi == null) { 9158 return null; 9159 } 9160 // If the provider is a singleton AND 9161 // (it's a call within the same user || the provider is a 9162 // privileged app) 9163 // Then allow connecting to the singleton provider 9164 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9165 cpi.name, cpi.flags) 9166 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9167 if (singleton) { 9168 userId = UserHandle.USER_OWNER; 9169 } 9170 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9171 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9172 9173 String msg; 9174 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9175 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9176 != null) { 9177 throw new SecurityException(msg); 9178 } 9179 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9180 9181 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9182 && !cpi.processName.equals("system")) { 9183 // If this content provider does not run in the system 9184 // process, and the system is not yet ready to run other 9185 // processes, then fail fast instead of hanging. 9186 throw new IllegalArgumentException( 9187 "Attempt to launch content provider before system ready"); 9188 } 9189 9190 // Make sure that the user who owns this provider is started. If not, 9191 // we don't want to allow it to run. 9192 if (mStartedUsers.get(userId) == null) { 9193 Slog.w(TAG, "Unable to launch app " 9194 + cpi.applicationInfo.packageName + "/" 9195 + cpi.applicationInfo.uid + " for provider " 9196 + name + ": user " + userId + " is stopped"); 9197 return null; 9198 } 9199 9200 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9201 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9202 cpr = mProviderMap.getProviderByClass(comp, userId); 9203 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9204 final boolean firstClass = cpr == null; 9205 if (firstClass) { 9206 try { 9207 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9208 ApplicationInfo ai = 9209 AppGlobals.getPackageManager(). 9210 getApplicationInfo( 9211 cpi.applicationInfo.packageName, 9212 STOCK_PM_FLAGS, userId); 9213 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9214 if (ai == null) { 9215 Slog.w(TAG, "No package info for content provider " 9216 + cpi.name); 9217 return null; 9218 } 9219 ai = getAppInfoForUser(ai, userId); 9220 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9221 } catch (RemoteException ex) { 9222 // pm is in same process, this will never happen. 9223 } 9224 } 9225 9226 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9227 9228 if (r != null && cpr.canRunHere(r)) { 9229 // If this is a multiprocess provider, then just return its 9230 // info and allow the caller to instantiate it. Only do 9231 // this if the provider is the same user as the caller's 9232 // process, or can run as root (so can be in any process). 9233 return cpr.newHolder(null); 9234 } 9235 9236 if (DEBUG_PROVIDER) { 9237 RuntimeException e = new RuntimeException("here"); 9238 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9239 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9240 } 9241 9242 // This is single process, and our app is now connecting to it. 9243 // See if we are already in the process of launching this 9244 // provider. 9245 final int N = mLaunchingProviders.size(); 9246 int i; 9247 for (i=0; i<N; i++) { 9248 if (mLaunchingProviders.get(i) == cpr) { 9249 break; 9250 } 9251 } 9252 9253 // If the provider is not already being launched, then get it 9254 // started. 9255 if (i >= N) { 9256 final long origId = Binder.clearCallingIdentity(); 9257 9258 try { 9259 // Content provider is now in use, its package can't be stopped. 9260 try { 9261 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9262 AppGlobals.getPackageManager().setPackageStoppedState( 9263 cpr.appInfo.packageName, false, userId); 9264 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9265 } catch (RemoteException e) { 9266 } catch (IllegalArgumentException e) { 9267 Slog.w(TAG, "Failed trying to unstop package " 9268 + cpr.appInfo.packageName + ": " + e); 9269 } 9270 9271 // Use existing process if already started 9272 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9273 ProcessRecord proc = getProcessRecordLocked( 9274 cpi.processName, cpr.appInfo.uid, false); 9275 if (proc != null && proc.thread != null) { 9276 if (DEBUG_PROVIDER) { 9277 Slog.d(TAG, "Installing in existing process " + proc); 9278 } 9279 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9280 proc.pubProviders.put(cpi.name, cpr); 9281 try { 9282 proc.thread.scheduleInstallProvider(cpi); 9283 } catch (RemoteException e) { 9284 } 9285 } else { 9286 checkTime(startTime, "getContentProviderImpl: before start process"); 9287 proc = startProcessLocked(cpi.processName, 9288 cpr.appInfo, false, 0, "content provider", 9289 new ComponentName(cpi.applicationInfo.packageName, 9290 cpi.name), false, false, false); 9291 checkTime(startTime, "getContentProviderImpl: after start process"); 9292 if (proc == null) { 9293 Slog.w(TAG, "Unable to launch app " 9294 + cpi.applicationInfo.packageName + "/" 9295 + cpi.applicationInfo.uid + " for provider " 9296 + name + ": process is bad"); 9297 return null; 9298 } 9299 } 9300 cpr.launchingApp = proc; 9301 mLaunchingProviders.add(cpr); 9302 } finally { 9303 Binder.restoreCallingIdentity(origId); 9304 } 9305 } 9306 9307 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9308 9309 // Make sure the provider is published (the same provider class 9310 // may be published under multiple names). 9311 if (firstClass) { 9312 mProviderMap.putProviderByClass(comp, cpr); 9313 } 9314 9315 mProviderMap.putProviderByName(name, cpr); 9316 conn = incProviderCountLocked(r, cpr, token, stable); 9317 if (conn != null) { 9318 conn.waiting = true; 9319 } 9320 } 9321 checkTime(startTime, "getContentProviderImpl: done!"); 9322 } 9323 9324 // Wait for the provider to be published... 9325 synchronized (cpr) { 9326 while (cpr.provider == null) { 9327 if (cpr.launchingApp == null) { 9328 Slog.w(TAG, "Unable to launch app " 9329 + cpi.applicationInfo.packageName + "/" 9330 + cpi.applicationInfo.uid + " for provider " 9331 + name + ": launching app became null"); 9332 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9333 UserHandle.getUserId(cpi.applicationInfo.uid), 9334 cpi.applicationInfo.packageName, 9335 cpi.applicationInfo.uid, name); 9336 return null; 9337 } 9338 try { 9339 if (DEBUG_MU) { 9340 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9341 + cpr.launchingApp); 9342 } 9343 if (conn != null) { 9344 conn.waiting = true; 9345 } 9346 cpr.wait(); 9347 } catch (InterruptedException ex) { 9348 } finally { 9349 if (conn != null) { 9350 conn.waiting = false; 9351 } 9352 } 9353 } 9354 } 9355 return cpr != null ? cpr.newHolder(conn) : null; 9356 } 9357 9358 @Override 9359 public final ContentProviderHolder getContentProvider( 9360 IApplicationThread caller, String name, int userId, boolean stable) { 9361 enforceNotIsolatedCaller("getContentProvider"); 9362 if (caller == null) { 9363 String msg = "null IApplicationThread when getting content provider " 9364 + name; 9365 Slog.w(TAG, msg); 9366 throw new SecurityException(msg); 9367 } 9368 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9369 // with cross-user grant. 9370 return getContentProviderImpl(caller, name, null, stable, userId); 9371 } 9372 9373 public ContentProviderHolder getContentProviderExternal( 9374 String name, int userId, IBinder token) { 9375 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9376 "Do not have permission in call getContentProviderExternal()"); 9377 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9378 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9379 return getContentProviderExternalUnchecked(name, token, userId); 9380 } 9381 9382 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9383 IBinder token, int userId) { 9384 return getContentProviderImpl(null, name, token, true, userId); 9385 } 9386 9387 /** 9388 * Drop a content provider from a ProcessRecord's bookkeeping 9389 */ 9390 public void removeContentProvider(IBinder connection, boolean stable) { 9391 enforceNotIsolatedCaller("removeContentProvider"); 9392 long ident = Binder.clearCallingIdentity(); 9393 try { 9394 synchronized (this) { 9395 ContentProviderConnection conn; 9396 try { 9397 conn = (ContentProviderConnection)connection; 9398 } catch (ClassCastException e) { 9399 String msg ="removeContentProvider: " + connection 9400 + " not a ContentProviderConnection"; 9401 Slog.w(TAG, msg); 9402 throw new IllegalArgumentException(msg); 9403 } 9404 if (conn == null) { 9405 throw new NullPointerException("connection is null"); 9406 } 9407 if (decProviderCountLocked(conn, null, null, stable)) { 9408 updateOomAdjLocked(); 9409 } 9410 } 9411 } finally { 9412 Binder.restoreCallingIdentity(ident); 9413 } 9414 } 9415 9416 public void removeContentProviderExternal(String name, IBinder token) { 9417 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9418 "Do not have permission in call removeContentProviderExternal()"); 9419 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9420 } 9421 9422 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9423 synchronized (this) { 9424 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9425 if(cpr == null) { 9426 //remove from mProvidersByClass 9427 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9428 return; 9429 } 9430 9431 //update content provider record entry info 9432 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9433 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9434 if (localCpr.hasExternalProcessHandles()) { 9435 if (localCpr.removeExternalProcessHandleLocked(token)) { 9436 updateOomAdjLocked(); 9437 } else { 9438 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9439 + " with no external reference for token: " 9440 + token + "."); 9441 } 9442 } else { 9443 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9444 + " with no external references."); 9445 } 9446 } 9447 } 9448 9449 public final void publishContentProviders(IApplicationThread caller, 9450 List<ContentProviderHolder> providers) { 9451 if (providers == null) { 9452 return; 9453 } 9454 9455 enforceNotIsolatedCaller("publishContentProviders"); 9456 synchronized (this) { 9457 final ProcessRecord r = getRecordForAppLocked(caller); 9458 if (DEBUG_MU) 9459 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9460 if (r == null) { 9461 throw new SecurityException( 9462 "Unable to find app for caller " + caller 9463 + " (pid=" + Binder.getCallingPid() 9464 + ") when publishing content providers"); 9465 } 9466 9467 final long origId = Binder.clearCallingIdentity(); 9468 9469 final int N = providers.size(); 9470 for (int i=0; i<N; i++) { 9471 ContentProviderHolder src = providers.get(i); 9472 if (src == null || src.info == null || src.provider == null) { 9473 continue; 9474 } 9475 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9476 if (DEBUG_MU) 9477 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9478 if (dst != null) { 9479 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9480 mProviderMap.putProviderByClass(comp, dst); 9481 String names[] = dst.info.authority.split(";"); 9482 for (int j = 0; j < names.length; j++) { 9483 mProviderMap.putProviderByName(names[j], dst); 9484 } 9485 9486 int NL = mLaunchingProviders.size(); 9487 int j; 9488 for (j=0; j<NL; j++) { 9489 if (mLaunchingProviders.get(j) == dst) { 9490 mLaunchingProviders.remove(j); 9491 j--; 9492 NL--; 9493 } 9494 } 9495 synchronized (dst) { 9496 dst.provider = src.provider; 9497 dst.proc = r; 9498 dst.notifyAll(); 9499 } 9500 updateOomAdjLocked(r); 9501 } 9502 } 9503 9504 Binder.restoreCallingIdentity(origId); 9505 } 9506 } 9507 9508 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9509 ContentProviderConnection conn; 9510 try { 9511 conn = (ContentProviderConnection)connection; 9512 } catch (ClassCastException e) { 9513 String msg ="refContentProvider: " + connection 9514 + " not a ContentProviderConnection"; 9515 Slog.w(TAG, msg); 9516 throw new IllegalArgumentException(msg); 9517 } 9518 if (conn == null) { 9519 throw new NullPointerException("connection is null"); 9520 } 9521 9522 synchronized (this) { 9523 if (stable > 0) { 9524 conn.numStableIncs += stable; 9525 } 9526 stable = conn.stableCount + stable; 9527 if (stable < 0) { 9528 throw new IllegalStateException("stableCount < 0: " + stable); 9529 } 9530 9531 if (unstable > 0) { 9532 conn.numUnstableIncs += unstable; 9533 } 9534 unstable = conn.unstableCount + unstable; 9535 if (unstable < 0) { 9536 throw new IllegalStateException("unstableCount < 0: " + unstable); 9537 } 9538 9539 if ((stable+unstable) <= 0) { 9540 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9541 + stable + " unstable=" + unstable); 9542 } 9543 conn.stableCount = stable; 9544 conn.unstableCount = unstable; 9545 return !conn.dead; 9546 } 9547 } 9548 9549 public void unstableProviderDied(IBinder connection) { 9550 ContentProviderConnection conn; 9551 try { 9552 conn = (ContentProviderConnection)connection; 9553 } catch (ClassCastException e) { 9554 String msg ="refContentProvider: " + connection 9555 + " not a ContentProviderConnection"; 9556 Slog.w(TAG, msg); 9557 throw new IllegalArgumentException(msg); 9558 } 9559 if (conn == null) { 9560 throw new NullPointerException("connection is null"); 9561 } 9562 9563 // Safely retrieve the content provider associated with the connection. 9564 IContentProvider provider; 9565 synchronized (this) { 9566 provider = conn.provider.provider; 9567 } 9568 9569 if (provider == null) { 9570 // Um, yeah, we're way ahead of you. 9571 return; 9572 } 9573 9574 // Make sure the caller is being honest with us. 9575 if (provider.asBinder().pingBinder()) { 9576 // Er, no, still looks good to us. 9577 synchronized (this) { 9578 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9579 + " says " + conn + " died, but we don't agree"); 9580 return; 9581 } 9582 } 9583 9584 // Well look at that! It's dead! 9585 synchronized (this) { 9586 if (conn.provider.provider != provider) { 9587 // But something changed... good enough. 9588 return; 9589 } 9590 9591 ProcessRecord proc = conn.provider.proc; 9592 if (proc == null || proc.thread == null) { 9593 // Seems like the process is already cleaned up. 9594 return; 9595 } 9596 9597 // As far as we're concerned, this is just like receiving a 9598 // death notification... just a bit prematurely. 9599 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9600 + ") early provider death"); 9601 final long ident = Binder.clearCallingIdentity(); 9602 try { 9603 appDiedLocked(proc); 9604 } finally { 9605 Binder.restoreCallingIdentity(ident); 9606 } 9607 } 9608 } 9609 9610 @Override 9611 public void appNotRespondingViaProvider(IBinder connection) { 9612 enforceCallingPermission( 9613 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9614 9615 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9616 if (conn == null) { 9617 Slog.w(TAG, "ContentProviderConnection is null"); 9618 return; 9619 } 9620 9621 final ProcessRecord host = conn.provider.proc; 9622 if (host == null) { 9623 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9624 return; 9625 } 9626 9627 final long token = Binder.clearCallingIdentity(); 9628 try { 9629 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9630 } finally { 9631 Binder.restoreCallingIdentity(token); 9632 } 9633 } 9634 9635 public final void installSystemProviders() { 9636 List<ProviderInfo> providers; 9637 synchronized (this) { 9638 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9639 providers = generateApplicationProvidersLocked(app); 9640 if (providers != null) { 9641 for (int i=providers.size()-1; i>=0; i--) { 9642 ProviderInfo pi = (ProviderInfo)providers.get(i); 9643 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9644 Slog.w(TAG, "Not installing system proc provider " + pi.name 9645 + ": not system .apk"); 9646 providers.remove(i); 9647 } 9648 } 9649 } 9650 } 9651 if (providers != null) { 9652 mSystemThread.installSystemProviders(providers); 9653 } 9654 9655 mCoreSettingsObserver = new CoreSettingsObserver(this); 9656 9657 //mUsageStatsService.monitorPackages(); 9658 } 9659 9660 /** 9661 * Allows apps to retrieve the MIME type of a URI. 9662 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9663 * users, then it does not need permission to access the ContentProvider. 9664 * Either, it needs cross-user uri grants. 9665 * 9666 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9667 * 9668 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9669 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9670 */ 9671 public String getProviderMimeType(Uri uri, int userId) { 9672 enforceNotIsolatedCaller("getProviderMimeType"); 9673 final String name = uri.getAuthority(); 9674 int callingUid = Binder.getCallingUid(); 9675 int callingPid = Binder.getCallingPid(); 9676 long ident = 0; 9677 boolean clearedIdentity = false; 9678 userId = unsafeConvertIncomingUser(userId); 9679 if (UserHandle.getUserId(callingUid) != userId) { 9680 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9681 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9682 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9683 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9684 clearedIdentity = true; 9685 ident = Binder.clearCallingIdentity(); 9686 } 9687 } 9688 ContentProviderHolder holder = null; 9689 try { 9690 holder = getContentProviderExternalUnchecked(name, null, userId); 9691 if (holder != null) { 9692 return holder.provider.getType(uri); 9693 } 9694 } catch (RemoteException e) { 9695 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9696 return null; 9697 } finally { 9698 // We need to clear the identity to call removeContentProviderExternalUnchecked 9699 if (!clearedIdentity) { 9700 ident = Binder.clearCallingIdentity(); 9701 } 9702 try { 9703 if (holder != null) { 9704 removeContentProviderExternalUnchecked(name, null, userId); 9705 } 9706 } finally { 9707 Binder.restoreCallingIdentity(ident); 9708 } 9709 } 9710 9711 return null; 9712 } 9713 9714 // ========================================================= 9715 // GLOBAL MANAGEMENT 9716 // ========================================================= 9717 9718 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9719 boolean isolated, int isolatedUid) { 9720 String proc = customProcess != null ? customProcess : info.processName; 9721 BatteryStatsImpl.Uid.Proc ps = null; 9722 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9723 int uid = info.uid; 9724 if (isolated) { 9725 if (isolatedUid == 0) { 9726 int userId = UserHandle.getUserId(uid); 9727 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9728 while (true) { 9729 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9730 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9731 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9732 } 9733 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9734 mNextIsolatedProcessUid++; 9735 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9736 // No process for this uid, use it. 9737 break; 9738 } 9739 stepsLeft--; 9740 if (stepsLeft <= 0) { 9741 return null; 9742 } 9743 } 9744 } else { 9745 // Special case for startIsolatedProcess (internal only), where 9746 // the uid of the isolated process is specified by the caller. 9747 uid = isolatedUid; 9748 } 9749 } 9750 return new ProcessRecord(stats, info, proc, uid); 9751 } 9752 9753 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9754 String abiOverride) { 9755 ProcessRecord app; 9756 if (!isolated) { 9757 app = getProcessRecordLocked(info.processName, info.uid, true); 9758 } else { 9759 app = null; 9760 } 9761 9762 if (app == null) { 9763 app = newProcessRecordLocked(info, null, isolated, 0); 9764 mProcessNames.put(info.processName, app.uid, app); 9765 if (isolated) { 9766 mIsolatedProcesses.put(app.uid, app); 9767 } 9768 updateLruProcessLocked(app, false, null); 9769 updateOomAdjLocked(); 9770 } 9771 9772 // This package really, really can not be stopped. 9773 try { 9774 AppGlobals.getPackageManager().setPackageStoppedState( 9775 info.packageName, false, UserHandle.getUserId(app.uid)); 9776 } catch (RemoteException e) { 9777 } catch (IllegalArgumentException e) { 9778 Slog.w(TAG, "Failed trying to unstop package " 9779 + info.packageName + ": " + e); 9780 } 9781 9782 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9783 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9784 app.persistent = true; 9785 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9786 } 9787 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9788 mPersistentStartingProcesses.add(app); 9789 startProcessLocked(app, "added application", app.processName, abiOverride, 9790 null /* entryPoint */, null /* entryPointArgs */); 9791 } 9792 9793 return app; 9794 } 9795 9796 public void unhandledBack() { 9797 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9798 "unhandledBack()"); 9799 9800 synchronized(this) { 9801 final long origId = Binder.clearCallingIdentity(); 9802 try { 9803 getFocusedStack().unhandledBackLocked(); 9804 } finally { 9805 Binder.restoreCallingIdentity(origId); 9806 } 9807 } 9808 } 9809 9810 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9811 enforceNotIsolatedCaller("openContentUri"); 9812 final int userId = UserHandle.getCallingUserId(); 9813 String name = uri.getAuthority(); 9814 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9815 ParcelFileDescriptor pfd = null; 9816 if (cph != null) { 9817 // We record the binder invoker's uid in thread-local storage before 9818 // going to the content provider to open the file. Later, in the code 9819 // that handles all permissions checks, we look for this uid and use 9820 // that rather than the Activity Manager's own uid. The effect is that 9821 // we do the check against the caller's permissions even though it looks 9822 // to the content provider like the Activity Manager itself is making 9823 // the request. 9824 sCallerIdentity.set(new Identity( 9825 Binder.getCallingPid(), Binder.getCallingUid())); 9826 try { 9827 pfd = cph.provider.openFile(null, uri, "r", null); 9828 } catch (FileNotFoundException e) { 9829 // do nothing; pfd will be returned null 9830 } finally { 9831 // Ensure that whatever happens, we clean up the identity state 9832 sCallerIdentity.remove(); 9833 } 9834 9835 // We've got the fd now, so we're done with the provider. 9836 removeContentProviderExternalUnchecked(name, null, userId); 9837 } else { 9838 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9839 } 9840 return pfd; 9841 } 9842 9843 // Actually is sleeping or shutting down or whatever else in the future 9844 // is an inactive state. 9845 public boolean isSleepingOrShuttingDown() { 9846 return mSleeping || mShuttingDown; 9847 } 9848 9849 public boolean isSleeping() { 9850 return mSleeping; 9851 } 9852 9853 void goingToSleep() { 9854 synchronized(this) { 9855 mWentToSleep = true; 9856 updateEventDispatchingLocked(); 9857 goToSleepIfNeededLocked(); 9858 } 9859 } 9860 9861 void finishRunningVoiceLocked() { 9862 if (mRunningVoice) { 9863 mRunningVoice = false; 9864 goToSleepIfNeededLocked(); 9865 } 9866 } 9867 9868 void goToSleepIfNeededLocked() { 9869 if (mWentToSleep && !mRunningVoice) { 9870 if (!mSleeping) { 9871 mSleeping = true; 9872 mStackSupervisor.goingToSleepLocked(); 9873 9874 // Initialize the wake times of all processes. 9875 checkExcessivePowerUsageLocked(false); 9876 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9877 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9878 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9879 } 9880 } 9881 } 9882 9883 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9884 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9885 // Never persist the home stack. 9886 return; 9887 } 9888 mTaskPersister.wakeup(task, flush); 9889 } 9890 9891 @Override 9892 public boolean shutdown(int timeout) { 9893 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9894 != PackageManager.PERMISSION_GRANTED) { 9895 throw new SecurityException("Requires permission " 9896 + android.Manifest.permission.SHUTDOWN); 9897 } 9898 9899 boolean timedout = false; 9900 9901 synchronized(this) { 9902 mShuttingDown = true; 9903 updateEventDispatchingLocked(); 9904 timedout = mStackSupervisor.shutdownLocked(timeout); 9905 } 9906 9907 mAppOpsService.shutdown(); 9908 if (mUsageStatsService != null) { 9909 mUsageStatsService.prepareShutdown(); 9910 } 9911 mBatteryStatsService.shutdown(); 9912 synchronized (this) { 9913 mProcessStats.shutdownLocked(); 9914 } 9915 notifyTaskPersisterLocked(null, true); 9916 9917 return timedout; 9918 } 9919 9920 public final void activitySlept(IBinder token) { 9921 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9922 9923 final long origId = Binder.clearCallingIdentity(); 9924 9925 synchronized (this) { 9926 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9927 if (r != null) { 9928 mStackSupervisor.activitySleptLocked(r); 9929 } 9930 } 9931 9932 Binder.restoreCallingIdentity(origId); 9933 } 9934 9935 void logLockScreen(String msg) { 9936 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9937 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9938 mWentToSleep + " mSleeping=" + mSleeping); 9939 } 9940 9941 private void comeOutOfSleepIfNeededLocked() { 9942 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9943 if (mSleeping) { 9944 mSleeping = false; 9945 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9946 } 9947 } 9948 } 9949 9950 void wakingUp() { 9951 synchronized(this) { 9952 mWentToSleep = false; 9953 updateEventDispatchingLocked(); 9954 comeOutOfSleepIfNeededLocked(); 9955 } 9956 } 9957 9958 void startRunningVoiceLocked() { 9959 if (!mRunningVoice) { 9960 mRunningVoice = true; 9961 comeOutOfSleepIfNeededLocked(); 9962 } 9963 } 9964 9965 private void updateEventDispatchingLocked() { 9966 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9967 } 9968 9969 public void setLockScreenShown(boolean shown) { 9970 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9971 != PackageManager.PERMISSION_GRANTED) { 9972 throw new SecurityException("Requires permission " 9973 + android.Manifest.permission.DEVICE_POWER); 9974 } 9975 9976 synchronized(this) { 9977 long ident = Binder.clearCallingIdentity(); 9978 try { 9979 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9980 mLockScreenShown = shown; 9981 comeOutOfSleepIfNeededLocked(); 9982 } finally { 9983 Binder.restoreCallingIdentity(ident); 9984 } 9985 } 9986 } 9987 9988 @Override 9989 public void stopAppSwitches() { 9990 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9991 != PackageManager.PERMISSION_GRANTED) { 9992 throw new SecurityException("Requires permission " 9993 + android.Manifest.permission.STOP_APP_SWITCHES); 9994 } 9995 9996 synchronized(this) { 9997 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9998 + APP_SWITCH_DELAY_TIME; 9999 mDidAppSwitch = false; 10000 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10001 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10002 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10003 } 10004 } 10005 10006 public void resumeAppSwitches() { 10007 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10008 != PackageManager.PERMISSION_GRANTED) { 10009 throw new SecurityException("Requires permission " 10010 + android.Manifest.permission.STOP_APP_SWITCHES); 10011 } 10012 10013 synchronized(this) { 10014 // Note that we don't execute any pending app switches... we will 10015 // let those wait until either the timeout, or the next start 10016 // activity request. 10017 mAppSwitchesAllowedTime = 0; 10018 } 10019 } 10020 10021 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10022 String name) { 10023 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10024 return true; 10025 } 10026 10027 final int perm = checkComponentPermission( 10028 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10029 callingUid, -1, true); 10030 if (perm == PackageManager.PERMISSION_GRANTED) { 10031 return true; 10032 } 10033 10034 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10035 return false; 10036 } 10037 10038 public void setDebugApp(String packageName, boolean waitForDebugger, 10039 boolean persistent) { 10040 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10041 "setDebugApp()"); 10042 10043 long ident = Binder.clearCallingIdentity(); 10044 try { 10045 // Note that this is not really thread safe if there are multiple 10046 // callers into it at the same time, but that's not a situation we 10047 // care about. 10048 if (persistent) { 10049 final ContentResolver resolver = mContext.getContentResolver(); 10050 Settings.Global.putString( 10051 resolver, Settings.Global.DEBUG_APP, 10052 packageName); 10053 Settings.Global.putInt( 10054 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10055 waitForDebugger ? 1 : 0); 10056 } 10057 10058 synchronized (this) { 10059 if (!persistent) { 10060 mOrigDebugApp = mDebugApp; 10061 mOrigWaitForDebugger = mWaitForDebugger; 10062 } 10063 mDebugApp = packageName; 10064 mWaitForDebugger = waitForDebugger; 10065 mDebugTransient = !persistent; 10066 if (packageName != null) { 10067 forceStopPackageLocked(packageName, -1, false, false, true, true, 10068 false, UserHandle.USER_ALL, "set debug app"); 10069 } 10070 } 10071 } finally { 10072 Binder.restoreCallingIdentity(ident); 10073 } 10074 } 10075 10076 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10077 synchronized (this) { 10078 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10079 if (!isDebuggable) { 10080 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10081 throw new SecurityException("Process not debuggable: " + app.packageName); 10082 } 10083 } 10084 10085 mOpenGlTraceApp = processName; 10086 } 10087 } 10088 10089 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10090 synchronized (this) { 10091 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10092 if (!isDebuggable) { 10093 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10094 throw new SecurityException("Process not debuggable: " + app.packageName); 10095 } 10096 } 10097 mProfileApp = processName; 10098 mProfileFile = profilerInfo.profileFile; 10099 if (mProfileFd != null) { 10100 try { 10101 mProfileFd.close(); 10102 } catch (IOException e) { 10103 } 10104 mProfileFd = null; 10105 } 10106 mProfileFd = profilerInfo.profileFd; 10107 mSamplingInterval = profilerInfo.samplingInterval; 10108 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10109 mProfileType = 0; 10110 } 10111 } 10112 10113 @Override 10114 public void setAlwaysFinish(boolean enabled) { 10115 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10116 "setAlwaysFinish()"); 10117 10118 Settings.Global.putInt( 10119 mContext.getContentResolver(), 10120 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10121 10122 synchronized (this) { 10123 mAlwaysFinishActivities = enabled; 10124 } 10125 } 10126 10127 @Override 10128 public void setActivityController(IActivityController controller) { 10129 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10130 "setActivityController()"); 10131 synchronized (this) { 10132 mController = controller; 10133 Watchdog.getInstance().setActivityController(controller); 10134 } 10135 } 10136 10137 @Override 10138 public void setUserIsMonkey(boolean userIsMonkey) { 10139 synchronized (this) { 10140 synchronized (mPidsSelfLocked) { 10141 final int callingPid = Binder.getCallingPid(); 10142 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10143 if (precessRecord == null) { 10144 throw new SecurityException("Unknown process: " + callingPid); 10145 } 10146 if (precessRecord.instrumentationUiAutomationConnection == null) { 10147 throw new SecurityException("Only an instrumentation process " 10148 + "with a UiAutomation can call setUserIsMonkey"); 10149 } 10150 } 10151 mUserIsMonkey = userIsMonkey; 10152 } 10153 } 10154 10155 @Override 10156 public boolean isUserAMonkey() { 10157 synchronized (this) { 10158 // If there is a controller also implies the user is a monkey. 10159 return (mUserIsMonkey || mController != null); 10160 } 10161 } 10162 10163 public void requestBugReport() { 10164 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10165 SystemProperties.set("ctl.start", "bugreport"); 10166 } 10167 10168 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10169 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10170 } 10171 10172 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10173 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10174 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10175 } 10176 return KEY_DISPATCHING_TIMEOUT; 10177 } 10178 10179 @Override 10180 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10181 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10182 != PackageManager.PERMISSION_GRANTED) { 10183 throw new SecurityException("Requires permission " 10184 + android.Manifest.permission.FILTER_EVENTS); 10185 } 10186 ProcessRecord proc; 10187 long timeout; 10188 synchronized (this) { 10189 synchronized (mPidsSelfLocked) { 10190 proc = mPidsSelfLocked.get(pid); 10191 } 10192 timeout = getInputDispatchingTimeoutLocked(proc); 10193 } 10194 10195 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10196 return -1; 10197 } 10198 10199 return timeout; 10200 } 10201 10202 /** 10203 * Handle input dispatching timeouts. 10204 * Returns whether input dispatching should be aborted or not. 10205 */ 10206 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10207 final ActivityRecord activity, final ActivityRecord parent, 10208 final boolean aboveSystem, String reason) { 10209 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10210 != PackageManager.PERMISSION_GRANTED) { 10211 throw new SecurityException("Requires permission " 10212 + android.Manifest.permission.FILTER_EVENTS); 10213 } 10214 10215 final String annotation; 10216 if (reason == null) { 10217 annotation = "Input dispatching timed out"; 10218 } else { 10219 annotation = "Input dispatching timed out (" + reason + ")"; 10220 } 10221 10222 if (proc != null) { 10223 synchronized (this) { 10224 if (proc.debugging) { 10225 return false; 10226 } 10227 10228 if (mDidDexOpt) { 10229 // Give more time since we were dexopting. 10230 mDidDexOpt = false; 10231 return false; 10232 } 10233 10234 if (proc.instrumentationClass != null) { 10235 Bundle info = new Bundle(); 10236 info.putString("shortMsg", "keyDispatchingTimedOut"); 10237 info.putString("longMsg", annotation); 10238 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10239 return true; 10240 } 10241 } 10242 mHandler.post(new Runnable() { 10243 @Override 10244 public void run() { 10245 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10246 } 10247 }); 10248 } 10249 10250 return true; 10251 } 10252 10253 public Bundle getAssistContextExtras(int requestType) { 10254 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10255 "getAssistContextExtras()"); 10256 PendingAssistExtras pae; 10257 Bundle extras = new Bundle(); 10258 synchronized (this) { 10259 ActivityRecord activity = getFocusedStack().mResumedActivity; 10260 if (activity == null) { 10261 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10262 return null; 10263 } 10264 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10265 if (activity.app == null || activity.app.thread == null) { 10266 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10267 return extras; 10268 } 10269 if (activity.app.pid == Binder.getCallingPid()) { 10270 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10271 return extras; 10272 } 10273 pae = new PendingAssistExtras(activity); 10274 try { 10275 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10276 requestType); 10277 mPendingAssistExtras.add(pae); 10278 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10279 } catch (RemoteException e) { 10280 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10281 return extras; 10282 } 10283 } 10284 synchronized (pae) { 10285 while (!pae.haveResult) { 10286 try { 10287 pae.wait(); 10288 } catch (InterruptedException e) { 10289 } 10290 } 10291 if (pae.result != null) { 10292 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10293 } 10294 } 10295 synchronized (this) { 10296 mPendingAssistExtras.remove(pae); 10297 mHandler.removeCallbacks(pae); 10298 } 10299 return extras; 10300 } 10301 10302 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10303 PendingAssistExtras pae = (PendingAssistExtras)token; 10304 synchronized (pae) { 10305 pae.result = extras; 10306 pae.haveResult = true; 10307 pae.notifyAll(); 10308 } 10309 } 10310 10311 public void registerProcessObserver(IProcessObserver observer) { 10312 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10313 "registerProcessObserver()"); 10314 synchronized (this) { 10315 mProcessObservers.register(observer); 10316 } 10317 } 10318 10319 @Override 10320 public void unregisterProcessObserver(IProcessObserver observer) { 10321 synchronized (this) { 10322 mProcessObservers.unregister(observer); 10323 } 10324 } 10325 10326 @Override 10327 public boolean convertFromTranslucent(IBinder token) { 10328 final long origId = Binder.clearCallingIdentity(); 10329 try { 10330 synchronized (this) { 10331 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10332 if (r == null) { 10333 return false; 10334 } 10335 final boolean translucentChanged = r.changeWindowTranslucency(true); 10336 if (translucentChanged) { 10337 r.task.stack.releaseBackgroundResources(); 10338 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10339 } 10340 mWindowManager.setAppFullscreen(token, true); 10341 return translucentChanged; 10342 } 10343 } finally { 10344 Binder.restoreCallingIdentity(origId); 10345 } 10346 } 10347 10348 @Override 10349 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10350 final long origId = Binder.clearCallingIdentity(); 10351 try { 10352 synchronized (this) { 10353 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10354 if (r == null) { 10355 return false; 10356 } 10357 int index = r.task.mActivities.lastIndexOf(r); 10358 if (index > 0) { 10359 ActivityRecord under = r.task.mActivities.get(index - 1); 10360 under.returningOptions = options; 10361 } 10362 final boolean translucentChanged = r.changeWindowTranslucency(false); 10363 if (translucentChanged) { 10364 r.task.stack.convertToTranslucent(r); 10365 } 10366 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10367 mWindowManager.setAppFullscreen(token, false); 10368 return translucentChanged; 10369 } 10370 } finally { 10371 Binder.restoreCallingIdentity(origId); 10372 } 10373 } 10374 10375 @Override 10376 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10377 final long origId = Binder.clearCallingIdentity(); 10378 try { 10379 synchronized (this) { 10380 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10381 if (r != null) { 10382 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10383 } 10384 } 10385 return false; 10386 } finally { 10387 Binder.restoreCallingIdentity(origId); 10388 } 10389 } 10390 10391 @Override 10392 public boolean isBackgroundVisibleBehind(IBinder token) { 10393 final long origId = Binder.clearCallingIdentity(); 10394 try { 10395 synchronized (this) { 10396 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10397 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10398 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10399 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10400 return visible; 10401 } 10402 } finally { 10403 Binder.restoreCallingIdentity(origId); 10404 } 10405 } 10406 10407 @Override 10408 public ActivityOptions getActivityOptions(IBinder token) { 10409 final long origId = Binder.clearCallingIdentity(); 10410 try { 10411 synchronized (this) { 10412 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10413 if (r != null) { 10414 final ActivityOptions activityOptions = r.pendingOptions; 10415 r.pendingOptions = null; 10416 return activityOptions; 10417 } 10418 return null; 10419 } 10420 } finally { 10421 Binder.restoreCallingIdentity(origId); 10422 } 10423 } 10424 10425 @Override 10426 public void setImmersive(IBinder token, boolean immersive) { 10427 synchronized(this) { 10428 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10429 if (r == null) { 10430 throw new IllegalArgumentException(); 10431 } 10432 r.immersive = immersive; 10433 10434 // update associated state if we're frontmost 10435 if (r == mFocusedActivity) { 10436 if (DEBUG_IMMERSIVE) { 10437 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10438 } 10439 applyUpdateLockStateLocked(r); 10440 } 10441 } 10442 } 10443 10444 @Override 10445 public boolean isImmersive(IBinder token) { 10446 synchronized (this) { 10447 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10448 if (r == null) { 10449 throw new IllegalArgumentException(); 10450 } 10451 return r.immersive; 10452 } 10453 } 10454 10455 public boolean isTopActivityImmersive() { 10456 enforceNotIsolatedCaller("startActivity"); 10457 synchronized (this) { 10458 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10459 return (r != null) ? r.immersive : false; 10460 } 10461 } 10462 10463 @Override 10464 public boolean isTopOfTask(IBinder token) { 10465 synchronized (this) { 10466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10467 if (r == null) { 10468 throw new IllegalArgumentException(); 10469 } 10470 return r.task.getTopActivity() == r; 10471 } 10472 } 10473 10474 public final void enterSafeMode() { 10475 synchronized(this) { 10476 // It only makes sense to do this before the system is ready 10477 // and started launching other packages. 10478 if (!mSystemReady) { 10479 try { 10480 AppGlobals.getPackageManager().enterSafeMode(); 10481 } catch (RemoteException e) { 10482 } 10483 } 10484 10485 mSafeMode = true; 10486 } 10487 } 10488 10489 public final void showSafeModeOverlay() { 10490 View v = LayoutInflater.from(mContext).inflate( 10491 com.android.internal.R.layout.safe_mode, null); 10492 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10493 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10494 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10495 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10496 lp.gravity = Gravity.BOTTOM | Gravity.START; 10497 lp.format = v.getBackground().getOpacity(); 10498 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10499 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10500 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10501 ((WindowManager)mContext.getSystemService( 10502 Context.WINDOW_SERVICE)).addView(v, lp); 10503 } 10504 10505 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10506 if (!(sender instanceof PendingIntentRecord)) { 10507 return; 10508 } 10509 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10510 synchronized (stats) { 10511 if (mBatteryStatsService.isOnBattery()) { 10512 mBatteryStatsService.enforceCallingPermission(); 10513 PendingIntentRecord rec = (PendingIntentRecord)sender; 10514 int MY_UID = Binder.getCallingUid(); 10515 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10516 BatteryStatsImpl.Uid.Pkg pkg = 10517 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10518 sourcePkg != null ? sourcePkg : rec.key.packageName); 10519 pkg.incWakeupsLocked(); 10520 } 10521 } 10522 } 10523 10524 public boolean killPids(int[] pids, String pReason, boolean secure) { 10525 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10526 throw new SecurityException("killPids only available to the system"); 10527 } 10528 String reason = (pReason == null) ? "Unknown" : pReason; 10529 // XXX Note: don't acquire main activity lock here, because the window 10530 // manager calls in with its locks held. 10531 10532 boolean killed = false; 10533 synchronized (mPidsSelfLocked) { 10534 int[] types = new int[pids.length]; 10535 int worstType = 0; 10536 for (int i=0; i<pids.length; i++) { 10537 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10538 if (proc != null) { 10539 int type = proc.setAdj; 10540 types[i] = type; 10541 if (type > worstType) { 10542 worstType = type; 10543 } 10544 } 10545 } 10546 10547 // If the worst oom_adj is somewhere in the cached proc LRU range, 10548 // then constrain it so we will kill all cached procs. 10549 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10550 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10551 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10552 } 10553 10554 // If this is not a secure call, don't let it kill processes that 10555 // are important. 10556 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10557 worstType = ProcessList.SERVICE_ADJ; 10558 } 10559 10560 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10561 for (int i=0; i<pids.length; i++) { 10562 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10563 if (proc == null) { 10564 continue; 10565 } 10566 int adj = proc.setAdj; 10567 if (adj >= worstType && !proc.killedByAm) { 10568 proc.kill(reason, true); 10569 killed = true; 10570 } 10571 } 10572 } 10573 return killed; 10574 } 10575 10576 @Override 10577 public void killUid(int uid, String reason) { 10578 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10579 throw new SecurityException("killUid only available to the system"); 10580 } 10581 synchronized (this) { 10582 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10583 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10584 reason != null ? reason : "kill uid"); 10585 } 10586 } 10587 10588 @Override 10589 public boolean killProcessesBelowForeground(String reason) { 10590 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10591 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10592 } 10593 10594 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10595 } 10596 10597 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10598 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10599 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10600 } 10601 10602 boolean killed = false; 10603 synchronized (mPidsSelfLocked) { 10604 final int size = mPidsSelfLocked.size(); 10605 for (int i = 0; i < size; i++) { 10606 final int pid = mPidsSelfLocked.keyAt(i); 10607 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10608 if (proc == null) continue; 10609 10610 final int adj = proc.setAdj; 10611 if (adj > belowAdj && !proc.killedByAm) { 10612 proc.kill(reason, true); 10613 killed = true; 10614 } 10615 } 10616 } 10617 return killed; 10618 } 10619 10620 @Override 10621 public void hang(final IBinder who, boolean allowRestart) { 10622 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10623 != PackageManager.PERMISSION_GRANTED) { 10624 throw new SecurityException("Requires permission " 10625 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10626 } 10627 10628 final IBinder.DeathRecipient death = new DeathRecipient() { 10629 @Override 10630 public void binderDied() { 10631 synchronized (this) { 10632 notifyAll(); 10633 } 10634 } 10635 }; 10636 10637 try { 10638 who.linkToDeath(death, 0); 10639 } catch (RemoteException e) { 10640 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10641 return; 10642 } 10643 10644 synchronized (this) { 10645 Watchdog.getInstance().setAllowRestart(allowRestart); 10646 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10647 synchronized (death) { 10648 while (who.isBinderAlive()) { 10649 try { 10650 death.wait(); 10651 } catch (InterruptedException e) { 10652 } 10653 } 10654 } 10655 Watchdog.getInstance().setAllowRestart(true); 10656 } 10657 } 10658 10659 @Override 10660 public void restart() { 10661 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10662 != PackageManager.PERMISSION_GRANTED) { 10663 throw new SecurityException("Requires permission " 10664 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10665 } 10666 10667 Log.i(TAG, "Sending shutdown broadcast..."); 10668 10669 BroadcastReceiver br = new BroadcastReceiver() { 10670 @Override public void onReceive(Context context, Intent intent) { 10671 // Now the broadcast is done, finish up the low-level shutdown. 10672 Log.i(TAG, "Shutting down activity manager..."); 10673 shutdown(10000); 10674 Log.i(TAG, "Shutdown complete, restarting!"); 10675 Process.killProcess(Process.myPid()); 10676 System.exit(10); 10677 } 10678 }; 10679 10680 // First send the high-level shut down broadcast. 10681 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10682 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10683 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10684 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10685 mContext.sendOrderedBroadcastAsUser(intent, 10686 UserHandle.ALL, null, br, mHandler, 0, null, null); 10687 */ 10688 br.onReceive(mContext, intent); 10689 } 10690 10691 private long getLowRamTimeSinceIdle(long now) { 10692 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10693 } 10694 10695 @Override 10696 public void performIdleMaintenance() { 10697 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10698 != PackageManager.PERMISSION_GRANTED) { 10699 throw new SecurityException("Requires permission " 10700 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10701 } 10702 10703 synchronized (this) { 10704 final long now = SystemClock.uptimeMillis(); 10705 final long timeSinceLastIdle = now - mLastIdleTime; 10706 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10707 mLastIdleTime = now; 10708 mLowRamTimeSinceLastIdle = 0; 10709 if (mLowRamStartTime != 0) { 10710 mLowRamStartTime = now; 10711 } 10712 10713 StringBuilder sb = new StringBuilder(128); 10714 sb.append("Idle maintenance over "); 10715 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10716 sb.append(" low RAM for "); 10717 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10718 Slog.i(TAG, sb.toString()); 10719 10720 // If at least 1/3 of our time since the last idle period has been spent 10721 // with RAM low, then we want to kill processes. 10722 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10723 10724 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10725 ProcessRecord proc = mLruProcesses.get(i); 10726 if (proc.notCachedSinceIdle) { 10727 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10728 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10729 if (doKilling && proc.initialIdlePss != 0 10730 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10731 proc.kill("idle maint (pss " + proc.lastPss 10732 + " from " + proc.initialIdlePss + ")", true); 10733 } 10734 } 10735 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10736 proc.notCachedSinceIdle = true; 10737 proc.initialIdlePss = 0; 10738 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10739 isSleeping(), now); 10740 } 10741 } 10742 10743 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10744 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10745 } 10746 } 10747 10748 private void retrieveSettings() { 10749 final ContentResolver resolver = mContext.getContentResolver(); 10750 String debugApp = Settings.Global.getString( 10751 resolver, Settings.Global.DEBUG_APP); 10752 boolean waitForDebugger = Settings.Global.getInt( 10753 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10754 boolean alwaysFinishActivities = Settings.Global.getInt( 10755 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10756 boolean forceRtl = Settings.Global.getInt( 10757 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10758 // Transfer any global setting for forcing RTL layout, into a System Property 10759 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10760 10761 Configuration configuration = new Configuration(); 10762 Settings.System.getConfiguration(resolver, configuration); 10763 if (forceRtl) { 10764 // This will take care of setting the correct layout direction flags 10765 configuration.setLayoutDirection(configuration.locale); 10766 } 10767 10768 synchronized (this) { 10769 mDebugApp = mOrigDebugApp = debugApp; 10770 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10771 mAlwaysFinishActivities = alwaysFinishActivities; 10772 // This happens before any activities are started, so we can 10773 // change mConfiguration in-place. 10774 updateConfigurationLocked(configuration, null, false, true); 10775 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10776 } 10777 } 10778 10779 /** Loads resources after the current configuration has been set. */ 10780 private void loadResourcesOnSystemReady() { 10781 final Resources res = mContext.getResources(); 10782 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10783 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10784 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10785 } 10786 10787 public boolean testIsSystemReady() { 10788 // no need to synchronize(this) just to read & return the value 10789 return mSystemReady; 10790 } 10791 10792 private static File getCalledPreBootReceiversFile() { 10793 File dataDir = Environment.getDataDirectory(); 10794 File systemDir = new File(dataDir, "system"); 10795 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10796 return fname; 10797 } 10798 10799 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10800 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10801 File file = getCalledPreBootReceiversFile(); 10802 FileInputStream fis = null; 10803 try { 10804 fis = new FileInputStream(file); 10805 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10806 int fvers = dis.readInt(); 10807 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10808 String vers = dis.readUTF(); 10809 String codename = dis.readUTF(); 10810 String build = dis.readUTF(); 10811 if (android.os.Build.VERSION.RELEASE.equals(vers) 10812 && android.os.Build.VERSION.CODENAME.equals(codename) 10813 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10814 int num = dis.readInt(); 10815 while (num > 0) { 10816 num--; 10817 String pkg = dis.readUTF(); 10818 String cls = dis.readUTF(); 10819 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10820 } 10821 } 10822 } 10823 } catch (FileNotFoundException e) { 10824 } catch (IOException e) { 10825 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10826 } finally { 10827 if (fis != null) { 10828 try { 10829 fis.close(); 10830 } catch (IOException e) { 10831 } 10832 } 10833 } 10834 return lastDoneReceivers; 10835 } 10836 10837 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10838 File file = getCalledPreBootReceiversFile(); 10839 FileOutputStream fos = null; 10840 DataOutputStream dos = null; 10841 try { 10842 fos = new FileOutputStream(file); 10843 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10844 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10845 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10846 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10847 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10848 dos.writeInt(list.size()); 10849 for (int i=0; i<list.size(); i++) { 10850 dos.writeUTF(list.get(i).getPackageName()); 10851 dos.writeUTF(list.get(i).getClassName()); 10852 } 10853 } catch (IOException e) { 10854 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10855 file.delete(); 10856 } finally { 10857 FileUtils.sync(fos); 10858 if (dos != null) { 10859 try { 10860 dos.close(); 10861 } catch (IOException e) { 10862 // TODO Auto-generated catch block 10863 e.printStackTrace(); 10864 } 10865 } 10866 } 10867 } 10868 10869 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10870 ArrayList<ComponentName> doneReceivers, int userId) { 10871 boolean waitingUpdate = false; 10872 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10873 List<ResolveInfo> ris = null; 10874 try { 10875 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10876 intent, null, 0, userId); 10877 } catch (RemoteException e) { 10878 } 10879 if (ris != null) { 10880 for (int i=ris.size()-1; i>=0; i--) { 10881 if ((ris.get(i).activityInfo.applicationInfo.flags 10882 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10883 ris.remove(i); 10884 } 10885 } 10886 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10887 10888 // For User 0, load the version number. When delivering to a new user, deliver 10889 // to all receivers. 10890 if (userId == UserHandle.USER_OWNER) { 10891 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10892 for (int i=0; i<ris.size(); i++) { 10893 ActivityInfo ai = ris.get(i).activityInfo; 10894 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10895 if (lastDoneReceivers.contains(comp)) { 10896 // We already did the pre boot receiver for this app with the current 10897 // platform version, so don't do it again... 10898 ris.remove(i); 10899 i--; 10900 // ...however, do keep it as one that has been done, so we don't 10901 // forget about it when rewriting the file of last done receivers. 10902 doneReceivers.add(comp); 10903 } 10904 } 10905 } 10906 10907 // If primary user, send broadcast to all available users, else just to userId 10908 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10909 : new int[] { userId }; 10910 for (int i = 0; i < ris.size(); i++) { 10911 ActivityInfo ai = ris.get(i).activityInfo; 10912 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10913 doneReceivers.add(comp); 10914 intent.setComponent(comp); 10915 for (int j=0; j<users.length; j++) { 10916 IIntentReceiver finisher = null; 10917 // On last receiver and user, set up a completion callback 10918 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10919 finisher = new IIntentReceiver.Stub() { 10920 public void performReceive(Intent intent, int resultCode, 10921 String data, Bundle extras, boolean ordered, 10922 boolean sticky, int sendingUser) { 10923 // The raw IIntentReceiver interface is called 10924 // with the AM lock held, so redispatch to 10925 // execute our code without the lock. 10926 mHandler.post(onFinishCallback); 10927 } 10928 }; 10929 } 10930 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10931 + " for user " + users[j]); 10932 broadcastIntentLocked(null, null, intent, null, finisher, 10933 0, null, null, null, AppOpsManager.OP_NONE, 10934 true, false, MY_PID, Process.SYSTEM_UID, 10935 users[j]); 10936 if (finisher != null) { 10937 waitingUpdate = true; 10938 } 10939 } 10940 } 10941 } 10942 10943 return waitingUpdate; 10944 } 10945 10946 public void systemReady(final Runnable goingCallback) { 10947 synchronized(this) { 10948 if (mSystemReady) { 10949 // If we're done calling all the receivers, run the next "boot phase" passed in 10950 // by the SystemServer 10951 if (goingCallback != null) { 10952 goingCallback.run(); 10953 } 10954 return; 10955 } 10956 10957 // Make sure we have the current profile info, since it is needed for 10958 // security checks. 10959 updateCurrentProfileIdsLocked(); 10960 10961 if (mRecentTasks == null) { 10962 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10963 if (!mRecentTasks.isEmpty()) { 10964 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10965 } 10966 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10967 mTaskPersister.startPersisting(); 10968 } 10969 10970 // Check to see if there are any update receivers to run. 10971 if (!mDidUpdate) { 10972 if (mWaitingUpdate) { 10973 return; 10974 } 10975 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10976 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10977 public void run() { 10978 synchronized (ActivityManagerService.this) { 10979 mDidUpdate = true; 10980 } 10981 writeLastDonePreBootReceivers(doneReceivers); 10982 showBootMessage(mContext.getText( 10983 R.string.android_upgrading_complete), 10984 false); 10985 systemReady(goingCallback); 10986 } 10987 }, doneReceivers, UserHandle.USER_OWNER); 10988 10989 if (mWaitingUpdate) { 10990 return; 10991 } 10992 mDidUpdate = true; 10993 } 10994 10995 mAppOpsService.systemReady(); 10996 mSystemReady = true; 10997 } 10998 10999 ArrayList<ProcessRecord> procsToKill = null; 11000 synchronized(mPidsSelfLocked) { 11001 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11002 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11003 if (!isAllowedWhileBooting(proc.info)){ 11004 if (procsToKill == null) { 11005 procsToKill = new ArrayList<ProcessRecord>(); 11006 } 11007 procsToKill.add(proc); 11008 } 11009 } 11010 } 11011 11012 synchronized(this) { 11013 if (procsToKill != null) { 11014 for (int i=procsToKill.size()-1; i>=0; i--) { 11015 ProcessRecord proc = procsToKill.get(i); 11016 Slog.i(TAG, "Removing system update proc: " + proc); 11017 removeProcessLocked(proc, true, false, "system update done"); 11018 } 11019 } 11020 11021 // Now that we have cleaned up any update processes, we 11022 // are ready to start launching real processes and know that 11023 // we won't trample on them any more. 11024 mProcessesReady = true; 11025 } 11026 11027 Slog.i(TAG, "System now ready"); 11028 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11029 SystemClock.uptimeMillis()); 11030 11031 synchronized(this) { 11032 // Make sure we have no pre-ready processes sitting around. 11033 11034 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11035 ResolveInfo ri = mContext.getPackageManager() 11036 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11037 STOCK_PM_FLAGS); 11038 CharSequence errorMsg = null; 11039 if (ri != null) { 11040 ActivityInfo ai = ri.activityInfo; 11041 ApplicationInfo app = ai.applicationInfo; 11042 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11043 mTopAction = Intent.ACTION_FACTORY_TEST; 11044 mTopData = null; 11045 mTopComponent = new ComponentName(app.packageName, 11046 ai.name); 11047 } else { 11048 errorMsg = mContext.getResources().getText( 11049 com.android.internal.R.string.factorytest_not_system); 11050 } 11051 } else { 11052 errorMsg = mContext.getResources().getText( 11053 com.android.internal.R.string.factorytest_no_action); 11054 } 11055 if (errorMsg != null) { 11056 mTopAction = null; 11057 mTopData = null; 11058 mTopComponent = null; 11059 Message msg = Message.obtain(); 11060 msg.what = SHOW_FACTORY_ERROR_MSG; 11061 msg.getData().putCharSequence("msg", errorMsg); 11062 mHandler.sendMessage(msg); 11063 } 11064 } 11065 } 11066 11067 retrieveSettings(); 11068 loadResourcesOnSystemReady(); 11069 11070 synchronized (this) { 11071 readGrantedUriPermissionsLocked(); 11072 } 11073 11074 if (goingCallback != null) goingCallback.run(); 11075 11076 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11077 Integer.toString(mCurrentUserId), mCurrentUserId); 11078 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11079 Integer.toString(mCurrentUserId), mCurrentUserId); 11080 mSystemServiceManager.startUser(mCurrentUserId); 11081 11082 synchronized (this) { 11083 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11084 try { 11085 List apps = AppGlobals.getPackageManager(). 11086 getPersistentApplications(STOCK_PM_FLAGS); 11087 if (apps != null) { 11088 int N = apps.size(); 11089 int i; 11090 for (i=0; i<N; i++) { 11091 ApplicationInfo info 11092 = (ApplicationInfo)apps.get(i); 11093 if (info != null && 11094 !info.packageName.equals("android")) { 11095 addAppLocked(info, false, null /* ABI override */); 11096 } 11097 } 11098 } 11099 } catch (RemoteException ex) { 11100 // pm is in same process, this will never happen. 11101 } 11102 } 11103 11104 // Start up initial activity. 11105 mBooting = true; 11106 11107 try { 11108 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11109 Message msg = Message.obtain(); 11110 msg.what = SHOW_UID_ERROR_MSG; 11111 mHandler.sendMessage(msg); 11112 } 11113 } catch (RemoteException e) { 11114 } 11115 11116 long ident = Binder.clearCallingIdentity(); 11117 try { 11118 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11120 | Intent.FLAG_RECEIVER_FOREGROUND); 11121 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11122 broadcastIntentLocked(null, null, intent, 11123 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11124 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11125 intent = new Intent(Intent.ACTION_USER_STARTING); 11126 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11127 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11128 broadcastIntentLocked(null, null, intent, 11129 null, new IIntentReceiver.Stub() { 11130 @Override 11131 public void performReceive(Intent intent, int resultCode, String data, 11132 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11133 throws RemoteException { 11134 } 11135 }, 0, null, null, 11136 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11137 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11138 } catch (Throwable t) { 11139 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11140 } finally { 11141 Binder.restoreCallingIdentity(ident); 11142 } 11143 mStackSupervisor.resumeTopActivitiesLocked(); 11144 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11145 } 11146 } 11147 11148 private boolean makeAppCrashingLocked(ProcessRecord app, 11149 String shortMsg, String longMsg, String stackTrace) { 11150 app.crashing = true; 11151 app.crashingReport = generateProcessError(app, 11152 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11153 startAppProblemLocked(app); 11154 app.stopFreezingAllLocked(); 11155 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11156 } 11157 11158 private void makeAppNotRespondingLocked(ProcessRecord app, 11159 String activity, String shortMsg, String longMsg) { 11160 app.notResponding = true; 11161 app.notRespondingReport = generateProcessError(app, 11162 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11163 activity, shortMsg, longMsg, null); 11164 startAppProblemLocked(app); 11165 app.stopFreezingAllLocked(); 11166 } 11167 11168 /** 11169 * Generate a process error record, suitable for attachment to a ProcessRecord. 11170 * 11171 * @param app The ProcessRecord in which the error occurred. 11172 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11173 * ActivityManager.AppErrorStateInfo 11174 * @param activity The activity associated with the crash, if known. 11175 * @param shortMsg Short message describing the crash. 11176 * @param longMsg Long message describing the crash. 11177 * @param stackTrace Full crash stack trace, may be null. 11178 * 11179 * @return Returns a fully-formed AppErrorStateInfo record. 11180 */ 11181 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11182 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11183 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11184 11185 report.condition = condition; 11186 report.processName = app.processName; 11187 report.pid = app.pid; 11188 report.uid = app.info.uid; 11189 report.tag = activity; 11190 report.shortMsg = shortMsg; 11191 report.longMsg = longMsg; 11192 report.stackTrace = stackTrace; 11193 11194 return report; 11195 } 11196 11197 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11198 synchronized (this) { 11199 app.crashing = false; 11200 app.crashingReport = null; 11201 app.notResponding = false; 11202 app.notRespondingReport = null; 11203 if (app.anrDialog == fromDialog) { 11204 app.anrDialog = null; 11205 } 11206 if (app.waitDialog == fromDialog) { 11207 app.waitDialog = null; 11208 } 11209 if (app.pid > 0 && app.pid != MY_PID) { 11210 handleAppCrashLocked(app, null, null, null); 11211 app.kill("user request after error", true); 11212 } 11213 } 11214 } 11215 11216 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11217 String stackTrace) { 11218 long now = SystemClock.uptimeMillis(); 11219 11220 Long crashTime; 11221 if (!app.isolated) { 11222 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11223 } else { 11224 crashTime = null; 11225 } 11226 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11227 // This process loses! 11228 Slog.w(TAG, "Process " + app.info.processName 11229 + " has crashed too many times: killing!"); 11230 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11231 app.userId, app.info.processName, app.uid); 11232 mStackSupervisor.handleAppCrashLocked(app); 11233 if (!app.persistent) { 11234 // We don't want to start this process again until the user 11235 // explicitly does so... but for persistent process, we really 11236 // need to keep it running. If a persistent process is actually 11237 // repeatedly crashing, then badness for everyone. 11238 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11239 app.info.processName); 11240 if (!app.isolated) { 11241 // XXX We don't have a way to mark isolated processes 11242 // as bad, since they don't have a peristent identity. 11243 mBadProcesses.put(app.info.processName, app.uid, 11244 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11245 mProcessCrashTimes.remove(app.info.processName, app.uid); 11246 } 11247 app.bad = true; 11248 app.removed = true; 11249 // Don't let services in this process be restarted and potentially 11250 // annoy the user repeatedly. Unless it is persistent, since those 11251 // processes run critical code. 11252 removeProcessLocked(app, false, false, "crash"); 11253 mStackSupervisor.resumeTopActivitiesLocked(); 11254 return false; 11255 } 11256 mStackSupervisor.resumeTopActivitiesLocked(); 11257 } else { 11258 mStackSupervisor.finishTopRunningActivityLocked(app); 11259 } 11260 11261 // Bump up the crash count of any services currently running in the proc. 11262 for (int i=app.services.size()-1; i>=0; i--) { 11263 // Any services running in the application need to be placed 11264 // back in the pending list. 11265 ServiceRecord sr = app.services.valueAt(i); 11266 sr.crashCount++; 11267 } 11268 11269 // If the crashing process is what we consider to be the "home process" and it has been 11270 // replaced by a third-party app, clear the package preferred activities from packages 11271 // with a home activity running in the process to prevent a repeatedly crashing app 11272 // from blocking the user to manually clear the list. 11273 final ArrayList<ActivityRecord> activities = app.activities; 11274 if (app == mHomeProcess && activities.size() > 0 11275 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11276 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11277 final ActivityRecord r = activities.get(activityNdx); 11278 if (r.isHomeActivity()) { 11279 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11280 try { 11281 ActivityThread.getPackageManager() 11282 .clearPackagePreferredActivities(r.packageName); 11283 } catch (RemoteException c) { 11284 // pm is in same process, this will never happen. 11285 } 11286 } 11287 } 11288 } 11289 11290 if (!app.isolated) { 11291 // XXX Can't keep track of crash times for isolated processes, 11292 // because they don't have a perisistent identity. 11293 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11294 } 11295 11296 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11297 return true; 11298 } 11299 11300 void startAppProblemLocked(ProcessRecord app) { 11301 // If this app is not running under the current user, then we 11302 // can't give it a report button because that would require 11303 // launching the report UI under a different user. 11304 app.errorReportReceiver = null; 11305 11306 for (int userId : mCurrentProfileIds) { 11307 if (app.userId == userId) { 11308 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11309 mContext, app.info.packageName, app.info.flags); 11310 } 11311 } 11312 skipCurrentReceiverLocked(app); 11313 } 11314 11315 void skipCurrentReceiverLocked(ProcessRecord app) { 11316 for (BroadcastQueue queue : mBroadcastQueues) { 11317 queue.skipCurrentReceiverLocked(app); 11318 } 11319 } 11320 11321 /** 11322 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11323 * The application process will exit immediately after this call returns. 11324 * @param app object of the crashing app, null for the system server 11325 * @param crashInfo describing the exception 11326 */ 11327 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11328 ProcessRecord r = findAppProcess(app, "Crash"); 11329 final String processName = app == null ? "system_server" 11330 : (r == null ? "unknown" : r.processName); 11331 11332 handleApplicationCrashInner("crash", r, processName, crashInfo); 11333 } 11334 11335 /* Native crash reporting uses this inner version because it needs to be somewhat 11336 * decoupled from the AM-managed cleanup lifecycle 11337 */ 11338 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11339 ApplicationErrorReport.CrashInfo crashInfo) { 11340 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11341 UserHandle.getUserId(Binder.getCallingUid()), processName, 11342 r == null ? -1 : r.info.flags, 11343 crashInfo.exceptionClassName, 11344 crashInfo.exceptionMessage, 11345 crashInfo.throwFileName, 11346 crashInfo.throwLineNumber); 11347 11348 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11349 11350 crashApplication(r, crashInfo); 11351 } 11352 11353 public void handleApplicationStrictModeViolation( 11354 IBinder app, 11355 int violationMask, 11356 StrictMode.ViolationInfo info) { 11357 ProcessRecord r = findAppProcess(app, "StrictMode"); 11358 if (r == null) { 11359 return; 11360 } 11361 11362 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11363 Integer stackFingerprint = info.hashCode(); 11364 boolean logIt = true; 11365 synchronized (mAlreadyLoggedViolatedStacks) { 11366 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11367 logIt = false; 11368 // TODO: sub-sample into EventLog for these, with 11369 // the info.durationMillis? Then we'd get 11370 // the relative pain numbers, without logging all 11371 // the stack traces repeatedly. We'd want to do 11372 // likewise in the client code, which also does 11373 // dup suppression, before the Binder call. 11374 } else { 11375 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11376 mAlreadyLoggedViolatedStacks.clear(); 11377 } 11378 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11379 } 11380 } 11381 if (logIt) { 11382 logStrictModeViolationToDropBox(r, info); 11383 } 11384 } 11385 11386 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11387 AppErrorResult result = new AppErrorResult(); 11388 synchronized (this) { 11389 final long origId = Binder.clearCallingIdentity(); 11390 11391 Message msg = Message.obtain(); 11392 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11393 HashMap<String, Object> data = new HashMap<String, Object>(); 11394 data.put("result", result); 11395 data.put("app", r); 11396 data.put("violationMask", violationMask); 11397 data.put("info", info); 11398 msg.obj = data; 11399 mHandler.sendMessage(msg); 11400 11401 Binder.restoreCallingIdentity(origId); 11402 } 11403 int res = result.get(); 11404 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11405 } 11406 } 11407 11408 // Depending on the policy in effect, there could be a bunch of 11409 // these in quick succession so we try to batch these together to 11410 // minimize disk writes, number of dropbox entries, and maximize 11411 // compression, by having more fewer, larger records. 11412 private void logStrictModeViolationToDropBox( 11413 ProcessRecord process, 11414 StrictMode.ViolationInfo info) { 11415 if (info == null) { 11416 return; 11417 } 11418 final boolean isSystemApp = process == null || 11419 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11420 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11421 final String processName = process == null ? "unknown" : process.processName; 11422 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11423 final DropBoxManager dbox = (DropBoxManager) 11424 mContext.getSystemService(Context.DROPBOX_SERVICE); 11425 11426 // Exit early if the dropbox isn't configured to accept this report type. 11427 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11428 11429 boolean bufferWasEmpty; 11430 boolean needsFlush; 11431 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11432 synchronized (sb) { 11433 bufferWasEmpty = sb.length() == 0; 11434 appendDropBoxProcessHeaders(process, processName, sb); 11435 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11436 sb.append("System-App: ").append(isSystemApp).append("\n"); 11437 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11438 if (info.violationNumThisLoop != 0) { 11439 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11440 } 11441 if (info.numAnimationsRunning != 0) { 11442 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11443 } 11444 if (info.broadcastIntentAction != null) { 11445 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11446 } 11447 if (info.durationMillis != -1) { 11448 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11449 } 11450 if (info.numInstances != -1) { 11451 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11452 } 11453 if (info.tags != null) { 11454 for (String tag : info.tags) { 11455 sb.append("Span-Tag: ").append(tag).append("\n"); 11456 } 11457 } 11458 sb.append("\n"); 11459 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11460 sb.append(info.crashInfo.stackTrace); 11461 } 11462 sb.append("\n"); 11463 11464 // Only buffer up to ~64k. Various logging bits truncate 11465 // things at 128k. 11466 needsFlush = (sb.length() > 64 * 1024); 11467 } 11468 11469 // Flush immediately if the buffer's grown too large, or this 11470 // is a non-system app. Non-system apps are isolated with a 11471 // different tag & policy and not batched. 11472 // 11473 // Batching is useful during internal testing with 11474 // StrictMode settings turned up high. Without batching, 11475 // thousands of separate files could be created on boot. 11476 if (!isSystemApp || needsFlush) { 11477 new Thread("Error dump: " + dropboxTag) { 11478 @Override 11479 public void run() { 11480 String report; 11481 synchronized (sb) { 11482 report = sb.toString(); 11483 sb.delete(0, sb.length()); 11484 sb.trimToSize(); 11485 } 11486 if (report.length() != 0) { 11487 dbox.addText(dropboxTag, report); 11488 } 11489 } 11490 }.start(); 11491 return; 11492 } 11493 11494 // System app batching: 11495 if (!bufferWasEmpty) { 11496 // An existing dropbox-writing thread is outstanding, so 11497 // we don't need to start it up. The existing thread will 11498 // catch the buffer appends we just did. 11499 return; 11500 } 11501 11502 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11503 // (After this point, we shouldn't access AMS internal data structures.) 11504 new Thread("Error dump: " + dropboxTag) { 11505 @Override 11506 public void run() { 11507 // 5 second sleep to let stacks arrive and be batched together 11508 try { 11509 Thread.sleep(5000); // 5 seconds 11510 } catch (InterruptedException e) {} 11511 11512 String errorReport; 11513 synchronized (mStrictModeBuffer) { 11514 errorReport = mStrictModeBuffer.toString(); 11515 if (errorReport.length() == 0) { 11516 return; 11517 } 11518 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11519 mStrictModeBuffer.trimToSize(); 11520 } 11521 dbox.addText(dropboxTag, errorReport); 11522 } 11523 }.start(); 11524 } 11525 11526 /** 11527 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11528 * @param app object of the crashing app, null for the system server 11529 * @param tag reported by the caller 11530 * @param system whether this wtf is coming from the system 11531 * @param crashInfo describing the context of the error 11532 * @return true if the process should exit immediately (WTF is fatal) 11533 */ 11534 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11535 final ApplicationErrorReport.CrashInfo crashInfo) { 11536 final ProcessRecord r = findAppProcess(app, "WTF"); 11537 final String processName = app == null ? "system_server" 11538 : (r == null ? "unknown" : r.processName); 11539 11540 EventLog.writeEvent(EventLogTags.AM_WTF, 11541 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11542 processName, 11543 r == null ? -1 : r.info.flags, 11544 tag, crashInfo.exceptionMessage); 11545 11546 if (system) { 11547 // If this is coming from the system, we could very well have low-level 11548 // system locks held, so we want to do this all asynchronously. And we 11549 // never want this to become fatal, so there is that too. 11550 mHandler.post(new Runnable() { 11551 @Override public void run() { 11552 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11553 crashInfo); 11554 } 11555 }); 11556 return false; 11557 } 11558 11559 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11560 11561 if (r != null && r.pid != Process.myPid() && 11562 Settings.Global.getInt(mContext.getContentResolver(), 11563 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11564 crashApplication(r, crashInfo); 11565 return true; 11566 } else { 11567 return false; 11568 } 11569 } 11570 11571 /** 11572 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11573 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11574 */ 11575 private ProcessRecord findAppProcess(IBinder app, String reason) { 11576 if (app == null) { 11577 return null; 11578 } 11579 11580 synchronized (this) { 11581 final int NP = mProcessNames.getMap().size(); 11582 for (int ip=0; ip<NP; ip++) { 11583 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11584 final int NA = apps.size(); 11585 for (int ia=0; ia<NA; ia++) { 11586 ProcessRecord p = apps.valueAt(ia); 11587 if (p.thread != null && p.thread.asBinder() == app) { 11588 return p; 11589 } 11590 } 11591 } 11592 11593 Slog.w(TAG, "Can't find mystery application for " + reason 11594 + " from pid=" + Binder.getCallingPid() 11595 + " uid=" + Binder.getCallingUid() + ": " + app); 11596 return null; 11597 } 11598 } 11599 11600 /** 11601 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11602 * to append various headers to the dropbox log text. 11603 */ 11604 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11605 StringBuilder sb) { 11606 // Watchdog thread ends up invoking this function (with 11607 // a null ProcessRecord) to add the stack file to dropbox. 11608 // Do not acquire a lock on this (am) in such cases, as it 11609 // could cause a potential deadlock, if and when watchdog 11610 // is invoked due to unavailability of lock on am and it 11611 // would prevent watchdog from killing system_server. 11612 if (process == null) { 11613 sb.append("Process: ").append(processName).append("\n"); 11614 return; 11615 } 11616 // Note: ProcessRecord 'process' is guarded by the service 11617 // instance. (notably process.pkgList, which could otherwise change 11618 // concurrently during execution of this method) 11619 synchronized (this) { 11620 sb.append("Process: ").append(processName).append("\n"); 11621 int flags = process.info.flags; 11622 IPackageManager pm = AppGlobals.getPackageManager(); 11623 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11624 for (int ip=0; ip<process.pkgList.size(); ip++) { 11625 String pkg = process.pkgList.keyAt(ip); 11626 sb.append("Package: ").append(pkg); 11627 try { 11628 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11629 if (pi != null) { 11630 sb.append(" v").append(pi.versionCode); 11631 if (pi.versionName != null) { 11632 sb.append(" (").append(pi.versionName).append(")"); 11633 } 11634 } 11635 } catch (RemoteException e) { 11636 Slog.e(TAG, "Error getting package info: " + pkg, e); 11637 } 11638 sb.append("\n"); 11639 } 11640 } 11641 } 11642 11643 private static String processClass(ProcessRecord process) { 11644 if (process == null || process.pid == MY_PID) { 11645 return "system_server"; 11646 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11647 return "system_app"; 11648 } else { 11649 return "data_app"; 11650 } 11651 } 11652 11653 /** 11654 * Write a description of an error (crash, WTF, ANR) to the drop box. 11655 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11656 * @param process which caused the error, null means the system server 11657 * @param activity which triggered the error, null if unknown 11658 * @param parent activity related to the error, null if unknown 11659 * @param subject line related to the error, null if absent 11660 * @param report in long form describing the error, null if absent 11661 * @param logFile to include in the report, null if none 11662 * @param crashInfo giving an application stack trace, null if absent 11663 */ 11664 public void addErrorToDropBox(String eventType, 11665 ProcessRecord process, String processName, ActivityRecord activity, 11666 ActivityRecord parent, String subject, 11667 final String report, final File logFile, 11668 final ApplicationErrorReport.CrashInfo crashInfo) { 11669 // NOTE -- this must never acquire the ActivityManagerService lock, 11670 // otherwise the watchdog may be prevented from resetting the system. 11671 11672 final String dropboxTag = processClass(process) + "_" + eventType; 11673 final DropBoxManager dbox = (DropBoxManager) 11674 mContext.getSystemService(Context.DROPBOX_SERVICE); 11675 11676 // Exit early if the dropbox isn't configured to accept this report type. 11677 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11678 11679 final StringBuilder sb = new StringBuilder(1024); 11680 appendDropBoxProcessHeaders(process, processName, sb); 11681 if (activity != null) { 11682 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11683 } 11684 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11685 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11686 } 11687 if (parent != null && parent != activity) { 11688 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11689 } 11690 if (subject != null) { 11691 sb.append("Subject: ").append(subject).append("\n"); 11692 } 11693 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11694 if (Debug.isDebuggerConnected()) { 11695 sb.append("Debugger: Connected\n"); 11696 } 11697 sb.append("\n"); 11698 11699 // Do the rest in a worker thread to avoid blocking the caller on I/O 11700 // (After this point, we shouldn't access AMS internal data structures.) 11701 Thread worker = new Thread("Error dump: " + dropboxTag) { 11702 @Override 11703 public void run() { 11704 if (report != null) { 11705 sb.append(report); 11706 } 11707 if (logFile != null) { 11708 try { 11709 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11710 "\n\n[[TRUNCATED]]")); 11711 } catch (IOException e) { 11712 Slog.e(TAG, "Error reading " + logFile, e); 11713 } 11714 } 11715 if (crashInfo != null && crashInfo.stackTrace != null) { 11716 sb.append(crashInfo.stackTrace); 11717 } 11718 11719 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11720 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11721 if (lines > 0) { 11722 sb.append("\n"); 11723 11724 // Merge several logcat streams, and take the last N lines 11725 InputStreamReader input = null; 11726 try { 11727 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11728 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11729 "-b", "crash", 11730 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11731 11732 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11733 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11734 input = new InputStreamReader(logcat.getInputStream()); 11735 11736 int num; 11737 char[] buf = new char[8192]; 11738 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11739 } catch (IOException e) { 11740 Slog.e(TAG, "Error running logcat", e); 11741 } finally { 11742 if (input != null) try { input.close(); } catch (IOException e) {} 11743 } 11744 } 11745 11746 dbox.addText(dropboxTag, sb.toString()); 11747 } 11748 }; 11749 11750 if (process == null) { 11751 // If process is null, we are being called from some internal code 11752 // and may be about to die -- run this synchronously. 11753 worker.run(); 11754 } else { 11755 worker.start(); 11756 } 11757 } 11758 11759 /** 11760 * Bring up the "unexpected error" dialog box for a crashing app. 11761 * Deal with edge cases (intercepts from instrumented applications, 11762 * ActivityController, error intent receivers, that sort of thing). 11763 * @param r the application crashing 11764 * @param crashInfo describing the failure 11765 */ 11766 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11767 long timeMillis = System.currentTimeMillis(); 11768 String shortMsg = crashInfo.exceptionClassName; 11769 String longMsg = crashInfo.exceptionMessage; 11770 String stackTrace = crashInfo.stackTrace; 11771 if (shortMsg != null && longMsg != null) { 11772 longMsg = shortMsg + ": " + longMsg; 11773 } else if (shortMsg != null) { 11774 longMsg = shortMsg; 11775 } 11776 11777 AppErrorResult result = new AppErrorResult(); 11778 synchronized (this) { 11779 if (mController != null) { 11780 try { 11781 String name = r != null ? r.processName : null; 11782 int pid = r != null ? r.pid : Binder.getCallingPid(); 11783 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11784 if (!mController.appCrashed(name, pid, 11785 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11786 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11787 && "Native crash".equals(crashInfo.exceptionClassName)) { 11788 Slog.w(TAG, "Skip killing native crashed app " + name 11789 + "(" + pid + ") during testing"); 11790 } else { 11791 Slog.w(TAG, "Force-killing crashed app " + name 11792 + " at watcher's request"); 11793 if (r != null) { 11794 r.kill("crash", true); 11795 } else { 11796 // Huh. 11797 Process.killProcess(pid); 11798 Process.killProcessGroup(uid, pid); 11799 } 11800 } 11801 return; 11802 } 11803 } catch (RemoteException e) { 11804 mController = null; 11805 Watchdog.getInstance().setActivityController(null); 11806 } 11807 } 11808 11809 final long origId = Binder.clearCallingIdentity(); 11810 11811 // If this process is running instrumentation, finish it. 11812 if (r != null && r.instrumentationClass != null) { 11813 Slog.w(TAG, "Error in app " + r.processName 11814 + " running instrumentation " + r.instrumentationClass + ":"); 11815 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11816 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11817 Bundle info = new Bundle(); 11818 info.putString("shortMsg", shortMsg); 11819 info.putString("longMsg", longMsg); 11820 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11821 Binder.restoreCallingIdentity(origId); 11822 return; 11823 } 11824 11825 // If we can't identify the process or it's already exceeded its crash quota, 11826 // quit right away without showing a crash dialog. 11827 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11828 Binder.restoreCallingIdentity(origId); 11829 return; 11830 } 11831 11832 Message msg = Message.obtain(); 11833 msg.what = SHOW_ERROR_MSG; 11834 HashMap data = new HashMap(); 11835 data.put("result", result); 11836 data.put("app", r); 11837 msg.obj = data; 11838 mHandler.sendMessage(msg); 11839 11840 Binder.restoreCallingIdentity(origId); 11841 } 11842 11843 int res = result.get(); 11844 11845 Intent appErrorIntent = null; 11846 synchronized (this) { 11847 if (r != null && !r.isolated) { 11848 // XXX Can't keep track of crash time for isolated processes, 11849 // since they don't have a persistent identity. 11850 mProcessCrashTimes.put(r.info.processName, r.uid, 11851 SystemClock.uptimeMillis()); 11852 } 11853 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11854 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11855 } 11856 } 11857 11858 if (appErrorIntent != null) { 11859 try { 11860 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11861 } catch (ActivityNotFoundException e) { 11862 Slog.w(TAG, "bug report receiver dissappeared", e); 11863 } 11864 } 11865 } 11866 11867 Intent createAppErrorIntentLocked(ProcessRecord r, 11868 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11869 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11870 if (report == null) { 11871 return null; 11872 } 11873 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11874 result.setComponent(r.errorReportReceiver); 11875 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11876 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11877 return result; 11878 } 11879 11880 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11881 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11882 if (r.errorReportReceiver == null) { 11883 return null; 11884 } 11885 11886 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11887 return null; 11888 } 11889 11890 ApplicationErrorReport report = new ApplicationErrorReport(); 11891 report.packageName = r.info.packageName; 11892 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11893 report.processName = r.processName; 11894 report.time = timeMillis; 11895 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11896 11897 if (r.crashing || r.forceCrashReport) { 11898 report.type = ApplicationErrorReport.TYPE_CRASH; 11899 report.crashInfo = crashInfo; 11900 } else if (r.notResponding) { 11901 report.type = ApplicationErrorReport.TYPE_ANR; 11902 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11903 11904 report.anrInfo.activity = r.notRespondingReport.tag; 11905 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11906 report.anrInfo.info = r.notRespondingReport.longMsg; 11907 } 11908 11909 return report; 11910 } 11911 11912 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11913 enforceNotIsolatedCaller("getProcessesInErrorState"); 11914 // assume our apps are happy - lazy create the list 11915 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11916 11917 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11918 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11919 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11920 11921 synchronized (this) { 11922 11923 // iterate across all processes 11924 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11925 ProcessRecord app = mLruProcesses.get(i); 11926 if (!allUsers && app.userId != userId) { 11927 continue; 11928 } 11929 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11930 // This one's in trouble, so we'll generate a report for it 11931 // crashes are higher priority (in case there's a crash *and* an anr) 11932 ActivityManager.ProcessErrorStateInfo report = null; 11933 if (app.crashing) { 11934 report = app.crashingReport; 11935 } else if (app.notResponding) { 11936 report = app.notRespondingReport; 11937 } 11938 11939 if (report != null) { 11940 if (errList == null) { 11941 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11942 } 11943 errList.add(report); 11944 } else { 11945 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11946 " crashing = " + app.crashing + 11947 " notResponding = " + app.notResponding); 11948 } 11949 } 11950 } 11951 } 11952 11953 return errList; 11954 } 11955 11956 static int procStateToImportance(int procState, int memAdj, 11957 ActivityManager.RunningAppProcessInfo currApp) { 11958 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11959 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11960 currApp.lru = memAdj; 11961 } else { 11962 currApp.lru = 0; 11963 } 11964 return imp; 11965 } 11966 11967 private void fillInProcMemInfo(ProcessRecord app, 11968 ActivityManager.RunningAppProcessInfo outInfo) { 11969 outInfo.pid = app.pid; 11970 outInfo.uid = app.info.uid; 11971 if (mHeavyWeightProcess == app) { 11972 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11973 } 11974 if (app.persistent) { 11975 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11976 } 11977 if (app.activities.size() > 0) { 11978 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11979 } 11980 outInfo.lastTrimLevel = app.trimMemoryLevel; 11981 int adj = app.curAdj; 11982 int procState = app.curProcState; 11983 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11984 outInfo.importanceReasonCode = app.adjTypeCode; 11985 outInfo.processState = app.curProcState; 11986 } 11987 11988 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11989 enforceNotIsolatedCaller("getRunningAppProcesses"); 11990 // Lazy instantiation of list 11991 List<ActivityManager.RunningAppProcessInfo> runList = null; 11992 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11993 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11994 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11995 synchronized (this) { 11996 // Iterate across all processes 11997 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11998 ProcessRecord app = mLruProcesses.get(i); 11999 if (!allUsers && app.userId != userId) { 12000 continue; 12001 } 12002 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12003 // Generate process state info for running application 12004 ActivityManager.RunningAppProcessInfo currApp = 12005 new ActivityManager.RunningAppProcessInfo(app.processName, 12006 app.pid, app.getPackageList()); 12007 fillInProcMemInfo(app, currApp); 12008 if (app.adjSource instanceof ProcessRecord) { 12009 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12010 currApp.importanceReasonImportance = 12011 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12012 app.adjSourceProcState); 12013 } else if (app.adjSource instanceof ActivityRecord) { 12014 ActivityRecord r = (ActivityRecord)app.adjSource; 12015 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12016 } 12017 if (app.adjTarget instanceof ComponentName) { 12018 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12019 } 12020 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12021 // + " lru=" + currApp.lru); 12022 if (runList == null) { 12023 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12024 } 12025 runList.add(currApp); 12026 } 12027 } 12028 } 12029 return runList; 12030 } 12031 12032 public List<ApplicationInfo> getRunningExternalApplications() { 12033 enforceNotIsolatedCaller("getRunningExternalApplications"); 12034 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12035 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12036 if (runningApps != null && runningApps.size() > 0) { 12037 Set<String> extList = new HashSet<String>(); 12038 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12039 if (app.pkgList != null) { 12040 for (String pkg : app.pkgList) { 12041 extList.add(pkg); 12042 } 12043 } 12044 } 12045 IPackageManager pm = AppGlobals.getPackageManager(); 12046 for (String pkg : extList) { 12047 try { 12048 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12049 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12050 retList.add(info); 12051 } 12052 } catch (RemoteException e) { 12053 } 12054 } 12055 } 12056 return retList; 12057 } 12058 12059 @Override 12060 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12061 enforceNotIsolatedCaller("getMyMemoryState"); 12062 synchronized (this) { 12063 ProcessRecord proc; 12064 synchronized (mPidsSelfLocked) { 12065 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12066 } 12067 fillInProcMemInfo(proc, outInfo); 12068 } 12069 } 12070 12071 @Override 12072 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12073 if (checkCallingPermission(android.Manifest.permission.DUMP) 12074 != PackageManager.PERMISSION_GRANTED) { 12075 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12076 + Binder.getCallingPid() 12077 + ", uid=" + Binder.getCallingUid() 12078 + " without permission " 12079 + android.Manifest.permission.DUMP); 12080 return; 12081 } 12082 12083 boolean dumpAll = false; 12084 boolean dumpClient = false; 12085 String dumpPackage = null; 12086 12087 int opti = 0; 12088 while (opti < args.length) { 12089 String opt = args[opti]; 12090 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12091 break; 12092 } 12093 opti++; 12094 if ("-a".equals(opt)) { 12095 dumpAll = true; 12096 } else if ("-c".equals(opt)) { 12097 dumpClient = true; 12098 } else if ("-h".equals(opt)) { 12099 pw.println("Activity manager dump options:"); 12100 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12101 pw.println(" cmd may be one of:"); 12102 pw.println(" a[ctivities]: activity stack state"); 12103 pw.println(" r[recents]: recent activities state"); 12104 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12105 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12106 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12107 pw.println(" o[om]: out of memory management"); 12108 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12109 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12110 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12111 pw.println(" service [COMP_SPEC]: service client-side state"); 12112 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12113 pw.println(" all: dump all activities"); 12114 pw.println(" top: dump the top activity"); 12115 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12116 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12117 pw.println(" a partial substring in a component name, a"); 12118 pw.println(" hex object identifier."); 12119 pw.println(" -a: include all available server state."); 12120 pw.println(" -c: include client state."); 12121 return; 12122 } else { 12123 pw.println("Unknown argument: " + opt + "; use -h for help"); 12124 } 12125 } 12126 12127 long origId = Binder.clearCallingIdentity(); 12128 boolean more = false; 12129 // Is the caller requesting to dump a particular piece of data? 12130 if (opti < args.length) { 12131 String cmd = args[opti]; 12132 opti++; 12133 if ("activities".equals(cmd) || "a".equals(cmd)) { 12134 synchronized (this) { 12135 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12136 } 12137 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12138 synchronized (this) { 12139 dumpRecentsLocked(fd, pw, args, opti, true, null); 12140 } 12141 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12142 String[] newArgs; 12143 String name; 12144 if (opti >= args.length) { 12145 name = null; 12146 newArgs = EMPTY_STRING_ARRAY; 12147 } else { 12148 name = args[opti]; 12149 opti++; 12150 newArgs = new String[args.length - opti]; 12151 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12152 args.length - opti); 12153 } 12154 synchronized (this) { 12155 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12156 } 12157 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12158 String[] newArgs; 12159 String name; 12160 if (opti >= args.length) { 12161 name = null; 12162 newArgs = EMPTY_STRING_ARRAY; 12163 } else { 12164 name = args[opti]; 12165 opti++; 12166 newArgs = new String[args.length - opti]; 12167 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12168 args.length - opti); 12169 } 12170 synchronized (this) { 12171 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12172 } 12173 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12174 String[] newArgs; 12175 String name; 12176 if (opti >= args.length) { 12177 name = null; 12178 newArgs = EMPTY_STRING_ARRAY; 12179 } else { 12180 name = args[opti]; 12181 opti++; 12182 newArgs = new String[args.length - opti]; 12183 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12184 args.length - opti); 12185 } 12186 synchronized (this) { 12187 dumpProcessesLocked(fd, pw, args, opti, true, name); 12188 } 12189 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12190 synchronized (this) { 12191 dumpOomLocked(fd, pw, args, opti, true); 12192 } 12193 } else if ("provider".equals(cmd)) { 12194 String[] newArgs; 12195 String name; 12196 if (opti >= args.length) { 12197 name = null; 12198 newArgs = EMPTY_STRING_ARRAY; 12199 } else { 12200 name = args[opti]; 12201 opti++; 12202 newArgs = new String[args.length - opti]; 12203 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12204 } 12205 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12206 pw.println("No providers match: " + name); 12207 pw.println("Use -h for help."); 12208 } 12209 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12210 synchronized (this) { 12211 dumpProvidersLocked(fd, pw, args, opti, true, null); 12212 } 12213 } else if ("service".equals(cmd)) { 12214 String[] newArgs; 12215 String name; 12216 if (opti >= args.length) { 12217 name = null; 12218 newArgs = EMPTY_STRING_ARRAY; 12219 } else { 12220 name = args[opti]; 12221 opti++; 12222 newArgs = new String[args.length - opti]; 12223 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12224 args.length - opti); 12225 } 12226 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12227 pw.println("No services match: " + name); 12228 pw.println("Use -h for help."); 12229 } 12230 } else if ("package".equals(cmd)) { 12231 String[] newArgs; 12232 if (opti >= args.length) { 12233 pw.println("package: no package name specified"); 12234 pw.println("Use -h for help."); 12235 } else { 12236 dumpPackage = args[opti]; 12237 opti++; 12238 newArgs = new String[args.length - opti]; 12239 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12240 args.length - opti); 12241 args = newArgs; 12242 opti = 0; 12243 more = true; 12244 } 12245 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12246 synchronized (this) { 12247 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12248 } 12249 } else { 12250 // Dumping a single activity? 12251 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12252 pw.println("Bad activity command, or no activities match: " + cmd); 12253 pw.println("Use -h for help."); 12254 } 12255 } 12256 if (!more) { 12257 Binder.restoreCallingIdentity(origId); 12258 return; 12259 } 12260 } 12261 12262 // No piece of data specified, dump everything. 12263 synchronized (this) { 12264 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12265 pw.println(); 12266 if (dumpAll) { 12267 pw.println("-------------------------------------------------------------------------------"); 12268 } 12269 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12270 pw.println(); 12271 if (dumpAll) { 12272 pw.println("-------------------------------------------------------------------------------"); 12273 } 12274 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12275 pw.println(); 12276 if (dumpAll) { 12277 pw.println("-------------------------------------------------------------------------------"); 12278 } 12279 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12280 pw.println(); 12281 if (dumpAll) { 12282 pw.println("-------------------------------------------------------------------------------"); 12283 } 12284 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12285 pw.println(); 12286 if (dumpAll) { 12287 pw.println("-------------------------------------------------------------------------------"); 12288 } 12289 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12290 pw.println(); 12291 if (dumpAll) { 12292 pw.println("-------------------------------------------------------------------------------"); 12293 } 12294 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12295 } 12296 Binder.restoreCallingIdentity(origId); 12297 } 12298 12299 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12300 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12301 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12302 12303 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12304 dumpPackage); 12305 boolean needSep = printedAnything; 12306 12307 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12308 dumpPackage, needSep, " mFocusedActivity: "); 12309 if (printed) { 12310 printedAnything = true; 12311 needSep = false; 12312 } 12313 12314 if (dumpPackage == null) { 12315 if (needSep) { 12316 pw.println(); 12317 } 12318 needSep = true; 12319 printedAnything = true; 12320 mStackSupervisor.dump(pw, " "); 12321 } 12322 12323 if (!printedAnything) { 12324 pw.println(" (nothing)"); 12325 } 12326 } 12327 12328 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12329 int opti, boolean dumpAll, String dumpPackage) { 12330 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12331 12332 boolean printedAnything = false; 12333 12334 if (mRecentTasks.size() > 0) { 12335 boolean printedHeader = false; 12336 12337 final int N = mRecentTasks.size(); 12338 for (int i=0; i<N; i++) { 12339 TaskRecord tr = mRecentTasks.get(i); 12340 if (dumpPackage != null) { 12341 if (tr.realActivity == null || 12342 !dumpPackage.equals(tr.realActivity)) { 12343 continue; 12344 } 12345 } 12346 if (!printedHeader) { 12347 pw.println(" Recent tasks:"); 12348 printedHeader = true; 12349 printedAnything = true; 12350 } 12351 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12352 pw.println(tr); 12353 if (dumpAll) { 12354 mRecentTasks.get(i).dump(pw, " "); 12355 } 12356 } 12357 } 12358 12359 if (!printedAnything) { 12360 pw.println(" (nothing)"); 12361 } 12362 } 12363 12364 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12365 int opti, boolean dumpAll, String dumpPackage) { 12366 boolean needSep = false; 12367 boolean printedAnything = false; 12368 int numPers = 0; 12369 12370 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12371 12372 if (dumpAll) { 12373 final int NP = mProcessNames.getMap().size(); 12374 for (int ip=0; ip<NP; ip++) { 12375 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12376 final int NA = procs.size(); 12377 for (int ia=0; ia<NA; ia++) { 12378 ProcessRecord r = procs.valueAt(ia); 12379 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12380 continue; 12381 } 12382 if (!needSep) { 12383 pw.println(" All known processes:"); 12384 needSep = true; 12385 printedAnything = true; 12386 } 12387 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12388 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12389 pw.print(" "); pw.println(r); 12390 r.dump(pw, " "); 12391 if (r.persistent) { 12392 numPers++; 12393 } 12394 } 12395 } 12396 } 12397 12398 if (mIsolatedProcesses.size() > 0) { 12399 boolean printed = false; 12400 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12401 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12402 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12403 continue; 12404 } 12405 if (!printed) { 12406 if (needSep) { 12407 pw.println(); 12408 } 12409 pw.println(" Isolated process list (sorted by uid):"); 12410 printedAnything = true; 12411 printed = true; 12412 needSep = true; 12413 } 12414 pw.println(String.format("%sIsolated #%2d: %s", 12415 " ", i, r.toString())); 12416 } 12417 } 12418 12419 if (mLruProcesses.size() > 0) { 12420 if (needSep) { 12421 pw.println(); 12422 } 12423 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12424 pw.print(" total, non-act at "); 12425 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12426 pw.print(", non-svc at "); 12427 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12428 pw.println("):"); 12429 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12430 needSep = true; 12431 printedAnything = true; 12432 } 12433 12434 if (dumpAll || dumpPackage != null) { 12435 synchronized (mPidsSelfLocked) { 12436 boolean printed = false; 12437 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12438 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12439 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12440 continue; 12441 } 12442 if (!printed) { 12443 if (needSep) pw.println(); 12444 needSep = true; 12445 pw.println(" PID mappings:"); 12446 printed = true; 12447 printedAnything = true; 12448 } 12449 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12450 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12451 } 12452 } 12453 } 12454 12455 if (mForegroundProcesses.size() > 0) { 12456 synchronized (mPidsSelfLocked) { 12457 boolean printed = false; 12458 for (int i=0; i<mForegroundProcesses.size(); i++) { 12459 ProcessRecord r = mPidsSelfLocked.get( 12460 mForegroundProcesses.valueAt(i).pid); 12461 if (dumpPackage != null && (r == null 12462 || !r.pkgList.containsKey(dumpPackage))) { 12463 continue; 12464 } 12465 if (!printed) { 12466 if (needSep) pw.println(); 12467 needSep = true; 12468 pw.println(" Foreground Processes:"); 12469 printed = true; 12470 printedAnything = true; 12471 } 12472 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12473 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12474 } 12475 } 12476 } 12477 12478 if (mPersistentStartingProcesses.size() > 0) { 12479 if (needSep) pw.println(); 12480 needSep = true; 12481 printedAnything = true; 12482 pw.println(" Persisent processes that are starting:"); 12483 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12484 "Starting Norm", "Restarting PERS", dumpPackage); 12485 } 12486 12487 if (mRemovedProcesses.size() > 0) { 12488 if (needSep) pw.println(); 12489 needSep = true; 12490 printedAnything = true; 12491 pw.println(" Processes that are being removed:"); 12492 dumpProcessList(pw, this, mRemovedProcesses, " ", 12493 "Removed Norm", "Removed PERS", dumpPackage); 12494 } 12495 12496 if (mProcessesOnHold.size() > 0) { 12497 if (needSep) pw.println(); 12498 needSep = true; 12499 printedAnything = true; 12500 pw.println(" Processes that are on old until the system is ready:"); 12501 dumpProcessList(pw, this, mProcessesOnHold, " ", 12502 "OnHold Norm", "OnHold PERS", dumpPackage); 12503 } 12504 12505 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12506 12507 if (mProcessCrashTimes.getMap().size() > 0) { 12508 boolean printed = false; 12509 long now = SystemClock.uptimeMillis(); 12510 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12511 final int NP = pmap.size(); 12512 for (int ip=0; ip<NP; ip++) { 12513 String pname = pmap.keyAt(ip); 12514 SparseArray<Long> uids = pmap.valueAt(ip); 12515 final int N = uids.size(); 12516 for (int i=0; i<N; i++) { 12517 int puid = uids.keyAt(i); 12518 ProcessRecord r = mProcessNames.get(pname, puid); 12519 if (dumpPackage != null && (r == null 12520 || !r.pkgList.containsKey(dumpPackage))) { 12521 continue; 12522 } 12523 if (!printed) { 12524 if (needSep) pw.println(); 12525 needSep = true; 12526 pw.println(" Time since processes crashed:"); 12527 printed = true; 12528 printedAnything = true; 12529 } 12530 pw.print(" Process "); pw.print(pname); 12531 pw.print(" uid "); pw.print(puid); 12532 pw.print(": last crashed "); 12533 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12534 pw.println(" ago"); 12535 } 12536 } 12537 } 12538 12539 if (mBadProcesses.getMap().size() > 0) { 12540 boolean printed = false; 12541 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12542 final int NP = pmap.size(); 12543 for (int ip=0; ip<NP; ip++) { 12544 String pname = pmap.keyAt(ip); 12545 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12546 final int N = uids.size(); 12547 for (int i=0; i<N; i++) { 12548 int puid = uids.keyAt(i); 12549 ProcessRecord r = mProcessNames.get(pname, puid); 12550 if (dumpPackage != null && (r == null 12551 || !r.pkgList.containsKey(dumpPackage))) { 12552 continue; 12553 } 12554 if (!printed) { 12555 if (needSep) pw.println(); 12556 needSep = true; 12557 pw.println(" Bad processes:"); 12558 printedAnything = true; 12559 } 12560 BadProcessInfo info = uids.valueAt(i); 12561 pw.print(" Bad process "); pw.print(pname); 12562 pw.print(" uid "); pw.print(puid); 12563 pw.print(": crashed at time "); pw.println(info.time); 12564 if (info.shortMsg != null) { 12565 pw.print(" Short msg: "); pw.println(info.shortMsg); 12566 } 12567 if (info.longMsg != null) { 12568 pw.print(" Long msg: "); pw.println(info.longMsg); 12569 } 12570 if (info.stack != null) { 12571 pw.println(" Stack:"); 12572 int lastPos = 0; 12573 for (int pos=0; pos<info.stack.length(); pos++) { 12574 if (info.stack.charAt(pos) == '\n') { 12575 pw.print(" "); 12576 pw.write(info.stack, lastPos, pos-lastPos); 12577 pw.println(); 12578 lastPos = pos+1; 12579 } 12580 } 12581 if (lastPos < info.stack.length()) { 12582 pw.print(" "); 12583 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12584 pw.println(); 12585 } 12586 } 12587 } 12588 } 12589 } 12590 12591 if (dumpPackage == null) { 12592 pw.println(); 12593 needSep = false; 12594 pw.println(" mStartedUsers:"); 12595 for (int i=0; i<mStartedUsers.size(); i++) { 12596 UserStartedState uss = mStartedUsers.valueAt(i); 12597 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12598 pw.print(": "); uss.dump("", pw); 12599 } 12600 pw.print(" mStartedUserArray: ["); 12601 for (int i=0; i<mStartedUserArray.length; i++) { 12602 if (i > 0) pw.print(", "); 12603 pw.print(mStartedUserArray[i]); 12604 } 12605 pw.println("]"); 12606 pw.print(" mUserLru: ["); 12607 for (int i=0; i<mUserLru.size(); i++) { 12608 if (i > 0) pw.print(", "); 12609 pw.print(mUserLru.get(i)); 12610 } 12611 pw.println("]"); 12612 if (dumpAll) { 12613 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12614 } 12615 synchronized (mUserProfileGroupIdsSelfLocked) { 12616 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12617 pw.println(" mUserProfileGroupIds:"); 12618 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12619 pw.print(" User #"); 12620 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12621 pw.print(" -> profile #"); 12622 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12623 } 12624 } 12625 } 12626 } 12627 if (mHomeProcess != null && (dumpPackage == null 12628 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12629 if (needSep) { 12630 pw.println(); 12631 needSep = false; 12632 } 12633 pw.println(" mHomeProcess: " + mHomeProcess); 12634 } 12635 if (mPreviousProcess != null && (dumpPackage == null 12636 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12637 if (needSep) { 12638 pw.println(); 12639 needSep = false; 12640 } 12641 pw.println(" mPreviousProcess: " + mPreviousProcess); 12642 } 12643 if (dumpAll) { 12644 StringBuilder sb = new StringBuilder(128); 12645 sb.append(" mPreviousProcessVisibleTime: "); 12646 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12647 pw.println(sb); 12648 } 12649 if (mHeavyWeightProcess != null && (dumpPackage == null 12650 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12651 if (needSep) { 12652 pw.println(); 12653 needSep = false; 12654 } 12655 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12656 } 12657 if (dumpPackage == null) { 12658 pw.println(" mConfiguration: " + mConfiguration); 12659 } 12660 if (dumpAll) { 12661 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12662 if (mCompatModePackages.getPackages().size() > 0) { 12663 boolean printed = false; 12664 for (Map.Entry<String, Integer> entry 12665 : mCompatModePackages.getPackages().entrySet()) { 12666 String pkg = entry.getKey(); 12667 int mode = entry.getValue(); 12668 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12669 continue; 12670 } 12671 if (!printed) { 12672 pw.println(" mScreenCompatPackages:"); 12673 printed = true; 12674 } 12675 pw.print(" "); pw.print(pkg); pw.print(": "); 12676 pw.print(mode); pw.println(); 12677 } 12678 } 12679 } 12680 if (dumpPackage == null) { 12681 if (mSleeping || mWentToSleep || mLockScreenShown) { 12682 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12683 + " mLockScreenShown " + mLockScreenShown); 12684 } 12685 if (mShuttingDown || mRunningVoice) { 12686 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12687 } 12688 } 12689 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12690 || mOrigWaitForDebugger) { 12691 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12692 || dumpPackage.equals(mOrigDebugApp)) { 12693 if (needSep) { 12694 pw.println(); 12695 needSep = false; 12696 } 12697 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12698 + " mDebugTransient=" + mDebugTransient 12699 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12700 } 12701 } 12702 if (mOpenGlTraceApp != null) { 12703 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12704 if (needSep) { 12705 pw.println(); 12706 needSep = false; 12707 } 12708 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12709 } 12710 } 12711 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12712 || mProfileFd != null) { 12713 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12714 if (needSep) { 12715 pw.println(); 12716 needSep = false; 12717 } 12718 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12719 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12720 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12721 + mAutoStopProfiler); 12722 pw.println(" mProfileType=" + mProfileType); 12723 } 12724 } 12725 if (dumpPackage == null) { 12726 if (mAlwaysFinishActivities || mController != null) { 12727 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12728 + " mController=" + mController); 12729 } 12730 if (dumpAll) { 12731 pw.println(" Total persistent processes: " + numPers); 12732 pw.println(" mProcessesReady=" + mProcessesReady 12733 + " mSystemReady=" + mSystemReady); 12734 pw.println(" mBooting=" + mBooting 12735 + " mBooted=" + mBooted 12736 + " mFactoryTest=" + mFactoryTest); 12737 pw.print(" mLastPowerCheckRealtime="); 12738 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12739 pw.println(""); 12740 pw.print(" mLastPowerCheckUptime="); 12741 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12742 pw.println(""); 12743 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12744 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12745 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12746 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12747 + " (" + mLruProcesses.size() + " total)" 12748 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12749 + " mNumServiceProcs=" + mNumServiceProcs 12750 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12751 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12752 + " mLastMemoryLevel" + mLastMemoryLevel 12753 + " mLastNumProcesses" + mLastNumProcesses); 12754 long now = SystemClock.uptimeMillis(); 12755 pw.print(" mLastIdleTime="); 12756 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12757 pw.print(" mLowRamSinceLastIdle="); 12758 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12759 pw.println(); 12760 } 12761 } 12762 12763 if (!printedAnything) { 12764 pw.println(" (nothing)"); 12765 } 12766 } 12767 12768 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12769 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12770 if (mProcessesToGc.size() > 0) { 12771 boolean printed = false; 12772 long now = SystemClock.uptimeMillis(); 12773 for (int i=0; i<mProcessesToGc.size(); i++) { 12774 ProcessRecord proc = mProcessesToGc.get(i); 12775 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12776 continue; 12777 } 12778 if (!printed) { 12779 if (needSep) pw.println(); 12780 needSep = true; 12781 pw.println(" Processes that are waiting to GC:"); 12782 printed = true; 12783 } 12784 pw.print(" Process "); pw.println(proc); 12785 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12786 pw.print(", last gced="); 12787 pw.print(now-proc.lastRequestedGc); 12788 pw.print(" ms ago, last lowMem="); 12789 pw.print(now-proc.lastLowMemory); 12790 pw.println(" ms ago"); 12791 12792 } 12793 } 12794 return needSep; 12795 } 12796 12797 void printOomLevel(PrintWriter pw, String name, int adj) { 12798 pw.print(" "); 12799 if (adj >= 0) { 12800 pw.print(' '); 12801 if (adj < 10) pw.print(' '); 12802 } else { 12803 if (adj > -10) pw.print(' '); 12804 } 12805 pw.print(adj); 12806 pw.print(": "); 12807 pw.print(name); 12808 pw.print(" ("); 12809 pw.print(mProcessList.getMemLevel(adj)/1024); 12810 pw.println(" kB)"); 12811 } 12812 12813 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12814 int opti, boolean dumpAll) { 12815 boolean needSep = false; 12816 12817 if (mLruProcesses.size() > 0) { 12818 if (needSep) pw.println(); 12819 needSep = true; 12820 pw.println(" OOM levels:"); 12821 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12822 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12823 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12824 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12825 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12826 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12827 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12828 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12829 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12830 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12831 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12832 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12833 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12834 12835 if (needSep) pw.println(); 12836 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12837 pw.print(" total, non-act at "); 12838 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12839 pw.print(", non-svc at "); 12840 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12841 pw.println("):"); 12842 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12843 needSep = true; 12844 } 12845 12846 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12847 12848 pw.println(); 12849 pw.println(" mHomeProcess: " + mHomeProcess); 12850 pw.println(" mPreviousProcess: " + mPreviousProcess); 12851 if (mHeavyWeightProcess != null) { 12852 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12853 } 12854 12855 return true; 12856 } 12857 12858 /** 12859 * There are three ways to call this: 12860 * - no provider specified: dump all the providers 12861 * - a flattened component name that matched an existing provider was specified as the 12862 * first arg: dump that one provider 12863 * - the first arg isn't the flattened component name of an existing provider: 12864 * dump all providers whose component contains the first arg as a substring 12865 */ 12866 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12867 int opti, boolean dumpAll) { 12868 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12869 } 12870 12871 static class ItemMatcher { 12872 ArrayList<ComponentName> components; 12873 ArrayList<String> strings; 12874 ArrayList<Integer> objects; 12875 boolean all; 12876 12877 ItemMatcher() { 12878 all = true; 12879 } 12880 12881 void build(String name) { 12882 ComponentName componentName = ComponentName.unflattenFromString(name); 12883 if (componentName != null) { 12884 if (components == null) { 12885 components = new ArrayList<ComponentName>(); 12886 } 12887 components.add(componentName); 12888 all = false; 12889 } else { 12890 int objectId = 0; 12891 // Not a '/' separated full component name; maybe an object ID? 12892 try { 12893 objectId = Integer.parseInt(name, 16); 12894 if (objects == null) { 12895 objects = new ArrayList<Integer>(); 12896 } 12897 objects.add(objectId); 12898 all = false; 12899 } catch (RuntimeException e) { 12900 // Not an integer; just do string match. 12901 if (strings == null) { 12902 strings = new ArrayList<String>(); 12903 } 12904 strings.add(name); 12905 all = false; 12906 } 12907 } 12908 } 12909 12910 int build(String[] args, int opti) { 12911 for (; opti<args.length; opti++) { 12912 String name = args[opti]; 12913 if ("--".equals(name)) { 12914 return opti+1; 12915 } 12916 build(name); 12917 } 12918 return opti; 12919 } 12920 12921 boolean match(Object object, ComponentName comp) { 12922 if (all) { 12923 return true; 12924 } 12925 if (components != null) { 12926 for (int i=0; i<components.size(); i++) { 12927 if (components.get(i).equals(comp)) { 12928 return true; 12929 } 12930 } 12931 } 12932 if (objects != null) { 12933 for (int i=0; i<objects.size(); i++) { 12934 if (System.identityHashCode(object) == objects.get(i)) { 12935 return true; 12936 } 12937 } 12938 } 12939 if (strings != null) { 12940 String flat = comp.flattenToString(); 12941 for (int i=0; i<strings.size(); i++) { 12942 if (flat.contains(strings.get(i))) { 12943 return true; 12944 } 12945 } 12946 } 12947 return false; 12948 } 12949 } 12950 12951 /** 12952 * There are three things that cmd can be: 12953 * - a flattened component name that matches an existing activity 12954 * - the cmd arg isn't the flattened component name of an existing activity: 12955 * dump all activity whose component contains the cmd as a substring 12956 * - A hex number of the ActivityRecord object instance. 12957 */ 12958 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12959 int opti, boolean dumpAll) { 12960 ArrayList<ActivityRecord> activities; 12961 12962 synchronized (this) { 12963 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12964 } 12965 12966 if (activities.size() <= 0) { 12967 return false; 12968 } 12969 12970 String[] newArgs = new String[args.length - opti]; 12971 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12972 12973 TaskRecord lastTask = null; 12974 boolean needSep = false; 12975 for (int i=activities.size()-1; i>=0; i--) { 12976 ActivityRecord r = activities.get(i); 12977 if (needSep) { 12978 pw.println(); 12979 } 12980 needSep = true; 12981 synchronized (this) { 12982 if (lastTask != r.task) { 12983 lastTask = r.task; 12984 pw.print("TASK "); pw.print(lastTask.affinity); 12985 pw.print(" id="); pw.println(lastTask.taskId); 12986 if (dumpAll) { 12987 lastTask.dump(pw, " "); 12988 } 12989 } 12990 } 12991 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12992 } 12993 return true; 12994 } 12995 12996 /** 12997 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12998 * there is a thread associated with the activity. 12999 */ 13000 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13001 final ActivityRecord r, String[] args, boolean dumpAll) { 13002 String innerPrefix = prefix + " "; 13003 synchronized (this) { 13004 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13005 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13006 pw.print(" pid="); 13007 if (r.app != null) pw.println(r.app.pid); 13008 else pw.println("(not running)"); 13009 if (dumpAll) { 13010 r.dump(pw, innerPrefix); 13011 } 13012 } 13013 if (r.app != null && r.app.thread != null) { 13014 // flush anything that is already in the PrintWriter since the thread is going 13015 // to write to the file descriptor directly 13016 pw.flush(); 13017 try { 13018 TransferPipe tp = new TransferPipe(); 13019 try { 13020 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13021 r.appToken, innerPrefix, args); 13022 tp.go(fd); 13023 } finally { 13024 tp.kill(); 13025 } 13026 } catch (IOException e) { 13027 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13028 } catch (RemoteException e) { 13029 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13030 } 13031 } 13032 } 13033 13034 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13035 int opti, boolean dumpAll, String dumpPackage) { 13036 boolean needSep = false; 13037 boolean onlyHistory = false; 13038 boolean printedAnything = false; 13039 13040 if ("history".equals(dumpPackage)) { 13041 if (opti < args.length && "-s".equals(args[opti])) { 13042 dumpAll = false; 13043 } 13044 onlyHistory = true; 13045 dumpPackage = null; 13046 } 13047 13048 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13049 if (!onlyHistory && dumpAll) { 13050 if (mRegisteredReceivers.size() > 0) { 13051 boolean printed = false; 13052 Iterator it = mRegisteredReceivers.values().iterator(); 13053 while (it.hasNext()) { 13054 ReceiverList r = (ReceiverList)it.next(); 13055 if (dumpPackage != null && (r.app == null || 13056 !dumpPackage.equals(r.app.info.packageName))) { 13057 continue; 13058 } 13059 if (!printed) { 13060 pw.println(" Registered Receivers:"); 13061 needSep = true; 13062 printed = true; 13063 printedAnything = true; 13064 } 13065 pw.print(" * "); pw.println(r); 13066 r.dump(pw, " "); 13067 } 13068 } 13069 13070 if (mReceiverResolver.dump(pw, needSep ? 13071 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13072 " ", dumpPackage, false)) { 13073 needSep = true; 13074 printedAnything = true; 13075 } 13076 } 13077 13078 for (BroadcastQueue q : mBroadcastQueues) { 13079 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13080 printedAnything |= needSep; 13081 } 13082 13083 needSep = true; 13084 13085 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13086 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13087 if (needSep) { 13088 pw.println(); 13089 } 13090 needSep = true; 13091 printedAnything = true; 13092 pw.print(" Sticky broadcasts for user "); 13093 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13094 StringBuilder sb = new StringBuilder(128); 13095 for (Map.Entry<String, ArrayList<Intent>> ent 13096 : mStickyBroadcasts.valueAt(user).entrySet()) { 13097 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13098 if (dumpAll) { 13099 pw.println(":"); 13100 ArrayList<Intent> intents = ent.getValue(); 13101 final int N = intents.size(); 13102 for (int i=0; i<N; i++) { 13103 sb.setLength(0); 13104 sb.append(" Intent: "); 13105 intents.get(i).toShortString(sb, false, true, false, false); 13106 pw.println(sb.toString()); 13107 Bundle bundle = intents.get(i).getExtras(); 13108 if (bundle != null) { 13109 pw.print(" "); 13110 pw.println(bundle.toString()); 13111 } 13112 } 13113 } else { 13114 pw.println(""); 13115 } 13116 } 13117 } 13118 } 13119 13120 if (!onlyHistory && dumpAll) { 13121 pw.println(); 13122 for (BroadcastQueue queue : mBroadcastQueues) { 13123 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13124 + queue.mBroadcastsScheduled); 13125 } 13126 pw.println(" mHandler:"); 13127 mHandler.dump(new PrintWriterPrinter(pw), " "); 13128 needSep = true; 13129 printedAnything = true; 13130 } 13131 13132 if (!printedAnything) { 13133 pw.println(" (nothing)"); 13134 } 13135 } 13136 13137 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13138 int opti, boolean dumpAll, String dumpPackage) { 13139 boolean needSep; 13140 boolean printedAnything = false; 13141 13142 ItemMatcher matcher = new ItemMatcher(); 13143 matcher.build(args, opti); 13144 13145 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13146 13147 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13148 printedAnything |= needSep; 13149 13150 if (mLaunchingProviders.size() > 0) { 13151 boolean printed = false; 13152 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13153 ContentProviderRecord r = mLaunchingProviders.get(i); 13154 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13155 continue; 13156 } 13157 if (!printed) { 13158 if (needSep) pw.println(); 13159 needSep = true; 13160 pw.println(" Launching content providers:"); 13161 printed = true; 13162 printedAnything = true; 13163 } 13164 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13165 pw.println(r); 13166 } 13167 } 13168 13169 if (mGrantedUriPermissions.size() > 0) { 13170 boolean printed = false; 13171 int dumpUid = -2; 13172 if (dumpPackage != null) { 13173 try { 13174 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13175 } catch (NameNotFoundException e) { 13176 dumpUid = -1; 13177 } 13178 } 13179 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13180 int uid = mGrantedUriPermissions.keyAt(i); 13181 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13182 continue; 13183 } 13184 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13185 if (!printed) { 13186 if (needSep) pw.println(); 13187 needSep = true; 13188 pw.println(" Granted Uri Permissions:"); 13189 printed = true; 13190 printedAnything = true; 13191 } 13192 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13193 for (UriPermission perm : perms.values()) { 13194 pw.print(" "); pw.println(perm); 13195 if (dumpAll) { 13196 perm.dump(pw, " "); 13197 } 13198 } 13199 } 13200 } 13201 13202 if (!printedAnything) { 13203 pw.println(" (nothing)"); 13204 } 13205 } 13206 13207 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13208 int opti, boolean dumpAll, String dumpPackage) { 13209 boolean printed = false; 13210 13211 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13212 13213 if (mIntentSenderRecords.size() > 0) { 13214 Iterator<WeakReference<PendingIntentRecord>> it 13215 = mIntentSenderRecords.values().iterator(); 13216 while (it.hasNext()) { 13217 WeakReference<PendingIntentRecord> ref = it.next(); 13218 PendingIntentRecord rec = ref != null ? ref.get(): null; 13219 if (dumpPackage != null && (rec == null 13220 || !dumpPackage.equals(rec.key.packageName))) { 13221 continue; 13222 } 13223 printed = true; 13224 if (rec != null) { 13225 pw.print(" * "); pw.println(rec); 13226 if (dumpAll) { 13227 rec.dump(pw, " "); 13228 } 13229 } else { 13230 pw.print(" * "); pw.println(ref); 13231 } 13232 } 13233 } 13234 13235 if (!printed) { 13236 pw.println(" (nothing)"); 13237 } 13238 } 13239 13240 private static final int dumpProcessList(PrintWriter pw, 13241 ActivityManagerService service, List list, 13242 String prefix, String normalLabel, String persistentLabel, 13243 String dumpPackage) { 13244 int numPers = 0; 13245 final int N = list.size()-1; 13246 for (int i=N; i>=0; i--) { 13247 ProcessRecord r = (ProcessRecord)list.get(i); 13248 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13249 continue; 13250 } 13251 pw.println(String.format("%s%s #%2d: %s", 13252 prefix, (r.persistent ? persistentLabel : normalLabel), 13253 i, r.toString())); 13254 if (r.persistent) { 13255 numPers++; 13256 } 13257 } 13258 return numPers; 13259 } 13260 13261 private static final boolean dumpProcessOomList(PrintWriter pw, 13262 ActivityManagerService service, List<ProcessRecord> origList, 13263 String prefix, String normalLabel, String persistentLabel, 13264 boolean inclDetails, String dumpPackage) { 13265 13266 ArrayList<Pair<ProcessRecord, Integer>> list 13267 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13268 for (int i=0; i<origList.size(); i++) { 13269 ProcessRecord r = origList.get(i); 13270 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13271 continue; 13272 } 13273 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13274 } 13275 13276 if (list.size() <= 0) { 13277 return false; 13278 } 13279 13280 Comparator<Pair<ProcessRecord, Integer>> comparator 13281 = new Comparator<Pair<ProcessRecord, Integer>>() { 13282 @Override 13283 public int compare(Pair<ProcessRecord, Integer> object1, 13284 Pair<ProcessRecord, Integer> object2) { 13285 if (object1.first.setAdj != object2.first.setAdj) { 13286 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13287 } 13288 if (object1.second.intValue() != object2.second.intValue()) { 13289 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13290 } 13291 return 0; 13292 } 13293 }; 13294 13295 Collections.sort(list, comparator); 13296 13297 final long curRealtime = SystemClock.elapsedRealtime(); 13298 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13299 final long curUptime = SystemClock.uptimeMillis(); 13300 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13301 13302 for (int i=list.size()-1; i>=0; i--) { 13303 ProcessRecord r = list.get(i).first; 13304 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13305 char schedGroup; 13306 switch (r.setSchedGroup) { 13307 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13308 schedGroup = 'B'; 13309 break; 13310 case Process.THREAD_GROUP_DEFAULT: 13311 schedGroup = 'F'; 13312 break; 13313 default: 13314 schedGroup = '?'; 13315 break; 13316 } 13317 char foreground; 13318 if (r.foregroundActivities) { 13319 foreground = 'A'; 13320 } else if (r.foregroundServices) { 13321 foreground = 'S'; 13322 } else { 13323 foreground = ' '; 13324 } 13325 String procState = ProcessList.makeProcStateString(r.curProcState); 13326 pw.print(prefix); 13327 pw.print(r.persistent ? persistentLabel : normalLabel); 13328 pw.print(" #"); 13329 int num = (origList.size()-1)-list.get(i).second; 13330 if (num < 10) pw.print(' '); 13331 pw.print(num); 13332 pw.print(": "); 13333 pw.print(oomAdj); 13334 pw.print(' '); 13335 pw.print(schedGroup); 13336 pw.print('/'); 13337 pw.print(foreground); 13338 pw.print('/'); 13339 pw.print(procState); 13340 pw.print(" trm:"); 13341 if (r.trimMemoryLevel < 10) pw.print(' '); 13342 pw.print(r.trimMemoryLevel); 13343 pw.print(' '); 13344 pw.print(r.toShortString()); 13345 pw.print(" ("); 13346 pw.print(r.adjType); 13347 pw.println(')'); 13348 if (r.adjSource != null || r.adjTarget != null) { 13349 pw.print(prefix); 13350 pw.print(" "); 13351 if (r.adjTarget instanceof ComponentName) { 13352 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13353 } else if (r.adjTarget != null) { 13354 pw.print(r.adjTarget.toString()); 13355 } else { 13356 pw.print("{null}"); 13357 } 13358 pw.print("<="); 13359 if (r.adjSource instanceof ProcessRecord) { 13360 pw.print("Proc{"); 13361 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13362 pw.println("}"); 13363 } else if (r.adjSource != null) { 13364 pw.println(r.adjSource.toString()); 13365 } else { 13366 pw.println("{null}"); 13367 } 13368 } 13369 if (inclDetails) { 13370 pw.print(prefix); 13371 pw.print(" "); 13372 pw.print("oom: max="); pw.print(r.maxAdj); 13373 pw.print(" curRaw="); pw.print(r.curRawAdj); 13374 pw.print(" setRaw="); pw.print(r.setRawAdj); 13375 pw.print(" cur="); pw.print(r.curAdj); 13376 pw.print(" set="); pw.println(r.setAdj); 13377 pw.print(prefix); 13378 pw.print(" "); 13379 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13380 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13381 pw.print(" lastPss="); pw.print(r.lastPss); 13382 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13383 pw.print(prefix); 13384 pw.print(" "); 13385 pw.print("cached="); pw.print(r.cached); 13386 pw.print(" empty="); pw.print(r.empty); 13387 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13388 13389 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13390 if (r.lastWakeTime != 0) { 13391 long wtime; 13392 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13393 synchronized (stats) { 13394 wtime = stats.getProcessWakeTime(r.info.uid, 13395 r.pid, curRealtime); 13396 } 13397 long timeUsed = wtime - r.lastWakeTime; 13398 pw.print(prefix); 13399 pw.print(" "); 13400 pw.print("keep awake over "); 13401 TimeUtils.formatDuration(realtimeSince, pw); 13402 pw.print(" used "); 13403 TimeUtils.formatDuration(timeUsed, pw); 13404 pw.print(" ("); 13405 pw.print((timeUsed*100)/realtimeSince); 13406 pw.println("%)"); 13407 } 13408 if (r.lastCpuTime != 0) { 13409 long timeUsed = r.curCpuTime - r.lastCpuTime; 13410 pw.print(prefix); 13411 pw.print(" "); 13412 pw.print("run cpu over "); 13413 TimeUtils.formatDuration(uptimeSince, pw); 13414 pw.print(" used "); 13415 TimeUtils.formatDuration(timeUsed, pw); 13416 pw.print(" ("); 13417 pw.print((timeUsed*100)/uptimeSince); 13418 pw.println("%)"); 13419 } 13420 } 13421 } 13422 } 13423 return true; 13424 } 13425 13426 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13427 ArrayList<ProcessRecord> procs; 13428 synchronized (this) { 13429 if (args != null && args.length > start 13430 && args[start].charAt(0) != '-') { 13431 procs = new ArrayList<ProcessRecord>(); 13432 int pid = -1; 13433 try { 13434 pid = Integer.parseInt(args[start]); 13435 } catch (NumberFormatException e) { 13436 } 13437 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13438 ProcessRecord proc = mLruProcesses.get(i); 13439 if (proc.pid == pid) { 13440 procs.add(proc); 13441 } else if (proc.processName.equals(args[start])) { 13442 procs.add(proc); 13443 } 13444 } 13445 if (procs.size() <= 0) { 13446 return null; 13447 } 13448 } else { 13449 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13450 } 13451 } 13452 return procs; 13453 } 13454 13455 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13456 PrintWriter pw, String[] args) { 13457 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13458 if (procs == null) { 13459 pw.println("No process found for: " + args[0]); 13460 return; 13461 } 13462 13463 long uptime = SystemClock.uptimeMillis(); 13464 long realtime = SystemClock.elapsedRealtime(); 13465 pw.println("Applications Graphics Acceleration Info:"); 13466 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13467 13468 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13469 ProcessRecord r = procs.get(i); 13470 if (r.thread != null) { 13471 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13472 pw.flush(); 13473 try { 13474 TransferPipe tp = new TransferPipe(); 13475 try { 13476 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13477 tp.go(fd); 13478 } finally { 13479 tp.kill(); 13480 } 13481 } catch (IOException e) { 13482 pw.println("Failure while dumping the app: " + r); 13483 pw.flush(); 13484 } catch (RemoteException e) { 13485 pw.println("Got a RemoteException while dumping the app " + r); 13486 pw.flush(); 13487 } 13488 } 13489 } 13490 } 13491 13492 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13493 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13494 if (procs == null) { 13495 pw.println("No process found for: " + args[0]); 13496 return; 13497 } 13498 13499 pw.println("Applications Database Info:"); 13500 13501 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13502 ProcessRecord r = procs.get(i); 13503 if (r.thread != null) { 13504 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13505 pw.flush(); 13506 try { 13507 TransferPipe tp = new TransferPipe(); 13508 try { 13509 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13510 tp.go(fd); 13511 } finally { 13512 tp.kill(); 13513 } 13514 } catch (IOException e) { 13515 pw.println("Failure while dumping the app: " + r); 13516 pw.flush(); 13517 } catch (RemoteException e) { 13518 pw.println("Got a RemoteException while dumping the app " + r); 13519 pw.flush(); 13520 } 13521 } 13522 } 13523 } 13524 13525 final static class MemItem { 13526 final boolean isProc; 13527 final String label; 13528 final String shortLabel; 13529 final long pss; 13530 final int id; 13531 final boolean hasActivities; 13532 ArrayList<MemItem> subitems; 13533 13534 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13535 boolean _hasActivities) { 13536 isProc = true; 13537 label = _label; 13538 shortLabel = _shortLabel; 13539 pss = _pss; 13540 id = _id; 13541 hasActivities = _hasActivities; 13542 } 13543 13544 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13545 isProc = false; 13546 label = _label; 13547 shortLabel = _shortLabel; 13548 pss = _pss; 13549 id = _id; 13550 hasActivities = false; 13551 } 13552 } 13553 13554 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13555 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13556 if (sort && !isCompact) { 13557 Collections.sort(items, new Comparator<MemItem>() { 13558 @Override 13559 public int compare(MemItem lhs, MemItem rhs) { 13560 if (lhs.pss < rhs.pss) { 13561 return 1; 13562 } else if (lhs.pss > rhs.pss) { 13563 return -1; 13564 } 13565 return 0; 13566 } 13567 }); 13568 } 13569 13570 for (int i=0; i<items.size(); i++) { 13571 MemItem mi = items.get(i); 13572 if (!isCompact) { 13573 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13574 } else if (mi.isProc) { 13575 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13576 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13577 pw.println(mi.hasActivities ? ",a" : ",e"); 13578 } else { 13579 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13580 pw.println(mi.pss); 13581 } 13582 if (mi.subitems != null) { 13583 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13584 true, isCompact); 13585 } 13586 } 13587 } 13588 13589 // These are in KB. 13590 static final long[] DUMP_MEM_BUCKETS = new long[] { 13591 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13592 120*1024, 160*1024, 200*1024, 13593 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13594 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13595 }; 13596 13597 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13598 boolean stackLike) { 13599 int start = label.lastIndexOf('.'); 13600 if (start >= 0) start++; 13601 else start = 0; 13602 int end = label.length(); 13603 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13604 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13605 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13606 out.append(bucket); 13607 out.append(stackLike ? "MB." : "MB "); 13608 out.append(label, start, end); 13609 return; 13610 } 13611 } 13612 out.append(memKB/1024); 13613 out.append(stackLike ? "MB." : "MB "); 13614 out.append(label, start, end); 13615 } 13616 13617 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13618 ProcessList.NATIVE_ADJ, 13619 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13620 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13621 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13622 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13623 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13624 }; 13625 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13626 "Native", 13627 "System", "Persistent", "Foreground", 13628 "Visible", "Perceptible", 13629 "Heavy Weight", "Backup", 13630 "A Services", "Home", 13631 "Previous", "B Services", "Cached" 13632 }; 13633 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13634 "native", 13635 "sys", "pers", "fore", 13636 "vis", "percept", 13637 "heavy", "backup", 13638 "servicea", "home", 13639 "prev", "serviceb", "cached" 13640 }; 13641 13642 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13643 long realtime, boolean isCheckinRequest, boolean isCompact) { 13644 if (isCheckinRequest || isCompact) { 13645 // short checkin version 13646 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13647 } else { 13648 pw.println("Applications Memory Usage (kB):"); 13649 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13650 } 13651 } 13652 13653 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13654 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13655 boolean dumpDetails = false; 13656 boolean dumpFullDetails = false; 13657 boolean dumpDalvik = false; 13658 boolean oomOnly = false; 13659 boolean isCompact = false; 13660 boolean localOnly = false; 13661 13662 int opti = 0; 13663 while (opti < args.length) { 13664 String opt = args[opti]; 13665 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13666 break; 13667 } 13668 opti++; 13669 if ("-a".equals(opt)) { 13670 dumpDetails = true; 13671 dumpFullDetails = true; 13672 dumpDalvik = true; 13673 } else if ("-d".equals(opt)) { 13674 dumpDalvik = true; 13675 } else if ("-c".equals(opt)) { 13676 isCompact = true; 13677 } else if ("--oom".equals(opt)) { 13678 oomOnly = true; 13679 } else if ("--local".equals(opt)) { 13680 localOnly = true; 13681 } else if ("-h".equals(opt)) { 13682 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13683 pw.println(" -a: include all available information for each process."); 13684 pw.println(" -d: include dalvik details when dumping process details."); 13685 pw.println(" -c: dump in a compact machine-parseable representation."); 13686 pw.println(" --oom: only show processes organized by oom adj."); 13687 pw.println(" --local: only collect details locally, don't call process."); 13688 pw.println("If [process] is specified it can be the name or "); 13689 pw.println("pid of a specific process to dump."); 13690 return; 13691 } else { 13692 pw.println("Unknown argument: " + opt + "; use -h for help"); 13693 } 13694 } 13695 13696 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13697 long uptime = SystemClock.uptimeMillis(); 13698 long realtime = SystemClock.elapsedRealtime(); 13699 final long[] tmpLong = new long[1]; 13700 13701 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13702 if (procs == null) { 13703 // No Java processes. Maybe they want to print a native process. 13704 if (args != null && args.length > opti 13705 && args[opti].charAt(0) != '-') { 13706 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13707 = new ArrayList<ProcessCpuTracker.Stats>(); 13708 updateCpuStatsNow(); 13709 int findPid = -1; 13710 try { 13711 findPid = Integer.parseInt(args[opti]); 13712 } catch (NumberFormatException e) { 13713 } 13714 synchronized (mProcessCpuThread) { 13715 final int N = mProcessCpuTracker.countStats(); 13716 for (int i=0; i<N; i++) { 13717 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13718 if (st.pid == findPid || (st.baseName != null 13719 && st.baseName.equals(args[opti]))) { 13720 nativeProcs.add(st); 13721 } 13722 } 13723 } 13724 if (nativeProcs.size() > 0) { 13725 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13726 isCompact); 13727 Debug.MemoryInfo mi = null; 13728 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13729 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13730 final int pid = r.pid; 13731 if (!isCheckinRequest && dumpDetails) { 13732 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13733 } 13734 if (mi == null) { 13735 mi = new Debug.MemoryInfo(); 13736 } 13737 if (dumpDetails || (!brief && !oomOnly)) { 13738 Debug.getMemoryInfo(pid, mi); 13739 } else { 13740 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13741 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13742 } 13743 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13744 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13745 if (isCheckinRequest) { 13746 pw.println(); 13747 } 13748 } 13749 return; 13750 } 13751 } 13752 pw.println("No process found for: " + args[opti]); 13753 return; 13754 } 13755 13756 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13757 dumpDetails = true; 13758 } 13759 13760 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13761 13762 String[] innerArgs = new String[args.length-opti]; 13763 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13764 13765 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13766 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13767 long nativePss=0, dalvikPss=0, otherPss=0; 13768 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13769 13770 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13771 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13772 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13773 13774 long totalPss = 0; 13775 long cachedPss = 0; 13776 13777 Debug.MemoryInfo mi = null; 13778 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13779 final ProcessRecord r = procs.get(i); 13780 final IApplicationThread thread; 13781 final int pid; 13782 final int oomAdj; 13783 final boolean hasActivities; 13784 synchronized (this) { 13785 thread = r.thread; 13786 pid = r.pid; 13787 oomAdj = r.getSetAdjWithServices(); 13788 hasActivities = r.activities.size() > 0; 13789 } 13790 if (thread != null) { 13791 if (!isCheckinRequest && dumpDetails) { 13792 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13793 } 13794 if (mi == null) { 13795 mi = new Debug.MemoryInfo(); 13796 } 13797 if (dumpDetails || (!brief && !oomOnly)) { 13798 Debug.getMemoryInfo(pid, mi); 13799 } else { 13800 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13801 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13802 } 13803 if (dumpDetails) { 13804 if (localOnly) { 13805 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13806 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13807 if (isCheckinRequest) { 13808 pw.println(); 13809 } 13810 } else { 13811 try { 13812 pw.flush(); 13813 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13814 dumpDalvik, innerArgs); 13815 } catch (RemoteException e) { 13816 if (!isCheckinRequest) { 13817 pw.println("Got RemoteException!"); 13818 pw.flush(); 13819 } 13820 } 13821 } 13822 } 13823 13824 final long myTotalPss = mi.getTotalPss(); 13825 final long myTotalUss = mi.getTotalUss(); 13826 13827 synchronized (this) { 13828 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13829 // Record this for posterity if the process has been stable. 13830 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13831 } 13832 } 13833 13834 if (!isCheckinRequest && mi != null) { 13835 totalPss += myTotalPss; 13836 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13837 (hasActivities ? " / activities)" : ")"), 13838 r.processName, myTotalPss, pid, hasActivities); 13839 procMems.add(pssItem); 13840 procMemsMap.put(pid, pssItem); 13841 13842 nativePss += mi.nativePss; 13843 dalvikPss += mi.dalvikPss; 13844 otherPss += mi.otherPss; 13845 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13846 long mem = mi.getOtherPss(j); 13847 miscPss[j] += mem; 13848 otherPss -= mem; 13849 } 13850 13851 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13852 cachedPss += myTotalPss; 13853 } 13854 13855 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13856 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13857 || oomIndex == (oomPss.length-1)) { 13858 oomPss[oomIndex] += myTotalPss; 13859 if (oomProcs[oomIndex] == null) { 13860 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13861 } 13862 oomProcs[oomIndex].add(pssItem); 13863 break; 13864 } 13865 } 13866 } 13867 } 13868 } 13869 13870 long nativeProcTotalPss = 0; 13871 13872 if (!isCheckinRequest && procs.size() > 1) { 13873 // If we are showing aggregations, also look for native processes to 13874 // include so that our aggregations are more accurate. 13875 updateCpuStatsNow(); 13876 synchronized (mProcessCpuThread) { 13877 final int N = mProcessCpuTracker.countStats(); 13878 for (int i=0; i<N; i++) { 13879 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13880 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13881 if (mi == null) { 13882 mi = new Debug.MemoryInfo(); 13883 } 13884 if (!brief && !oomOnly) { 13885 Debug.getMemoryInfo(st.pid, mi); 13886 } else { 13887 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13888 mi.nativePrivateDirty = (int)tmpLong[0]; 13889 } 13890 13891 final long myTotalPss = mi.getTotalPss(); 13892 totalPss += myTotalPss; 13893 nativeProcTotalPss += myTotalPss; 13894 13895 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13896 st.name, myTotalPss, st.pid, false); 13897 procMems.add(pssItem); 13898 13899 nativePss += mi.nativePss; 13900 dalvikPss += mi.dalvikPss; 13901 otherPss += mi.otherPss; 13902 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13903 long mem = mi.getOtherPss(j); 13904 miscPss[j] += mem; 13905 otherPss -= mem; 13906 } 13907 oomPss[0] += myTotalPss; 13908 if (oomProcs[0] == null) { 13909 oomProcs[0] = new ArrayList<MemItem>(); 13910 } 13911 oomProcs[0].add(pssItem); 13912 } 13913 } 13914 } 13915 13916 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13917 13918 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13919 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13920 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13921 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13922 String label = Debug.MemoryInfo.getOtherLabel(j); 13923 catMems.add(new MemItem(label, label, miscPss[j], j)); 13924 } 13925 13926 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13927 for (int j=0; j<oomPss.length; j++) { 13928 if (oomPss[j] != 0) { 13929 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13930 : DUMP_MEM_OOM_LABEL[j]; 13931 MemItem item = new MemItem(label, label, oomPss[j], 13932 DUMP_MEM_OOM_ADJ[j]); 13933 item.subitems = oomProcs[j]; 13934 oomMems.add(item); 13935 } 13936 } 13937 13938 if (!brief && !oomOnly && !isCompact) { 13939 pw.println(); 13940 pw.println("Total PSS by process:"); 13941 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13942 pw.println(); 13943 } 13944 if (!isCompact) { 13945 pw.println("Total PSS by OOM adjustment:"); 13946 } 13947 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13948 if (!brief && !oomOnly) { 13949 PrintWriter out = categoryPw != null ? categoryPw : pw; 13950 if (!isCompact) { 13951 out.println(); 13952 out.println("Total PSS by category:"); 13953 } 13954 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13955 } 13956 if (!isCompact) { 13957 pw.println(); 13958 } 13959 MemInfoReader memInfo = new MemInfoReader(); 13960 memInfo.readMemInfo(); 13961 if (nativeProcTotalPss > 0) { 13962 synchronized (this) { 13963 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13964 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13965 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13966 nativeProcTotalPss); 13967 } 13968 } 13969 if (!brief) { 13970 if (!isCompact) { 13971 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13972 pw.print(" kB (status "); 13973 switch (mLastMemoryLevel) { 13974 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13975 pw.println("normal)"); 13976 break; 13977 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13978 pw.println("moderate)"); 13979 break; 13980 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13981 pw.println("low)"); 13982 break; 13983 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13984 pw.println("critical)"); 13985 break; 13986 default: 13987 pw.print(mLastMemoryLevel); 13988 pw.println(")"); 13989 break; 13990 } 13991 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13992 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13993 pw.print(cachedPss); pw.print(" cached pss + "); 13994 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13995 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13996 } else { 13997 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13998 pw.print(cachedPss + memInfo.getCachedSizeKb() 13999 + memInfo.getFreeSizeKb()); pw.print(","); 14000 pw.println(totalPss - cachedPss); 14001 } 14002 } 14003 if (!isCompact) { 14004 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14005 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14006 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14007 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14008 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14009 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14010 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14011 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14012 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14013 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14014 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14015 } 14016 if (!brief) { 14017 if (memInfo.getZramTotalSizeKb() != 0) { 14018 if (!isCompact) { 14019 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14020 pw.print(" kB physical used for "); 14021 pw.print(memInfo.getSwapTotalSizeKb() 14022 - memInfo.getSwapFreeSizeKb()); 14023 pw.print(" kB in swap ("); 14024 pw.print(memInfo.getSwapTotalSizeKb()); 14025 pw.println(" kB total swap)"); 14026 } else { 14027 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14028 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14029 pw.println(memInfo.getSwapFreeSizeKb()); 14030 } 14031 } 14032 final int[] SINGLE_LONG_FORMAT = new int[] { 14033 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14034 }; 14035 long[] longOut = new long[1]; 14036 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14037 SINGLE_LONG_FORMAT, null, longOut, null); 14038 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14039 longOut[0] = 0; 14040 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14041 SINGLE_LONG_FORMAT, null, longOut, null); 14042 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14043 longOut[0] = 0; 14044 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14045 SINGLE_LONG_FORMAT, null, longOut, null); 14046 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14047 longOut[0] = 0; 14048 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14049 SINGLE_LONG_FORMAT, null, longOut, null); 14050 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14051 if (!isCompact) { 14052 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14053 pw.print(" KSM: "); pw.print(sharing); 14054 pw.print(" kB saved from shared "); 14055 pw.print(shared); pw.println(" kB"); 14056 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14057 pw.print(voltile); pw.println(" kB volatile"); 14058 } 14059 pw.print(" Tuning: "); 14060 pw.print(ActivityManager.staticGetMemoryClass()); 14061 pw.print(" (large "); 14062 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14063 pw.print("), oom "); 14064 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14065 pw.print(" kB"); 14066 pw.print(", restore limit "); 14067 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14068 pw.print(" kB"); 14069 if (ActivityManager.isLowRamDeviceStatic()) { 14070 pw.print(" (low-ram)"); 14071 } 14072 if (ActivityManager.isHighEndGfx()) { 14073 pw.print(" (high-end-gfx)"); 14074 } 14075 pw.println(); 14076 } else { 14077 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14078 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14079 pw.println(voltile); 14080 pw.print("tuning,"); 14081 pw.print(ActivityManager.staticGetMemoryClass()); 14082 pw.print(','); 14083 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14084 pw.print(','); 14085 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14086 if (ActivityManager.isLowRamDeviceStatic()) { 14087 pw.print(",low-ram"); 14088 } 14089 if (ActivityManager.isHighEndGfx()) { 14090 pw.print(",high-end-gfx"); 14091 } 14092 pw.println(); 14093 } 14094 } 14095 } 14096 } 14097 14098 /** 14099 * Searches array of arguments for the specified string 14100 * @param args array of argument strings 14101 * @param value value to search for 14102 * @return true if the value is contained in the array 14103 */ 14104 private static boolean scanArgs(String[] args, String value) { 14105 if (args != null) { 14106 for (String arg : args) { 14107 if (value.equals(arg)) { 14108 return true; 14109 } 14110 } 14111 } 14112 return false; 14113 } 14114 14115 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14116 ContentProviderRecord cpr, boolean always) { 14117 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14118 14119 if (!inLaunching || always) { 14120 synchronized (cpr) { 14121 cpr.launchingApp = null; 14122 cpr.notifyAll(); 14123 } 14124 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14125 String names[] = cpr.info.authority.split(";"); 14126 for (int j = 0; j < names.length; j++) { 14127 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14128 } 14129 } 14130 14131 for (int i=0; i<cpr.connections.size(); i++) { 14132 ContentProviderConnection conn = cpr.connections.get(i); 14133 if (conn.waiting) { 14134 // If this connection is waiting for the provider, then we don't 14135 // need to mess with its process unless we are always removing 14136 // or for some reason the provider is not currently launching. 14137 if (inLaunching && !always) { 14138 continue; 14139 } 14140 } 14141 ProcessRecord capp = conn.client; 14142 conn.dead = true; 14143 if (conn.stableCount > 0) { 14144 if (!capp.persistent && capp.thread != null 14145 && capp.pid != 0 14146 && capp.pid != MY_PID) { 14147 capp.kill("depends on provider " 14148 + cpr.name.flattenToShortString() 14149 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14150 } 14151 } else if (capp.thread != null && conn.provider.provider != null) { 14152 try { 14153 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14154 } catch (RemoteException e) { 14155 } 14156 // In the protocol here, we don't expect the client to correctly 14157 // clean up this connection, we'll just remove it. 14158 cpr.connections.remove(i); 14159 conn.client.conProviders.remove(conn); 14160 } 14161 } 14162 14163 if (inLaunching && always) { 14164 mLaunchingProviders.remove(cpr); 14165 } 14166 return inLaunching; 14167 } 14168 14169 /** 14170 * Main code for cleaning up a process when it has gone away. This is 14171 * called both as a result of the process dying, or directly when stopping 14172 * a process when running in single process mode. 14173 */ 14174 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14175 boolean restarting, boolean allowRestart, int index) { 14176 if (index >= 0) { 14177 removeLruProcessLocked(app); 14178 ProcessList.remove(app.pid); 14179 } 14180 14181 mProcessesToGc.remove(app); 14182 mPendingPssProcesses.remove(app); 14183 14184 // Dismiss any open dialogs. 14185 if (app.crashDialog != null && !app.forceCrashReport) { 14186 app.crashDialog.dismiss(); 14187 app.crashDialog = null; 14188 } 14189 if (app.anrDialog != null) { 14190 app.anrDialog.dismiss(); 14191 app.anrDialog = null; 14192 } 14193 if (app.waitDialog != null) { 14194 app.waitDialog.dismiss(); 14195 app.waitDialog = null; 14196 } 14197 14198 app.crashing = false; 14199 app.notResponding = false; 14200 14201 app.resetPackageList(mProcessStats); 14202 app.unlinkDeathRecipient(); 14203 app.makeInactive(mProcessStats); 14204 app.waitingToKill = null; 14205 app.forcingToForeground = null; 14206 updateProcessForegroundLocked(app, false, false); 14207 app.foregroundActivities = false; 14208 app.hasShownUi = false; 14209 app.treatLikeActivity = false; 14210 app.hasAboveClient = false; 14211 app.hasClientActivities = false; 14212 14213 mServices.killServicesLocked(app, allowRestart); 14214 14215 boolean restart = false; 14216 14217 // Remove published content providers. 14218 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14219 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14220 final boolean always = app.bad || !allowRestart; 14221 if (removeDyingProviderLocked(app, cpr, always) || always) { 14222 // We left the provider in the launching list, need to 14223 // restart it. 14224 restart = true; 14225 } 14226 14227 cpr.provider = null; 14228 cpr.proc = null; 14229 } 14230 app.pubProviders.clear(); 14231 14232 // Take care of any launching providers waiting for this process. 14233 if (checkAppInLaunchingProvidersLocked(app, false)) { 14234 restart = true; 14235 } 14236 14237 // Unregister from connected content providers. 14238 if (!app.conProviders.isEmpty()) { 14239 for (int i=0; i<app.conProviders.size(); i++) { 14240 ContentProviderConnection conn = app.conProviders.get(i); 14241 conn.provider.connections.remove(conn); 14242 } 14243 app.conProviders.clear(); 14244 } 14245 14246 // At this point there may be remaining entries in mLaunchingProviders 14247 // where we were the only one waiting, so they are no longer of use. 14248 // Look for these and clean up if found. 14249 // XXX Commented out for now. Trying to figure out a way to reproduce 14250 // the actual situation to identify what is actually going on. 14251 if (false) { 14252 for (int i=0; i<mLaunchingProviders.size(); i++) { 14253 ContentProviderRecord cpr = (ContentProviderRecord) 14254 mLaunchingProviders.get(i); 14255 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14256 synchronized (cpr) { 14257 cpr.launchingApp = null; 14258 cpr.notifyAll(); 14259 } 14260 } 14261 } 14262 } 14263 14264 skipCurrentReceiverLocked(app); 14265 14266 // Unregister any receivers. 14267 for (int i=app.receivers.size()-1; i>=0; i--) { 14268 removeReceiverLocked(app.receivers.valueAt(i)); 14269 } 14270 app.receivers.clear(); 14271 14272 // If the app is undergoing backup, tell the backup manager about it 14273 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14274 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14275 + mBackupTarget.appInfo + " died during backup"); 14276 try { 14277 IBackupManager bm = IBackupManager.Stub.asInterface( 14278 ServiceManager.getService(Context.BACKUP_SERVICE)); 14279 bm.agentDisconnected(app.info.packageName); 14280 } catch (RemoteException e) { 14281 // can't happen; backup manager is local 14282 } 14283 } 14284 14285 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14286 ProcessChangeItem item = mPendingProcessChanges.get(i); 14287 if (item.pid == app.pid) { 14288 mPendingProcessChanges.remove(i); 14289 mAvailProcessChanges.add(item); 14290 } 14291 } 14292 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14293 14294 // If the caller is restarting this app, then leave it in its 14295 // current lists and let the caller take care of it. 14296 if (restarting) { 14297 return; 14298 } 14299 14300 if (!app.persistent || app.isolated) { 14301 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14302 "Removing non-persistent process during cleanup: " + app); 14303 mProcessNames.remove(app.processName, app.uid); 14304 mIsolatedProcesses.remove(app.uid); 14305 if (mHeavyWeightProcess == app) { 14306 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14307 mHeavyWeightProcess.userId, 0)); 14308 mHeavyWeightProcess = null; 14309 } 14310 } else if (!app.removed) { 14311 // This app is persistent, so we need to keep its record around. 14312 // If it is not already on the pending app list, add it there 14313 // and start a new process for it. 14314 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14315 mPersistentStartingProcesses.add(app); 14316 restart = true; 14317 } 14318 } 14319 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14320 "Clean-up removing on hold: " + app); 14321 mProcessesOnHold.remove(app); 14322 14323 if (app == mHomeProcess) { 14324 mHomeProcess = null; 14325 } 14326 if (app == mPreviousProcess) { 14327 mPreviousProcess = null; 14328 } 14329 14330 if (restart && !app.isolated) { 14331 // We have components that still need to be running in the 14332 // process, so re-launch it. 14333 mProcessNames.put(app.processName, app.uid, app); 14334 startProcessLocked(app, "restart", app.processName); 14335 } else if (app.pid > 0 && app.pid != MY_PID) { 14336 // Goodbye! 14337 boolean removed; 14338 synchronized (mPidsSelfLocked) { 14339 mPidsSelfLocked.remove(app.pid); 14340 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14341 } 14342 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14343 if (app.isolated) { 14344 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14345 } 14346 app.setPid(0); 14347 } 14348 } 14349 14350 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14351 // Look through the content providers we are waiting to have launched, 14352 // and if any run in this process then either schedule a restart of 14353 // the process or kill the client waiting for it if this process has 14354 // gone bad. 14355 int NL = mLaunchingProviders.size(); 14356 boolean restart = false; 14357 for (int i=0; i<NL; i++) { 14358 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14359 if (cpr.launchingApp == app) { 14360 if (!alwaysBad && !app.bad) { 14361 restart = true; 14362 } else { 14363 removeDyingProviderLocked(app, cpr, true); 14364 // cpr should have been removed from mLaunchingProviders 14365 NL = mLaunchingProviders.size(); 14366 i--; 14367 } 14368 } 14369 } 14370 return restart; 14371 } 14372 14373 // ========================================================= 14374 // SERVICES 14375 // ========================================================= 14376 14377 @Override 14378 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14379 int flags) { 14380 enforceNotIsolatedCaller("getServices"); 14381 synchronized (this) { 14382 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14383 } 14384 } 14385 14386 @Override 14387 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14388 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14389 synchronized (this) { 14390 return mServices.getRunningServiceControlPanelLocked(name); 14391 } 14392 } 14393 14394 @Override 14395 public ComponentName startService(IApplicationThread caller, Intent service, 14396 String resolvedType, int userId) { 14397 enforceNotIsolatedCaller("startService"); 14398 // Refuse possible leaked file descriptors 14399 if (service != null && service.hasFileDescriptors() == true) { 14400 throw new IllegalArgumentException("File descriptors passed in Intent"); 14401 } 14402 14403 if (DEBUG_SERVICE) 14404 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14405 synchronized(this) { 14406 final int callingPid = Binder.getCallingPid(); 14407 final int callingUid = Binder.getCallingUid(); 14408 final long origId = Binder.clearCallingIdentity(); 14409 ComponentName res = mServices.startServiceLocked(caller, service, 14410 resolvedType, callingPid, callingUid, userId); 14411 Binder.restoreCallingIdentity(origId); 14412 return res; 14413 } 14414 } 14415 14416 ComponentName startServiceInPackage(int uid, 14417 Intent service, String resolvedType, int userId) { 14418 synchronized(this) { 14419 if (DEBUG_SERVICE) 14420 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14421 final long origId = Binder.clearCallingIdentity(); 14422 ComponentName res = mServices.startServiceLocked(null, service, 14423 resolvedType, -1, uid, userId); 14424 Binder.restoreCallingIdentity(origId); 14425 return res; 14426 } 14427 } 14428 14429 @Override 14430 public int stopService(IApplicationThread caller, Intent service, 14431 String resolvedType, int userId) { 14432 enforceNotIsolatedCaller("stopService"); 14433 // Refuse possible leaked file descriptors 14434 if (service != null && service.hasFileDescriptors() == true) { 14435 throw new IllegalArgumentException("File descriptors passed in Intent"); 14436 } 14437 14438 synchronized(this) { 14439 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14440 } 14441 } 14442 14443 @Override 14444 public IBinder peekService(Intent service, String resolvedType) { 14445 enforceNotIsolatedCaller("peekService"); 14446 // Refuse possible leaked file descriptors 14447 if (service != null && service.hasFileDescriptors() == true) { 14448 throw new IllegalArgumentException("File descriptors passed in Intent"); 14449 } 14450 synchronized(this) { 14451 return mServices.peekServiceLocked(service, resolvedType); 14452 } 14453 } 14454 14455 @Override 14456 public boolean stopServiceToken(ComponentName className, IBinder token, 14457 int startId) { 14458 synchronized(this) { 14459 return mServices.stopServiceTokenLocked(className, token, startId); 14460 } 14461 } 14462 14463 @Override 14464 public void setServiceForeground(ComponentName className, IBinder token, 14465 int id, Notification notification, boolean removeNotification) { 14466 synchronized(this) { 14467 mServices.setServiceForegroundLocked(className, token, id, notification, 14468 removeNotification); 14469 } 14470 } 14471 14472 @Override 14473 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14474 boolean requireFull, String name, String callerPackage) { 14475 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14476 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14477 } 14478 14479 int unsafeConvertIncomingUser(int userId) { 14480 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14481 ? mCurrentUserId : userId; 14482 } 14483 14484 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14485 int allowMode, String name, String callerPackage) { 14486 final int callingUserId = UserHandle.getUserId(callingUid); 14487 if (callingUserId == userId) { 14488 return userId; 14489 } 14490 14491 // Note that we may be accessing mCurrentUserId outside of a lock... 14492 // shouldn't be a big deal, if this is being called outside 14493 // of a locked context there is intrinsically a race with 14494 // the value the caller will receive and someone else changing it. 14495 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14496 // we will switch to the calling user if access to the current user fails. 14497 int targetUserId = unsafeConvertIncomingUser(userId); 14498 14499 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14500 final boolean allow; 14501 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14502 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14503 // If the caller has this permission, they always pass go. And collect $200. 14504 allow = true; 14505 } else if (allowMode == ALLOW_FULL_ONLY) { 14506 // We require full access, sucks to be you. 14507 allow = false; 14508 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14509 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14510 // If the caller does not have either permission, they are always doomed. 14511 allow = false; 14512 } else if (allowMode == ALLOW_NON_FULL) { 14513 // We are blanket allowing non-full access, you lucky caller! 14514 allow = true; 14515 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14516 // We may or may not allow this depending on whether the two users are 14517 // in the same profile. 14518 synchronized (mUserProfileGroupIdsSelfLocked) { 14519 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14520 UserInfo.NO_PROFILE_GROUP_ID); 14521 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14522 UserInfo.NO_PROFILE_GROUP_ID); 14523 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14524 && callingProfile == targetProfile; 14525 } 14526 } else { 14527 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14528 } 14529 if (!allow) { 14530 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14531 // In this case, they would like to just execute as their 14532 // owner user instead of failing. 14533 targetUserId = callingUserId; 14534 } else { 14535 StringBuilder builder = new StringBuilder(128); 14536 builder.append("Permission Denial: "); 14537 builder.append(name); 14538 if (callerPackage != null) { 14539 builder.append(" from "); 14540 builder.append(callerPackage); 14541 } 14542 builder.append(" asks to run as user "); 14543 builder.append(userId); 14544 builder.append(" but is calling from user "); 14545 builder.append(UserHandle.getUserId(callingUid)); 14546 builder.append("; this requires "); 14547 builder.append(INTERACT_ACROSS_USERS_FULL); 14548 if (allowMode != ALLOW_FULL_ONLY) { 14549 builder.append(" or "); 14550 builder.append(INTERACT_ACROSS_USERS); 14551 } 14552 String msg = builder.toString(); 14553 Slog.w(TAG, msg); 14554 throw new SecurityException(msg); 14555 } 14556 } 14557 } 14558 if (!allowAll && targetUserId < 0) { 14559 throw new IllegalArgumentException( 14560 "Call does not support special user #" + targetUserId); 14561 } 14562 // Check shell permission 14563 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14564 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14565 targetUserId)) { 14566 throw new SecurityException("Shell does not have permission to access user " 14567 + targetUserId + "\n " + Debug.getCallers(3)); 14568 } 14569 } 14570 return targetUserId; 14571 } 14572 14573 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14574 String className, int flags) { 14575 boolean result = false; 14576 // For apps that don't have pre-defined UIDs, check for permission 14577 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14578 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14579 if (ActivityManager.checkUidPermission( 14580 INTERACT_ACROSS_USERS, 14581 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14582 ComponentName comp = new ComponentName(aInfo.packageName, className); 14583 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14584 + " requests FLAG_SINGLE_USER, but app does not hold " 14585 + INTERACT_ACROSS_USERS; 14586 Slog.w(TAG, msg); 14587 throw new SecurityException(msg); 14588 } 14589 // Permission passed 14590 result = true; 14591 } 14592 } else if ("system".equals(componentProcessName)) { 14593 result = true; 14594 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14595 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14596 // Phone app is allowed to export singleuser providers. 14597 result = true; 14598 } else { 14599 // App with pre-defined UID, check if it's a persistent app 14600 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14601 } 14602 if (DEBUG_MU) { 14603 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14604 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14605 } 14606 return result; 14607 } 14608 14609 /** 14610 * Checks to see if the caller is in the same app as the singleton 14611 * component, or the component is in a special app. It allows special apps 14612 * to export singleton components but prevents exporting singleton 14613 * components for regular apps. 14614 */ 14615 boolean isValidSingletonCall(int callingUid, int componentUid) { 14616 int componentAppId = UserHandle.getAppId(componentUid); 14617 return UserHandle.isSameApp(callingUid, componentUid) 14618 || componentAppId == Process.SYSTEM_UID 14619 || componentAppId == Process.PHONE_UID 14620 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14621 == PackageManager.PERMISSION_GRANTED; 14622 } 14623 14624 public int bindService(IApplicationThread caller, IBinder token, 14625 Intent service, String resolvedType, 14626 IServiceConnection connection, int flags, int userId) { 14627 enforceNotIsolatedCaller("bindService"); 14628 14629 // Refuse possible leaked file descriptors 14630 if (service != null && service.hasFileDescriptors() == true) { 14631 throw new IllegalArgumentException("File descriptors passed in Intent"); 14632 } 14633 14634 synchronized(this) { 14635 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14636 connection, flags, userId); 14637 } 14638 } 14639 14640 public boolean unbindService(IServiceConnection connection) { 14641 synchronized (this) { 14642 return mServices.unbindServiceLocked(connection); 14643 } 14644 } 14645 14646 public void publishService(IBinder token, Intent intent, IBinder service) { 14647 // Refuse possible leaked file descriptors 14648 if (intent != null && intent.hasFileDescriptors() == true) { 14649 throw new IllegalArgumentException("File descriptors passed in Intent"); 14650 } 14651 14652 synchronized(this) { 14653 if (!(token instanceof ServiceRecord)) { 14654 throw new IllegalArgumentException("Invalid service token"); 14655 } 14656 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14657 } 14658 } 14659 14660 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14661 // Refuse possible leaked file descriptors 14662 if (intent != null && intent.hasFileDescriptors() == true) { 14663 throw new IllegalArgumentException("File descriptors passed in Intent"); 14664 } 14665 14666 synchronized(this) { 14667 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14668 } 14669 } 14670 14671 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14672 synchronized(this) { 14673 if (!(token instanceof ServiceRecord)) { 14674 throw new IllegalArgumentException("Invalid service token"); 14675 } 14676 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14677 } 14678 } 14679 14680 // ========================================================= 14681 // BACKUP AND RESTORE 14682 // ========================================================= 14683 14684 // Cause the target app to be launched if necessary and its backup agent 14685 // instantiated. The backup agent will invoke backupAgentCreated() on the 14686 // activity manager to announce its creation. 14687 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14688 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14689 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14690 14691 synchronized(this) { 14692 // !!! TODO: currently no check here that we're already bound 14693 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14695 synchronized (stats) { 14696 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14697 } 14698 14699 // Backup agent is now in use, its package can't be stopped. 14700 try { 14701 AppGlobals.getPackageManager().setPackageStoppedState( 14702 app.packageName, false, UserHandle.getUserId(app.uid)); 14703 } catch (RemoteException e) { 14704 } catch (IllegalArgumentException e) { 14705 Slog.w(TAG, "Failed trying to unstop package " 14706 + app.packageName + ": " + e); 14707 } 14708 14709 BackupRecord r = new BackupRecord(ss, app, backupMode); 14710 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14711 ? new ComponentName(app.packageName, app.backupAgentName) 14712 : new ComponentName("android", "FullBackupAgent"); 14713 // startProcessLocked() returns existing proc's record if it's already running 14714 ProcessRecord proc = startProcessLocked(app.processName, app, 14715 false, 0, "backup", hostingName, false, false, false); 14716 if (proc == null) { 14717 Slog.e(TAG, "Unable to start backup agent process " + r); 14718 return false; 14719 } 14720 14721 r.app = proc; 14722 mBackupTarget = r; 14723 mBackupAppName = app.packageName; 14724 14725 // Try not to kill the process during backup 14726 updateOomAdjLocked(proc); 14727 14728 // If the process is already attached, schedule the creation of the backup agent now. 14729 // If it is not yet live, this will be done when it attaches to the framework. 14730 if (proc.thread != null) { 14731 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14732 try { 14733 proc.thread.scheduleCreateBackupAgent(app, 14734 compatibilityInfoForPackageLocked(app), backupMode); 14735 } catch (RemoteException e) { 14736 // Will time out on the backup manager side 14737 } 14738 } else { 14739 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14740 } 14741 // Invariants: at this point, the target app process exists and the application 14742 // is either already running or in the process of coming up. mBackupTarget and 14743 // mBackupAppName describe the app, so that when it binds back to the AM we 14744 // know that it's scheduled for a backup-agent operation. 14745 } 14746 14747 return true; 14748 } 14749 14750 @Override 14751 public void clearPendingBackup() { 14752 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14753 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14754 14755 synchronized (this) { 14756 mBackupTarget = null; 14757 mBackupAppName = null; 14758 } 14759 } 14760 14761 // A backup agent has just come up 14762 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14763 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14764 + " = " + agent); 14765 14766 synchronized(this) { 14767 if (!agentPackageName.equals(mBackupAppName)) { 14768 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14769 return; 14770 } 14771 } 14772 14773 long oldIdent = Binder.clearCallingIdentity(); 14774 try { 14775 IBackupManager bm = IBackupManager.Stub.asInterface( 14776 ServiceManager.getService(Context.BACKUP_SERVICE)); 14777 bm.agentConnected(agentPackageName, agent); 14778 } catch (RemoteException e) { 14779 // can't happen; the backup manager service is local 14780 } catch (Exception e) { 14781 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14782 e.printStackTrace(); 14783 } finally { 14784 Binder.restoreCallingIdentity(oldIdent); 14785 } 14786 } 14787 14788 // done with this agent 14789 public void unbindBackupAgent(ApplicationInfo appInfo) { 14790 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14791 if (appInfo == null) { 14792 Slog.w(TAG, "unbind backup agent for null app"); 14793 return; 14794 } 14795 14796 synchronized(this) { 14797 try { 14798 if (mBackupAppName == null) { 14799 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14800 return; 14801 } 14802 14803 if (!mBackupAppName.equals(appInfo.packageName)) { 14804 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14805 return; 14806 } 14807 14808 // Not backing this app up any more; reset its OOM adjustment 14809 final ProcessRecord proc = mBackupTarget.app; 14810 updateOomAdjLocked(proc); 14811 14812 // If the app crashed during backup, 'thread' will be null here 14813 if (proc.thread != null) { 14814 try { 14815 proc.thread.scheduleDestroyBackupAgent(appInfo, 14816 compatibilityInfoForPackageLocked(appInfo)); 14817 } catch (Exception e) { 14818 Slog.e(TAG, "Exception when unbinding backup agent:"); 14819 e.printStackTrace(); 14820 } 14821 } 14822 } finally { 14823 mBackupTarget = null; 14824 mBackupAppName = null; 14825 } 14826 } 14827 } 14828 // ========================================================= 14829 // BROADCASTS 14830 // ========================================================= 14831 14832 private final List getStickiesLocked(String action, IntentFilter filter, 14833 List cur, int userId) { 14834 final ContentResolver resolver = mContext.getContentResolver(); 14835 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14836 if (stickies == null) { 14837 return cur; 14838 } 14839 final ArrayList<Intent> list = stickies.get(action); 14840 if (list == null) { 14841 return cur; 14842 } 14843 int N = list.size(); 14844 for (int i=0; i<N; i++) { 14845 Intent intent = list.get(i); 14846 if (filter.match(resolver, intent, true, TAG) >= 0) { 14847 if (cur == null) { 14848 cur = new ArrayList<Intent>(); 14849 } 14850 cur.add(intent); 14851 } 14852 } 14853 return cur; 14854 } 14855 14856 boolean isPendingBroadcastProcessLocked(int pid) { 14857 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14858 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14859 } 14860 14861 void skipPendingBroadcastLocked(int pid) { 14862 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14863 for (BroadcastQueue queue : mBroadcastQueues) { 14864 queue.skipPendingBroadcastLocked(pid); 14865 } 14866 } 14867 14868 // The app just attached; send any pending broadcasts that it should receive 14869 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14870 boolean didSomething = false; 14871 for (BroadcastQueue queue : mBroadcastQueues) { 14872 didSomething |= queue.sendPendingBroadcastsLocked(app); 14873 } 14874 return didSomething; 14875 } 14876 14877 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14878 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14879 enforceNotIsolatedCaller("registerReceiver"); 14880 int callingUid; 14881 int callingPid; 14882 synchronized(this) { 14883 ProcessRecord callerApp = null; 14884 if (caller != null) { 14885 callerApp = getRecordForAppLocked(caller); 14886 if (callerApp == null) { 14887 throw new SecurityException( 14888 "Unable to find app for caller " + caller 14889 + " (pid=" + Binder.getCallingPid() 14890 + ") when registering receiver " + receiver); 14891 } 14892 if (callerApp.info.uid != Process.SYSTEM_UID && 14893 !callerApp.pkgList.containsKey(callerPackage) && 14894 !"android".equals(callerPackage)) { 14895 throw new SecurityException("Given caller package " + callerPackage 14896 + " is not running in process " + callerApp); 14897 } 14898 callingUid = callerApp.info.uid; 14899 callingPid = callerApp.pid; 14900 } else { 14901 callerPackage = null; 14902 callingUid = Binder.getCallingUid(); 14903 callingPid = Binder.getCallingPid(); 14904 } 14905 14906 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14907 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14908 14909 List allSticky = null; 14910 14911 // Look for any matching sticky broadcasts... 14912 Iterator actions = filter.actionsIterator(); 14913 if (actions != null) { 14914 while (actions.hasNext()) { 14915 String action = (String)actions.next(); 14916 allSticky = getStickiesLocked(action, filter, allSticky, 14917 UserHandle.USER_ALL); 14918 allSticky = getStickiesLocked(action, filter, allSticky, 14919 UserHandle.getUserId(callingUid)); 14920 } 14921 } else { 14922 allSticky = getStickiesLocked(null, filter, allSticky, 14923 UserHandle.USER_ALL); 14924 allSticky = getStickiesLocked(null, filter, allSticky, 14925 UserHandle.getUserId(callingUid)); 14926 } 14927 14928 // The first sticky in the list is returned directly back to 14929 // the client. 14930 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14931 14932 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14933 + ": " + sticky); 14934 14935 if (receiver == null) { 14936 return sticky; 14937 } 14938 14939 ReceiverList rl 14940 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14941 if (rl == null) { 14942 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14943 userId, receiver); 14944 if (rl.app != null) { 14945 rl.app.receivers.add(rl); 14946 } else { 14947 try { 14948 receiver.asBinder().linkToDeath(rl, 0); 14949 } catch (RemoteException e) { 14950 return sticky; 14951 } 14952 rl.linkedToDeath = true; 14953 } 14954 mRegisteredReceivers.put(receiver.asBinder(), rl); 14955 } else if (rl.uid != callingUid) { 14956 throw new IllegalArgumentException( 14957 "Receiver requested to register for uid " + callingUid 14958 + " was previously registered for uid " + rl.uid); 14959 } else if (rl.pid != callingPid) { 14960 throw new IllegalArgumentException( 14961 "Receiver requested to register for pid " + callingPid 14962 + " was previously registered for pid " + rl.pid); 14963 } else if (rl.userId != userId) { 14964 throw new IllegalArgumentException( 14965 "Receiver requested to register for user " + userId 14966 + " was previously registered for user " + rl.userId); 14967 } 14968 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14969 permission, callingUid, userId); 14970 rl.add(bf); 14971 if (!bf.debugCheck()) { 14972 Slog.w(TAG, "==> For Dynamic broadast"); 14973 } 14974 mReceiverResolver.addFilter(bf); 14975 14976 // Enqueue broadcasts for all existing stickies that match 14977 // this filter. 14978 if (allSticky != null) { 14979 ArrayList receivers = new ArrayList(); 14980 receivers.add(bf); 14981 14982 int N = allSticky.size(); 14983 for (int i=0; i<N; i++) { 14984 Intent intent = (Intent)allSticky.get(i); 14985 BroadcastQueue queue = broadcastQueueForIntent(intent); 14986 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14987 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14988 null, null, false, true, true, -1); 14989 queue.enqueueParallelBroadcastLocked(r); 14990 queue.scheduleBroadcastsLocked(); 14991 } 14992 } 14993 14994 return sticky; 14995 } 14996 } 14997 14998 public void unregisterReceiver(IIntentReceiver receiver) { 14999 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15000 15001 final long origId = Binder.clearCallingIdentity(); 15002 try { 15003 boolean doTrim = false; 15004 15005 synchronized(this) { 15006 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15007 if (rl != null) { 15008 if (rl.curBroadcast != null) { 15009 BroadcastRecord r = rl.curBroadcast; 15010 final boolean doNext = finishReceiverLocked( 15011 receiver.asBinder(), r.resultCode, r.resultData, 15012 r.resultExtras, r.resultAbort); 15013 if (doNext) { 15014 doTrim = true; 15015 r.queue.processNextBroadcast(false); 15016 } 15017 } 15018 15019 if (rl.app != null) { 15020 rl.app.receivers.remove(rl); 15021 } 15022 removeReceiverLocked(rl); 15023 if (rl.linkedToDeath) { 15024 rl.linkedToDeath = false; 15025 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15026 } 15027 } 15028 } 15029 15030 // If we actually concluded any broadcasts, we might now be able 15031 // to trim the recipients' apps from our working set 15032 if (doTrim) { 15033 trimApplications(); 15034 return; 15035 } 15036 15037 } finally { 15038 Binder.restoreCallingIdentity(origId); 15039 } 15040 } 15041 15042 void removeReceiverLocked(ReceiverList rl) { 15043 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15044 int N = rl.size(); 15045 for (int i=0; i<N; i++) { 15046 mReceiverResolver.removeFilter(rl.get(i)); 15047 } 15048 } 15049 15050 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15051 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15052 ProcessRecord r = mLruProcesses.get(i); 15053 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15054 try { 15055 r.thread.dispatchPackageBroadcast(cmd, packages); 15056 } catch (RemoteException ex) { 15057 } 15058 } 15059 } 15060 } 15061 15062 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15063 int callingUid, int[] users) { 15064 List<ResolveInfo> receivers = null; 15065 try { 15066 HashSet<ComponentName> singleUserReceivers = null; 15067 boolean scannedFirstReceivers = false; 15068 for (int user : users) { 15069 // Skip users that have Shell restrictions 15070 if (callingUid == Process.SHELL_UID 15071 && getUserManagerLocked().hasUserRestriction( 15072 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15073 continue; 15074 } 15075 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15076 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15077 if (user != 0 && newReceivers != null) { 15078 // If this is not the primary user, we need to check for 15079 // any receivers that should be filtered out. 15080 for (int i=0; i<newReceivers.size(); i++) { 15081 ResolveInfo ri = newReceivers.get(i); 15082 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15083 newReceivers.remove(i); 15084 i--; 15085 } 15086 } 15087 } 15088 if (newReceivers != null && newReceivers.size() == 0) { 15089 newReceivers = null; 15090 } 15091 if (receivers == null) { 15092 receivers = newReceivers; 15093 } else if (newReceivers != null) { 15094 // We need to concatenate the additional receivers 15095 // found with what we have do far. This would be easy, 15096 // but we also need to de-dup any receivers that are 15097 // singleUser. 15098 if (!scannedFirstReceivers) { 15099 // Collect any single user receivers we had already retrieved. 15100 scannedFirstReceivers = true; 15101 for (int i=0; i<receivers.size(); i++) { 15102 ResolveInfo ri = receivers.get(i); 15103 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15104 ComponentName cn = new ComponentName( 15105 ri.activityInfo.packageName, ri.activityInfo.name); 15106 if (singleUserReceivers == null) { 15107 singleUserReceivers = new HashSet<ComponentName>(); 15108 } 15109 singleUserReceivers.add(cn); 15110 } 15111 } 15112 } 15113 // Add the new results to the existing results, tracking 15114 // and de-dupping single user receivers. 15115 for (int i=0; i<newReceivers.size(); i++) { 15116 ResolveInfo ri = newReceivers.get(i); 15117 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15118 ComponentName cn = new ComponentName( 15119 ri.activityInfo.packageName, ri.activityInfo.name); 15120 if (singleUserReceivers == null) { 15121 singleUserReceivers = new HashSet<ComponentName>(); 15122 } 15123 if (!singleUserReceivers.contains(cn)) { 15124 singleUserReceivers.add(cn); 15125 receivers.add(ri); 15126 } 15127 } else { 15128 receivers.add(ri); 15129 } 15130 } 15131 } 15132 } 15133 } catch (RemoteException ex) { 15134 // pm is in same process, this will never happen. 15135 } 15136 return receivers; 15137 } 15138 15139 private final int broadcastIntentLocked(ProcessRecord callerApp, 15140 String callerPackage, Intent intent, String resolvedType, 15141 IIntentReceiver resultTo, int resultCode, String resultData, 15142 Bundle map, String requiredPermission, int appOp, 15143 boolean ordered, boolean sticky, int callingPid, int callingUid, 15144 int userId) { 15145 intent = new Intent(intent); 15146 15147 // By default broadcasts do not go to stopped apps. 15148 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15149 15150 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15151 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15152 + " ordered=" + ordered + " userid=" + userId); 15153 if ((resultTo != null) && !ordered) { 15154 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15155 } 15156 15157 userId = handleIncomingUser(callingPid, callingUid, userId, 15158 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15159 15160 // Make sure that the user who is receiving this broadcast is started. 15161 // If not, we will just skip it. 15162 15163 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15164 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15165 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15166 Slog.w(TAG, "Skipping broadcast of " + intent 15167 + ": user " + userId + " is stopped"); 15168 return ActivityManager.BROADCAST_SUCCESS; 15169 } 15170 } 15171 15172 /* 15173 * Prevent non-system code (defined here to be non-persistent 15174 * processes) from sending protected broadcasts. 15175 */ 15176 int callingAppId = UserHandle.getAppId(callingUid); 15177 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15178 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15179 || callingAppId == Process.NFC_UID || callingUid == 0) { 15180 // Always okay. 15181 } else if (callerApp == null || !callerApp.persistent) { 15182 try { 15183 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15184 intent.getAction())) { 15185 String msg = "Permission Denial: not allowed to send broadcast " 15186 + intent.getAction() + " from pid=" 15187 + callingPid + ", uid=" + callingUid; 15188 Slog.w(TAG, msg); 15189 throw new SecurityException(msg); 15190 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15191 // Special case for compatibility: we don't want apps to send this, 15192 // but historically it has not been protected and apps may be using it 15193 // to poke their own app widget. So, instead of making it protected, 15194 // just limit it to the caller. 15195 if (callerApp == null) { 15196 String msg = "Permission Denial: not allowed to send broadcast " 15197 + intent.getAction() + " from unknown caller."; 15198 Slog.w(TAG, msg); 15199 throw new SecurityException(msg); 15200 } else if (intent.getComponent() != null) { 15201 // They are good enough to send to an explicit component... verify 15202 // it is being sent to the calling app. 15203 if (!intent.getComponent().getPackageName().equals( 15204 callerApp.info.packageName)) { 15205 String msg = "Permission Denial: not allowed to send broadcast " 15206 + intent.getAction() + " to " 15207 + intent.getComponent().getPackageName() + " from " 15208 + callerApp.info.packageName; 15209 Slog.w(TAG, msg); 15210 throw new SecurityException(msg); 15211 } 15212 } else { 15213 // Limit broadcast to their own package. 15214 intent.setPackage(callerApp.info.packageName); 15215 } 15216 } 15217 } catch (RemoteException e) { 15218 Slog.w(TAG, "Remote exception", e); 15219 return ActivityManager.BROADCAST_SUCCESS; 15220 } 15221 } 15222 15223 // Handle special intents: if this broadcast is from the package 15224 // manager about a package being removed, we need to remove all of 15225 // its activities from the history stack. 15226 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15227 intent.getAction()); 15228 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15229 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15230 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15231 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15232 || uidRemoved) { 15233 if (checkComponentPermission( 15234 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15235 callingPid, callingUid, -1, true) 15236 == PackageManager.PERMISSION_GRANTED) { 15237 if (uidRemoved) { 15238 final Bundle intentExtras = intent.getExtras(); 15239 final int uid = intentExtras != null 15240 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15241 if (uid >= 0) { 15242 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15243 synchronized (bs) { 15244 bs.removeUidStatsLocked(uid); 15245 } 15246 mAppOpsService.uidRemoved(uid); 15247 } 15248 } else { 15249 // If resources are unavailable just force stop all 15250 // those packages and flush the attribute cache as well. 15251 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15252 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15253 if (list != null && (list.length > 0)) { 15254 for (String pkg : list) { 15255 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15256 "storage unmount"); 15257 } 15258 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15259 sendPackageBroadcastLocked( 15260 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15261 } 15262 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15263 intent.getAction())) { 15264 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15265 } else { 15266 Uri data = intent.getData(); 15267 String ssp; 15268 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15269 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15270 intent.getAction()); 15271 boolean fullUninstall = removed && 15272 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15273 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15274 forceStopPackageLocked(ssp, UserHandle.getAppId( 15275 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15276 false, fullUninstall, userId, 15277 removed ? "pkg removed" : "pkg changed"); 15278 } 15279 if (removed) { 15280 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15281 new String[] {ssp}, userId); 15282 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15283 mAppOpsService.packageRemoved( 15284 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15285 15286 // Remove all permissions granted from/to this package 15287 removeUriPermissionsForPackageLocked(ssp, userId, true); 15288 } 15289 } 15290 } 15291 } 15292 } 15293 } else { 15294 String msg = "Permission Denial: " + intent.getAction() 15295 + " broadcast from " + callerPackage + " (pid=" + callingPid 15296 + ", uid=" + callingUid + ")" 15297 + " requires " 15298 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15299 Slog.w(TAG, msg); 15300 throw new SecurityException(msg); 15301 } 15302 15303 // Special case for adding a package: by default turn on compatibility 15304 // mode. 15305 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15306 Uri data = intent.getData(); 15307 String ssp; 15308 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15309 mCompatModePackages.handlePackageAddedLocked(ssp, 15310 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15311 } 15312 } 15313 15314 /* 15315 * If this is the time zone changed action, queue up a message that will reset the timezone 15316 * of all currently running processes. This message will get queued up before the broadcast 15317 * happens. 15318 */ 15319 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15320 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15321 } 15322 15323 /* 15324 * If the user set the time, let all running processes know. 15325 */ 15326 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15327 final int is24Hour = intent.getBooleanExtra( 15328 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15329 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15330 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15331 synchronized (stats) { 15332 stats.noteCurrentTimeChangedLocked(); 15333 } 15334 } 15335 15336 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15337 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15338 } 15339 15340 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15341 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15342 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15343 } 15344 15345 // Add to the sticky list if requested. 15346 if (sticky) { 15347 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15348 callingPid, callingUid) 15349 != PackageManager.PERMISSION_GRANTED) { 15350 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15351 + callingPid + ", uid=" + callingUid 15352 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15353 Slog.w(TAG, msg); 15354 throw new SecurityException(msg); 15355 } 15356 if (requiredPermission != null) { 15357 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15358 + " and enforce permission " + requiredPermission); 15359 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15360 } 15361 if (intent.getComponent() != null) { 15362 throw new SecurityException( 15363 "Sticky broadcasts can't target a specific component"); 15364 } 15365 // We use userId directly here, since the "all" target is maintained 15366 // as a separate set of sticky broadcasts. 15367 if (userId != UserHandle.USER_ALL) { 15368 // But first, if this is not a broadcast to all users, then 15369 // make sure it doesn't conflict with an existing broadcast to 15370 // all users. 15371 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15372 UserHandle.USER_ALL); 15373 if (stickies != null) { 15374 ArrayList<Intent> list = stickies.get(intent.getAction()); 15375 if (list != null) { 15376 int N = list.size(); 15377 int i; 15378 for (i=0; i<N; i++) { 15379 if (intent.filterEquals(list.get(i))) { 15380 throw new IllegalArgumentException( 15381 "Sticky broadcast " + intent + " for user " 15382 + userId + " conflicts with existing global broadcast"); 15383 } 15384 } 15385 } 15386 } 15387 } 15388 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15389 if (stickies == null) { 15390 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15391 mStickyBroadcasts.put(userId, stickies); 15392 } 15393 ArrayList<Intent> list = stickies.get(intent.getAction()); 15394 if (list == null) { 15395 list = new ArrayList<Intent>(); 15396 stickies.put(intent.getAction(), list); 15397 } 15398 int N = list.size(); 15399 int i; 15400 for (i=0; i<N; i++) { 15401 if (intent.filterEquals(list.get(i))) { 15402 // This sticky already exists, replace it. 15403 list.set(i, new Intent(intent)); 15404 break; 15405 } 15406 } 15407 if (i >= N) { 15408 list.add(new Intent(intent)); 15409 } 15410 } 15411 15412 int[] users; 15413 if (userId == UserHandle.USER_ALL) { 15414 // Caller wants broadcast to go to all started users. 15415 users = mStartedUserArray; 15416 } else { 15417 // Caller wants broadcast to go to one specific user. 15418 users = new int[] {userId}; 15419 } 15420 15421 // Figure out who all will receive this broadcast. 15422 List receivers = null; 15423 List<BroadcastFilter> registeredReceivers = null; 15424 // Need to resolve the intent to interested receivers... 15425 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15426 == 0) { 15427 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15428 } 15429 if (intent.getComponent() == null) { 15430 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15431 // Query one target user at a time, excluding shell-restricted users 15432 UserManagerService ums = getUserManagerLocked(); 15433 for (int i = 0; i < users.length; i++) { 15434 if (ums.hasUserRestriction( 15435 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15436 continue; 15437 } 15438 List<BroadcastFilter> registeredReceiversForUser = 15439 mReceiverResolver.queryIntent(intent, 15440 resolvedType, false, users[i]); 15441 if (registeredReceivers == null) { 15442 registeredReceivers = registeredReceiversForUser; 15443 } else if (registeredReceiversForUser != null) { 15444 registeredReceivers.addAll(registeredReceiversForUser); 15445 } 15446 } 15447 } else { 15448 registeredReceivers = mReceiverResolver.queryIntent(intent, 15449 resolvedType, false, userId); 15450 } 15451 } 15452 15453 final boolean replacePending = 15454 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15455 15456 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15457 + " replacePending=" + replacePending); 15458 15459 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15460 if (!ordered && NR > 0) { 15461 // If we are not serializing this broadcast, then send the 15462 // registered receivers separately so they don't wait for the 15463 // components to be launched. 15464 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15465 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15466 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15467 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15468 ordered, sticky, false, userId); 15469 if (DEBUG_BROADCAST) Slog.v( 15470 TAG, "Enqueueing parallel broadcast " + r); 15471 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15472 if (!replaced) { 15473 queue.enqueueParallelBroadcastLocked(r); 15474 queue.scheduleBroadcastsLocked(); 15475 } 15476 registeredReceivers = null; 15477 NR = 0; 15478 } 15479 15480 // Merge into one list. 15481 int ir = 0; 15482 if (receivers != null) { 15483 // A special case for PACKAGE_ADDED: do not allow the package 15484 // being added to see this broadcast. This prevents them from 15485 // using this as a back door to get run as soon as they are 15486 // installed. Maybe in the future we want to have a special install 15487 // broadcast or such for apps, but we'd like to deliberately make 15488 // this decision. 15489 String skipPackages[] = null; 15490 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15491 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15492 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15493 Uri data = intent.getData(); 15494 if (data != null) { 15495 String pkgName = data.getSchemeSpecificPart(); 15496 if (pkgName != null) { 15497 skipPackages = new String[] { pkgName }; 15498 } 15499 } 15500 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15501 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15502 } 15503 if (skipPackages != null && (skipPackages.length > 0)) { 15504 for (String skipPackage : skipPackages) { 15505 if (skipPackage != null) { 15506 int NT = receivers.size(); 15507 for (int it=0; it<NT; it++) { 15508 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15509 if (curt.activityInfo.packageName.equals(skipPackage)) { 15510 receivers.remove(it); 15511 it--; 15512 NT--; 15513 } 15514 } 15515 } 15516 } 15517 } 15518 15519 int NT = receivers != null ? receivers.size() : 0; 15520 int it = 0; 15521 ResolveInfo curt = null; 15522 BroadcastFilter curr = null; 15523 while (it < NT && ir < NR) { 15524 if (curt == null) { 15525 curt = (ResolveInfo)receivers.get(it); 15526 } 15527 if (curr == null) { 15528 curr = registeredReceivers.get(ir); 15529 } 15530 if (curr.getPriority() >= curt.priority) { 15531 // Insert this broadcast record into the final list. 15532 receivers.add(it, curr); 15533 ir++; 15534 curr = null; 15535 it++; 15536 NT++; 15537 } else { 15538 // Skip to the next ResolveInfo in the final list. 15539 it++; 15540 curt = null; 15541 } 15542 } 15543 } 15544 while (ir < NR) { 15545 if (receivers == null) { 15546 receivers = new ArrayList(); 15547 } 15548 receivers.add(registeredReceivers.get(ir)); 15549 ir++; 15550 } 15551 15552 if ((receivers != null && receivers.size() > 0) 15553 || resultTo != null) { 15554 BroadcastQueue queue = broadcastQueueForIntent(intent); 15555 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15556 callerPackage, callingPid, callingUid, resolvedType, 15557 requiredPermission, appOp, receivers, resultTo, resultCode, 15558 resultData, map, ordered, sticky, false, userId); 15559 if (DEBUG_BROADCAST) Slog.v( 15560 TAG, "Enqueueing ordered broadcast " + r 15561 + ": prev had " + queue.mOrderedBroadcasts.size()); 15562 if (DEBUG_BROADCAST) { 15563 int seq = r.intent.getIntExtra("seq", -1); 15564 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15565 } 15566 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15567 if (!replaced) { 15568 queue.enqueueOrderedBroadcastLocked(r); 15569 queue.scheduleBroadcastsLocked(); 15570 } 15571 } 15572 15573 return ActivityManager.BROADCAST_SUCCESS; 15574 } 15575 15576 final Intent verifyBroadcastLocked(Intent intent) { 15577 // Refuse possible leaked file descriptors 15578 if (intent != null && intent.hasFileDescriptors() == true) { 15579 throw new IllegalArgumentException("File descriptors passed in Intent"); 15580 } 15581 15582 int flags = intent.getFlags(); 15583 15584 if (!mProcessesReady) { 15585 // if the caller really truly claims to know what they're doing, go 15586 // ahead and allow the broadcast without launching any receivers 15587 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15588 intent = new Intent(intent); 15589 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15590 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15591 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15592 + " before boot completion"); 15593 throw new IllegalStateException("Cannot broadcast before boot completed"); 15594 } 15595 } 15596 15597 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15598 throw new IllegalArgumentException( 15599 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15600 } 15601 15602 return intent; 15603 } 15604 15605 public final int broadcastIntent(IApplicationThread caller, 15606 Intent intent, String resolvedType, IIntentReceiver resultTo, 15607 int resultCode, String resultData, Bundle map, 15608 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15609 enforceNotIsolatedCaller("broadcastIntent"); 15610 synchronized(this) { 15611 intent = verifyBroadcastLocked(intent); 15612 15613 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15614 final int callingPid = Binder.getCallingPid(); 15615 final int callingUid = Binder.getCallingUid(); 15616 final long origId = Binder.clearCallingIdentity(); 15617 int res = broadcastIntentLocked(callerApp, 15618 callerApp != null ? callerApp.info.packageName : null, 15619 intent, resolvedType, resultTo, 15620 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15621 callingPid, callingUid, userId); 15622 Binder.restoreCallingIdentity(origId); 15623 return res; 15624 } 15625 } 15626 15627 int broadcastIntentInPackage(String packageName, int uid, 15628 Intent intent, String resolvedType, IIntentReceiver resultTo, 15629 int resultCode, String resultData, Bundle map, 15630 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15631 synchronized(this) { 15632 intent = verifyBroadcastLocked(intent); 15633 15634 final long origId = Binder.clearCallingIdentity(); 15635 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15636 resultTo, resultCode, resultData, map, requiredPermission, 15637 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15638 Binder.restoreCallingIdentity(origId); 15639 return res; 15640 } 15641 } 15642 15643 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15644 // Refuse possible leaked file descriptors 15645 if (intent != null && intent.hasFileDescriptors() == true) { 15646 throw new IllegalArgumentException("File descriptors passed in Intent"); 15647 } 15648 15649 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15650 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15651 15652 synchronized(this) { 15653 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15654 != PackageManager.PERMISSION_GRANTED) { 15655 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15656 + Binder.getCallingPid() 15657 + ", uid=" + Binder.getCallingUid() 15658 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15659 Slog.w(TAG, msg); 15660 throw new SecurityException(msg); 15661 } 15662 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15663 if (stickies != null) { 15664 ArrayList<Intent> list = stickies.get(intent.getAction()); 15665 if (list != null) { 15666 int N = list.size(); 15667 int i; 15668 for (i=0; i<N; i++) { 15669 if (intent.filterEquals(list.get(i))) { 15670 list.remove(i); 15671 break; 15672 } 15673 } 15674 if (list.size() <= 0) { 15675 stickies.remove(intent.getAction()); 15676 } 15677 } 15678 if (stickies.size() <= 0) { 15679 mStickyBroadcasts.remove(userId); 15680 } 15681 } 15682 } 15683 } 15684 15685 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15686 String resultData, Bundle resultExtras, boolean resultAbort) { 15687 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15688 if (r == null) { 15689 Slog.w(TAG, "finishReceiver called but not found on queue"); 15690 return false; 15691 } 15692 15693 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15694 } 15695 15696 void backgroundServicesFinishedLocked(int userId) { 15697 for (BroadcastQueue queue : mBroadcastQueues) { 15698 queue.backgroundServicesFinishedLocked(userId); 15699 } 15700 } 15701 15702 public void finishReceiver(IBinder who, int resultCode, String resultData, 15703 Bundle resultExtras, boolean resultAbort) { 15704 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15705 15706 // Refuse possible leaked file descriptors 15707 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15708 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15709 } 15710 15711 final long origId = Binder.clearCallingIdentity(); 15712 try { 15713 boolean doNext = false; 15714 BroadcastRecord r; 15715 15716 synchronized(this) { 15717 r = broadcastRecordForReceiverLocked(who); 15718 if (r != null) { 15719 doNext = r.queue.finishReceiverLocked(r, resultCode, 15720 resultData, resultExtras, resultAbort, true); 15721 } 15722 } 15723 15724 if (doNext) { 15725 r.queue.processNextBroadcast(false); 15726 } 15727 trimApplications(); 15728 } finally { 15729 Binder.restoreCallingIdentity(origId); 15730 } 15731 } 15732 15733 // ========================================================= 15734 // INSTRUMENTATION 15735 // ========================================================= 15736 15737 public boolean startInstrumentation(ComponentName className, 15738 String profileFile, int flags, Bundle arguments, 15739 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15740 int userId, String abiOverride) { 15741 enforceNotIsolatedCaller("startInstrumentation"); 15742 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15743 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15744 // Refuse possible leaked file descriptors 15745 if (arguments != null && arguments.hasFileDescriptors()) { 15746 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15747 } 15748 15749 synchronized(this) { 15750 InstrumentationInfo ii = null; 15751 ApplicationInfo ai = null; 15752 try { 15753 ii = mContext.getPackageManager().getInstrumentationInfo( 15754 className, STOCK_PM_FLAGS); 15755 ai = AppGlobals.getPackageManager().getApplicationInfo( 15756 ii.targetPackage, STOCK_PM_FLAGS, userId); 15757 } catch (PackageManager.NameNotFoundException e) { 15758 } catch (RemoteException e) { 15759 } 15760 if (ii == null) { 15761 reportStartInstrumentationFailure(watcher, className, 15762 "Unable to find instrumentation info for: " + className); 15763 return false; 15764 } 15765 if (ai == null) { 15766 reportStartInstrumentationFailure(watcher, className, 15767 "Unable to find instrumentation target package: " + ii.targetPackage); 15768 return false; 15769 } 15770 15771 int match = mContext.getPackageManager().checkSignatures( 15772 ii.targetPackage, ii.packageName); 15773 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15774 String msg = "Permission Denial: starting instrumentation " 15775 + className + " from pid=" 15776 + Binder.getCallingPid() 15777 + ", uid=" + Binder.getCallingPid() 15778 + " not allowed because package " + ii.packageName 15779 + " does not have a signature matching the target " 15780 + ii.targetPackage; 15781 reportStartInstrumentationFailure(watcher, className, msg); 15782 throw new SecurityException(msg); 15783 } 15784 15785 final long origId = Binder.clearCallingIdentity(); 15786 // Instrumentation can kill and relaunch even persistent processes 15787 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15788 "start instr"); 15789 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15790 app.instrumentationClass = className; 15791 app.instrumentationInfo = ai; 15792 app.instrumentationProfileFile = profileFile; 15793 app.instrumentationArguments = arguments; 15794 app.instrumentationWatcher = watcher; 15795 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15796 app.instrumentationResultClass = className; 15797 Binder.restoreCallingIdentity(origId); 15798 } 15799 15800 return true; 15801 } 15802 15803 /** 15804 * Report errors that occur while attempting to start Instrumentation. Always writes the 15805 * error to the logs, but if somebody is watching, send the report there too. This enables 15806 * the "am" command to report errors with more information. 15807 * 15808 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15809 * @param cn The component name of the instrumentation. 15810 * @param report The error report. 15811 */ 15812 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15813 ComponentName cn, String report) { 15814 Slog.w(TAG, report); 15815 try { 15816 if (watcher != null) { 15817 Bundle results = new Bundle(); 15818 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15819 results.putString("Error", report); 15820 watcher.instrumentationStatus(cn, -1, results); 15821 } 15822 } catch (RemoteException e) { 15823 Slog.w(TAG, e); 15824 } 15825 } 15826 15827 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15828 if (app.instrumentationWatcher != null) { 15829 try { 15830 // NOTE: IInstrumentationWatcher *must* be oneway here 15831 app.instrumentationWatcher.instrumentationFinished( 15832 app.instrumentationClass, 15833 resultCode, 15834 results); 15835 } catch (RemoteException e) { 15836 } 15837 } 15838 if (app.instrumentationUiAutomationConnection != null) { 15839 try { 15840 app.instrumentationUiAutomationConnection.shutdown(); 15841 } catch (RemoteException re) { 15842 /* ignore */ 15843 } 15844 // Only a UiAutomation can set this flag and now that 15845 // it is finished we make sure it is reset to its default. 15846 mUserIsMonkey = false; 15847 } 15848 app.instrumentationWatcher = null; 15849 app.instrumentationUiAutomationConnection = null; 15850 app.instrumentationClass = null; 15851 app.instrumentationInfo = null; 15852 app.instrumentationProfileFile = null; 15853 app.instrumentationArguments = null; 15854 15855 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15856 "finished inst"); 15857 } 15858 15859 public void finishInstrumentation(IApplicationThread target, 15860 int resultCode, Bundle results) { 15861 int userId = UserHandle.getCallingUserId(); 15862 // Refuse possible leaked file descriptors 15863 if (results != null && results.hasFileDescriptors()) { 15864 throw new IllegalArgumentException("File descriptors passed in Intent"); 15865 } 15866 15867 synchronized(this) { 15868 ProcessRecord app = getRecordForAppLocked(target); 15869 if (app == null) { 15870 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15871 return; 15872 } 15873 final long origId = Binder.clearCallingIdentity(); 15874 finishInstrumentationLocked(app, resultCode, results); 15875 Binder.restoreCallingIdentity(origId); 15876 } 15877 } 15878 15879 // ========================================================= 15880 // CONFIGURATION 15881 // ========================================================= 15882 15883 public ConfigurationInfo getDeviceConfigurationInfo() { 15884 ConfigurationInfo config = new ConfigurationInfo(); 15885 synchronized (this) { 15886 config.reqTouchScreen = mConfiguration.touchscreen; 15887 config.reqKeyboardType = mConfiguration.keyboard; 15888 config.reqNavigation = mConfiguration.navigation; 15889 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15890 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15891 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15892 } 15893 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15894 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15895 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15896 } 15897 config.reqGlEsVersion = GL_ES_VERSION; 15898 } 15899 return config; 15900 } 15901 15902 ActivityStack getFocusedStack() { 15903 return mStackSupervisor.getFocusedStack(); 15904 } 15905 15906 public Configuration getConfiguration() { 15907 Configuration ci; 15908 synchronized(this) { 15909 ci = new Configuration(mConfiguration); 15910 } 15911 return ci; 15912 } 15913 15914 public void updatePersistentConfiguration(Configuration values) { 15915 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15916 "updateConfiguration()"); 15917 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15918 "updateConfiguration()"); 15919 if (values == null) { 15920 throw new NullPointerException("Configuration must not be null"); 15921 } 15922 15923 synchronized(this) { 15924 final long origId = Binder.clearCallingIdentity(); 15925 updateConfigurationLocked(values, null, true, false); 15926 Binder.restoreCallingIdentity(origId); 15927 } 15928 } 15929 15930 public void updateConfiguration(Configuration values) { 15931 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15932 "updateConfiguration()"); 15933 15934 synchronized(this) { 15935 if (values == null && mWindowManager != null) { 15936 // sentinel: fetch the current configuration from the window manager 15937 values = mWindowManager.computeNewConfiguration(); 15938 } 15939 15940 if (mWindowManager != null) { 15941 mProcessList.applyDisplaySize(mWindowManager); 15942 } 15943 15944 final long origId = Binder.clearCallingIdentity(); 15945 if (values != null) { 15946 Settings.System.clearConfiguration(values); 15947 } 15948 updateConfigurationLocked(values, null, false, false); 15949 Binder.restoreCallingIdentity(origId); 15950 } 15951 } 15952 15953 /** 15954 * Do either or both things: (1) change the current configuration, and (2) 15955 * make sure the given activity is running with the (now) current 15956 * configuration. Returns true if the activity has been left running, or 15957 * false if <var>starting</var> is being destroyed to match the new 15958 * configuration. 15959 * @param persistent TODO 15960 */ 15961 boolean updateConfigurationLocked(Configuration values, 15962 ActivityRecord starting, boolean persistent, boolean initLocale) { 15963 int changes = 0; 15964 15965 if (values != null) { 15966 Configuration newConfig = new Configuration(mConfiguration); 15967 changes = newConfig.updateFrom(values); 15968 if (changes != 0) { 15969 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15970 Slog.i(TAG, "Updating configuration to: " + values); 15971 } 15972 15973 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15974 15975 if (values.locale != null && !initLocale) { 15976 saveLocaleLocked(values.locale, 15977 !values.locale.equals(mConfiguration.locale), 15978 values.userSetLocale); 15979 } 15980 15981 mConfigurationSeq++; 15982 if (mConfigurationSeq <= 0) { 15983 mConfigurationSeq = 1; 15984 } 15985 newConfig.seq = mConfigurationSeq; 15986 mConfiguration = newConfig; 15987 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15988 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15989 //mUsageStatsService.noteStartConfig(newConfig); 15990 15991 final Configuration configCopy = new Configuration(mConfiguration); 15992 15993 // TODO: If our config changes, should we auto dismiss any currently 15994 // showing dialogs? 15995 mShowDialogs = shouldShowDialogs(newConfig); 15996 15997 AttributeCache ac = AttributeCache.instance(); 15998 if (ac != null) { 15999 ac.updateConfiguration(configCopy); 16000 } 16001 16002 // Make sure all resources in our process are updated 16003 // right now, so that anyone who is going to retrieve 16004 // resource values after we return will be sure to get 16005 // the new ones. This is especially important during 16006 // boot, where the first config change needs to guarantee 16007 // all resources have that config before following boot 16008 // code is executed. 16009 mSystemThread.applyConfigurationToResources(configCopy); 16010 16011 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16012 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16013 msg.obj = new Configuration(configCopy); 16014 mHandler.sendMessage(msg); 16015 } 16016 16017 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16018 ProcessRecord app = mLruProcesses.get(i); 16019 try { 16020 if (app.thread != null) { 16021 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16022 + app.processName + " new config " + mConfiguration); 16023 app.thread.scheduleConfigurationChanged(configCopy); 16024 } 16025 } catch (Exception e) { 16026 } 16027 } 16028 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16029 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16030 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16031 | Intent.FLAG_RECEIVER_FOREGROUND); 16032 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16033 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16034 Process.SYSTEM_UID, UserHandle.USER_ALL); 16035 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16036 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16037 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16038 broadcastIntentLocked(null, null, intent, 16039 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16040 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16041 } 16042 } 16043 } 16044 16045 boolean kept = true; 16046 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16047 // mainStack is null during startup. 16048 if (mainStack != null) { 16049 if (changes != 0 && starting == null) { 16050 // If the configuration changed, and the caller is not already 16051 // in the process of starting an activity, then find the top 16052 // activity to check if its configuration needs to change. 16053 starting = mainStack.topRunningActivityLocked(null); 16054 } 16055 16056 if (starting != null) { 16057 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16058 // And we need to make sure at this point that all other activities 16059 // are made visible with the correct configuration. 16060 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16061 } 16062 } 16063 16064 if (values != null && mWindowManager != null) { 16065 mWindowManager.setNewConfiguration(mConfiguration); 16066 } 16067 16068 return kept; 16069 } 16070 16071 /** 16072 * Decide based on the configuration whether we should shouw the ANR, 16073 * crash, etc dialogs. The idea is that if there is no affordnace to 16074 * press the on-screen buttons, we shouldn't show the dialog. 16075 * 16076 * A thought: SystemUI might also want to get told about this, the Power 16077 * dialog / global actions also might want different behaviors. 16078 */ 16079 private static final boolean shouldShowDialogs(Configuration config) { 16080 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16081 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16082 } 16083 16084 /** 16085 * Save the locale. You must be inside a synchronized (this) block. 16086 */ 16087 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16088 if(isDiff) { 16089 SystemProperties.set("user.language", l.getLanguage()); 16090 SystemProperties.set("user.region", l.getCountry()); 16091 } 16092 16093 if(isPersist) { 16094 SystemProperties.set("persist.sys.language", l.getLanguage()); 16095 SystemProperties.set("persist.sys.country", l.getCountry()); 16096 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16097 } 16098 } 16099 16100 @Override 16101 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16102 synchronized (this) { 16103 ActivityRecord srec = ActivityRecord.forToken(token); 16104 if (srec.task != null && srec.task.stack != null) { 16105 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16106 } 16107 } 16108 return false; 16109 } 16110 16111 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16112 Intent resultData) { 16113 16114 synchronized (this) { 16115 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16116 if (stack != null) { 16117 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16118 } 16119 return false; 16120 } 16121 } 16122 16123 public int getLaunchedFromUid(IBinder activityToken) { 16124 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16125 if (srec == null) { 16126 return -1; 16127 } 16128 return srec.launchedFromUid; 16129 } 16130 16131 public String getLaunchedFromPackage(IBinder activityToken) { 16132 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16133 if (srec == null) { 16134 return null; 16135 } 16136 return srec.launchedFromPackage; 16137 } 16138 16139 // ========================================================= 16140 // LIFETIME MANAGEMENT 16141 // ========================================================= 16142 16143 // Returns which broadcast queue the app is the current [or imminent] receiver 16144 // on, or 'null' if the app is not an active broadcast recipient. 16145 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16146 BroadcastRecord r = app.curReceiver; 16147 if (r != null) { 16148 return r.queue; 16149 } 16150 16151 // It's not the current receiver, but it might be starting up to become one 16152 synchronized (this) { 16153 for (BroadcastQueue queue : mBroadcastQueues) { 16154 r = queue.mPendingBroadcast; 16155 if (r != null && r.curApp == app) { 16156 // found it; report which queue it's in 16157 return queue; 16158 } 16159 } 16160 } 16161 16162 return null; 16163 } 16164 16165 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16166 boolean doingAll, long now) { 16167 if (mAdjSeq == app.adjSeq) { 16168 // This adjustment has already been computed. 16169 return app.curRawAdj; 16170 } 16171 16172 if (app.thread == null) { 16173 app.adjSeq = mAdjSeq; 16174 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16175 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16176 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16177 } 16178 16179 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16180 app.adjSource = null; 16181 app.adjTarget = null; 16182 app.empty = false; 16183 app.cached = false; 16184 16185 final int activitiesSize = app.activities.size(); 16186 16187 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16188 // The max adjustment doesn't allow this app to be anything 16189 // below foreground, so it is not worth doing work for it. 16190 app.adjType = "fixed"; 16191 app.adjSeq = mAdjSeq; 16192 app.curRawAdj = app.maxAdj; 16193 app.foregroundActivities = false; 16194 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16195 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16196 // System processes can do UI, and when they do we want to have 16197 // them trim their memory after the user leaves the UI. To 16198 // facilitate this, here we need to determine whether or not it 16199 // is currently showing UI. 16200 app.systemNoUi = true; 16201 if (app == TOP_APP) { 16202 app.systemNoUi = false; 16203 } else if (activitiesSize > 0) { 16204 for (int j = 0; j < activitiesSize; j++) { 16205 final ActivityRecord r = app.activities.get(j); 16206 if (r.visible) { 16207 app.systemNoUi = false; 16208 } 16209 } 16210 } 16211 if (!app.systemNoUi) { 16212 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16213 } 16214 return (app.curAdj=app.maxAdj); 16215 } 16216 16217 app.systemNoUi = false; 16218 16219 // Determine the importance of the process, starting with most 16220 // important to least, and assign an appropriate OOM adjustment. 16221 int adj; 16222 int schedGroup; 16223 int procState; 16224 boolean foregroundActivities = false; 16225 BroadcastQueue queue; 16226 if (app == TOP_APP) { 16227 // The last app on the list is the foreground app. 16228 adj = ProcessList.FOREGROUND_APP_ADJ; 16229 schedGroup = Process.THREAD_GROUP_DEFAULT; 16230 app.adjType = "top-activity"; 16231 foregroundActivities = true; 16232 procState = ActivityManager.PROCESS_STATE_TOP; 16233 } else if (app.instrumentationClass != null) { 16234 // Don't want to kill running instrumentation. 16235 adj = ProcessList.FOREGROUND_APP_ADJ; 16236 schedGroup = Process.THREAD_GROUP_DEFAULT; 16237 app.adjType = "instrumentation"; 16238 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16239 } else if ((queue = isReceivingBroadcast(app)) != null) { 16240 // An app that is currently receiving a broadcast also 16241 // counts as being in the foreground for OOM killer purposes. 16242 // It's placed in a sched group based on the nature of the 16243 // broadcast as reflected by which queue it's active in. 16244 adj = ProcessList.FOREGROUND_APP_ADJ; 16245 schedGroup = (queue == mFgBroadcastQueue) 16246 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16247 app.adjType = "broadcast"; 16248 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16249 } else if (app.executingServices.size() > 0) { 16250 // An app that is currently executing a service callback also 16251 // counts as being in the foreground. 16252 adj = ProcessList.FOREGROUND_APP_ADJ; 16253 schedGroup = app.execServicesFg ? 16254 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16255 app.adjType = "exec-service"; 16256 procState = ActivityManager.PROCESS_STATE_SERVICE; 16257 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16258 } else { 16259 // As far as we know the process is empty. We may change our mind later. 16260 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16261 // At this point we don't actually know the adjustment. Use the cached adj 16262 // value that the caller wants us to. 16263 adj = cachedAdj; 16264 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16265 app.cached = true; 16266 app.empty = true; 16267 app.adjType = "cch-empty"; 16268 } 16269 16270 // Examine all activities if not already foreground. 16271 if (!foregroundActivities && activitiesSize > 0) { 16272 for (int j = 0; j < activitiesSize; j++) { 16273 final ActivityRecord r = app.activities.get(j); 16274 if (r.app != app) { 16275 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16276 + app + "?!?"); 16277 continue; 16278 } 16279 if (r.visible) { 16280 // App has a visible activity; only upgrade adjustment. 16281 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16282 adj = ProcessList.VISIBLE_APP_ADJ; 16283 app.adjType = "visible"; 16284 } 16285 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16286 procState = ActivityManager.PROCESS_STATE_TOP; 16287 } 16288 schedGroup = Process.THREAD_GROUP_DEFAULT; 16289 app.cached = false; 16290 app.empty = false; 16291 foregroundActivities = true; 16292 break; 16293 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16294 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16295 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16296 app.adjType = "pausing"; 16297 } 16298 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16299 procState = ActivityManager.PROCESS_STATE_TOP; 16300 } 16301 schedGroup = Process.THREAD_GROUP_DEFAULT; 16302 app.cached = false; 16303 app.empty = false; 16304 foregroundActivities = true; 16305 } else if (r.state == ActivityState.STOPPING) { 16306 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16307 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16308 app.adjType = "stopping"; 16309 } 16310 // For the process state, we will at this point consider the 16311 // process to be cached. It will be cached either as an activity 16312 // or empty depending on whether the activity is finishing. We do 16313 // this so that we can treat the process as cached for purposes of 16314 // memory trimming (determing current memory level, trim command to 16315 // send to process) since there can be an arbitrary number of stopping 16316 // processes and they should soon all go into the cached state. 16317 if (!r.finishing) { 16318 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16319 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16320 } 16321 } 16322 app.cached = false; 16323 app.empty = false; 16324 foregroundActivities = true; 16325 } else { 16326 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16327 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16328 app.adjType = "cch-act"; 16329 } 16330 } 16331 } 16332 } 16333 16334 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16335 if (app.foregroundServices) { 16336 // The user is aware of this app, so make it visible. 16337 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16338 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16339 app.cached = false; 16340 app.adjType = "fg-service"; 16341 schedGroup = Process.THREAD_GROUP_DEFAULT; 16342 } else if (app.forcingToForeground != null) { 16343 // The user is aware of this app, so make it visible. 16344 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16345 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16346 app.cached = false; 16347 app.adjType = "force-fg"; 16348 app.adjSource = app.forcingToForeground; 16349 schedGroup = Process.THREAD_GROUP_DEFAULT; 16350 } 16351 } 16352 16353 if (app == mHeavyWeightProcess) { 16354 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16355 // We don't want to kill the current heavy-weight process. 16356 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16357 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16358 app.cached = false; 16359 app.adjType = "heavy"; 16360 } 16361 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16362 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16363 } 16364 } 16365 16366 if (app == mHomeProcess) { 16367 if (adj > ProcessList.HOME_APP_ADJ) { 16368 // This process is hosting what we currently consider to be the 16369 // home app, so we don't want to let it go into the background. 16370 adj = ProcessList.HOME_APP_ADJ; 16371 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16372 app.cached = false; 16373 app.adjType = "home"; 16374 } 16375 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16376 procState = ActivityManager.PROCESS_STATE_HOME; 16377 } 16378 } 16379 16380 if (app == mPreviousProcess && app.activities.size() > 0) { 16381 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16382 // This was the previous process that showed UI to the user. 16383 // We want to try to keep it around more aggressively, to give 16384 // a good experience around switching between two apps. 16385 adj = ProcessList.PREVIOUS_APP_ADJ; 16386 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16387 app.cached = false; 16388 app.adjType = "previous"; 16389 } 16390 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16391 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16392 } 16393 } 16394 16395 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16396 + " reason=" + app.adjType); 16397 16398 // By default, we use the computed adjustment. It may be changed if 16399 // there are applications dependent on our services or providers, but 16400 // this gives us a baseline and makes sure we don't get into an 16401 // infinite recursion. 16402 app.adjSeq = mAdjSeq; 16403 app.curRawAdj = adj; 16404 app.hasStartedServices = false; 16405 16406 if (mBackupTarget != null && app == mBackupTarget.app) { 16407 // If possible we want to avoid killing apps while they're being backed up 16408 if (adj > ProcessList.BACKUP_APP_ADJ) { 16409 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16410 adj = ProcessList.BACKUP_APP_ADJ; 16411 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16412 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16413 } 16414 app.adjType = "backup"; 16415 app.cached = false; 16416 } 16417 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16418 procState = ActivityManager.PROCESS_STATE_BACKUP; 16419 } 16420 } 16421 16422 boolean mayBeTop = false; 16423 16424 for (int is = app.services.size()-1; 16425 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16426 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16427 || procState > ActivityManager.PROCESS_STATE_TOP); 16428 is--) { 16429 ServiceRecord s = app.services.valueAt(is); 16430 if (s.startRequested) { 16431 app.hasStartedServices = true; 16432 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16433 procState = ActivityManager.PROCESS_STATE_SERVICE; 16434 } 16435 if (app.hasShownUi && app != mHomeProcess) { 16436 // If this process has shown some UI, let it immediately 16437 // go to the LRU list because it may be pretty heavy with 16438 // UI stuff. We'll tag it with a label just to help 16439 // debug and understand what is going on. 16440 if (adj > ProcessList.SERVICE_ADJ) { 16441 app.adjType = "cch-started-ui-services"; 16442 } 16443 } else { 16444 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16445 // This service has seen some activity within 16446 // recent memory, so we will keep its process ahead 16447 // of the background processes. 16448 if (adj > ProcessList.SERVICE_ADJ) { 16449 adj = ProcessList.SERVICE_ADJ; 16450 app.adjType = "started-services"; 16451 app.cached = false; 16452 } 16453 } 16454 // If we have let the service slide into the background 16455 // state, still have some text describing what it is doing 16456 // even though the service no longer has an impact. 16457 if (adj > ProcessList.SERVICE_ADJ) { 16458 app.adjType = "cch-started-services"; 16459 } 16460 } 16461 } 16462 for (int conni = s.connections.size()-1; 16463 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16464 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16465 || procState > ActivityManager.PROCESS_STATE_TOP); 16466 conni--) { 16467 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16468 for (int i = 0; 16469 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16470 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16471 || procState > ActivityManager.PROCESS_STATE_TOP); 16472 i++) { 16473 // XXX should compute this based on the max of 16474 // all connected clients. 16475 ConnectionRecord cr = clist.get(i); 16476 if (cr.binding.client == app) { 16477 // Binding to ourself is not interesting. 16478 continue; 16479 } 16480 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16481 ProcessRecord client = cr.binding.client; 16482 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16483 TOP_APP, doingAll, now); 16484 int clientProcState = client.curProcState; 16485 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16486 // If the other app is cached for any reason, for purposes here 16487 // we are going to consider it empty. The specific cached state 16488 // doesn't propagate except under certain conditions. 16489 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16490 } 16491 String adjType = null; 16492 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16493 // Not doing bind OOM management, so treat 16494 // this guy more like a started service. 16495 if (app.hasShownUi && app != mHomeProcess) { 16496 // If this process has shown some UI, let it immediately 16497 // go to the LRU list because it may be pretty heavy with 16498 // UI stuff. We'll tag it with a label just to help 16499 // debug and understand what is going on. 16500 if (adj > clientAdj) { 16501 adjType = "cch-bound-ui-services"; 16502 } 16503 app.cached = false; 16504 clientAdj = adj; 16505 clientProcState = procState; 16506 } else { 16507 if (now >= (s.lastActivity 16508 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16509 // This service has not seen activity within 16510 // recent memory, so allow it to drop to the 16511 // LRU list if there is no other reason to keep 16512 // it around. We'll also tag it with a label just 16513 // to help debug and undertand what is going on. 16514 if (adj > clientAdj) { 16515 adjType = "cch-bound-services"; 16516 } 16517 clientAdj = adj; 16518 } 16519 } 16520 } 16521 if (adj > clientAdj) { 16522 // If this process has recently shown UI, and 16523 // the process that is binding to it is less 16524 // important than being visible, then we don't 16525 // care about the binding as much as we care 16526 // about letting this process get into the LRU 16527 // list to be killed and restarted if needed for 16528 // memory. 16529 if (app.hasShownUi && app != mHomeProcess 16530 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16531 adjType = "cch-bound-ui-services"; 16532 } else { 16533 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16534 |Context.BIND_IMPORTANT)) != 0) { 16535 adj = clientAdj; 16536 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16537 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16538 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16539 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16540 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16541 adj = clientAdj; 16542 } else { 16543 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16544 adj = ProcessList.VISIBLE_APP_ADJ; 16545 } 16546 } 16547 if (!client.cached) { 16548 app.cached = false; 16549 } 16550 adjType = "service"; 16551 } 16552 } 16553 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16554 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16555 schedGroup = Process.THREAD_GROUP_DEFAULT; 16556 } 16557 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16558 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16559 // Special handling of clients who are in the top state. 16560 // We *may* want to consider this process to be in the 16561 // top state as well, but only if there is not another 16562 // reason for it to be running. Being on the top is a 16563 // special state, meaning you are specifically running 16564 // for the current top app. If the process is already 16565 // running in the background for some other reason, it 16566 // is more important to continue considering it to be 16567 // in the background state. 16568 mayBeTop = true; 16569 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16570 } else { 16571 // Special handling for above-top states (persistent 16572 // processes). These should not bring the current process 16573 // into the top state, since they are not on top. Instead 16574 // give them the best state after that. 16575 clientProcState = 16576 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16577 } 16578 } 16579 } else { 16580 if (clientProcState < 16581 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16582 clientProcState = 16583 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16584 } 16585 } 16586 if (procState > clientProcState) { 16587 procState = clientProcState; 16588 } 16589 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16590 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16591 app.pendingUiClean = true; 16592 } 16593 if (adjType != null) { 16594 app.adjType = adjType; 16595 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16596 .REASON_SERVICE_IN_USE; 16597 app.adjSource = cr.binding.client; 16598 app.adjSourceProcState = clientProcState; 16599 app.adjTarget = s.name; 16600 } 16601 } 16602 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16603 app.treatLikeActivity = true; 16604 } 16605 final ActivityRecord a = cr.activity; 16606 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16607 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16608 (a.visible || a.state == ActivityState.RESUMED 16609 || a.state == ActivityState.PAUSING)) { 16610 adj = ProcessList.FOREGROUND_APP_ADJ; 16611 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16612 schedGroup = Process.THREAD_GROUP_DEFAULT; 16613 } 16614 app.cached = false; 16615 app.adjType = "service"; 16616 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16617 .REASON_SERVICE_IN_USE; 16618 app.adjSource = a; 16619 app.adjSourceProcState = procState; 16620 app.adjTarget = s.name; 16621 } 16622 } 16623 } 16624 } 16625 } 16626 16627 for (int provi = app.pubProviders.size()-1; 16628 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16629 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16630 || procState > ActivityManager.PROCESS_STATE_TOP); 16631 provi--) { 16632 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16633 for (int i = cpr.connections.size()-1; 16634 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16635 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16636 || procState > ActivityManager.PROCESS_STATE_TOP); 16637 i--) { 16638 ContentProviderConnection conn = cpr.connections.get(i); 16639 ProcessRecord client = conn.client; 16640 if (client == app) { 16641 // Being our own client is not interesting. 16642 continue; 16643 } 16644 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16645 int clientProcState = client.curProcState; 16646 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16647 // If the other app is cached for any reason, for purposes here 16648 // we are going to consider it empty. 16649 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16650 } 16651 if (adj > clientAdj) { 16652 if (app.hasShownUi && app != mHomeProcess 16653 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16654 app.adjType = "cch-ui-provider"; 16655 } else { 16656 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16657 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16658 app.adjType = "provider"; 16659 } 16660 app.cached &= client.cached; 16661 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16662 .REASON_PROVIDER_IN_USE; 16663 app.adjSource = client; 16664 app.adjSourceProcState = clientProcState; 16665 app.adjTarget = cpr.name; 16666 } 16667 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16668 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16669 // Special handling of clients who are in the top state. 16670 // We *may* want to consider this process to be in the 16671 // top state as well, but only if there is not another 16672 // reason for it to be running. Being on the top is a 16673 // special state, meaning you are specifically running 16674 // for the current top app. If the process is already 16675 // running in the background for some other reason, it 16676 // is more important to continue considering it to be 16677 // in the background state. 16678 mayBeTop = true; 16679 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16680 } else { 16681 // Special handling for above-top states (persistent 16682 // processes). These should not bring the current process 16683 // into the top state, since they are not on top. Instead 16684 // give them the best state after that. 16685 clientProcState = 16686 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16687 } 16688 } 16689 if (procState > clientProcState) { 16690 procState = clientProcState; 16691 } 16692 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16693 schedGroup = Process.THREAD_GROUP_DEFAULT; 16694 } 16695 } 16696 // If the provider has external (non-framework) process 16697 // dependencies, ensure that its adjustment is at least 16698 // FOREGROUND_APP_ADJ. 16699 if (cpr.hasExternalProcessHandles()) { 16700 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16701 adj = ProcessList.FOREGROUND_APP_ADJ; 16702 schedGroup = Process.THREAD_GROUP_DEFAULT; 16703 app.cached = false; 16704 app.adjType = "provider"; 16705 app.adjTarget = cpr.name; 16706 } 16707 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16708 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16709 } 16710 } 16711 } 16712 16713 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16714 // A client of one of our services or providers is in the top state. We 16715 // *may* want to be in the top state, but not if we are already running in 16716 // the background for some other reason. For the decision here, we are going 16717 // to pick out a few specific states that we want to remain in when a client 16718 // is top (states that tend to be longer-term) and otherwise allow it to go 16719 // to the top state. 16720 switch (procState) { 16721 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16722 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16723 case ActivityManager.PROCESS_STATE_SERVICE: 16724 // These all are longer-term states, so pull them up to the top 16725 // of the background states, but not all the way to the top state. 16726 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16727 break; 16728 default: 16729 // Otherwise, top is a better choice, so take it. 16730 procState = ActivityManager.PROCESS_STATE_TOP; 16731 break; 16732 } 16733 } 16734 16735 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16736 if (app.hasClientActivities) { 16737 // This is a cached process, but with client activities. Mark it so. 16738 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16739 app.adjType = "cch-client-act"; 16740 } else if (app.treatLikeActivity) { 16741 // This is a cached process, but somebody wants us to treat it like it has 16742 // an activity, okay! 16743 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16744 app.adjType = "cch-as-act"; 16745 } 16746 } 16747 16748 if (adj == ProcessList.SERVICE_ADJ) { 16749 if (doingAll) { 16750 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16751 mNewNumServiceProcs++; 16752 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16753 if (!app.serviceb) { 16754 // This service isn't far enough down on the LRU list to 16755 // normally be a B service, but if we are low on RAM and it 16756 // is large we want to force it down since we would prefer to 16757 // keep launcher over it. 16758 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16759 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16760 app.serviceHighRam = true; 16761 app.serviceb = true; 16762 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16763 } else { 16764 mNewNumAServiceProcs++; 16765 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16766 } 16767 } else { 16768 app.serviceHighRam = false; 16769 } 16770 } 16771 if (app.serviceb) { 16772 adj = ProcessList.SERVICE_B_ADJ; 16773 } 16774 } 16775 16776 app.curRawAdj = adj; 16777 16778 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16779 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16780 if (adj > app.maxAdj) { 16781 adj = app.maxAdj; 16782 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16783 schedGroup = Process.THREAD_GROUP_DEFAULT; 16784 } 16785 } 16786 16787 // Do final modification to adj. Everything we do between here and applying 16788 // the final setAdj must be done in this function, because we will also use 16789 // it when computing the final cached adj later. Note that we don't need to 16790 // worry about this for max adj above, since max adj will always be used to 16791 // keep it out of the cached vaues. 16792 app.curAdj = app.modifyRawOomAdj(adj); 16793 app.curSchedGroup = schedGroup; 16794 app.curProcState = procState; 16795 app.foregroundActivities = foregroundActivities; 16796 16797 return app.curRawAdj; 16798 } 16799 16800 /** 16801 * Schedule PSS collection of a process. 16802 */ 16803 void requestPssLocked(ProcessRecord proc, int procState) { 16804 if (mPendingPssProcesses.contains(proc)) { 16805 return; 16806 } 16807 if (mPendingPssProcesses.size() == 0) { 16808 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16809 } 16810 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16811 proc.pssProcState = procState; 16812 mPendingPssProcesses.add(proc); 16813 } 16814 16815 /** 16816 * Schedule PSS collection of all processes. 16817 */ 16818 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16819 if (!always) { 16820 if (now < (mLastFullPssTime + 16821 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16822 return; 16823 } 16824 } 16825 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16826 mLastFullPssTime = now; 16827 mFullPssPending = true; 16828 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16829 mPendingPssProcesses.clear(); 16830 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16831 ProcessRecord app = mLruProcesses.get(i); 16832 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16833 app.pssProcState = app.setProcState; 16834 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16835 isSleeping(), now); 16836 mPendingPssProcesses.add(app); 16837 } 16838 } 16839 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16840 } 16841 16842 /** 16843 * Ask a given process to GC right now. 16844 */ 16845 final void performAppGcLocked(ProcessRecord app) { 16846 try { 16847 app.lastRequestedGc = SystemClock.uptimeMillis(); 16848 if (app.thread != null) { 16849 if (app.reportLowMemory) { 16850 app.reportLowMemory = false; 16851 app.thread.scheduleLowMemory(); 16852 } else { 16853 app.thread.processInBackground(); 16854 } 16855 } 16856 } catch (Exception e) { 16857 // whatever. 16858 } 16859 } 16860 16861 /** 16862 * Returns true if things are idle enough to perform GCs. 16863 */ 16864 private final boolean canGcNowLocked() { 16865 boolean processingBroadcasts = false; 16866 for (BroadcastQueue q : mBroadcastQueues) { 16867 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16868 processingBroadcasts = true; 16869 } 16870 } 16871 return !processingBroadcasts 16872 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16873 } 16874 16875 /** 16876 * Perform GCs on all processes that are waiting for it, but only 16877 * if things are idle. 16878 */ 16879 final void performAppGcsLocked() { 16880 final int N = mProcessesToGc.size(); 16881 if (N <= 0) { 16882 return; 16883 } 16884 if (canGcNowLocked()) { 16885 while (mProcessesToGc.size() > 0) { 16886 ProcessRecord proc = mProcessesToGc.remove(0); 16887 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16888 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16889 <= SystemClock.uptimeMillis()) { 16890 // To avoid spamming the system, we will GC processes one 16891 // at a time, waiting a few seconds between each. 16892 performAppGcLocked(proc); 16893 scheduleAppGcsLocked(); 16894 return; 16895 } else { 16896 // It hasn't been long enough since we last GCed this 16897 // process... put it in the list to wait for its time. 16898 addProcessToGcListLocked(proc); 16899 break; 16900 } 16901 } 16902 } 16903 16904 scheduleAppGcsLocked(); 16905 } 16906 } 16907 16908 /** 16909 * If all looks good, perform GCs on all processes waiting for them. 16910 */ 16911 final void performAppGcsIfAppropriateLocked() { 16912 if (canGcNowLocked()) { 16913 performAppGcsLocked(); 16914 return; 16915 } 16916 // Still not idle, wait some more. 16917 scheduleAppGcsLocked(); 16918 } 16919 16920 /** 16921 * Schedule the execution of all pending app GCs. 16922 */ 16923 final void scheduleAppGcsLocked() { 16924 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16925 16926 if (mProcessesToGc.size() > 0) { 16927 // Schedule a GC for the time to the next process. 16928 ProcessRecord proc = mProcessesToGc.get(0); 16929 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16930 16931 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16932 long now = SystemClock.uptimeMillis(); 16933 if (when < (now+GC_TIMEOUT)) { 16934 when = now + GC_TIMEOUT; 16935 } 16936 mHandler.sendMessageAtTime(msg, when); 16937 } 16938 } 16939 16940 /** 16941 * Add a process to the array of processes waiting to be GCed. Keeps the 16942 * list in sorted order by the last GC time. The process can't already be 16943 * on the list. 16944 */ 16945 final void addProcessToGcListLocked(ProcessRecord proc) { 16946 boolean added = false; 16947 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16948 if (mProcessesToGc.get(i).lastRequestedGc < 16949 proc.lastRequestedGc) { 16950 added = true; 16951 mProcessesToGc.add(i+1, proc); 16952 break; 16953 } 16954 } 16955 if (!added) { 16956 mProcessesToGc.add(0, proc); 16957 } 16958 } 16959 16960 /** 16961 * Set up to ask a process to GC itself. This will either do it 16962 * immediately, or put it on the list of processes to gc the next 16963 * time things are idle. 16964 */ 16965 final void scheduleAppGcLocked(ProcessRecord app) { 16966 long now = SystemClock.uptimeMillis(); 16967 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16968 return; 16969 } 16970 if (!mProcessesToGc.contains(app)) { 16971 addProcessToGcListLocked(app); 16972 scheduleAppGcsLocked(); 16973 } 16974 } 16975 16976 final void checkExcessivePowerUsageLocked(boolean doKills) { 16977 updateCpuStatsNow(); 16978 16979 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16980 boolean doWakeKills = doKills; 16981 boolean doCpuKills = doKills; 16982 if (mLastPowerCheckRealtime == 0) { 16983 doWakeKills = false; 16984 } 16985 if (mLastPowerCheckUptime == 0) { 16986 doCpuKills = false; 16987 } 16988 if (stats.isScreenOn()) { 16989 doWakeKills = false; 16990 } 16991 final long curRealtime = SystemClock.elapsedRealtime(); 16992 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16993 final long curUptime = SystemClock.uptimeMillis(); 16994 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16995 mLastPowerCheckRealtime = curRealtime; 16996 mLastPowerCheckUptime = curUptime; 16997 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16998 doWakeKills = false; 16999 } 17000 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17001 doCpuKills = false; 17002 } 17003 int i = mLruProcesses.size(); 17004 while (i > 0) { 17005 i--; 17006 ProcessRecord app = mLruProcesses.get(i); 17007 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17008 long wtime; 17009 synchronized (stats) { 17010 wtime = stats.getProcessWakeTime(app.info.uid, 17011 app.pid, curRealtime); 17012 } 17013 long wtimeUsed = wtime - app.lastWakeTime; 17014 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17015 if (DEBUG_POWER) { 17016 StringBuilder sb = new StringBuilder(128); 17017 sb.append("Wake for "); 17018 app.toShortString(sb); 17019 sb.append(": over "); 17020 TimeUtils.formatDuration(realtimeSince, sb); 17021 sb.append(" used "); 17022 TimeUtils.formatDuration(wtimeUsed, sb); 17023 sb.append(" ("); 17024 sb.append((wtimeUsed*100)/realtimeSince); 17025 sb.append("%)"); 17026 Slog.i(TAG, sb.toString()); 17027 sb.setLength(0); 17028 sb.append("CPU for "); 17029 app.toShortString(sb); 17030 sb.append(": over "); 17031 TimeUtils.formatDuration(uptimeSince, sb); 17032 sb.append(" used "); 17033 TimeUtils.formatDuration(cputimeUsed, sb); 17034 sb.append(" ("); 17035 sb.append((cputimeUsed*100)/uptimeSince); 17036 sb.append("%)"); 17037 Slog.i(TAG, sb.toString()); 17038 } 17039 // If a process has held a wake lock for more 17040 // than 50% of the time during this period, 17041 // that sounds bad. Kill! 17042 if (doWakeKills && realtimeSince > 0 17043 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17044 synchronized (stats) { 17045 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17046 realtimeSince, wtimeUsed); 17047 } 17048 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17049 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17050 } else if (doCpuKills && uptimeSince > 0 17051 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17052 synchronized (stats) { 17053 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17054 uptimeSince, cputimeUsed); 17055 } 17056 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17057 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17058 } else { 17059 app.lastWakeTime = wtime; 17060 app.lastCpuTime = app.curCpuTime; 17061 } 17062 } 17063 } 17064 } 17065 17066 private final boolean applyOomAdjLocked(ProcessRecord app, 17067 ProcessRecord TOP_APP, boolean doingAll, long now) { 17068 boolean success = true; 17069 17070 if (app.curRawAdj != app.setRawAdj) { 17071 app.setRawAdj = app.curRawAdj; 17072 } 17073 17074 int changes = 0; 17075 17076 if (app.curAdj != app.setAdj) { 17077 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17078 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17079 TAG, "Set " + app.pid + " " + app.processName + 17080 " adj " + app.curAdj + ": " + app.adjType); 17081 app.setAdj = app.curAdj; 17082 } 17083 17084 if (app.setSchedGroup != app.curSchedGroup) { 17085 app.setSchedGroup = app.curSchedGroup; 17086 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17087 "Setting process group of " + app.processName 17088 + " to " + app.curSchedGroup); 17089 if (app.waitingToKill != null && 17090 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17091 app.kill(app.waitingToKill, true); 17092 success = false; 17093 } else { 17094 if (true) { 17095 long oldId = Binder.clearCallingIdentity(); 17096 try { 17097 Process.setProcessGroup(app.pid, app.curSchedGroup); 17098 } catch (Exception e) { 17099 Slog.w(TAG, "Failed setting process group of " + app.pid 17100 + " to " + app.curSchedGroup); 17101 e.printStackTrace(); 17102 } finally { 17103 Binder.restoreCallingIdentity(oldId); 17104 } 17105 } else { 17106 if (app.thread != null) { 17107 try { 17108 app.thread.setSchedulingGroup(app.curSchedGroup); 17109 } catch (RemoteException e) { 17110 } 17111 } 17112 } 17113 Process.setSwappiness(app.pid, 17114 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17115 } 17116 } 17117 if (app.repForegroundActivities != app.foregroundActivities) { 17118 app.repForegroundActivities = app.foregroundActivities; 17119 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17120 } 17121 if (app.repProcState != app.curProcState) { 17122 app.repProcState = app.curProcState; 17123 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17124 if (app.thread != null) { 17125 try { 17126 if (false) { 17127 //RuntimeException h = new RuntimeException("here"); 17128 Slog.i(TAG, "Sending new process state " + app.repProcState 17129 + " to " + app /*, h*/); 17130 } 17131 app.thread.setProcessState(app.repProcState); 17132 } catch (RemoteException e) { 17133 } 17134 } 17135 } 17136 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17137 app.setProcState)) { 17138 app.lastStateTime = now; 17139 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17140 isSleeping(), now); 17141 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17142 + ProcessList.makeProcStateString(app.setProcState) + " to " 17143 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17144 + (app.nextPssTime-now) + ": " + app); 17145 } else { 17146 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17147 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17148 requestPssLocked(app, app.setProcState); 17149 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17150 isSleeping(), now); 17151 } else if (false && DEBUG_PSS) { 17152 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17153 } 17154 } 17155 if (app.setProcState != app.curProcState) { 17156 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17157 "Proc state change of " + app.processName 17158 + " to " + app.curProcState); 17159 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17160 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17161 if (setImportant && !curImportant) { 17162 // This app is no longer something we consider important enough to allow to 17163 // use arbitrary amounts of battery power. Note 17164 // its current wake lock time to later know to kill it if 17165 // it is not behaving well. 17166 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17167 synchronized (stats) { 17168 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17169 app.pid, SystemClock.elapsedRealtime()); 17170 } 17171 app.lastCpuTime = app.curCpuTime; 17172 17173 } 17174 app.setProcState = app.curProcState; 17175 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17176 app.notCachedSinceIdle = false; 17177 } 17178 if (!doingAll) { 17179 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17180 } else { 17181 app.procStateChanged = true; 17182 } 17183 } 17184 17185 if (changes != 0) { 17186 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17187 int i = mPendingProcessChanges.size()-1; 17188 ProcessChangeItem item = null; 17189 while (i >= 0) { 17190 item = mPendingProcessChanges.get(i); 17191 if (item.pid == app.pid) { 17192 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17193 break; 17194 } 17195 i--; 17196 } 17197 if (i < 0) { 17198 // No existing item in pending changes; need a new one. 17199 final int NA = mAvailProcessChanges.size(); 17200 if (NA > 0) { 17201 item = mAvailProcessChanges.remove(NA-1); 17202 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17203 } else { 17204 item = new ProcessChangeItem(); 17205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17206 } 17207 item.changes = 0; 17208 item.pid = app.pid; 17209 item.uid = app.info.uid; 17210 if (mPendingProcessChanges.size() == 0) { 17211 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17212 "*** Enqueueing dispatch processes changed!"); 17213 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17214 } 17215 mPendingProcessChanges.add(item); 17216 } 17217 item.changes |= changes; 17218 item.processState = app.repProcState; 17219 item.foregroundActivities = app.repForegroundActivities; 17220 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17221 + Integer.toHexString(System.identityHashCode(item)) 17222 + " " + app.toShortString() + ": changes=" + item.changes 17223 + " procState=" + item.processState 17224 + " foreground=" + item.foregroundActivities 17225 + " type=" + app.adjType + " source=" + app.adjSource 17226 + " target=" + app.adjTarget); 17227 } 17228 17229 return success; 17230 } 17231 17232 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17233 if (proc.thread != null) { 17234 if (proc.baseProcessTracker != null) { 17235 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17236 } 17237 if (proc.repProcState >= 0) { 17238 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17239 proc.repProcState); 17240 } 17241 } 17242 } 17243 17244 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17245 ProcessRecord TOP_APP, boolean doingAll, long now) { 17246 if (app.thread == null) { 17247 return false; 17248 } 17249 17250 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17251 17252 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17253 } 17254 17255 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17256 boolean oomAdj) { 17257 if (isForeground != proc.foregroundServices) { 17258 proc.foregroundServices = isForeground; 17259 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17260 proc.info.uid); 17261 if (isForeground) { 17262 if (curProcs == null) { 17263 curProcs = new ArrayList<ProcessRecord>(); 17264 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17265 } 17266 if (!curProcs.contains(proc)) { 17267 curProcs.add(proc); 17268 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17269 proc.info.packageName, proc.info.uid); 17270 } 17271 } else { 17272 if (curProcs != null) { 17273 if (curProcs.remove(proc)) { 17274 mBatteryStatsService.noteEvent( 17275 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17276 proc.info.packageName, proc.info.uid); 17277 if (curProcs.size() <= 0) { 17278 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17279 } 17280 } 17281 } 17282 } 17283 if (oomAdj) { 17284 updateOomAdjLocked(); 17285 } 17286 } 17287 } 17288 17289 private final ActivityRecord resumedAppLocked() { 17290 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17291 String pkg; 17292 int uid; 17293 if (act != null) { 17294 pkg = act.packageName; 17295 uid = act.info.applicationInfo.uid; 17296 } else { 17297 pkg = null; 17298 uid = -1; 17299 } 17300 // Has the UID or resumed package name changed? 17301 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17302 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17303 if (mCurResumedPackage != null) { 17304 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17305 mCurResumedPackage, mCurResumedUid); 17306 } 17307 mCurResumedPackage = pkg; 17308 mCurResumedUid = uid; 17309 if (mCurResumedPackage != null) { 17310 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17311 mCurResumedPackage, mCurResumedUid); 17312 } 17313 } 17314 return act; 17315 } 17316 17317 final boolean updateOomAdjLocked(ProcessRecord app) { 17318 final ActivityRecord TOP_ACT = resumedAppLocked(); 17319 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17320 final boolean wasCached = app.cached; 17321 17322 mAdjSeq++; 17323 17324 // This is the desired cached adjusment we want to tell it to use. 17325 // If our app is currently cached, we know it, and that is it. Otherwise, 17326 // we don't know it yet, and it needs to now be cached we will then 17327 // need to do a complete oom adj. 17328 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17329 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17330 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17331 SystemClock.uptimeMillis()); 17332 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17333 // Changed to/from cached state, so apps after it in the LRU 17334 // list may also be changed. 17335 updateOomAdjLocked(); 17336 } 17337 return success; 17338 } 17339 17340 final void updateOomAdjLocked() { 17341 final ActivityRecord TOP_ACT = resumedAppLocked(); 17342 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17343 final long now = SystemClock.uptimeMillis(); 17344 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17345 final int N = mLruProcesses.size(); 17346 17347 if (false) { 17348 RuntimeException e = new RuntimeException(); 17349 e.fillInStackTrace(); 17350 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17351 } 17352 17353 mAdjSeq++; 17354 mNewNumServiceProcs = 0; 17355 mNewNumAServiceProcs = 0; 17356 17357 final int emptyProcessLimit; 17358 final int cachedProcessLimit; 17359 if (mProcessLimit <= 0) { 17360 emptyProcessLimit = cachedProcessLimit = 0; 17361 } else if (mProcessLimit == 1) { 17362 emptyProcessLimit = 1; 17363 cachedProcessLimit = 0; 17364 } else { 17365 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17366 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17367 } 17368 17369 // Let's determine how many processes we have running vs. 17370 // how many slots we have for background processes; we may want 17371 // to put multiple processes in a slot of there are enough of 17372 // them. 17373 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17374 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17375 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17376 if (numEmptyProcs > cachedProcessLimit) { 17377 // If there are more empty processes than our limit on cached 17378 // processes, then use the cached process limit for the factor. 17379 // This ensures that the really old empty processes get pushed 17380 // down to the bottom, so if we are running low on memory we will 17381 // have a better chance at keeping around more cached processes 17382 // instead of a gazillion empty processes. 17383 numEmptyProcs = cachedProcessLimit; 17384 } 17385 int emptyFactor = numEmptyProcs/numSlots; 17386 if (emptyFactor < 1) emptyFactor = 1; 17387 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17388 if (cachedFactor < 1) cachedFactor = 1; 17389 int stepCached = 0; 17390 int stepEmpty = 0; 17391 int numCached = 0; 17392 int numEmpty = 0; 17393 int numTrimming = 0; 17394 17395 mNumNonCachedProcs = 0; 17396 mNumCachedHiddenProcs = 0; 17397 17398 // First update the OOM adjustment for each of the 17399 // application processes based on their current state. 17400 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17401 int nextCachedAdj = curCachedAdj+1; 17402 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17403 int nextEmptyAdj = curEmptyAdj+2; 17404 for (int i=N-1; i>=0; i--) { 17405 ProcessRecord app = mLruProcesses.get(i); 17406 if (!app.killedByAm && app.thread != null) { 17407 app.procStateChanged = false; 17408 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17409 17410 // If we haven't yet assigned the final cached adj 17411 // to the process, do that now. 17412 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17413 switch (app.curProcState) { 17414 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17415 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17416 // This process is a cached process holding activities... 17417 // assign it the next cached value for that type, and then 17418 // step that cached level. 17419 app.curRawAdj = curCachedAdj; 17420 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17421 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17422 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17423 + ")"); 17424 if (curCachedAdj != nextCachedAdj) { 17425 stepCached++; 17426 if (stepCached >= cachedFactor) { 17427 stepCached = 0; 17428 curCachedAdj = nextCachedAdj; 17429 nextCachedAdj += 2; 17430 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17431 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17432 } 17433 } 17434 } 17435 break; 17436 default: 17437 // For everything else, assign next empty cached process 17438 // level and bump that up. Note that this means that 17439 // long-running services that have dropped down to the 17440 // cached level will be treated as empty (since their process 17441 // state is still as a service), which is what we want. 17442 app.curRawAdj = curEmptyAdj; 17443 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17444 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17445 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17446 + ")"); 17447 if (curEmptyAdj != nextEmptyAdj) { 17448 stepEmpty++; 17449 if (stepEmpty >= emptyFactor) { 17450 stepEmpty = 0; 17451 curEmptyAdj = nextEmptyAdj; 17452 nextEmptyAdj += 2; 17453 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17454 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17455 } 17456 } 17457 } 17458 break; 17459 } 17460 } 17461 17462 applyOomAdjLocked(app, TOP_APP, true, now); 17463 17464 // Count the number of process types. 17465 switch (app.curProcState) { 17466 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17467 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17468 mNumCachedHiddenProcs++; 17469 numCached++; 17470 if (numCached > cachedProcessLimit) { 17471 app.kill("cached #" + numCached, true); 17472 } 17473 break; 17474 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17475 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17476 && app.lastActivityTime < oldTime) { 17477 app.kill("empty for " 17478 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17479 / 1000) + "s", true); 17480 } else { 17481 numEmpty++; 17482 if (numEmpty > emptyProcessLimit) { 17483 app.kill("empty #" + numEmpty, true); 17484 } 17485 } 17486 break; 17487 default: 17488 mNumNonCachedProcs++; 17489 break; 17490 } 17491 17492 if (app.isolated && app.services.size() <= 0) { 17493 // If this is an isolated process, and there are no 17494 // services running in it, then the process is no longer 17495 // needed. We agressively kill these because we can by 17496 // definition not re-use the same process again, and it is 17497 // good to avoid having whatever code was running in them 17498 // left sitting around after no longer needed. 17499 app.kill("isolated not needed", true); 17500 } 17501 17502 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17503 && !app.killedByAm) { 17504 numTrimming++; 17505 } 17506 } 17507 } 17508 17509 mNumServiceProcs = mNewNumServiceProcs; 17510 17511 // Now determine the memory trimming level of background processes. 17512 // Unfortunately we need to start at the back of the list to do this 17513 // properly. We only do this if the number of background apps we 17514 // are managing to keep around is less than half the maximum we desire; 17515 // if we are keeping a good number around, we'll let them use whatever 17516 // memory they want. 17517 final int numCachedAndEmpty = numCached + numEmpty; 17518 int memFactor; 17519 if (numCached <= ProcessList.TRIM_CACHED_APPS 17520 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17521 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17522 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17523 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17524 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17525 } else { 17526 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17527 } 17528 } else { 17529 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17530 } 17531 // We always allow the memory level to go up (better). We only allow it to go 17532 // down if we are in a state where that is allowed, *and* the total number of processes 17533 // has gone down since last time. 17534 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17535 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17536 + " last=" + mLastNumProcesses); 17537 if (memFactor > mLastMemoryLevel) { 17538 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17539 memFactor = mLastMemoryLevel; 17540 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17541 } 17542 } 17543 mLastMemoryLevel = memFactor; 17544 mLastNumProcesses = mLruProcesses.size(); 17545 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17546 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17547 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17548 if (mLowRamStartTime == 0) { 17549 mLowRamStartTime = now; 17550 } 17551 int step = 0; 17552 int fgTrimLevel; 17553 switch (memFactor) { 17554 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17555 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17556 break; 17557 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17558 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17559 break; 17560 default: 17561 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17562 break; 17563 } 17564 int factor = numTrimming/3; 17565 int minFactor = 2; 17566 if (mHomeProcess != null) minFactor++; 17567 if (mPreviousProcess != null) minFactor++; 17568 if (factor < minFactor) factor = minFactor; 17569 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17570 for (int i=N-1; i>=0; i--) { 17571 ProcessRecord app = mLruProcesses.get(i); 17572 if (allChanged || app.procStateChanged) { 17573 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17574 app.procStateChanged = false; 17575 } 17576 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17577 && !app.killedByAm) { 17578 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17579 try { 17580 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17581 "Trimming memory of " + app.processName 17582 + " to " + curLevel); 17583 app.thread.scheduleTrimMemory(curLevel); 17584 } catch (RemoteException e) { 17585 } 17586 if (false) { 17587 // For now we won't do this; our memory trimming seems 17588 // to be good enough at this point that destroying 17589 // activities causes more harm than good. 17590 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17591 && app != mHomeProcess && app != mPreviousProcess) { 17592 // Need to do this on its own message because the stack may not 17593 // be in a consistent state at this point. 17594 // For these apps we will also finish their activities 17595 // to help them free memory. 17596 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17597 } 17598 } 17599 } 17600 app.trimMemoryLevel = curLevel; 17601 step++; 17602 if (step >= factor) { 17603 step = 0; 17604 switch (curLevel) { 17605 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17606 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17607 break; 17608 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17609 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17610 break; 17611 } 17612 } 17613 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17614 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17615 && app.thread != null) { 17616 try { 17617 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17618 "Trimming memory of heavy-weight " + app.processName 17619 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17620 app.thread.scheduleTrimMemory( 17621 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17622 } catch (RemoteException e) { 17623 } 17624 } 17625 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17626 } else { 17627 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17628 || app.systemNoUi) && app.pendingUiClean) { 17629 // If this application is now in the background and it 17630 // had done UI, then give it the special trim level to 17631 // have it free UI resources. 17632 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17633 if (app.trimMemoryLevel < level && app.thread != null) { 17634 try { 17635 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17636 "Trimming memory of bg-ui " + app.processName 17637 + " to " + level); 17638 app.thread.scheduleTrimMemory(level); 17639 } catch (RemoteException e) { 17640 } 17641 } 17642 app.pendingUiClean = false; 17643 } 17644 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17645 try { 17646 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17647 "Trimming memory of fg " + app.processName 17648 + " to " + fgTrimLevel); 17649 app.thread.scheduleTrimMemory(fgTrimLevel); 17650 } catch (RemoteException e) { 17651 } 17652 } 17653 app.trimMemoryLevel = fgTrimLevel; 17654 } 17655 } 17656 } else { 17657 if (mLowRamStartTime != 0) { 17658 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17659 mLowRamStartTime = 0; 17660 } 17661 for (int i=N-1; i>=0; i--) { 17662 ProcessRecord app = mLruProcesses.get(i); 17663 if (allChanged || app.procStateChanged) { 17664 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17665 app.procStateChanged = false; 17666 } 17667 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17668 || app.systemNoUi) && app.pendingUiClean) { 17669 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17670 && app.thread != null) { 17671 try { 17672 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17673 "Trimming memory of ui hidden " + app.processName 17674 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17675 app.thread.scheduleTrimMemory( 17676 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17677 } catch (RemoteException e) { 17678 } 17679 } 17680 app.pendingUiClean = false; 17681 } 17682 app.trimMemoryLevel = 0; 17683 } 17684 } 17685 17686 if (mAlwaysFinishActivities) { 17687 // Need to do this on its own message because the stack may not 17688 // be in a consistent state at this point. 17689 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17690 } 17691 17692 if (allChanged) { 17693 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17694 } 17695 17696 if (mProcessStats.shouldWriteNowLocked(now)) { 17697 mHandler.post(new Runnable() { 17698 @Override public void run() { 17699 synchronized (ActivityManagerService.this) { 17700 mProcessStats.writeStateAsyncLocked(); 17701 } 17702 } 17703 }); 17704 } 17705 17706 if (DEBUG_OOM_ADJ) { 17707 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17708 } 17709 } 17710 17711 final void trimApplications() { 17712 synchronized (this) { 17713 int i; 17714 17715 // First remove any unused application processes whose package 17716 // has been removed. 17717 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17718 final ProcessRecord app = mRemovedProcesses.get(i); 17719 if (app.activities.size() == 0 17720 && app.curReceiver == null && app.services.size() == 0) { 17721 Slog.i( 17722 TAG, "Exiting empty application process " 17723 + app.processName + " (" 17724 + (app.thread != null ? app.thread.asBinder() : null) 17725 + ")\n"); 17726 if (app.pid > 0 && app.pid != MY_PID) { 17727 app.kill("empty", false); 17728 } else { 17729 try { 17730 app.thread.scheduleExit(); 17731 } catch (Exception e) { 17732 // Ignore exceptions. 17733 } 17734 } 17735 cleanUpApplicationRecordLocked(app, false, true, -1); 17736 mRemovedProcesses.remove(i); 17737 17738 if (app.persistent) { 17739 addAppLocked(app.info, false, null /* ABI override */); 17740 } 17741 } 17742 } 17743 17744 // Now update the oom adj for all processes. 17745 updateOomAdjLocked(); 17746 } 17747 } 17748 17749 /** This method sends the specified signal to each of the persistent apps */ 17750 public void signalPersistentProcesses(int sig) throws RemoteException { 17751 if (sig != Process.SIGNAL_USR1) { 17752 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17753 } 17754 17755 synchronized (this) { 17756 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17757 != PackageManager.PERMISSION_GRANTED) { 17758 throw new SecurityException("Requires permission " 17759 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17760 } 17761 17762 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17763 ProcessRecord r = mLruProcesses.get(i); 17764 if (r.thread != null && r.persistent) { 17765 Process.sendSignal(r.pid, sig); 17766 } 17767 } 17768 } 17769 } 17770 17771 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17772 if (proc == null || proc == mProfileProc) { 17773 proc = mProfileProc; 17774 profileType = mProfileType; 17775 clearProfilerLocked(); 17776 } 17777 if (proc == null) { 17778 return; 17779 } 17780 try { 17781 proc.thread.profilerControl(false, null, profileType); 17782 } catch (RemoteException e) { 17783 throw new IllegalStateException("Process disappeared"); 17784 } 17785 } 17786 17787 private void clearProfilerLocked() { 17788 if (mProfileFd != null) { 17789 try { 17790 mProfileFd.close(); 17791 } catch (IOException e) { 17792 } 17793 } 17794 mProfileApp = null; 17795 mProfileProc = null; 17796 mProfileFile = null; 17797 mProfileType = 0; 17798 mAutoStopProfiler = false; 17799 mSamplingInterval = 0; 17800 } 17801 17802 public boolean profileControl(String process, int userId, boolean start, 17803 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17804 17805 try { 17806 synchronized (this) { 17807 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17808 // its own permission. 17809 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17810 != PackageManager.PERMISSION_GRANTED) { 17811 throw new SecurityException("Requires permission " 17812 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17813 } 17814 17815 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17816 throw new IllegalArgumentException("null profile info or fd"); 17817 } 17818 17819 ProcessRecord proc = null; 17820 if (process != null) { 17821 proc = findProcessLocked(process, userId, "profileControl"); 17822 } 17823 17824 if (start && (proc == null || proc.thread == null)) { 17825 throw new IllegalArgumentException("Unknown process: " + process); 17826 } 17827 17828 if (start) { 17829 stopProfilerLocked(null, 0); 17830 setProfileApp(proc.info, proc.processName, profilerInfo); 17831 mProfileProc = proc; 17832 mProfileType = profileType; 17833 ParcelFileDescriptor fd = profilerInfo.profileFd; 17834 try { 17835 fd = fd.dup(); 17836 } catch (IOException e) { 17837 fd = null; 17838 } 17839 profilerInfo.profileFd = fd; 17840 proc.thread.profilerControl(start, profilerInfo, profileType); 17841 fd = null; 17842 mProfileFd = null; 17843 } else { 17844 stopProfilerLocked(proc, profileType); 17845 if (profilerInfo != null && profilerInfo.profileFd != null) { 17846 try { 17847 profilerInfo.profileFd.close(); 17848 } catch (IOException e) { 17849 } 17850 } 17851 } 17852 17853 return true; 17854 } 17855 } catch (RemoteException e) { 17856 throw new IllegalStateException("Process disappeared"); 17857 } finally { 17858 if (profilerInfo != null && profilerInfo.profileFd != null) { 17859 try { 17860 profilerInfo.profileFd.close(); 17861 } catch (IOException e) { 17862 } 17863 } 17864 } 17865 } 17866 17867 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17868 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17869 userId, true, ALLOW_FULL_ONLY, callName, null); 17870 ProcessRecord proc = null; 17871 try { 17872 int pid = Integer.parseInt(process); 17873 synchronized (mPidsSelfLocked) { 17874 proc = mPidsSelfLocked.get(pid); 17875 } 17876 } catch (NumberFormatException e) { 17877 } 17878 17879 if (proc == null) { 17880 ArrayMap<String, SparseArray<ProcessRecord>> all 17881 = mProcessNames.getMap(); 17882 SparseArray<ProcessRecord> procs = all.get(process); 17883 if (procs != null && procs.size() > 0) { 17884 proc = procs.valueAt(0); 17885 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17886 for (int i=1; i<procs.size(); i++) { 17887 ProcessRecord thisProc = procs.valueAt(i); 17888 if (thisProc.userId == userId) { 17889 proc = thisProc; 17890 break; 17891 } 17892 } 17893 } 17894 } 17895 } 17896 17897 return proc; 17898 } 17899 17900 public boolean dumpHeap(String process, int userId, boolean managed, 17901 String path, ParcelFileDescriptor fd) throws RemoteException { 17902 17903 try { 17904 synchronized (this) { 17905 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17906 // its own permission (same as profileControl). 17907 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17908 != PackageManager.PERMISSION_GRANTED) { 17909 throw new SecurityException("Requires permission " 17910 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17911 } 17912 17913 if (fd == null) { 17914 throw new IllegalArgumentException("null fd"); 17915 } 17916 17917 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17918 if (proc == null || proc.thread == null) { 17919 throw new IllegalArgumentException("Unknown process: " + process); 17920 } 17921 17922 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17923 if (!isDebuggable) { 17924 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17925 throw new SecurityException("Process not debuggable: " + proc); 17926 } 17927 } 17928 17929 proc.thread.dumpHeap(managed, path, fd); 17930 fd = null; 17931 return true; 17932 } 17933 } catch (RemoteException e) { 17934 throw new IllegalStateException("Process disappeared"); 17935 } finally { 17936 if (fd != null) { 17937 try { 17938 fd.close(); 17939 } catch (IOException e) { 17940 } 17941 } 17942 } 17943 } 17944 17945 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17946 public void monitor() { 17947 synchronized (this) { } 17948 } 17949 17950 void onCoreSettingsChange(Bundle settings) { 17951 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17952 ProcessRecord processRecord = mLruProcesses.get(i); 17953 try { 17954 if (processRecord.thread != null) { 17955 processRecord.thread.setCoreSettings(settings); 17956 } 17957 } catch (RemoteException re) { 17958 /* ignore */ 17959 } 17960 } 17961 } 17962 17963 // Multi-user methods 17964 17965 /** 17966 * Start user, if its not already running, but don't bring it to foreground. 17967 */ 17968 @Override 17969 public boolean startUserInBackground(final int userId) { 17970 return startUser(userId, /* foreground */ false); 17971 } 17972 17973 /** 17974 * Start user, if its not already running, and bring it to foreground. 17975 */ 17976 boolean startUserInForeground(final int userId, Dialog dlg) { 17977 boolean result = startUser(userId, /* foreground */ true); 17978 dlg.dismiss(); 17979 return result; 17980 } 17981 17982 /** 17983 * Refreshes the list of users related to the current user when either a 17984 * user switch happens or when a new related user is started in the 17985 * background. 17986 */ 17987 private void updateCurrentProfileIdsLocked() { 17988 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17989 mCurrentUserId, false /* enabledOnly */); 17990 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17991 for (int i = 0; i < currentProfileIds.length; i++) { 17992 currentProfileIds[i] = profiles.get(i).id; 17993 } 17994 mCurrentProfileIds = currentProfileIds; 17995 17996 synchronized (mUserProfileGroupIdsSelfLocked) { 17997 mUserProfileGroupIdsSelfLocked.clear(); 17998 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17999 for (int i = 0; i < users.size(); i++) { 18000 UserInfo user = users.get(i); 18001 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18002 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18003 } 18004 } 18005 } 18006 } 18007 18008 private Set getProfileIdsLocked(int userId) { 18009 Set userIds = new HashSet<Integer>(); 18010 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18011 userId, false /* enabledOnly */); 18012 for (UserInfo user : profiles) { 18013 userIds.add(Integer.valueOf(user.id)); 18014 } 18015 return userIds; 18016 } 18017 18018 @Override 18019 public boolean switchUser(final int userId) { 18020 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18021 String userName; 18022 synchronized (this) { 18023 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18024 if (userInfo == null) { 18025 Slog.w(TAG, "No user info for user #" + userId); 18026 return false; 18027 } 18028 if (userInfo.isManagedProfile()) { 18029 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18030 return false; 18031 } 18032 userName = userInfo.name; 18033 mTargetUserId = userId; 18034 } 18035 mHandler.removeMessages(START_USER_SWITCH_MSG); 18036 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18037 return true; 18038 } 18039 18040 private void showUserSwitchDialog(int userId, String userName) { 18041 // The dialog will show and then initiate the user switch by calling startUserInForeground 18042 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18043 true /* above system */); 18044 d.show(); 18045 } 18046 18047 private boolean startUser(final int userId, final boolean foreground) { 18048 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18049 != PackageManager.PERMISSION_GRANTED) { 18050 String msg = "Permission Denial: switchUser() from pid=" 18051 + Binder.getCallingPid() 18052 + ", uid=" + Binder.getCallingUid() 18053 + " requires " + INTERACT_ACROSS_USERS_FULL; 18054 Slog.w(TAG, msg); 18055 throw new SecurityException(msg); 18056 } 18057 18058 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18059 18060 final long ident = Binder.clearCallingIdentity(); 18061 try { 18062 synchronized (this) { 18063 final int oldUserId = mCurrentUserId; 18064 if (oldUserId == userId) { 18065 return true; 18066 } 18067 18068 mStackSupervisor.setLockTaskModeLocked(null, false); 18069 18070 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18071 if (userInfo == null) { 18072 Slog.w(TAG, "No user info for user #" + userId); 18073 return false; 18074 } 18075 if (foreground && userInfo.isManagedProfile()) { 18076 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18077 return false; 18078 } 18079 18080 if (foreground) { 18081 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18082 R.anim.screen_user_enter); 18083 } 18084 18085 boolean needStart = false; 18086 18087 // If the user we are switching to is not currently started, then 18088 // we need to start it now. 18089 if (mStartedUsers.get(userId) == null) { 18090 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18091 updateStartedUserArrayLocked(); 18092 needStart = true; 18093 } 18094 18095 final Integer userIdInt = Integer.valueOf(userId); 18096 mUserLru.remove(userIdInt); 18097 mUserLru.add(userIdInt); 18098 18099 if (foreground) { 18100 mCurrentUserId = userId; 18101 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18102 updateCurrentProfileIdsLocked(); 18103 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18104 // Once the internal notion of the active user has switched, we lock the device 18105 // with the option to show the user switcher on the keyguard. 18106 mWindowManager.lockNow(null); 18107 } else { 18108 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18109 updateCurrentProfileIdsLocked(); 18110 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18111 mUserLru.remove(currentUserIdInt); 18112 mUserLru.add(currentUserIdInt); 18113 } 18114 18115 final UserStartedState uss = mStartedUsers.get(userId); 18116 18117 // Make sure user is in the started state. If it is currently 18118 // stopping, we need to knock that off. 18119 if (uss.mState == UserStartedState.STATE_STOPPING) { 18120 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18121 // so we can just fairly silently bring the user back from 18122 // the almost-dead. 18123 uss.mState = UserStartedState.STATE_RUNNING; 18124 updateStartedUserArrayLocked(); 18125 needStart = true; 18126 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18127 // This means ACTION_SHUTDOWN has been sent, so we will 18128 // need to treat this as a new boot of the user. 18129 uss.mState = UserStartedState.STATE_BOOTING; 18130 updateStartedUserArrayLocked(); 18131 needStart = true; 18132 } 18133 18134 if (uss.mState == UserStartedState.STATE_BOOTING) { 18135 // Booting up a new user, need to tell system services about it. 18136 // Note that this is on the same handler as scheduling of broadcasts, 18137 // which is important because it needs to go first. 18138 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18139 } 18140 18141 if (foreground) { 18142 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18143 oldUserId)); 18144 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18145 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18146 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18147 oldUserId, userId, uss)); 18148 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18149 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18150 } 18151 18152 if (needStart) { 18153 // Send USER_STARTED broadcast 18154 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18155 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18156 | Intent.FLAG_RECEIVER_FOREGROUND); 18157 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18158 broadcastIntentLocked(null, null, intent, 18159 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18160 false, false, MY_PID, Process.SYSTEM_UID, userId); 18161 } 18162 18163 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18164 if (userId != UserHandle.USER_OWNER) { 18165 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18166 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18167 broadcastIntentLocked(null, null, intent, null, 18168 new IIntentReceiver.Stub() { 18169 public void performReceive(Intent intent, int resultCode, 18170 String data, Bundle extras, boolean ordered, 18171 boolean sticky, int sendingUser) { 18172 onUserInitialized(uss, foreground, oldUserId, userId); 18173 } 18174 }, 0, null, null, null, AppOpsManager.OP_NONE, 18175 true, false, MY_PID, Process.SYSTEM_UID, 18176 userId); 18177 uss.initializing = true; 18178 } else { 18179 getUserManagerLocked().makeInitialized(userInfo.id); 18180 } 18181 } 18182 18183 if (foreground) { 18184 if (!uss.initializing) { 18185 moveUserToForeground(uss, oldUserId, userId); 18186 } 18187 } else { 18188 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18189 } 18190 18191 if (needStart) { 18192 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18193 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18194 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18195 broadcastIntentLocked(null, null, intent, 18196 null, new IIntentReceiver.Stub() { 18197 @Override 18198 public void performReceive(Intent intent, int resultCode, String data, 18199 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18200 throws RemoteException { 18201 } 18202 }, 0, null, null, 18203 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18204 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18205 } 18206 } 18207 } finally { 18208 Binder.restoreCallingIdentity(ident); 18209 } 18210 18211 return true; 18212 } 18213 18214 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18215 long ident = Binder.clearCallingIdentity(); 18216 try { 18217 Intent intent; 18218 if (oldUserId >= 0) { 18219 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18220 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18221 int count = profiles.size(); 18222 for (int i = 0; i < count; i++) { 18223 int profileUserId = profiles.get(i).id; 18224 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18225 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18226 | Intent.FLAG_RECEIVER_FOREGROUND); 18227 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18228 broadcastIntentLocked(null, null, intent, 18229 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18230 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18231 } 18232 } 18233 if (newUserId >= 0) { 18234 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18235 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18236 int count = profiles.size(); 18237 for (int i = 0; i < count; i++) { 18238 int profileUserId = profiles.get(i).id; 18239 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18241 | Intent.FLAG_RECEIVER_FOREGROUND); 18242 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18243 broadcastIntentLocked(null, null, intent, 18244 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18245 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18246 } 18247 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18248 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18249 | Intent.FLAG_RECEIVER_FOREGROUND); 18250 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18251 broadcastIntentLocked(null, null, intent, 18252 null, null, 0, null, null, 18253 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18254 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18255 } 18256 } finally { 18257 Binder.restoreCallingIdentity(ident); 18258 } 18259 } 18260 18261 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18262 final int newUserId) { 18263 final int N = mUserSwitchObservers.beginBroadcast(); 18264 if (N > 0) { 18265 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18266 int mCount = 0; 18267 @Override 18268 public void sendResult(Bundle data) throws RemoteException { 18269 synchronized (ActivityManagerService.this) { 18270 if (mCurUserSwitchCallback == this) { 18271 mCount++; 18272 if (mCount == N) { 18273 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18274 } 18275 } 18276 } 18277 } 18278 }; 18279 synchronized (this) { 18280 uss.switching = true; 18281 mCurUserSwitchCallback = callback; 18282 } 18283 for (int i=0; i<N; i++) { 18284 try { 18285 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18286 newUserId, callback); 18287 } catch (RemoteException e) { 18288 } 18289 } 18290 } else { 18291 synchronized (this) { 18292 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18293 } 18294 } 18295 mUserSwitchObservers.finishBroadcast(); 18296 } 18297 18298 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18299 synchronized (this) { 18300 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18301 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18302 } 18303 } 18304 18305 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18306 mCurUserSwitchCallback = null; 18307 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18308 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18309 oldUserId, newUserId, uss)); 18310 } 18311 18312 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18313 synchronized (this) { 18314 if (foreground) { 18315 moveUserToForeground(uss, oldUserId, newUserId); 18316 } 18317 } 18318 18319 completeSwitchAndInitalize(uss, newUserId, true, false); 18320 } 18321 18322 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18323 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18324 if (homeInFront) { 18325 startHomeActivityLocked(newUserId); 18326 } else { 18327 mStackSupervisor.resumeTopActivitiesLocked(); 18328 } 18329 EventLogTags.writeAmSwitchUser(newUserId); 18330 getUserManagerLocked().userForeground(newUserId); 18331 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18332 } 18333 18334 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18335 completeSwitchAndInitalize(uss, newUserId, false, true); 18336 } 18337 18338 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18339 boolean clearInitializing, boolean clearSwitching) { 18340 boolean unfrozen = false; 18341 synchronized (this) { 18342 if (clearInitializing) { 18343 uss.initializing = false; 18344 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18345 } 18346 if (clearSwitching) { 18347 uss.switching = false; 18348 } 18349 if (!uss.switching && !uss.initializing) { 18350 mWindowManager.stopFreezingScreen(); 18351 unfrozen = true; 18352 } 18353 } 18354 if (unfrozen) { 18355 final int N = mUserSwitchObservers.beginBroadcast(); 18356 for (int i=0; i<N; i++) { 18357 try { 18358 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18359 } catch (RemoteException e) { 18360 } 18361 } 18362 mUserSwitchObservers.finishBroadcast(); 18363 } 18364 } 18365 18366 void scheduleStartProfilesLocked() { 18367 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18368 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18369 DateUtils.SECOND_IN_MILLIS); 18370 } 18371 } 18372 18373 void startProfilesLocked() { 18374 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18375 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18376 mCurrentUserId, false /* enabledOnly */); 18377 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18378 for (UserInfo user : profiles) { 18379 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18380 && user.id != mCurrentUserId) { 18381 toStart.add(user); 18382 } 18383 } 18384 final int n = toStart.size(); 18385 int i = 0; 18386 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18387 startUserInBackground(toStart.get(i).id); 18388 } 18389 if (i < n) { 18390 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18391 } 18392 } 18393 18394 void finishUserBoot(UserStartedState uss) { 18395 synchronized (this) { 18396 if (uss.mState == UserStartedState.STATE_BOOTING 18397 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18398 uss.mState = UserStartedState.STATE_RUNNING; 18399 final int userId = uss.mHandle.getIdentifier(); 18400 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18401 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18402 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18403 broadcastIntentLocked(null, null, intent, 18404 null, null, 0, null, null, 18405 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18406 true, false, MY_PID, Process.SYSTEM_UID, userId); 18407 } 18408 } 18409 } 18410 18411 void finishUserSwitch(UserStartedState uss) { 18412 synchronized (this) { 18413 finishUserBoot(uss); 18414 18415 startProfilesLocked(); 18416 18417 int num = mUserLru.size(); 18418 int i = 0; 18419 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18420 Integer oldUserId = mUserLru.get(i); 18421 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18422 if (oldUss == null) { 18423 // Shouldn't happen, but be sane if it does. 18424 mUserLru.remove(i); 18425 num--; 18426 continue; 18427 } 18428 if (oldUss.mState == UserStartedState.STATE_STOPPING 18429 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18430 // This user is already stopping, doesn't count. 18431 num--; 18432 i++; 18433 continue; 18434 } 18435 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18436 // Owner and current can't be stopped, but count as running. 18437 i++; 18438 continue; 18439 } 18440 // This is a user to be stopped. 18441 stopUserLocked(oldUserId, null); 18442 num--; 18443 i++; 18444 } 18445 } 18446 } 18447 18448 @Override 18449 public int stopUser(final int userId, final IStopUserCallback callback) { 18450 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18451 != PackageManager.PERMISSION_GRANTED) { 18452 String msg = "Permission Denial: switchUser() from pid=" 18453 + Binder.getCallingPid() 18454 + ", uid=" + Binder.getCallingUid() 18455 + " requires " + INTERACT_ACROSS_USERS_FULL; 18456 Slog.w(TAG, msg); 18457 throw new SecurityException(msg); 18458 } 18459 if (userId <= 0) { 18460 throw new IllegalArgumentException("Can't stop primary user " + userId); 18461 } 18462 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18463 synchronized (this) { 18464 return stopUserLocked(userId, callback); 18465 } 18466 } 18467 18468 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18469 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18470 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18471 return ActivityManager.USER_OP_IS_CURRENT; 18472 } 18473 18474 final UserStartedState uss = mStartedUsers.get(userId); 18475 if (uss == null) { 18476 // User is not started, nothing to do... but we do need to 18477 // callback if requested. 18478 if (callback != null) { 18479 mHandler.post(new Runnable() { 18480 @Override 18481 public void run() { 18482 try { 18483 callback.userStopped(userId); 18484 } catch (RemoteException e) { 18485 } 18486 } 18487 }); 18488 } 18489 return ActivityManager.USER_OP_SUCCESS; 18490 } 18491 18492 if (callback != null) { 18493 uss.mStopCallbacks.add(callback); 18494 } 18495 18496 if (uss.mState != UserStartedState.STATE_STOPPING 18497 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18498 uss.mState = UserStartedState.STATE_STOPPING; 18499 updateStartedUserArrayLocked(); 18500 18501 long ident = Binder.clearCallingIdentity(); 18502 try { 18503 // We are going to broadcast ACTION_USER_STOPPING and then 18504 // once that is done send a final ACTION_SHUTDOWN and then 18505 // stop the user. 18506 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18507 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18508 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18509 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18510 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18511 // This is the result receiver for the final shutdown broadcast. 18512 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18513 @Override 18514 public void performReceive(Intent intent, int resultCode, String data, 18515 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18516 finishUserStop(uss); 18517 } 18518 }; 18519 // This is the result receiver for the initial stopping broadcast. 18520 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18521 @Override 18522 public void performReceive(Intent intent, int resultCode, String data, 18523 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18524 // On to the next. 18525 synchronized (ActivityManagerService.this) { 18526 if (uss.mState != UserStartedState.STATE_STOPPING) { 18527 // Whoops, we are being started back up. Abort, abort! 18528 return; 18529 } 18530 uss.mState = UserStartedState.STATE_SHUTDOWN; 18531 } 18532 mBatteryStatsService.noteEvent( 18533 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18534 Integer.toString(userId), userId); 18535 mSystemServiceManager.stopUser(userId); 18536 broadcastIntentLocked(null, null, shutdownIntent, 18537 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18538 true, false, MY_PID, Process.SYSTEM_UID, userId); 18539 } 18540 }; 18541 // Kick things off. 18542 broadcastIntentLocked(null, null, stoppingIntent, 18543 null, stoppingReceiver, 0, null, null, 18544 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18545 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18546 } finally { 18547 Binder.restoreCallingIdentity(ident); 18548 } 18549 } 18550 18551 return ActivityManager.USER_OP_SUCCESS; 18552 } 18553 18554 void finishUserStop(UserStartedState uss) { 18555 final int userId = uss.mHandle.getIdentifier(); 18556 boolean stopped; 18557 ArrayList<IStopUserCallback> callbacks; 18558 synchronized (this) { 18559 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18560 if (mStartedUsers.get(userId) != uss) { 18561 stopped = false; 18562 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18563 stopped = false; 18564 } else { 18565 stopped = true; 18566 // User can no longer run. 18567 mStartedUsers.remove(userId); 18568 mUserLru.remove(Integer.valueOf(userId)); 18569 updateStartedUserArrayLocked(); 18570 18571 // Clean up all state and processes associated with the user. 18572 // Kill all the processes for the user. 18573 forceStopUserLocked(userId, "finish user"); 18574 } 18575 18576 // Explicitly remove the old information in mRecentTasks. 18577 removeRecentTasksForUserLocked(userId); 18578 } 18579 18580 for (int i=0; i<callbacks.size(); i++) { 18581 try { 18582 if (stopped) callbacks.get(i).userStopped(userId); 18583 else callbacks.get(i).userStopAborted(userId); 18584 } catch (RemoteException e) { 18585 } 18586 } 18587 18588 if (stopped) { 18589 mSystemServiceManager.cleanupUser(userId); 18590 synchronized (this) { 18591 mStackSupervisor.removeUserLocked(userId); 18592 } 18593 } 18594 } 18595 18596 @Override 18597 public UserInfo getCurrentUser() { 18598 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18599 != PackageManager.PERMISSION_GRANTED) && ( 18600 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18601 != PackageManager.PERMISSION_GRANTED)) { 18602 String msg = "Permission Denial: getCurrentUser() from pid=" 18603 + Binder.getCallingPid() 18604 + ", uid=" + Binder.getCallingUid() 18605 + " requires " + INTERACT_ACROSS_USERS; 18606 Slog.w(TAG, msg); 18607 throw new SecurityException(msg); 18608 } 18609 synchronized (this) { 18610 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18611 return getUserManagerLocked().getUserInfo(userId); 18612 } 18613 } 18614 18615 int getCurrentUserIdLocked() { 18616 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18617 } 18618 18619 @Override 18620 public boolean isUserRunning(int userId, boolean orStopped) { 18621 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18622 != PackageManager.PERMISSION_GRANTED) { 18623 String msg = "Permission Denial: isUserRunning() from pid=" 18624 + Binder.getCallingPid() 18625 + ", uid=" + Binder.getCallingUid() 18626 + " requires " + INTERACT_ACROSS_USERS; 18627 Slog.w(TAG, msg); 18628 throw new SecurityException(msg); 18629 } 18630 synchronized (this) { 18631 return isUserRunningLocked(userId, orStopped); 18632 } 18633 } 18634 18635 boolean isUserRunningLocked(int userId, boolean orStopped) { 18636 UserStartedState state = mStartedUsers.get(userId); 18637 if (state == null) { 18638 return false; 18639 } 18640 if (orStopped) { 18641 return true; 18642 } 18643 return state.mState != UserStartedState.STATE_STOPPING 18644 && state.mState != UserStartedState.STATE_SHUTDOWN; 18645 } 18646 18647 @Override 18648 public int[] getRunningUserIds() { 18649 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18650 != PackageManager.PERMISSION_GRANTED) { 18651 String msg = "Permission Denial: isUserRunning() from pid=" 18652 + Binder.getCallingPid() 18653 + ", uid=" + Binder.getCallingUid() 18654 + " requires " + INTERACT_ACROSS_USERS; 18655 Slog.w(TAG, msg); 18656 throw new SecurityException(msg); 18657 } 18658 synchronized (this) { 18659 return mStartedUserArray; 18660 } 18661 } 18662 18663 private void updateStartedUserArrayLocked() { 18664 int num = 0; 18665 for (int i=0; i<mStartedUsers.size(); i++) { 18666 UserStartedState uss = mStartedUsers.valueAt(i); 18667 // This list does not include stopping users. 18668 if (uss.mState != UserStartedState.STATE_STOPPING 18669 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18670 num++; 18671 } 18672 } 18673 mStartedUserArray = new int[num]; 18674 num = 0; 18675 for (int i=0; i<mStartedUsers.size(); i++) { 18676 UserStartedState uss = mStartedUsers.valueAt(i); 18677 if (uss.mState != UserStartedState.STATE_STOPPING 18678 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18679 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18680 num++; 18681 } 18682 } 18683 } 18684 18685 @Override 18686 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18687 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18688 != PackageManager.PERMISSION_GRANTED) { 18689 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18690 + Binder.getCallingPid() 18691 + ", uid=" + Binder.getCallingUid() 18692 + " requires " + INTERACT_ACROSS_USERS_FULL; 18693 Slog.w(TAG, msg); 18694 throw new SecurityException(msg); 18695 } 18696 18697 mUserSwitchObservers.register(observer); 18698 } 18699 18700 @Override 18701 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18702 mUserSwitchObservers.unregister(observer); 18703 } 18704 18705 private boolean userExists(int userId) { 18706 if (userId == 0) { 18707 return true; 18708 } 18709 UserManagerService ums = getUserManagerLocked(); 18710 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18711 } 18712 18713 int[] getUsersLocked() { 18714 UserManagerService ums = getUserManagerLocked(); 18715 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18716 } 18717 18718 UserManagerService getUserManagerLocked() { 18719 if (mUserManager == null) { 18720 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18721 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18722 } 18723 return mUserManager; 18724 } 18725 18726 private int applyUserId(int uid, int userId) { 18727 return UserHandle.getUid(userId, uid); 18728 } 18729 18730 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18731 if (info == null) return null; 18732 ApplicationInfo newInfo = new ApplicationInfo(info); 18733 newInfo.uid = applyUserId(info.uid, userId); 18734 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18735 + info.packageName; 18736 return newInfo; 18737 } 18738 18739 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18740 if (aInfo == null 18741 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18742 return aInfo; 18743 } 18744 18745 ActivityInfo info = new ActivityInfo(aInfo); 18746 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18747 return info; 18748 } 18749 18750 private final class LocalService extends ActivityManagerInternal { 18751 @Override 18752 public void goingToSleep() { 18753 ActivityManagerService.this.goingToSleep(); 18754 } 18755 18756 @Override 18757 public void wakingUp() { 18758 ActivityManagerService.this.wakingUp(); 18759 } 18760 18761 @Override 18762 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18763 String processName, String abiOverride, int uid, Runnable crashHandler) { 18764 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18765 processName, abiOverride, uid, crashHandler); 18766 } 18767 } 18768 18769 /** 18770 * An implementation of IAppTask, that allows an app to manage its own tasks via 18771 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18772 * only the process that calls getAppTasks() can call the AppTask methods. 18773 */ 18774 class AppTaskImpl extends IAppTask.Stub { 18775 private int mTaskId; 18776 private int mCallingUid; 18777 18778 public AppTaskImpl(int taskId, int callingUid) { 18779 mTaskId = taskId; 18780 mCallingUid = callingUid; 18781 } 18782 18783 private void checkCaller() { 18784 if (mCallingUid != Binder.getCallingUid()) { 18785 throw new SecurityException("Caller " + mCallingUid 18786 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18787 } 18788 } 18789 18790 @Override 18791 public void finishAndRemoveTask() { 18792 checkCaller(); 18793 18794 synchronized (ActivityManagerService.this) { 18795 long origId = Binder.clearCallingIdentity(); 18796 try { 18797 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18798 if (tr == null) { 18799 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18800 } 18801 // Only kill the process if we are not a new document 18802 int flags = tr.getBaseIntent().getFlags(); 18803 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18804 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18805 removeTaskByIdLocked(mTaskId, 18806 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18807 } finally { 18808 Binder.restoreCallingIdentity(origId); 18809 } 18810 } 18811 } 18812 18813 @Override 18814 public ActivityManager.RecentTaskInfo getTaskInfo() { 18815 checkCaller(); 18816 18817 synchronized (ActivityManagerService.this) { 18818 long origId = Binder.clearCallingIdentity(); 18819 try { 18820 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18821 if (tr == null) { 18822 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18823 } 18824 return createRecentTaskInfoFromTaskRecord(tr); 18825 } finally { 18826 Binder.restoreCallingIdentity(origId); 18827 } 18828 } 18829 } 18830 18831 @Override 18832 public void moveToFront() { 18833 checkCaller(); 18834 18835 final TaskRecord tr; 18836 synchronized (ActivityManagerService.this) { 18837 tr = recentTaskForIdLocked(mTaskId); 18838 if (tr == null) { 18839 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18840 } 18841 if (tr.getRootActivity() != null) { 18842 long origId = Binder.clearCallingIdentity(); 18843 try { 18844 moveTaskToFrontLocked(tr.taskId, 0, null); 18845 return; 18846 } finally { 18847 Binder.restoreCallingIdentity(origId); 18848 } 18849 } 18850 } 18851 18852 startActivityFromRecentsInner(tr.taskId, null); 18853 } 18854 18855 @Override 18856 public int startActivity(IBinder whoThread, String callingPackage, 18857 Intent intent, String resolvedType, Bundle options) { 18858 checkCaller(); 18859 18860 int callingUser = UserHandle.getCallingUserId(); 18861 TaskRecord tr; 18862 IApplicationThread appThread; 18863 synchronized (ActivityManagerService.this) { 18864 tr = recentTaskForIdLocked(mTaskId); 18865 if (tr == null) { 18866 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18867 } 18868 appThread = ApplicationThreadNative.asInterface(whoThread); 18869 if (appThread == null) { 18870 throw new IllegalArgumentException("Bad app thread " + appThread); 18871 } 18872 } 18873 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18874 resolvedType, null, null, null, null, 0, 0, null, null, 18875 null, options, callingUser, null, tr); 18876 } 18877 18878 @Override 18879 public void setExcludeFromRecents(boolean exclude) { 18880 checkCaller(); 18881 18882 synchronized (ActivityManagerService.this) { 18883 long origId = Binder.clearCallingIdentity(); 18884 try { 18885 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18886 if (tr == null) { 18887 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18888 } 18889 Intent intent = tr.getBaseIntent(); 18890 if (exclude) { 18891 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18892 } else { 18893 intent.setFlags(intent.getFlags() 18894 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18895 } 18896 } finally { 18897 Binder.restoreCallingIdentity(origId); 18898 } 18899 } 18900 } 18901 } 18902} 18903