ActivityManagerService.java revision d412563922f46feb4d3c3ba1500f34bddd21d73c
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * Set while the keyguard is waiting for an activity to draw. 941 * In this state, if we are sleeping, we allow Activities to launch 942 * so that they can draw before Keyguard dismisses itself. 943 */ 944 private boolean mKeyguardWaitingForDraw = false; 945 946 /** 947 * State of external calls telling us if the device is asleep. 948 */ 949 private boolean mWentToSleep = false; 950 951 /** 952 * State of external call telling us if the lock screen is shown. 953 */ 954 private boolean mLockScreenShown = false; 955 956 /** 957 * Set if we are shutting down the system, similar to sleeping. 958 */ 959 boolean mShuttingDown = false; 960 961 /** 962 * Current sequence id for oom_adj computation traversal. 963 */ 964 int mAdjSeq = 0; 965 966 /** 967 * Current sequence id for process LRU updating. 968 */ 969 int mLruSeq = 0; 970 971 /** 972 * Keep track of the non-cached/empty process we last found, to help 973 * determine how to distribute cached/empty processes next time. 974 */ 975 int mNumNonCachedProcs = 0; 976 977 /** 978 * Keep track of the number of cached hidden procs, to balance oom adj 979 * distribution between those and empty procs. 980 */ 981 int mNumCachedHiddenProcs = 0; 982 983 /** 984 * Keep track of the number of service processes we last found, to 985 * determine on the next iteration which should be B services. 986 */ 987 int mNumServiceProcs = 0; 988 int mNewNumAServiceProcs = 0; 989 int mNewNumServiceProcs = 0; 990 991 /** 992 * Allow the current computed overall memory level of the system to go down? 993 * This is set to false when we are killing processes for reasons other than 994 * memory management, so that the now smaller process list will not be taken as 995 * an indication that memory is tighter. 996 */ 997 boolean mAllowLowerMemLevel = false; 998 999 /** 1000 * The last computed memory level, for holding when we are in a state that 1001 * processes are going away for other reasons. 1002 */ 1003 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1004 1005 /** 1006 * The last total number of process we have, to determine if changes actually look 1007 * like a shrinking number of process due to lower RAM. 1008 */ 1009 int mLastNumProcesses; 1010 1011 /** 1012 * The uptime of the last time we performed idle maintenance. 1013 */ 1014 long mLastIdleTime = SystemClock.uptimeMillis(); 1015 1016 /** 1017 * Total time spent with RAM that has been added in the past since the last idle time. 1018 */ 1019 long mLowRamTimeSinceLastIdle = 0; 1020 1021 /** 1022 * If RAM is currently low, when that horrible situation started. 1023 */ 1024 long mLowRamStartTime = 0; 1025 1026 /** 1027 * For reporting to battery stats the current top application. 1028 */ 1029 private String mCurResumedPackage = null; 1030 private int mCurResumedUid = -1; 1031 1032 /** 1033 * For reporting to battery stats the apps currently running foreground 1034 * service. The ProcessMap is package/uid tuples; each of these contain 1035 * an array of the currently foreground processes. 1036 */ 1037 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1038 = new ProcessMap<ArrayList<ProcessRecord>>(); 1039 1040 /** 1041 * This is set if we had to do a delayed dexopt of an app before launching 1042 * it, to increase the ANR timeouts in that case. 1043 */ 1044 boolean mDidDexOpt; 1045 1046 /** 1047 * Set if the systemServer made a call to enterSafeMode. 1048 */ 1049 boolean mSafeMode; 1050 1051 String mDebugApp = null; 1052 boolean mWaitForDebugger = false; 1053 boolean mDebugTransient = false; 1054 String mOrigDebugApp = null; 1055 boolean mOrigWaitForDebugger = false; 1056 boolean mAlwaysFinishActivities = false; 1057 IActivityController mController = null; 1058 String mProfileApp = null; 1059 ProcessRecord mProfileProc = null; 1060 String mProfileFile; 1061 ParcelFileDescriptor mProfileFd; 1062 int mSamplingInterval = 0; 1063 boolean mAutoStopProfiler = false; 1064 int mProfileType = 0; 1065 String mOpenGlTraceApp = null; 1066 1067 static class ProcessChangeItem { 1068 static final int CHANGE_ACTIVITIES = 1<<0; 1069 static final int CHANGE_PROCESS_STATE = 1<<1; 1070 int changes; 1071 int uid; 1072 int pid; 1073 int processState; 1074 boolean foregroundActivities; 1075 } 1076 1077 final RemoteCallbackList<IProcessObserver> mProcessObservers 1078 = new RemoteCallbackList<IProcessObserver>(); 1079 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1080 1081 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1082 = new ArrayList<ProcessChangeItem>(); 1083 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1084 = new ArrayList<ProcessChangeItem>(); 1085 1086 /** 1087 * Runtime CPU use collection thread. This object's lock is used to 1088 * perform synchronization with the thread (notifying it to run). 1089 */ 1090 final Thread mProcessCpuThread; 1091 1092 /** 1093 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1094 * Must acquire this object's lock when accessing it. 1095 * NOTE: this lock will be held while doing long operations (trawling 1096 * through all processes in /proc), so it should never be acquired by 1097 * any critical paths such as when holding the main activity manager lock. 1098 */ 1099 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1100 MONITOR_THREAD_CPU_USAGE); 1101 final AtomicLong mLastCpuTime = new AtomicLong(0); 1102 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1103 1104 long mLastWriteTime = 0; 1105 1106 /** 1107 * Used to retain an update lock when the foreground activity is in 1108 * immersive mode. 1109 */ 1110 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1111 1112 /** 1113 * Set to true after the system has finished booting. 1114 */ 1115 boolean mBooted = false; 1116 1117 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1118 int mProcessLimitOverride = -1; 1119 1120 WindowManagerService mWindowManager; 1121 1122 final ActivityThread mSystemThread; 1123 1124 // Holds the current foreground user's id 1125 int mCurrentUserId = 0; 1126 // Holds the target user's id during a user switch 1127 int mTargetUserId = UserHandle.USER_NULL; 1128 // If there are multiple profiles for the current user, their ids are here 1129 // Currently only the primary user can have managed profiles 1130 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1131 1132 /** 1133 * Mapping from each known user ID to the profile group ID it is associated with. 1134 */ 1135 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1136 1137 private UserManagerService mUserManager; 1138 1139 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1140 final ProcessRecord mApp; 1141 final int mPid; 1142 final IApplicationThread mAppThread; 1143 1144 AppDeathRecipient(ProcessRecord app, int pid, 1145 IApplicationThread thread) { 1146 if (localLOGV) Slog.v( 1147 TAG, "New death recipient " + this 1148 + " for thread " + thread.asBinder()); 1149 mApp = app; 1150 mPid = pid; 1151 mAppThread = thread; 1152 } 1153 1154 @Override 1155 public void binderDied() { 1156 if (localLOGV) Slog.v( 1157 TAG, "Death received in " + this 1158 + " for thread " + mAppThread.asBinder()); 1159 synchronized(ActivityManagerService.this) { 1160 appDiedLocked(mApp, mPid, mAppThread); 1161 } 1162 } 1163 } 1164 1165 static final int SHOW_ERROR_MSG = 1; 1166 static final int SHOW_NOT_RESPONDING_MSG = 2; 1167 static final int SHOW_FACTORY_ERROR_MSG = 3; 1168 static final int UPDATE_CONFIGURATION_MSG = 4; 1169 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1170 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1171 static final int SERVICE_TIMEOUT_MSG = 12; 1172 static final int UPDATE_TIME_ZONE = 13; 1173 static final int SHOW_UID_ERROR_MSG = 14; 1174 static final int IM_FEELING_LUCKY_MSG = 15; 1175 static final int PROC_START_TIMEOUT_MSG = 20; 1176 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1177 static final int KILL_APPLICATION_MSG = 22; 1178 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1179 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1180 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1181 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1182 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1183 static final int CLEAR_DNS_CACHE_MSG = 28; 1184 static final int UPDATE_HTTP_PROXY_MSG = 29; 1185 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1186 static final int DISPATCH_PROCESSES_CHANGED = 31; 1187 static final int DISPATCH_PROCESS_DIED = 32; 1188 static final int REPORT_MEM_USAGE_MSG = 33; 1189 static final int REPORT_USER_SWITCH_MSG = 34; 1190 static final int CONTINUE_USER_SWITCH_MSG = 35; 1191 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1192 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1193 static final int PERSIST_URI_GRANTS_MSG = 38; 1194 static final int REQUEST_ALL_PSS_MSG = 39; 1195 static final int START_PROFILES_MSG = 40; 1196 static final int UPDATE_TIME = 41; 1197 static final int SYSTEM_USER_START_MSG = 42; 1198 static final int SYSTEM_USER_CURRENT_MSG = 43; 1199 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1200 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1201 static final int START_USER_SWITCH_MSG = 46; 1202 1203 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1204 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1205 static final int FIRST_COMPAT_MODE_MSG = 300; 1206 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1207 1208 AlertDialog mUidAlert; 1209 CompatModeDialog mCompatModeDialog; 1210 long mLastMemUsageReportTime = 0; 1211 1212 private LockToAppRequestDialog mLockToAppRequest; 1213 1214 /** 1215 * Flag whether the current user is a "monkey", i.e. whether 1216 * the UI is driven by a UI automation tool. 1217 */ 1218 private boolean mUserIsMonkey; 1219 1220 /** Flag whether the device has a Recents UI */ 1221 boolean mHasRecents; 1222 1223 /** The dimensions of the thumbnails in the Recents UI. */ 1224 int mThumbnailWidth; 1225 int mThumbnailHeight; 1226 1227 final ServiceThread mHandlerThread; 1228 final MainHandler mHandler; 1229 1230 final class MainHandler extends Handler { 1231 public MainHandler(Looper looper) { 1232 super(looper, null, true); 1233 } 1234 1235 @Override 1236 public void handleMessage(Message msg) { 1237 switch (msg.what) { 1238 case SHOW_ERROR_MSG: { 1239 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1240 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1241 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1242 synchronized (ActivityManagerService.this) { 1243 ProcessRecord proc = (ProcessRecord)data.get("app"); 1244 AppErrorResult res = (AppErrorResult) data.get("result"); 1245 if (proc != null && proc.crashDialog != null) { 1246 Slog.e(TAG, "App already has crash dialog: " + proc); 1247 if (res != null) { 1248 res.set(0); 1249 } 1250 return; 1251 } 1252 boolean isBackground = (UserHandle.getAppId(proc.uid) 1253 >= Process.FIRST_APPLICATION_UID 1254 && proc.pid != MY_PID); 1255 for (int userId : mCurrentProfileIds) { 1256 isBackground &= (proc.userId != userId); 1257 } 1258 if (isBackground && !showBackground) { 1259 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1260 if (res != null) { 1261 res.set(0); 1262 } 1263 return; 1264 } 1265 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1266 Dialog d = new AppErrorDialog(mContext, 1267 ActivityManagerService.this, res, proc); 1268 d.show(); 1269 proc.crashDialog = d; 1270 } else { 1271 // The device is asleep, so just pretend that the user 1272 // saw a crash dialog and hit "force quit". 1273 if (res != null) { 1274 res.set(0); 1275 } 1276 } 1277 } 1278 1279 ensureBootCompleted(); 1280 } break; 1281 case SHOW_NOT_RESPONDING_MSG: { 1282 synchronized (ActivityManagerService.this) { 1283 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1284 ProcessRecord proc = (ProcessRecord)data.get("app"); 1285 if (proc != null && proc.anrDialog != null) { 1286 Slog.e(TAG, "App already has anr dialog: " + proc); 1287 return; 1288 } 1289 1290 Intent intent = new Intent("android.intent.action.ANR"); 1291 if (!mProcessesReady) { 1292 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1293 | Intent.FLAG_RECEIVER_FOREGROUND); 1294 } 1295 broadcastIntentLocked(null, null, intent, 1296 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1297 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1298 1299 if (mShowDialogs) { 1300 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1301 mContext, proc, (ActivityRecord)data.get("activity"), 1302 msg.arg1 != 0); 1303 d.show(); 1304 proc.anrDialog = d; 1305 } else { 1306 // Just kill the app if there is no dialog to be shown. 1307 killAppAtUsersRequest(proc, null); 1308 } 1309 } 1310 1311 ensureBootCompleted(); 1312 } break; 1313 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1314 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1315 synchronized (ActivityManagerService.this) { 1316 ProcessRecord proc = (ProcessRecord) data.get("app"); 1317 if (proc == null) { 1318 Slog.e(TAG, "App not found when showing strict mode dialog."); 1319 break; 1320 } 1321 if (proc.crashDialog != null) { 1322 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1323 return; 1324 } 1325 AppErrorResult res = (AppErrorResult) data.get("result"); 1326 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1327 Dialog d = new StrictModeViolationDialog(mContext, 1328 ActivityManagerService.this, res, proc); 1329 d.show(); 1330 proc.crashDialog = d; 1331 } else { 1332 // The device is asleep, so just pretend that the user 1333 // saw a crash dialog and hit "force quit". 1334 res.set(0); 1335 } 1336 } 1337 ensureBootCompleted(); 1338 } break; 1339 case SHOW_FACTORY_ERROR_MSG: { 1340 Dialog d = new FactoryErrorDialog( 1341 mContext, msg.getData().getCharSequence("msg")); 1342 d.show(); 1343 ensureBootCompleted(); 1344 } break; 1345 case UPDATE_CONFIGURATION_MSG: { 1346 final ContentResolver resolver = mContext.getContentResolver(); 1347 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1348 } break; 1349 case GC_BACKGROUND_PROCESSES_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 performAppGcsIfAppropriateLocked(); 1352 } 1353 } break; 1354 case WAIT_FOR_DEBUGGER_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 ProcessRecord app = (ProcessRecord)msg.obj; 1357 if (msg.arg1 != 0) { 1358 if (!app.waitedForDebugger) { 1359 Dialog d = new AppWaitingForDebuggerDialog( 1360 ActivityManagerService.this, 1361 mContext, app); 1362 app.waitDialog = d; 1363 app.waitedForDebugger = true; 1364 d.show(); 1365 } 1366 } else { 1367 if (app.waitDialog != null) { 1368 app.waitDialog.dismiss(); 1369 app.waitDialog = null; 1370 } 1371 } 1372 } 1373 } break; 1374 case SERVICE_TIMEOUT_MSG: { 1375 if (mDidDexOpt) { 1376 mDidDexOpt = false; 1377 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1378 nmsg.obj = msg.obj; 1379 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1380 return; 1381 } 1382 mServices.serviceTimeout((ProcessRecord)msg.obj); 1383 } break; 1384 case UPDATE_TIME_ZONE: { 1385 synchronized (ActivityManagerService.this) { 1386 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1387 ProcessRecord r = mLruProcesses.get(i); 1388 if (r.thread != null) { 1389 try { 1390 r.thread.updateTimeZone(); 1391 } catch (RemoteException ex) { 1392 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1393 } 1394 } 1395 } 1396 } 1397 } break; 1398 case CLEAR_DNS_CACHE_MSG: { 1399 synchronized (ActivityManagerService.this) { 1400 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1401 ProcessRecord r = mLruProcesses.get(i); 1402 if (r.thread != null) { 1403 try { 1404 r.thread.clearDnsCache(); 1405 } catch (RemoteException ex) { 1406 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1407 } 1408 } 1409 } 1410 } 1411 } break; 1412 case UPDATE_HTTP_PROXY_MSG: { 1413 ProxyInfo proxy = (ProxyInfo)msg.obj; 1414 String host = ""; 1415 String port = ""; 1416 String exclList = ""; 1417 Uri pacFileUrl = Uri.EMPTY; 1418 if (proxy != null) { 1419 host = proxy.getHost(); 1420 port = Integer.toString(proxy.getPort()); 1421 exclList = proxy.getExclusionListAsString(); 1422 pacFileUrl = proxy.getPacFileUrl(); 1423 } 1424 synchronized (ActivityManagerService.this) { 1425 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1426 ProcessRecord r = mLruProcesses.get(i); 1427 if (r.thread != null) { 1428 try { 1429 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1430 } catch (RemoteException ex) { 1431 Slog.w(TAG, "Failed to update http proxy for: " + 1432 r.info.processName); 1433 } 1434 } 1435 } 1436 } 1437 } break; 1438 case SHOW_UID_ERROR_MSG: { 1439 String title = "System UIDs Inconsistent"; 1440 String text = "UIDs on the system are inconsistent, you need to wipe your" 1441 + " data partition or your device will be unstable."; 1442 Log.e(TAG, title + ": " + text); 1443 if (mShowDialogs) { 1444 // XXX This is a temporary dialog, no need to localize. 1445 AlertDialog d = new BaseErrorDialog(mContext); 1446 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1447 d.setCancelable(false); 1448 d.setTitle(title); 1449 d.setMessage(text); 1450 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1451 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1452 mUidAlert = d; 1453 d.show(); 1454 } 1455 } break; 1456 case IM_FEELING_LUCKY_MSG: { 1457 if (mUidAlert != null) { 1458 mUidAlert.dismiss(); 1459 mUidAlert = null; 1460 } 1461 } break; 1462 case PROC_START_TIMEOUT_MSG: { 1463 if (mDidDexOpt) { 1464 mDidDexOpt = false; 1465 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1466 nmsg.obj = msg.obj; 1467 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1468 return; 1469 } 1470 ProcessRecord app = (ProcessRecord)msg.obj; 1471 synchronized (ActivityManagerService.this) { 1472 processStartTimedOutLocked(app); 1473 } 1474 } break; 1475 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1476 synchronized (ActivityManagerService.this) { 1477 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1478 } 1479 } break; 1480 case KILL_APPLICATION_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 int appid = msg.arg1; 1483 boolean restart = (msg.arg2 == 1); 1484 Bundle bundle = (Bundle)msg.obj; 1485 String pkg = bundle.getString("pkg"); 1486 String reason = bundle.getString("reason"); 1487 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1488 false, UserHandle.USER_ALL, reason); 1489 } 1490 } break; 1491 case FINALIZE_PENDING_INTENT_MSG: { 1492 ((PendingIntentRecord)msg.obj).completeFinalize(); 1493 } break; 1494 case POST_HEAVY_NOTIFICATION_MSG: { 1495 INotificationManager inm = NotificationManager.getService(); 1496 if (inm == null) { 1497 return; 1498 } 1499 1500 ActivityRecord root = (ActivityRecord)msg.obj; 1501 ProcessRecord process = root.app; 1502 if (process == null) { 1503 return; 1504 } 1505 1506 try { 1507 Context context = mContext.createPackageContext(process.info.packageName, 0); 1508 String text = mContext.getString(R.string.heavy_weight_notification, 1509 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1510 Notification notification = new Notification(); 1511 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1512 notification.when = 0; 1513 notification.flags = Notification.FLAG_ONGOING_EVENT; 1514 notification.tickerText = text; 1515 notification.defaults = 0; // please be quiet 1516 notification.sound = null; 1517 notification.vibrate = null; 1518 notification.color = mContext.getResources().getColor( 1519 com.android.internal.R.color.system_notification_accent_color); 1520 notification.setLatestEventInfo(context, text, 1521 mContext.getText(R.string.heavy_weight_notification_detail), 1522 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1523 PendingIntent.FLAG_CANCEL_CURRENT, null, 1524 new UserHandle(root.userId))); 1525 1526 try { 1527 int[] outId = new int[1]; 1528 inm.enqueueNotificationWithTag("android", "android", null, 1529 R.string.heavy_weight_notification, 1530 notification, outId, root.userId); 1531 } catch (RuntimeException e) { 1532 Slog.w(ActivityManagerService.TAG, 1533 "Error showing notification for heavy-weight app", e); 1534 } catch (RemoteException e) { 1535 } 1536 } catch (NameNotFoundException e) { 1537 Slog.w(TAG, "Unable to create context for heavy notification", e); 1538 } 1539 } break; 1540 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1541 INotificationManager inm = NotificationManager.getService(); 1542 if (inm == null) { 1543 return; 1544 } 1545 try { 1546 inm.cancelNotificationWithTag("android", null, 1547 R.string.heavy_weight_notification, msg.arg1); 1548 } catch (RuntimeException e) { 1549 Slog.w(ActivityManagerService.TAG, 1550 "Error canceling notification for service", e); 1551 } catch (RemoteException e) { 1552 } 1553 } break; 1554 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1555 synchronized (ActivityManagerService.this) { 1556 checkExcessivePowerUsageLocked(true); 1557 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1558 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1559 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1560 } 1561 } break; 1562 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1563 synchronized (ActivityManagerService.this) { 1564 ActivityRecord ar = (ActivityRecord)msg.obj; 1565 if (mCompatModeDialog != null) { 1566 if (mCompatModeDialog.mAppInfo.packageName.equals( 1567 ar.info.applicationInfo.packageName)) { 1568 return; 1569 } 1570 mCompatModeDialog.dismiss(); 1571 mCompatModeDialog = null; 1572 } 1573 if (ar != null && false) { 1574 if (mCompatModePackages.getPackageAskCompatModeLocked( 1575 ar.packageName)) { 1576 int mode = mCompatModePackages.computeCompatModeLocked( 1577 ar.info.applicationInfo); 1578 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1579 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1580 mCompatModeDialog = new CompatModeDialog( 1581 ActivityManagerService.this, mContext, 1582 ar.info.applicationInfo); 1583 mCompatModeDialog.show(); 1584 } 1585 } 1586 } 1587 } 1588 break; 1589 } 1590 case DISPATCH_PROCESSES_CHANGED: { 1591 dispatchProcessesChanged(); 1592 break; 1593 } 1594 case DISPATCH_PROCESS_DIED: { 1595 final int pid = msg.arg1; 1596 final int uid = msg.arg2; 1597 dispatchProcessDied(pid, uid); 1598 break; 1599 } 1600 case REPORT_MEM_USAGE_MSG: { 1601 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1602 Thread thread = new Thread() { 1603 @Override public void run() { 1604 final SparseArray<ProcessMemInfo> infoMap 1605 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1606 for (int i=0, N=memInfos.size(); i<N; i++) { 1607 ProcessMemInfo mi = memInfos.get(i); 1608 infoMap.put(mi.pid, mi); 1609 } 1610 updateCpuStatsNow(); 1611 synchronized (mProcessCpuTracker) { 1612 final int N = mProcessCpuTracker.countStats(); 1613 for (int i=0; i<N; i++) { 1614 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1615 if (st.vsize > 0) { 1616 long pss = Debug.getPss(st.pid, null); 1617 if (pss > 0) { 1618 if (infoMap.indexOfKey(st.pid) < 0) { 1619 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1620 ProcessList.NATIVE_ADJ, -1, "native", null); 1621 mi.pss = pss; 1622 memInfos.add(mi); 1623 } 1624 } 1625 } 1626 } 1627 } 1628 1629 long totalPss = 0; 1630 for (int i=0, N=memInfos.size(); i<N; i++) { 1631 ProcessMemInfo mi = memInfos.get(i); 1632 if (mi.pss == 0) { 1633 mi.pss = Debug.getPss(mi.pid, null); 1634 } 1635 totalPss += mi.pss; 1636 } 1637 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1638 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1639 if (lhs.oomAdj != rhs.oomAdj) { 1640 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1641 } 1642 if (lhs.pss != rhs.pss) { 1643 return lhs.pss < rhs.pss ? 1 : -1; 1644 } 1645 return 0; 1646 } 1647 }); 1648 1649 StringBuilder tag = new StringBuilder(128); 1650 StringBuilder stack = new StringBuilder(128); 1651 tag.append("Low on memory -- "); 1652 appendMemBucket(tag, totalPss, "total", false); 1653 appendMemBucket(stack, totalPss, "total", true); 1654 1655 StringBuilder logBuilder = new StringBuilder(1024); 1656 logBuilder.append("Low on memory:\n"); 1657 1658 boolean firstLine = true; 1659 int lastOomAdj = Integer.MIN_VALUE; 1660 for (int i=0, N=memInfos.size(); i<N; i++) { 1661 ProcessMemInfo mi = memInfos.get(i); 1662 1663 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1664 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1665 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1666 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1667 if (lastOomAdj != mi.oomAdj) { 1668 lastOomAdj = mi.oomAdj; 1669 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1670 tag.append(" / "); 1671 } 1672 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1673 if (firstLine) { 1674 stack.append(":"); 1675 firstLine = false; 1676 } 1677 stack.append("\n\t at "); 1678 } else { 1679 stack.append("$"); 1680 } 1681 } else { 1682 tag.append(" "); 1683 stack.append("$"); 1684 } 1685 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1686 appendMemBucket(tag, mi.pss, mi.name, false); 1687 } 1688 appendMemBucket(stack, mi.pss, mi.name, true); 1689 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1690 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1691 stack.append("("); 1692 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1693 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1694 stack.append(DUMP_MEM_OOM_LABEL[k]); 1695 stack.append(":"); 1696 stack.append(DUMP_MEM_OOM_ADJ[k]); 1697 } 1698 } 1699 stack.append(")"); 1700 } 1701 } 1702 1703 logBuilder.append(" "); 1704 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1705 logBuilder.append(' '); 1706 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1707 logBuilder.append(' '); 1708 ProcessList.appendRamKb(logBuilder, mi.pss); 1709 logBuilder.append(" kB: "); 1710 logBuilder.append(mi.name); 1711 logBuilder.append(" ("); 1712 logBuilder.append(mi.pid); 1713 logBuilder.append(") "); 1714 logBuilder.append(mi.adjType); 1715 logBuilder.append('\n'); 1716 if (mi.adjReason != null) { 1717 logBuilder.append(" "); 1718 logBuilder.append(mi.adjReason); 1719 logBuilder.append('\n'); 1720 } 1721 } 1722 1723 logBuilder.append(" "); 1724 ProcessList.appendRamKb(logBuilder, totalPss); 1725 logBuilder.append(" kB: TOTAL\n"); 1726 1727 long[] infos = new long[Debug.MEMINFO_COUNT]; 1728 Debug.getMemInfo(infos); 1729 logBuilder.append(" MemInfo: "); 1730 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1731 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1732 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1733 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1734 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1735 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1736 logBuilder.append(" ZRAM: "); 1737 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1738 logBuilder.append(" kB RAM, "); 1739 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1740 logBuilder.append(" kB swap total, "); 1741 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1742 logBuilder.append(" kB swap free\n"); 1743 } 1744 Slog.i(TAG, logBuilder.toString()); 1745 1746 StringBuilder dropBuilder = new StringBuilder(1024); 1747 /* 1748 StringWriter oomSw = new StringWriter(); 1749 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1750 StringWriter catSw = new StringWriter(); 1751 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1752 String[] emptyArgs = new String[] { }; 1753 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1754 oomPw.flush(); 1755 String oomString = oomSw.toString(); 1756 */ 1757 dropBuilder.append(stack); 1758 dropBuilder.append('\n'); 1759 dropBuilder.append('\n'); 1760 dropBuilder.append(logBuilder); 1761 dropBuilder.append('\n'); 1762 /* 1763 dropBuilder.append(oomString); 1764 dropBuilder.append('\n'); 1765 */ 1766 StringWriter catSw = new StringWriter(); 1767 synchronized (ActivityManagerService.this) { 1768 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1769 String[] emptyArgs = new String[] { }; 1770 catPw.println(); 1771 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1772 catPw.println(); 1773 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1774 false, false, null); 1775 catPw.println(); 1776 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1777 catPw.flush(); 1778 } 1779 dropBuilder.append(catSw.toString()); 1780 addErrorToDropBox("lowmem", null, "system_server", null, 1781 null, tag.toString(), dropBuilder.toString(), null, null); 1782 //Slog.i(TAG, "Sent to dropbox:"); 1783 //Slog.i(TAG, dropBuilder.toString()); 1784 synchronized (ActivityManagerService.this) { 1785 long now = SystemClock.uptimeMillis(); 1786 if (mLastMemUsageReportTime < now) { 1787 mLastMemUsageReportTime = now; 1788 } 1789 } 1790 } 1791 }; 1792 thread.start(); 1793 break; 1794 } 1795 case START_USER_SWITCH_MSG: { 1796 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1797 break; 1798 } 1799 case REPORT_USER_SWITCH_MSG: { 1800 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1801 break; 1802 } 1803 case CONTINUE_USER_SWITCH_MSG: { 1804 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1805 break; 1806 } 1807 case USER_SWITCH_TIMEOUT_MSG: { 1808 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1809 break; 1810 } 1811 case IMMERSIVE_MODE_LOCK_MSG: { 1812 final boolean nextState = (msg.arg1 != 0); 1813 if (mUpdateLock.isHeld() != nextState) { 1814 if (DEBUG_IMMERSIVE) { 1815 final ActivityRecord r = (ActivityRecord) msg.obj; 1816 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1817 } 1818 if (nextState) { 1819 mUpdateLock.acquire(); 1820 } else { 1821 mUpdateLock.release(); 1822 } 1823 } 1824 break; 1825 } 1826 case PERSIST_URI_GRANTS_MSG: { 1827 writeGrantedUriPermissions(); 1828 break; 1829 } 1830 case REQUEST_ALL_PSS_MSG: { 1831 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1832 break; 1833 } 1834 case START_PROFILES_MSG: { 1835 synchronized (ActivityManagerService.this) { 1836 startProfilesLocked(); 1837 } 1838 break; 1839 } 1840 case UPDATE_TIME: { 1841 synchronized (ActivityManagerService.this) { 1842 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1843 ProcessRecord r = mLruProcesses.get(i); 1844 if (r.thread != null) { 1845 try { 1846 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1847 } catch (RemoteException ex) { 1848 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1849 } 1850 } 1851 } 1852 } 1853 break; 1854 } 1855 case SYSTEM_USER_START_MSG: { 1856 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1857 Integer.toString(msg.arg1), msg.arg1); 1858 mSystemServiceManager.startUser(msg.arg1); 1859 break; 1860 } 1861 case SYSTEM_USER_CURRENT_MSG: { 1862 mBatteryStatsService.noteEvent( 1863 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1864 Integer.toString(msg.arg2), msg.arg2); 1865 mBatteryStatsService.noteEvent( 1866 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1867 Integer.toString(msg.arg1), msg.arg1); 1868 mSystemServiceManager.switchUser(msg.arg1); 1869 mLockToAppRequest.clearPrompt(); 1870 break; 1871 } 1872 case ENTER_ANIMATION_COMPLETE_MSG: { 1873 synchronized (ActivityManagerService.this) { 1874 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1875 if (r != null && r.app != null && r.app.thread != null) { 1876 try { 1877 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1878 } catch (RemoteException e) { 1879 } 1880 } 1881 } 1882 break; 1883 } 1884 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1885 enableScreenAfterBoot(); 1886 break; 1887 } 1888 } 1889 } 1890 }; 1891 1892 static final int COLLECT_PSS_BG_MSG = 1; 1893 1894 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1895 @Override 1896 public void handleMessage(Message msg) { 1897 switch (msg.what) { 1898 case COLLECT_PSS_BG_MSG: { 1899 long start = SystemClock.uptimeMillis(); 1900 MemInfoReader memInfo = null; 1901 synchronized (ActivityManagerService.this) { 1902 if (mFullPssPending) { 1903 mFullPssPending = false; 1904 memInfo = new MemInfoReader(); 1905 } 1906 } 1907 if (memInfo != null) { 1908 updateCpuStatsNow(); 1909 long nativeTotalPss = 0; 1910 synchronized (mProcessCpuTracker) { 1911 final int N = mProcessCpuTracker.countStats(); 1912 for (int j=0; j<N; j++) { 1913 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1914 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1915 // This is definitely an application process; skip it. 1916 continue; 1917 } 1918 synchronized (mPidsSelfLocked) { 1919 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1920 // This is one of our own processes; skip it. 1921 continue; 1922 } 1923 } 1924 nativeTotalPss += Debug.getPss(st.pid, null); 1925 } 1926 } 1927 memInfo.readMemInfo(); 1928 synchronized (ActivityManagerService.this) { 1929 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1930 + (SystemClock.uptimeMillis()-start) + "ms"); 1931 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1932 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1933 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1934 +memInfo.getSlabSizeKb(), 1935 nativeTotalPss); 1936 } 1937 } 1938 1939 int i=0, num=0; 1940 long[] tmp = new long[1]; 1941 do { 1942 ProcessRecord proc; 1943 int procState; 1944 int pid; 1945 synchronized (ActivityManagerService.this) { 1946 if (i >= mPendingPssProcesses.size()) { 1947 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1948 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1949 mPendingPssProcesses.clear(); 1950 return; 1951 } 1952 proc = mPendingPssProcesses.get(i); 1953 procState = proc.pssProcState; 1954 if (proc.thread != null && procState == proc.setProcState) { 1955 pid = proc.pid; 1956 } else { 1957 proc = null; 1958 pid = 0; 1959 } 1960 i++; 1961 } 1962 if (proc != null) { 1963 long pss = Debug.getPss(pid, tmp); 1964 synchronized (ActivityManagerService.this) { 1965 if (proc.thread != null && proc.setProcState == procState 1966 && proc.pid == pid) { 1967 num++; 1968 proc.lastPssTime = SystemClock.uptimeMillis(); 1969 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1970 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1971 + ": " + pss + " lastPss=" + proc.lastPss 1972 + " state=" + ProcessList.makeProcStateString(procState)); 1973 if (proc.initialIdlePss == 0) { 1974 proc.initialIdlePss = pss; 1975 } 1976 proc.lastPss = pss; 1977 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1978 proc.lastCachedPss = pss; 1979 } 1980 } 1981 } 1982 } 1983 } while (true); 1984 } 1985 } 1986 } 1987 }; 1988 1989 /** 1990 * Monitor for package changes and update our internal state. 1991 */ 1992 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1993 @Override 1994 public void onPackageRemoved(String packageName, int uid) { 1995 // Remove all tasks with activities in the specified package from the list of recent tasks 1996 synchronized (ActivityManagerService.this) { 1997 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1998 TaskRecord tr = mRecentTasks.get(i); 1999 ComponentName cn = tr.intent.getComponent(); 2000 if (cn != null && cn.getPackageName().equals(packageName)) { 2001 // If the package name matches, remove the task and kill the process 2002 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2003 } 2004 } 2005 } 2006 } 2007 2008 @Override 2009 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2010 onPackageModified(packageName); 2011 return true; 2012 } 2013 2014 @Override 2015 public void onPackageModified(String packageName) { 2016 final PackageManager pm = mContext.getPackageManager(); 2017 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2018 new ArrayList<Pair<Intent, Integer>>(); 2019 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2020 // Copy the list of recent tasks so that we don't hold onto the lock on 2021 // ActivityManagerService for long periods while checking if components exist. 2022 synchronized (ActivityManagerService.this) { 2023 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2024 TaskRecord tr = mRecentTasks.get(i); 2025 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2026 } 2027 } 2028 // Check the recent tasks and filter out all tasks with components that no longer exist. 2029 Intent tmpI = new Intent(); 2030 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2031 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2032 ComponentName cn = p.first.getComponent(); 2033 if (cn != null && cn.getPackageName().equals(packageName)) { 2034 try { 2035 // Add the task to the list to remove if the component no longer exists 2036 tmpI.setComponent(cn); 2037 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2038 tasksToRemove.add(p.second); 2039 } 2040 } catch (Exception e) {} 2041 } 2042 } 2043 // Prune all the tasks with removed components from the list of recent tasks 2044 synchronized (ActivityManagerService.this) { 2045 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2046 // Remove the task but don't kill the process (since other components in that 2047 // package may still be running and in the background) 2048 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2049 } 2050 } 2051 } 2052 2053 @Override 2054 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2055 // Force stop the specified packages 2056 if (packages != null) { 2057 for (String pkg : packages) { 2058 synchronized (ActivityManagerService.this) { 2059 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2060 "finished booting")) { 2061 return true; 2062 } 2063 } 2064 } 2065 } 2066 return false; 2067 } 2068 }; 2069 2070 public void setSystemProcess() { 2071 try { 2072 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2073 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2074 ServiceManager.addService("meminfo", new MemBinder(this)); 2075 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2076 ServiceManager.addService("dbinfo", new DbBinder(this)); 2077 if (MONITOR_CPU_USAGE) { 2078 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2079 } 2080 ServiceManager.addService("permission", new PermissionController(this)); 2081 2082 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2083 "android", STOCK_PM_FLAGS); 2084 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2085 2086 synchronized (this) { 2087 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2088 app.persistent = true; 2089 app.pid = MY_PID; 2090 app.maxAdj = ProcessList.SYSTEM_ADJ; 2091 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2092 mProcessNames.put(app.processName, app.uid, app); 2093 synchronized (mPidsSelfLocked) { 2094 mPidsSelfLocked.put(app.pid, app); 2095 } 2096 updateLruProcessLocked(app, false, null); 2097 updateOomAdjLocked(); 2098 } 2099 } catch (PackageManager.NameNotFoundException e) { 2100 throw new RuntimeException( 2101 "Unable to find android system package", e); 2102 } 2103 } 2104 2105 public void setWindowManager(WindowManagerService wm) { 2106 mWindowManager = wm; 2107 mStackSupervisor.setWindowManager(wm); 2108 } 2109 2110 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2111 mUsageStatsService = usageStatsManager; 2112 } 2113 2114 public void startObservingNativeCrashes() { 2115 final NativeCrashListener ncl = new NativeCrashListener(this); 2116 ncl.start(); 2117 } 2118 2119 public IAppOpsService getAppOpsService() { 2120 return mAppOpsService; 2121 } 2122 2123 static class MemBinder extends Binder { 2124 ActivityManagerService mActivityManagerService; 2125 MemBinder(ActivityManagerService activityManagerService) { 2126 mActivityManagerService = activityManagerService; 2127 } 2128 2129 @Override 2130 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2131 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2132 != PackageManager.PERMISSION_GRANTED) { 2133 pw.println("Permission Denial: can't dump meminfo from from pid=" 2134 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2135 + " without permission " + android.Manifest.permission.DUMP); 2136 return; 2137 } 2138 2139 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2140 } 2141 } 2142 2143 static class GraphicsBinder extends Binder { 2144 ActivityManagerService mActivityManagerService; 2145 GraphicsBinder(ActivityManagerService activityManagerService) { 2146 mActivityManagerService = activityManagerService; 2147 } 2148 2149 @Override 2150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2151 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2152 != PackageManager.PERMISSION_GRANTED) { 2153 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2154 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2155 + " without permission " + android.Manifest.permission.DUMP); 2156 return; 2157 } 2158 2159 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2160 } 2161 } 2162 2163 static class DbBinder extends Binder { 2164 ActivityManagerService mActivityManagerService; 2165 DbBinder(ActivityManagerService activityManagerService) { 2166 mActivityManagerService = activityManagerService; 2167 } 2168 2169 @Override 2170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2171 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2172 != PackageManager.PERMISSION_GRANTED) { 2173 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2174 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2175 + " without permission " + android.Manifest.permission.DUMP); 2176 return; 2177 } 2178 2179 mActivityManagerService.dumpDbInfo(fd, pw, args); 2180 } 2181 } 2182 2183 static class CpuBinder extends Binder { 2184 ActivityManagerService mActivityManagerService; 2185 CpuBinder(ActivityManagerService activityManagerService) { 2186 mActivityManagerService = activityManagerService; 2187 } 2188 2189 @Override 2190 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2191 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2192 != PackageManager.PERMISSION_GRANTED) { 2193 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2194 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2195 + " without permission " + android.Manifest.permission.DUMP); 2196 return; 2197 } 2198 2199 synchronized (mActivityManagerService.mProcessCpuTracker) { 2200 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2201 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2202 SystemClock.uptimeMillis())); 2203 } 2204 } 2205 } 2206 2207 public static final class Lifecycle extends SystemService { 2208 private final ActivityManagerService mService; 2209 2210 public Lifecycle(Context context) { 2211 super(context); 2212 mService = new ActivityManagerService(context); 2213 } 2214 2215 @Override 2216 public void onStart() { 2217 mService.start(); 2218 } 2219 2220 public ActivityManagerService getService() { 2221 return mService; 2222 } 2223 } 2224 2225 // Note: This method is invoked on the main thread but may need to attach various 2226 // handlers to other threads. So take care to be explicit about the looper. 2227 public ActivityManagerService(Context systemContext) { 2228 mContext = systemContext; 2229 mFactoryTest = FactoryTest.getMode(); 2230 mSystemThread = ActivityThread.currentActivityThread(); 2231 2232 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2233 2234 mHandlerThread = new ServiceThread(TAG, 2235 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2236 mHandlerThread.start(); 2237 mHandler = new MainHandler(mHandlerThread.getLooper()); 2238 2239 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2240 "foreground", BROADCAST_FG_TIMEOUT, false); 2241 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2242 "background", BROADCAST_BG_TIMEOUT, true); 2243 mBroadcastQueues[0] = mFgBroadcastQueue; 2244 mBroadcastQueues[1] = mBgBroadcastQueue; 2245 2246 mServices = new ActiveServices(this); 2247 mProviderMap = new ProviderMap(this); 2248 2249 // TODO: Move creation of battery stats service outside of activity manager service. 2250 File dataDir = Environment.getDataDirectory(); 2251 File systemDir = new File(dataDir, "system"); 2252 systemDir.mkdirs(); 2253 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2254 mBatteryStatsService.getActiveStatistics().readLocked(); 2255 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2256 mOnBattery = DEBUG_POWER ? true 2257 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2258 mBatteryStatsService.getActiveStatistics().setCallback(this); 2259 2260 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2261 2262 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2263 2264 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2265 2266 // User 0 is the first and only user that runs at boot. 2267 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2268 mUserLru.add(Integer.valueOf(0)); 2269 updateStartedUserArrayLocked(); 2270 2271 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2272 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2273 2274 mConfiguration.setToDefaults(); 2275 mConfiguration.setLocale(Locale.getDefault()); 2276 2277 mConfigurationSeq = mConfiguration.seq = 1; 2278 mProcessCpuTracker.init(); 2279 2280 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2281 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2282 mStackSupervisor = new ActivityStackSupervisor(this); 2283 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2284 2285 mProcessCpuThread = new Thread("CpuTracker") { 2286 @Override 2287 public void run() { 2288 while (true) { 2289 try { 2290 try { 2291 synchronized(this) { 2292 final long now = SystemClock.uptimeMillis(); 2293 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2294 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2295 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2296 // + ", write delay=" + nextWriteDelay); 2297 if (nextWriteDelay < nextCpuDelay) { 2298 nextCpuDelay = nextWriteDelay; 2299 } 2300 if (nextCpuDelay > 0) { 2301 mProcessCpuMutexFree.set(true); 2302 this.wait(nextCpuDelay); 2303 } 2304 } 2305 } catch (InterruptedException e) { 2306 } 2307 updateCpuStatsNow(); 2308 } catch (Exception e) { 2309 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2310 } 2311 } 2312 } 2313 }; 2314 2315 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2316 2317 Watchdog.getInstance().addMonitor(this); 2318 Watchdog.getInstance().addThread(mHandler); 2319 } 2320 2321 public void setSystemServiceManager(SystemServiceManager mgr) { 2322 mSystemServiceManager = mgr; 2323 } 2324 2325 private void start() { 2326 Process.removeAllProcessGroups(); 2327 mProcessCpuThread.start(); 2328 2329 mBatteryStatsService.publish(mContext); 2330 mAppOpsService.publish(mContext); 2331 Slog.d("AppOps", "AppOpsService published"); 2332 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2333 } 2334 2335 public void initPowerManagement() { 2336 mStackSupervisor.initPowerManagement(); 2337 mBatteryStatsService.initPowerManagement(); 2338 } 2339 2340 @Override 2341 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2342 throws RemoteException { 2343 if (code == SYSPROPS_TRANSACTION) { 2344 // We need to tell all apps about the system property change. 2345 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2346 synchronized(this) { 2347 final int NP = mProcessNames.getMap().size(); 2348 for (int ip=0; ip<NP; ip++) { 2349 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2350 final int NA = apps.size(); 2351 for (int ia=0; ia<NA; ia++) { 2352 ProcessRecord app = apps.valueAt(ia); 2353 if (app.thread != null) { 2354 procs.add(app.thread.asBinder()); 2355 } 2356 } 2357 } 2358 } 2359 2360 int N = procs.size(); 2361 for (int i=0; i<N; i++) { 2362 Parcel data2 = Parcel.obtain(); 2363 try { 2364 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2365 } catch (RemoteException e) { 2366 } 2367 data2.recycle(); 2368 } 2369 } 2370 try { 2371 return super.onTransact(code, data, reply, flags); 2372 } catch (RuntimeException e) { 2373 // The activity manager only throws security exceptions, so let's 2374 // log all others. 2375 if (!(e instanceof SecurityException)) { 2376 Slog.wtf(TAG, "Activity Manager Crash", e); 2377 } 2378 throw e; 2379 } 2380 } 2381 2382 void updateCpuStats() { 2383 final long now = SystemClock.uptimeMillis(); 2384 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2385 return; 2386 } 2387 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2388 synchronized (mProcessCpuThread) { 2389 mProcessCpuThread.notify(); 2390 } 2391 } 2392 } 2393 2394 void updateCpuStatsNow() { 2395 synchronized (mProcessCpuTracker) { 2396 mProcessCpuMutexFree.set(false); 2397 final long now = SystemClock.uptimeMillis(); 2398 boolean haveNewCpuStats = false; 2399 2400 if (MONITOR_CPU_USAGE && 2401 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2402 mLastCpuTime.set(now); 2403 haveNewCpuStats = true; 2404 mProcessCpuTracker.update(); 2405 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2406 //Slog.i(TAG, "Total CPU usage: " 2407 // + mProcessCpu.getTotalCpuPercent() + "%"); 2408 2409 // Slog the cpu usage if the property is set. 2410 if ("true".equals(SystemProperties.get("events.cpu"))) { 2411 int user = mProcessCpuTracker.getLastUserTime(); 2412 int system = mProcessCpuTracker.getLastSystemTime(); 2413 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2414 int irq = mProcessCpuTracker.getLastIrqTime(); 2415 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2416 int idle = mProcessCpuTracker.getLastIdleTime(); 2417 2418 int total = user + system + iowait + irq + softIrq + idle; 2419 if (total == 0) total = 1; 2420 2421 EventLog.writeEvent(EventLogTags.CPU, 2422 ((user+system+iowait+irq+softIrq) * 100) / total, 2423 (user * 100) / total, 2424 (system * 100) / total, 2425 (iowait * 100) / total, 2426 (irq * 100) / total, 2427 (softIrq * 100) / total); 2428 } 2429 } 2430 2431 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2432 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2433 synchronized(bstats) { 2434 synchronized(mPidsSelfLocked) { 2435 if (haveNewCpuStats) { 2436 if (mOnBattery) { 2437 int perc = bstats.startAddingCpuLocked(); 2438 int totalUTime = 0; 2439 int totalSTime = 0; 2440 final int N = mProcessCpuTracker.countStats(); 2441 for (int i=0; i<N; i++) { 2442 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2443 if (!st.working) { 2444 continue; 2445 } 2446 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2447 int otherUTime = (st.rel_utime*perc)/100; 2448 int otherSTime = (st.rel_stime*perc)/100; 2449 totalUTime += otherUTime; 2450 totalSTime += otherSTime; 2451 if (pr != null) { 2452 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2453 if (ps == null || !ps.isActive()) { 2454 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2455 pr.info.uid, pr.processName); 2456 } 2457 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2458 st.rel_stime-otherSTime); 2459 ps.addSpeedStepTimes(cpuSpeedTimes); 2460 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2461 } else { 2462 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2463 if (ps == null || !ps.isActive()) { 2464 st.batteryStats = ps = bstats.getProcessStatsLocked( 2465 bstats.mapUid(st.uid), st.name); 2466 } 2467 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2468 st.rel_stime-otherSTime); 2469 ps.addSpeedStepTimes(cpuSpeedTimes); 2470 } 2471 } 2472 bstats.finishAddingCpuLocked(perc, totalUTime, 2473 totalSTime, cpuSpeedTimes); 2474 } 2475 } 2476 } 2477 2478 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2479 mLastWriteTime = now; 2480 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2481 } 2482 } 2483 } 2484 } 2485 2486 @Override 2487 public void batteryNeedsCpuUpdate() { 2488 updateCpuStatsNow(); 2489 } 2490 2491 @Override 2492 public void batteryPowerChanged(boolean onBattery) { 2493 // When plugging in, update the CPU stats first before changing 2494 // the plug state. 2495 updateCpuStatsNow(); 2496 synchronized (this) { 2497 synchronized(mPidsSelfLocked) { 2498 mOnBattery = DEBUG_POWER ? true : onBattery; 2499 } 2500 } 2501 } 2502 2503 /** 2504 * Initialize the application bind args. These are passed to each 2505 * process when the bindApplication() IPC is sent to the process. They're 2506 * lazily setup to make sure the services are running when they're asked for. 2507 */ 2508 private HashMap<String, IBinder> getCommonServicesLocked() { 2509 if (mAppBindArgs == null) { 2510 mAppBindArgs = new HashMap<String, IBinder>(); 2511 2512 // Setup the application init args 2513 mAppBindArgs.put("package", ServiceManager.getService("package")); 2514 mAppBindArgs.put("window", ServiceManager.getService("window")); 2515 mAppBindArgs.put(Context.ALARM_SERVICE, 2516 ServiceManager.getService(Context.ALARM_SERVICE)); 2517 } 2518 return mAppBindArgs; 2519 } 2520 2521 final void setFocusedActivityLocked(ActivityRecord r) { 2522 if (mFocusedActivity != r) { 2523 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2524 mFocusedActivity = r; 2525 if (r.task != null && r.task.voiceInteractor != null) { 2526 startRunningVoiceLocked(); 2527 } else { 2528 finishRunningVoiceLocked(); 2529 } 2530 mStackSupervisor.setFocusedStack(r); 2531 if (r != null) { 2532 mWindowManager.setFocusedApp(r.appToken, true); 2533 } 2534 applyUpdateLockStateLocked(r); 2535 } 2536 } 2537 2538 final void clearFocusedActivity(ActivityRecord r) { 2539 if (mFocusedActivity == r) { 2540 mFocusedActivity = null; 2541 } 2542 } 2543 2544 @Override 2545 public void setFocusedStack(int stackId) { 2546 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2547 synchronized (ActivityManagerService.this) { 2548 ActivityStack stack = mStackSupervisor.getStack(stackId); 2549 if (stack != null) { 2550 ActivityRecord r = stack.topRunningActivityLocked(null); 2551 if (r != null) { 2552 setFocusedActivityLocked(r); 2553 } 2554 } 2555 } 2556 } 2557 2558 @Override 2559 public void notifyActivityDrawn(IBinder token) { 2560 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2561 synchronized (this) { 2562 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2563 if (r != null) { 2564 r.task.stack.notifyActivityDrawnLocked(r); 2565 } 2566 } 2567 } 2568 2569 final void applyUpdateLockStateLocked(ActivityRecord r) { 2570 // Modifications to the UpdateLock state are done on our handler, outside 2571 // the activity manager's locks. The new state is determined based on the 2572 // state *now* of the relevant activity record. The object is passed to 2573 // the handler solely for logging detail, not to be consulted/modified. 2574 final boolean nextState = r != null && r.immersive; 2575 mHandler.sendMessage( 2576 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2577 } 2578 2579 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2580 Message msg = Message.obtain(); 2581 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2582 msg.obj = r.task.askedCompatMode ? null : r; 2583 mHandler.sendMessage(msg); 2584 } 2585 2586 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2587 String what, Object obj, ProcessRecord srcApp) { 2588 app.lastActivityTime = now; 2589 2590 if (app.activities.size() > 0) { 2591 // Don't want to touch dependent processes that are hosting activities. 2592 return index; 2593 } 2594 2595 int lrui = mLruProcesses.lastIndexOf(app); 2596 if (lrui < 0) { 2597 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2598 + what + " " + obj + " from " + srcApp); 2599 return index; 2600 } 2601 2602 if (lrui >= index) { 2603 // Don't want to cause this to move dependent processes *back* in the 2604 // list as if they were less frequently used. 2605 return index; 2606 } 2607 2608 if (lrui >= mLruProcessActivityStart) { 2609 // Don't want to touch dependent processes that are hosting activities. 2610 return index; 2611 } 2612 2613 mLruProcesses.remove(lrui); 2614 if (index > 0) { 2615 index--; 2616 } 2617 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2618 + " in LRU list: " + app); 2619 mLruProcesses.add(index, app); 2620 return index; 2621 } 2622 2623 final void removeLruProcessLocked(ProcessRecord app) { 2624 int lrui = mLruProcesses.lastIndexOf(app); 2625 if (lrui >= 0) { 2626 if (!app.killed) { 2627 Slog.wtf(TAG, "Removing process that hasn't been killed: " + app); 2628 Process.killProcessQuiet(app.pid); 2629 Process.killProcessGroup(app.info.uid, app.pid); 2630 } 2631 if (lrui <= mLruProcessActivityStart) { 2632 mLruProcessActivityStart--; 2633 } 2634 if (lrui <= mLruProcessServiceStart) { 2635 mLruProcessServiceStart--; 2636 } 2637 mLruProcesses.remove(lrui); 2638 } 2639 } 2640 2641 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2642 ProcessRecord client) { 2643 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2644 || app.treatLikeActivity; 2645 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2646 if (!activityChange && hasActivity) { 2647 // The process has activities, so we are only allowing activity-based adjustments 2648 // to move it. It should be kept in the front of the list with other 2649 // processes that have activities, and we don't want those to change their 2650 // order except due to activity operations. 2651 return; 2652 } 2653 2654 mLruSeq++; 2655 final long now = SystemClock.uptimeMillis(); 2656 app.lastActivityTime = now; 2657 2658 // First a quick reject: if the app is already at the position we will 2659 // put it, then there is nothing to do. 2660 if (hasActivity) { 2661 final int N = mLruProcesses.size(); 2662 if (N > 0 && mLruProcesses.get(N-1) == app) { 2663 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2664 return; 2665 } 2666 } else { 2667 if (mLruProcessServiceStart > 0 2668 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2669 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2670 return; 2671 } 2672 } 2673 2674 int lrui = mLruProcesses.lastIndexOf(app); 2675 2676 if (app.persistent && lrui >= 0) { 2677 // We don't care about the position of persistent processes, as long as 2678 // they are in the list. 2679 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2680 return; 2681 } 2682 2683 /* In progress: compute new position first, so we can avoid doing work 2684 if the process is not actually going to move. Not yet working. 2685 int addIndex; 2686 int nextIndex; 2687 boolean inActivity = false, inService = false; 2688 if (hasActivity) { 2689 // Process has activities, put it at the very tipsy-top. 2690 addIndex = mLruProcesses.size(); 2691 nextIndex = mLruProcessServiceStart; 2692 inActivity = true; 2693 } else if (hasService) { 2694 // Process has services, put it at the top of the service list. 2695 addIndex = mLruProcessActivityStart; 2696 nextIndex = mLruProcessServiceStart; 2697 inActivity = true; 2698 inService = true; 2699 } else { 2700 // Process not otherwise of interest, it goes to the top of the non-service area. 2701 addIndex = mLruProcessServiceStart; 2702 if (client != null) { 2703 int clientIndex = mLruProcesses.lastIndexOf(client); 2704 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2705 + app); 2706 if (clientIndex >= 0 && addIndex > clientIndex) { 2707 addIndex = clientIndex; 2708 } 2709 } 2710 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2711 } 2712 2713 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2714 + mLruProcessActivityStart + "): " + app); 2715 */ 2716 2717 if (lrui >= 0) { 2718 if (lrui < mLruProcessActivityStart) { 2719 mLruProcessActivityStart--; 2720 } 2721 if (lrui < mLruProcessServiceStart) { 2722 mLruProcessServiceStart--; 2723 } 2724 /* 2725 if (addIndex > lrui) { 2726 addIndex--; 2727 } 2728 if (nextIndex > lrui) { 2729 nextIndex--; 2730 } 2731 */ 2732 mLruProcesses.remove(lrui); 2733 } 2734 2735 /* 2736 mLruProcesses.add(addIndex, app); 2737 if (inActivity) { 2738 mLruProcessActivityStart++; 2739 } 2740 if (inService) { 2741 mLruProcessActivityStart++; 2742 } 2743 */ 2744 2745 int nextIndex; 2746 if (hasActivity) { 2747 final int N = mLruProcesses.size(); 2748 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2749 // Process doesn't have activities, but has clients with 2750 // activities... move it up, but one below the top (the top 2751 // should always have a real activity). 2752 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2753 mLruProcesses.add(N-1, app); 2754 // To keep it from spamming the LRU list (by making a bunch of clients), 2755 // we will push down any other entries owned by the app. 2756 final int uid = app.info.uid; 2757 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2758 ProcessRecord subProc = mLruProcesses.get(i); 2759 if (subProc.info.uid == uid) { 2760 // We want to push this one down the list. If the process after 2761 // it is for the same uid, however, don't do so, because we don't 2762 // want them internally to be re-ordered. 2763 if (mLruProcesses.get(i-1).info.uid != uid) { 2764 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2765 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2766 ProcessRecord tmp = mLruProcesses.get(i); 2767 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2768 mLruProcesses.set(i-1, tmp); 2769 i--; 2770 } 2771 } else { 2772 // A gap, we can stop here. 2773 break; 2774 } 2775 } 2776 } else { 2777 // Process has activities, put it at the very tipsy-top. 2778 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2779 mLruProcesses.add(app); 2780 } 2781 nextIndex = mLruProcessServiceStart; 2782 } else if (hasService) { 2783 // Process has services, put it at the top of the service list. 2784 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2785 mLruProcesses.add(mLruProcessActivityStart, app); 2786 nextIndex = mLruProcessServiceStart; 2787 mLruProcessActivityStart++; 2788 } else { 2789 // Process not otherwise of interest, it goes to the top of the non-service area. 2790 int index = mLruProcessServiceStart; 2791 if (client != null) { 2792 // If there is a client, don't allow the process to be moved up higher 2793 // in the list than that client. 2794 int clientIndex = mLruProcesses.lastIndexOf(client); 2795 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2796 + " when updating " + app); 2797 if (clientIndex <= lrui) { 2798 // Don't allow the client index restriction to push it down farther in the 2799 // list than it already is. 2800 clientIndex = lrui; 2801 } 2802 if (clientIndex >= 0 && index > clientIndex) { 2803 index = clientIndex; 2804 } 2805 } 2806 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2807 mLruProcesses.add(index, app); 2808 nextIndex = index-1; 2809 mLruProcessActivityStart++; 2810 mLruProcessServiceStart++; 2811 } 2812 2813 // If the app is currently using a content provider or service, 2814 // bump those processes as well. 2815 for (int j=app.connections.size()-1; j>=0; j--) { 2816 ConnectionRecord cr = app.connections.valueAt(j); 2817 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2818 && cr.binding.service.app != null 2819 && cr.binding.service.app.lruSeq != mLruSeq 2820 && !cr.binding.service.app.persistent) { 2821 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2822 "service connection", cr, app); 2823 } 2824 } 2825 for (int j=app.conProviders.size()-1; j>=0; j--) { 2826 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2827 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2828 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2829 "provider reference", cpr, app); 2830 } 2831 } 2832 } 2833 2834 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2835 if (uid == Process.SYSTEM_UID) { 2836 // The system gets to run in any process. If there are multiple 2837 // processes with the same uid, just pick the first (this 2838 // should never happen). 2839 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2840 if (procs == null) return null; 2841 final int N = procs.size(); 2842 for (int i = 0; i < N; i++) { 2843 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2844 } 2845 } 2846 ProcessRecord proc = mProcessNames.get(processName, uid); 2847 if (false && proc != null && !keepIfLarge 2848 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2849 && proc.lastCachedPss >= 4000) { 2850 // Turn this condition on to cause killing to happen regularly, for testing. 2851 if (proc.baseProcessTracker != null) { 2852 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2853 } 2854 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2855 } else if (proc != null && !keepIfLarge 2856 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2857 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2858 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2859 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2860 if (proc.baseProcessTracker != null) { 2861 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2862 } 2863 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2864 } 2865 } 2866 return proc; 2867 } 2868 2869 void ensurePackageDexOpt(String packageName) { 2870 IPackageManager pm = AppGlobals.getPackageManager(); 2871 try { 2872 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2873 mDidDexOpt = true; 2874 } 2875 } catch (RemoteException e) { 2876 } 2877 } 2878 2879 boolean isNextTransitionForward() { 2880 int transit = mWindowManager.getPendingAppTransition(); 2881 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2882 || transit == AppTransition.TRANSIT_TASK_OPEN 2883 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2884 } 2885 2886 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2887 String processName, String abiOverride, int uid, Runnable crashHandler) { 2888 synchronized(this) { 2889 ApplicationInfo info = new ApplicationInfo(); 2890 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2891 // For isolated processes, the former contains the parent's uid and the latter the 2892 // actual uid of the isolated process. 2893 // In the special case introduced by this method (which is, starting an isolated 2894 // process directly from the SystemServer without an actual parent app process) the 2895 // closest thing to a parent's uid is SYSTEM_UID. 2896 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2897 // the |isolated| logic in the ProcessRecord constructor. 2898 info.uid = Process.SYSTEM_UID; 2899 info.processName = processName; 2900 info.className = entryPoint; 2901 info.packageName = "android"; 2902 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2903 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2904 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2905 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2906 crashHandler); 2907 return proc != null ? proc.pid : 0; 2908 } 2909 } 2910 2911 final ProcessRecord startProcessLocked(String processName, 2912 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2913 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2914 boolean isolated, boolean keepIfLarge) { 2915 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2916 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2917 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2918 null /* crashHandler */); 2919 } 2920 2921 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2922 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2923 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2924 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2925 long startTime = SystemClock.elapsedRealtime(); 2926 ProcessRecord app; 2927 if (!isolated) { 2928 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2929 checkTime(startTime, "startProcess: after getProcessRecord"); 2930 } else { 2931 // If this is an isolated process, it can't re-use an existing process. 2932 app = null; 2933 } 2934 // We don't have to do anything more if: 2935 // (1) There is an existing application record; and 2936 // (2) The caller doesn't think it is dead, OR there is no thread 2937 // object attached to it so we know it couldn't have crashed; and 2938 // (3) There is a pid assigned to it, so it is either starting or 2939 // already running. 2940 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2941 + " app=" + app + " knownToBeDead=" + knownToBeDead 2942 + " thread=" + (app != null ? app.thread : null) 2943 + " pid=" + (app != null ? app.pid : -1)); 2944 if (app != null && app.pid > 0) { 2945 if (!knownToBeDead || app.thread == null) { 2946 // We already have the app running, or are waiting for it to 2947 // come up (we have a pid but not yet its thread), so keep it. 2948 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2949 // If this is a new package in the process, add the package to the list 2950 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2951 checkTime(startTime, "startProcess: done, added package to proc"); 2952 return app; 2953 } 2954 2955 // An application record is attached to a previous process, 2956 // clean it up now. 2957 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2958 checkTime(startTime, "startProcess: bad proc running, killing"); 2959 Process.killProcessGroup(app.info.uid, app.pid); 2960 handleAppDiedLocked(app, true, true); 2961 checkTime(startTime, "startProcess: done killing old proc"); 2962 } 2963 2964 String hostingNameStr = hostingName != null 2965 ? hostingName.flattenToShortString() : null; 2966 2967 if (!isolated) { 2968 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2969 // If we are in the background, then check to see if this process 2970 // is bad. If so, we will just silently fail. 2971 if (mBadProcesses.get(info.processName, info.uid) != null) { 2972 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2973 + "/" + info.processName); 2974 return null; 2975 } 2976 } else { 2977 // When the user is explicitly starting a process, then clear its 2978 // crash count so that we won't make it bad until they see at 2979 // least one crash dialog again, and make the process good again 2980 // if it had been bad. 2981 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2982 + "/" + info.processName); 2983 mProcessCrashTimes.remove(info.processName, info.uid); 2984 if (mBadProcesses.get(info.processName, info.uid) != null) { 2985 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2986 UserHandle.getUserId(info.uid), info.uid, 2987 info.processName); 2988 mBadProcesses.remove(info.processName, info.uid); 2989 if (app != null) { 2990 app.bad = false; 2991 } 2992 } 2993 } 2994 } 2995 2996 if (app == null) { 2997 checkTime(startTime, "startProcess: creating new process record"); 2998 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2999 app.crashHandler = crashHandler; 3000 if (app == null) { 3001 Slog.w(TAG, "Failed making new process record for " 3002 + processName + "/" + info.uid + " isolated=" + isolated); 3003 return null; 3004 } 3005 mProcessNames.put(processName, app.uid, app); 3006 if (isolated) { 3007 mIsolatedProcesses.put(app.uid, app); 3008 } 3009 checkTime(startTime, "startProcess: done creating new process record"); 3010 } else { 3011 // If this is a new package in the process, add the package to the list 3012 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3013 checkTime(startTime, "startProcess: added package to existing proc"); 3014 } 3015 3016 // If the system is not ready yet, then hold off on starting this 3017 // process until it is. 3018 if (!mProcessesReady 3019 && !isAllowedWhileBooting(info) 3020 && !allowWhileBooting) { 3021 if (!mProcessesOnHold.contains(app)) { 3022 mProcessesOnHold.add(app); 3023 } 3024 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3025 checkTime(startTime, "startProcess: returning with proc on hold"); 3026 return app; 3027 } 3028 3029 checkTime(startTime, "startProcess: stepping in to startProcess"); 3030 startProcessLocked( 3031 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3032 checkTime(startTime, "startProcess: done starting proc!"); 3033 return (app.pid != 0) ? app : null; 3034 } 3035 3036 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3037 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3038 } 3039 3040 private final void startProcessLocked(ProcessRecord app, 3041 String hostingType, String hostingNameStr) { 3042 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3043 null /* entryPoint */, null /* entryPointArgs */); 3044 } 3045 3046 private final void startProcessLocked(ProcessRecord app, String hostingType, 3047 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3048 long startTime = SystemClock.elapsedRealtime(); 3049 if (app.pid > 0 && app.pid != MY_PID) { 3050 checkTime(startTime, "startProcess: removing from pids map"); 3051 synchronized (mPidsSelfLocked) { 3052 mPidsSelfLocked.remove(app.pid); 3053 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3054 } 3055 checkTime(startTime, "startProcess: done removing from pids map"); 3056 app.setPid(0); 3057 } 3058 3059 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3060 "startProcessLocked removing on hold: " + app); 3061 mProcessesOnHold.remove(app); 3062 3063 checkTime(startTime, "startProcess: starting to update cpu stats"); 3064 updateCpuStats(); 3065 checkTime(startTime, "startProcess: done updating cpu stats"); 3066 3067 try { 3068 int uid = app.uid; 3069 3070 int[] gids = null; 3071 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3072 if (!app.isolated) { 3073 int[] permGids = null; 3074 try { 3075 checkTime(startTime, "startProcess: getting gids from package manager"); 3076 final PackageManager pm = mContext.getPackageManager(); 3077 permGids = pm.getPackageGids(app.info.packageName); 3078 3079 if (Environment.isExternalStorageEmulated()) { 3080 checkTime(startTime, "startProcess: checking external storage perm"); 3081 if (pm.checkPermission( 3082 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3083 app.info.packageName) == PERMISSION_GRANTED) { 3084 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3085 } else { 3086 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3087 } 3088 } 3089 } catch (PackageManager.NameNotFoundException e) { 3090 Slog.w(TAG, "Unable to retrieve gids", e); 3091 } 3092 3093 /* 3094 * Add shared application and profile GIDs so applications can share some 3095 * resources like shared libraries and access user-wide resources 3096 */ 3097 if (permGids == null) { 3098 gids = new int[2]; 3099 } else { 3100 gids = new int[permGids.length + 2]; 3101 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3102 } 3103 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3104 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3105 } 3106 checkTime(startTime, "startProcess: building args"); 3107 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3108 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3109 && mTopComponent != null 3110 && app.processName.equals(mTopComponent.getPackageName())) { 3111 uid = 0; 3112 } 3113 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3114 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3115 uid = 0; 3116 } 3117 } 3118 int debugFlags = 0; 3119 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3121 // Also turn on CheckJNI for debuggable apps. It's quite 3122 // awkward to turn on otherwise. 3123 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3124 } 3125 // Run the app in safe mode if its manifest requests so or the 3126 // system is booted in safe mode. 3127 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3128 mSafeMode == true) { 3129 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3130 } 3131 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3132 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3133 } 3134 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3135 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3136 } 3137 if ("1".equals(SystemProperties.get("debug.assert"))) { 3138 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3139 } 3140 3141 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3142 if (requiredAbi == null) { 3143 requiredAbi = Build.SUPPORTED_ABIS[0]; 3144 } 3145 3146 String instructionSet = null; 3147 if (app.info.primaryCpuAbi != null) { 3148 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3149 } 3150 3151 // Start the process. It will either succeed and return a result containing 3152 // the PID of the new process, or else throw a RuntimeException. 3153 boolean isActivityProcess = (entryPoint == null); 3154 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3155 checkTime(startTime, "startProcess: asking zygote to start proc"); 3156 Process.ProcessStartResult startResult = Process.start(entryPoint, 3157 app.processName, uid, uid, gids, debugFlags, mountExternal, 3158 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3159 entryPointArgs); 3160 checkTime(startTime, "startProcess: returned from zygote!"); 3161 3162 if (app.isolated) { 3163 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3164 } 3165 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3166 checkTime(startTime, "startProcess: done updating battery stats"); 3167 3168 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3169 UserHandle.getUserId(uid), startResult.pid, uid, 3170 app.processName, hostingType, 3171 hostingNameStr != null ? hostingNameStr : ""); 3172 3173 if (app.persistent) { 3174 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3175 } 3176 3177 checkTime(startTime, "startProcess: building log message"); 3178 StringBuilder buf = mStringBuilder; 3179 buf.setLength(0); 3180 buf.append("Start proc "); 3181 buf.append(app.processName); 3182 if (!isActivityProcess) { 3183 buf.append(" ["); 3184 buf.append(entryPoint); 3185 buf.append("]"); 3186 } 3187 buf.append(" for "); 3188 buf.append(hostingType); 3189 if (hostingNameStr != null) { 3190 buf.append(" "); 3191 buf.append(hostingNameStr); 3192 } 3193 buf.append(": pid="); 3194 buf.append(startResult.pid); 3195 buf.append(" uid="); 3196 buf.append(uid); 3197 buf.append(" gids={"); 3198 if (gids != null) { 3199 for (int gi=0; gi<gids.length; gi++) { 3200 if (gi != 0) buf.append(", "); 3201 buf.append(gids[gi]); 3202 3203 } 3204 } 3205 buf.append("}"); 3206 if (requiredAbi != null) { 3207 buf.append(" abi="); 3208 buf.append(requiredAbi); 3209 } 3210 Slog.i(TAG, buf.toString()); 3211 app.setPid(startResult.pid); 3212 app.usingWrapper = startResult.usingWrapper; 3213 app.removed = false; 3214 app.killed = false; 3215 app.killedByAm = false; 3216 checkTime(startTime, "startProcess: starting to update pids map"); 3217 synchronized (mPidsSelfLocked) { 3218 this.mPidsSelfLocked.put(startResult.pid, app); 3219 if (isActivityProcess) { 3220 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3221 msg.obj = app; 3222 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3223 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3224 } 3225 } 3226 checkTime(startTime, "startProcess: done updating pids map"); 3227 } catch (RuntimeException e) { 3228 // XXX do better error recovery. 3229 app.setPid(0); 3230 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3231 if (app.isolated) { 3232 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3233 } 3234 Slog.e(TAG, "Failure starting process " + app.processName, e); 3235 } 3236 } 3237 3238 void updateUsageStats(ActivityRecord component, boolean resumed) { 3239 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3240 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3241 if (resumed) { 3242 if (mUsageStatsService != null) { 3243 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3244 UsageEvents.Event.MOVE_TO_FOREGROUND); 3245 } 3246 synchronized (stats) { 3247 stats.noteActivityResumedLocked(component.app.uid); 3248 } 3249 } else { 3250 if (mUsageStatsService != null) { 3251 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3252 UsageEvents.Event.MOVE_TO_BACKGROUND); 3253 } 3254 synchronized (stats) { 3255 stats.noteActivityPausedLocked(component.app.uid); 3256 } 3257 } 3258 } 3259 3260 Intent getHomeIntent() { 3261 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3262 intent.setComponent(mTopComponent); 3263 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3264 intent.addCategory(Intent.CATEGORY_HOME); 3265 } 3266 return intent; 3267 } 3268 3269 boolean startHomeActivityLocked(int userId) { 3270 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3271 && mTopAction == null) { 3272 // We are running in factory test mode, but unable to find 3273 // the factory test app, so just sit around displaying the 3274 // error message and don't try to start anything. 3275 return false; 3276 } 3277 Intent intent = getHomeIntent(); 3278 ActivityInfo aInfo = 3279 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3280 if (aInfo != null) { 3281 intent.setComponent(new ComponentName( 3282 aInfo.applicationInfo.packageName, aInfo.name)); 3283 // Don't do this if the home app is currently being 3284 // instrumented. 3285 aInfo = new ActivityInfo(aInfo); 3286 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3287 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3288 aInfo.applicationInfo.uid, true); 3289 if (app == null || app.instrumentationClass == null) { 3290 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3291 mStackSupervisor.startHomeActivity(intent, aInfo); 3292 } 3293 } 3294 3295 return true; 3296 } 3297 3298 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3299 ActivityInfo ai = null; 3300 ComponentName comp = intent.getComponent(); 3301 try { 3302 if (comp != null) { 3303 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3304 } else { 3305 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3306 intent, 3307 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3308 flags, userId); 3309 3310 if (info != null) { 3311 ai = info.activityInfo; 3312 } 3313 } 3314 } catch (RemoteException e) { 3315 // ignore 3316 } 3317 3318 return ai; 3319 } 3320 3321 /** 3322 * Starts the "new version setup screen" if appropriate. 3323 */ 3324 void startSetupActivityLocked() { 3325 // Only do this once per boot. 3326 if (mCheckedForSetup) { 3327 return; 3328 } 3329 3330 // We will show this screen if the current one is a different 3331 // version than the last one shown, and we are not running in 3332 // low-level factory test mode. 3333 final ContentResolver resolver = mContext.getContentResolver(); 3334 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3335 Settings.Global.getInt(resolver, 3336 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3337 mCheckedForSetup = true; 3338 3339 // See if we should be showing the platform update setup UI. 3340 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3341 List<ResolveInfo> ris = mContext.getPackageManager() 3342 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3343 3344 // We don't allow third party apps to replace this. 3345 ResolveInfo ri = null; 3346 for (int i=0; ris != null && i<ris.size(); i++) { 3347 if ((ris.get(i).activityInfo.applicationInfo.flags 3348 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3349 ri = ris.get(i); 3350 break; 3351 } 3352 } 3353 3354 if (ri != null) { 3355 String vers = ri.activityInfo.metaData != null 3356 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3357 : null; 3358 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3359 vers = ri.activityInfo.applicationInfo.metaData.getString( 3360 Intent.METADATA_SETUP_VERSION); 3361 } 3362 String lastVers = Settings.Secure.getString( 3363 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3364 if (vers != null && !vers.equals(lastVers)) { 3365 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3366 intent.setComponent(new ComponentName( 3367 ri.activityInfo.packageName, ri.activityInfo.name)); 3368 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3369 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3370 null); 3371 } 3372 } 3373 } 3374 } 3375 3376 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3377 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3378 } 3379 3380 void enforceNotIsolatedCaller(String caller) { 3381 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3382 throw new SecurityException("Isolated process not allowed to call " + caller); 3383 } 3384 } 3385 3386 void enforceShellRestriction(String restriction, int userHandle) { 3387 if (Binder.getCallingUid() == Process.SHELL_UID) { 3388 if (userHandle < 0 3389 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3390 throw new SecurityException("Shell does not have permission to access user " 3391 + userHandle); 3392 } 3393 } 3394 } 3395 3396 @Override 3397 public int getFrontActivityScreenCompatMode() { 3398 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3399 synchronized (this) { 3400 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3401 } 3402 } 3403 3404 @Override 3405 public void setFrontActivityScreenCompatMode(int mode) { 3406 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3407 "setFrontActivityScreenCompatMode"); 3408 synchronized (this) { 3409 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3410 } 3411 } 3412 3413 @Override 3414 public int getPackageScreenCompatMode(String packageName) { 3415 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3416 synchronized (this) { 3417 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3418 } 3419 } 3420 3421 @Override 3422 public void setPackageScreenCompatMode(String packageName, int mode) { 3423 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3424 "setPackageScreenCompatMode"); 3425 synchronized (this) { 3426 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3427 } 3428 } 3429 3430 @Override 3431 public boolean getPackageAskScreenCompat(String packageName) { 3432 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3433 synchronized (this) { 3434 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3435 } 3436 } 3437 3438 @Override 3439 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3440 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3441 "setPackageAskScreenCompat"); 3442 synchronized (this) { 3443 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3444 } 3445 } 3446 3447 private void dispatchProcessesChanged() { 3448 int N; 3449 synchronized (this) { 3450 N = mPendingProcessChanges.size(); 3451 if (mActiveProcessChanges.length < N) { 3452 mActiveProcessChanges = new ProcessChangeItem[N]; 3453 } 3454 mPendingProcessChanges.toArray(mActiveProcessChanges); 3455 mAvailProcessChanges.addAll(mPendingProcessChanges); 3456 mPendingProcessChanges.clear(); 3457 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3458 } 3459 3460 int i = mProcessObservers.beginBroadcast(); 3461 while (i > 0) { 3462 i--; 3463 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3464 if (observer != null) { 3465 try { 3466 for (int j=0; j<N; j++) { 3467 ProcessChangeItem item = mActiveProcessChanges[j]; 3468 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3469 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3470 + item.pid + " uid=" + item.uid + ": " 3471 + item.foregroundActivities); 3472 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3473 item.foregroundActivities); 3474 } 3475 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3476 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3477 + item.pid + " uid=" + item.uid + ": " + item.processState); 3478 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3479 } 3480 } 3481 } catch (RemoteException e) { 3482 } 3483 } 3484 } 3485 mProcessObservers.finishBroadcast(); 3486 } 3487 3488 private void dispatchProcessDied(int pid, int uid) { 3489 int i = mProcessObservers.beginBroadcast(); 3490 while (i > 0) { 3491 i--; 3492 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3493 if (observer != null) { 3494 try { 3495 observer.onProcessDied(pid, uid); 3496 } catch (RemoteException e) { 3497 } 3498 } 3499 } 3500 mProcessObservers.finishBroadcast(); 3501 } 3502 3503 @Override 3504 public final int startActivity(IApplicationThread caller, String callingPackage, 3505 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3506 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3507 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3508 resultWho, requestCode, startFlags, profilerInfo, options, 3509 UserHandle.getCallingUserId()); 3510 } 3511 3512 @Override 3513 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3514 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3515 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3516 enforceNotIsolatedCaller("startActivity"); 3517 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3518 false, ALLOW_FULL_ONLY, "startActivity", null); 3519 // TODO: Switch to user app stacks here. 3520 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3521 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3522 profilerInfo, null, null, options, userId, null, null); 3523 } 3524 3525 @Override 3526 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3527 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3528 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3529 3530 // This is very dangerous -- it allows you to perform a start activity (including 3531 // permission grants) as any app that may launch one of your own activities. So 3532 // we will only allow this to be done from activities that are part of the core framework, 3533 // and then only when they are running as the system. 3534 final ActivityRecord sourceRecord; 3535 final int targetUid; 3536 final String targetPackage; 3537 synchronized (this) { 3538 if (resultTo == null) { 3539 throw new SecurityException("Must be called from an activity"); 3540 } 3541 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3542 if (sourceRecord == null) { 3543 throw new SecurityException("Called with bad activity token: " + resultTo); 3544 } 3545 if (!sourceRecord.info.packageName.equals("android")) { 3546 throw new SecurityException( 3547 "Must be called from an activity that is declared in the android package"); 3548 } 3549 if (sourceRecord.app == null) { 3550 throw new SecurityException("Called without a process attached to activity"); 3551 } 3552 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3553 // This is still okay, as long as this activity is running under the 3554 // uid of the original calling activity. 3555 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3556 throw new SecurityException( 3557 "Calling activity in uid " + sourceRecord.app.uid 3558 + " must be system uid or original calling uid " 3559 + sourceRecord.launchedFromUid); 3560 } 3561 } 3562 targetUid = sourceRecord.launchedFromUid; 3563 targetPackage = sourceRecord.launchedFromPackage; 3564 } 3565 3566 // TODO: Switch to user app stacks here. 3567 try { 3568 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3569 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3570 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3571 return ret; 3572 } catch (SecurityException e) { 3573 // XXX need to figure out how to propagate to original app. 3574 // A SecurityException here is generally actually a fault of the original 3575 // calling activity (such as a fairly granting permissions), so propagate it 3576 // back to them. 3577 /* 3578 StringBuilder msg = new StringBuilder(); 3579 msg.append("While launching"); 3580 msg.append(intent.toString()); 3581 msg.append(": "); 3582 msg.append(e.getMessage()); 3583 */ 3584 throw e; 3585 } 3586 } 3587 3588 @Override 3589 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3590 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3591 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3592 enforceNotIsolatedCaller("startActivityAndWait"); 3593 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3594 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3595 WaitResult res = new WaitResult(); 3596 // TODO: Switch to user app stacks here. 3597 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3598 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3599 options, userId, null, null); 3600 return res; 3601 } 3602 3603 @Override 3604 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3605 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3606 int startFlags, Configuration config, Bundle options, int userId) { 3607 enforceNotIsolatedCaller("startActivityWithConfig"); 3608 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3609 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3610 // TODO: Switch to user app stacks here. 3611 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3612 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3613 null, null, config, options, userId, null, null); 3614 return ret; 3615 } 3616 3617 @Override 3618 public int startActivityIntentSender(IApplicationThread caller, 3619 IntentSender intent, Intent fillInIntent, String resolvedType, 3620 IBinder resultTo, String resultWho, int requestCode, 3621 int flagsMask, int flagsValues, Bundle options) { 3622 enforceNotIsolatedCaller("startActivityIntentSender"); 3623 // Refuse possible leaked file descriptors 3624 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3625 throw new IllegalArgumentException("File descriptors passed in Intent"); 3626 } 3627 3628 IIntentSender sender = intent.getTarget(); 3629 if (!(sender instanceof PendingIntentRecord)) { 3630 throw new IllegalArgumentException("Bad PendingIntent object"); 3631 } 3632 3633 PendingIntentRecord pir = (PendingIntentRecord)sender; 3634 3635 synchronized (this) { 3636 // If this is coming from the currently resumed activity, it is 3637 // effectively saying that app switches are allowed at this point. 3638 final ActivityStack stack = getFocusedStack(); 3639 if (stack.mResumedActivity != null && 3640 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3641 mAppSwitchesAllowedTime = 0; 3642 } 3643 } 3644 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3645 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3646 return ret; 3647 } 3648 3649 @Override 3650 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3651 Intent intent, String resolvedType, IVoiceInteractionSession session, 3652 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3653 Bundle options, int userId) { 3654 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3655 != PackageManager.PERMISSION_GRANTED) { 3656 String msg = "Permission Denial: startVoiceActivity() from pid=" 3657 + Binder.getCallingPid() 3658 + ", uid=" + Binder.getCallingUid() 3659 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3660 Slog.w(TAG, msg); 3661 throw new SecurityException(msg); 3662 } 3663 if (session == null || interactor == null) { 3664 throw new NullPointerException("null session or interactor"); 3665 } 3666 userId = handleIncomingUser(callingPid, callingUid, userId, 3667 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3668 // TODO: Switch to user app stacks here. 3669 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3670 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3671 null, options, userId, null, null); 3672 } 3673 3674 @Override 3675 public boolean startNextMatchingActivity(IBinder callingActivity, 3676 Intent intent, Bundle options) { 3677 // Refuse possible leaked file descriptors 3678 if (intent != null && intent.hasFileDescriptors() == true) { 3679 throw new IllegalArgumentException("File descriptors passed in Intent"); 3680 } 3681 3682 synchronized (this) { 3683 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3684 if (r == null) { 3685 ActivityOptions.abort(options); 3686 return false; 3687 } 3688 if (r.app == null || r.app.thread == null) { 3689 // The caller is not running... d'oh! 3690 ActivityOptions.abort(options); 3691 return false; 3692 } 3693 intent = new Intent(intent); 3694 // The caller is not allowed to change the data. 3695 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3696 // And we are resetting to find the next component... 3697 intent.setComponent(null); 3698 3699 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3700 3701 ActivityInfo aInfo = null; 3702 try { 3703 List<ResolveInfo> resolves = 3704 AppGlobals.getPackageManager().queryIntentActivities( 3705 intent, r.resolvedType, 3706 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3707 UserHandle.getCallingUserId()); 3708 3709 // Look for the original activity in the list... 3710 final int N = resolves != null ? resolves.size() : 0; 3711 for (int i=0; i<N; i++) { 3712 ResolveInfo rInfo = resolves.get(i); 3713 if (rInfo.activityInfo.packageName.equals(r.packageName) 3714 && rInfo.activityInfo.name.equals(r.info.name)) { 3715 // We found the current one... the next matching is 3716 // after it. 3717 i++; 3718 if (i<N) { 3719 aInfo = resolves.get(i).activityInfo; 3720 } 3721 if (debug) { 3722 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3723 + "/" + r.info.name); 3724 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3725 + "/" + aInfo.name); 3726 } 3727 break; 3728 } 3729 } 3730 } catch (RemoteException e) { 3731 } 3732 3733 if (aInfo == null) { 3734 // Nobody who is next! 3735 ActivityOptions.abort(options); 3736 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3737 return false; 3738 } 3739 3740 intent.setComponent(new ComponentName( 3741 aInfo.applicationInfo.packageName, aInfo.name)); 3742 intent.setFlags(intent.getFlags()&~( 3743 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3744 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3745 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3746 Intent.FLAG_ACTIVITY_NEW_TASK)); 3747 3748 // Okay now we need to start the new activity, replacing the 3749 // currently running activity. This is a little tricky because 3750 // we want to start the new one as if the current one is finished, 3751 // but not finish the current one first so that there is no flicker. 3752 // And thus... 3753 final boolean wasFinishing = r.finishing; 3754 r.finishing = true; 3755 3756 // Propagate reply information over to the new activity. 3757 final ActivityRecord resultTo = r.resultTo; 3758 final String resultWho = r.resultWho; 3759 final int requestCode = r.requestCode; 3760 r.resultTo = null; 3761 if (resultTo != null) { 3762 resultTo.removeResultsLocked(r, resultWho, requestCode); 3763 } 3764 3765 final long origId = Binder.clearCallingIdentity(); 3766 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3767 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3768 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3769 -1, r.launchedFromUid, 0, options, false, null, null, null); 3770 Binder.restoreCallingIdentity(origId); 3771 3772 r.finishing = wasFinishing; 3773 if (res != ActivityManager.START_SUCCESS) { 3774 return false; 3775 } 3776 return true; 3777 } 3778 } 3779 3780 @Override 3781 public final int startActivityFromRecents(int taskId, Bundle options) { 3782 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3783 String msg = "Permission Denial: startActivityFromRecents called without " + 3784 START_TASKS_FROM_RECENTS; 3785 Slog.w(TAG, msg); 3786 throw new SecurityException(msg); 3787 } 3788 return startActivityFromRecentsInner(taskId, options); 3789 } 3790 3791 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3792 final TaskRecord task; 3793 final int callingUid; 3794 final String callingPackage; 3795 final Intent intent; 3796 final int userId; 3797 synchronized (this) { 3798 task = recentTaskForIdLocked(taskId); 3799 if (task == null) { 3800 throw new IllegalArgumentException("Task " + taskId + " not found."); 3801 } 3802 callingUid = task.mCallingUid; 3803 callingPackage = task.mCallingPackage; 3804 intent = task.intent; 3805 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3806 userId = task.userId; 3807 } 3808 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3809 options, userId, null, task); 3810 } 3811 3812 final int startActivityInPackage(int uid, String callingPackage, 3813 Intent intent, String resolvedType, IBinder resultTo, 3814 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3815 IActivityContainer container, TaskRecord inTask) { 3816 3817 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3818 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3819 3820 // TODO: Switch to user app stacks here. 3821 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3822 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3823 null, null, null, options, userId, container, inTask); 3824 return ret; 3825 } 3826 3827 @Override 3828 public final int startActivities(IApplicationThread caller, String callingPackage, 3829 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3830 int userId) { 3831 enforceNotIsolatedCaller("startActivities"); 3832 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3833 false, ALLOW_FULL_ONLY, "startActivity", null); 3834 // TODO: Switch to user app stacks here. 3835 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3836 resolvedTypes, resultTo, options, userId); 3837 return ret; 3838 } 3839 3840 final int startActivitiesInPackage(int uid, String callingPackage, 3841 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3842 Bundle options, int userId) { 3843 3844 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3845 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3846 // TODO: Switch to user app stacks here. 3847 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3848 resultTo, options, userId); 3849 return ret; 3850 } 3851 3852 //explicitly remove thd old information in mRecentTasks when removing existing user. 3853 private void removeRecentTasksForUserLocked(int userId) { 3854 if(userId <= 0) { 3855 Slog.i(TAG, "Can't remove recent task on user " + userId); 3856 return; 3857 } 3858 3859 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3860 TaskRecord tr = mRecentTasks.get(i); 3861 if (tr.userId == userId) { 3862 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3863 + " when finishing user" + userId); 3864 mRecentTasks.remove(i); 3865 tr.removedFromRecents(mTaskPersister); 3866 } 3867 } 3868 3869 // Remove tasks from persistent storage. 3870 mTaskPersister.wakeup(null, true); 3871 } 3872 3873 // Sort by taskId 3874 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3875 @Override 3876 public int compare(TaskRecord lhs, TaskRecord rhs) { 3877 return rhs.taskId - lhs.taskId; 3878 } 3879 }; 3880 3881 // Extract the affiliates of the chain containing mRecentTasks[start]. 3882 private int processNextAffiliateChain(int start) { 3883 final TaskRecord startTask = mRecentTasks.get(start); 3884 final int affiliateId = startTask.mAffiliatedTaskId; 3885 3886 // Quick identification of isolated tasks. I.e. those not launched behind. 3887 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3888 startTask.mNextAffiliate == null) { 3889 // There is still a slim chance that there are other tasks that point to this task 3890 // and that the chain is so messed up that this task no longer points to them but 3891 // the gain of this optimization outweighs the risk. 3892 startTask.inRecents = true; 3893 return start + 1; 3894 } 3895 3896 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3897 mTmpRecents.clear(); 3898 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3899 final TaskRecord task = mRecentTasks.get(i); 3900 if (task.mAffiliatedTaskId == affiliateId) { 3901 mRecentTasks.remove(i); 3902 mTmpRecents.add(task); 3903 } 3904 } 3905 3906 // Sort them all by taskId. That is the order they were create in and that order will 3907 // always be correct. 3908 Collections.sort(mTmpRecents, mTaskRecordComparator); 3909 3910 // Go through and fix up the linked list. 3911 // The first one is the end of the chain and has no next. 3912 final TaskRecord first = mTmpRecents.get(0); 3913 first.inRecents = true; 3914 if (first.mNextAffiliate != null) { 3915 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3916 first.setNextAffiliate(null); 3917 mTaskPersister.wakeup(first, false); 3918 } 3919 // Everything in the middle is doubly linked from next to prev. 3920 final int tmpSize = mTmpRecents.size(); 3921 for (int i = 0; i < tmpSize - 1; ++i) { 3922 final TaskRecord next = mTmpRecents.get(i); 3923 final TaskRecord prev = mTmpRecents.get(i + 1); 3924 if (next.mPrevAffiliate != prev) { 3925 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3926 " setting prev=" + prev); 3927 next.setPrevAffiliate(prev); 3928 mTaskPersister.wakeup(next, false); 3929 } 3930 if (prev.mNextAffiliate != next) { 3931 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3932 " setting next=" + next); 3933 prev.setNextAffiliate(next); 3934 mTaskPersister.wakeup(prev, false); 3935 } 3936 prev.inRecents = true; 3937 } 3938 // The last one is the beginning of the list and has no prev. 3939 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3940 if (last.mPrevAffiliate != null) { 3941 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3942 last.setPrevAffiliate(null); 3943 mTaskPersister.wakeup(last, false); 3944 } 3945 3946 // Insert the group back into mRecentTasks at start. 3947 mRecentTasks.addAll(start, mTmpRecents); 3948 3949 // Let the caller know where we left off. 3950 return start + tmpSize; 3951 } 3952 3953 /** 3954 * Update the recent tasks lists: make sure tasks should still be here (their 3955 * applications / activities still exist), update their availability, fixup ordering 3956 * of affiliations. 3957 */ 3958 void cleanupRecentTasksLocked(int userId) { 3959 if (mRecentTasks == null) { 3960 // Happens when called from the packagemanager broadcast before boot. 3961 return; 3962 } 3963 3964 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3965 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3966 final IPackageManager pm = AppGlobals.getPackageManager(); 3967 final ActivityInfo dummyAct = new ActivityInfo(); 3968 final ApplicationInfo dummyApp = new ApplicationInfo(); 3969 3970 int N = mRecentTasks.size(); 3971 3972 int[] users = userId == UserHandle.USER_ALL 3973 ? getUsersLocked() : new int[] { userId }; 3974 for (int user : users) { 3975 for (int i = 0; i < N; i++) { 3976 TaskRecord task = mRecentTasks.get(i); 3977 if (task.userId != user) { 3978 // Only look at tasks for the user ID of interest. 3979 continue; 3980 } 3981 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3982 // This situation is broken, and we should just get rid of it now. 3983 mRecentTasks.remove(i); 3984 task.removedFromRecents(mTaskPersister); 3985 i--; 3986 N--; 3987 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3988 continue; 3989 } 3990 // Check whether this activity is currently available. 3991 if (task.realActivity != null) { 3992 ActivityInfo ai = availActCache.get(task.realActivity); 3993 if (ai == null) { 3994 try { 3995 ai = pm.getActivityInfo(task.realActivity, 3996 PackageManager.GET_UNINSTALLED_PACKAGES 3997 | PackageManager.GET_DISABLED_COMPONENTS, user); 3998 } catch (RemoteException e) { 3999 // Will never happen. 4000 continue; 4001 } 4002 if (ai == null) { 4003 ai = dummyAct; 4004 } 4005 availActCache.put(task.realActivity, ai); 4006 } 4007 if (ai == dummyAct) { 4008 // This could be either because the activity no longer exists, or the 4009 // app is temporarily gone. For the former we want to remove the recents 4010 // entry; for the latter we want to mark it as unavailable. 4011 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4012 if (app == null) { 4013 try { 4014 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4015 PackageManager.GET_UNINSTALLED_PACKAGES 4016 | PackageManager.GET_DISABLED_COMPONENTS, user); 4017 } catch (RemoteException e) { 4018 // Will never happen. 4019 continue; 4020 } 4021 if (app == null) { 4022 app = dummyApp; 4023 } 4024 availAppCache.put(task.realActivity.getPackageName(), app); 4025 } 4026 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4027 // Doesn't exist any more! Good-bye. 4028 mRecentTasks.remove(i); 4029 task.removedFromRecents(mTaskPersister); 4030 i--; 4031 N--; 4032 Slog.w(TAG, "Removing no longer valid recent: " + task); 4033 continue; 4034 } else { 4035 // Otherwise just not available for now. 4036 if (task.isAvailable) { 4037 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4038 + task); 4039 } 4040 task.isAvailable = false; 4041 } 4042 } else { 4043 if (!ai.enabled || !ai.applicationInfo.enabled 4044 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4045 if (task.isAvailable) { 4046 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4047 + task + " (enabled=" + ai.enabled + "/" 4048 + ai.applicationInfo.enabled + " flags=" 4049 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4050 } 4051 task.isAvailable = false; 4052 } else { 4053 if (!task.isAvailable) { 4054 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4055 + task); 4056 } 4057 task.isAvailable = true; 4058 } 4059 } 4060 } 4061 } 4062 } 4063 4064 // Verify the affiliate chain for each task. 4065 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4066 } 4067 4068 mTmpRecents.clear(); 4069 // mRecentTasks is now in sorted, affiliated order. 4070 } 4071 4072 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4073 int N = mRecentTasks.size(); 4074 TaskRecord top = task; 4075 int topIndex = taskIndex; 4076 while (top.mNextAffiliate != null && topIndex > 0) { 4077 top = top.mNextAffiliate; 4078 topIndex--; 4079 } 4080 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4081 + topIndex + " from intial " + taskIndex); 4082 // Find the end of the chain, doing a sanity check along the way. 4083 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4084 int endIndex = topIndex; 4085 TaskRecord prev = top; 4086 while (endIndex < N) { 4087 TaskRecord cur = mRecentTasks.get(endIndex); 4088 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4089 + endIndex + " " + cur); 4090 if (cur == top) { 4091 // Verify start of the chain. 4092 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4093 Slog.wtf(TAG, "Bad chain @" + endIndex 4094 + ": first task has next affiliate: " + prev); 4095 sane = false; 4096 break; 4097 } 4098 } else { 4099 // Verify middle of the chain's next points back to the one before. 4100 if (cur.mNextAffiliate != prev 4101 || cur.mNextAffiliateTaskId != prev.taskId) { 4102 Slog.wtf(TAG, "Bad chain @" + endIndex 4103 + ": middle task " + cur + " @" + endIndex 4104 + " has bad next affiliate " 4105 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4106 + ", expected " + prev); 4107 sane = false; 4108 break; 4109 } 4110 } 4111 if (cur.mPrevAffiliateTaskId == -1) { 4112 // Chain ends here. 4113 if (cur.mPrevAffiliate != null) { 4114 Slog.wtf(TAG, "Bad chain @" + endIndex 4115 + ": last task " + cur + " has previous affiliate " 4116 + cur.mPrevAffiliate); 4117 sane = false; 4118 } 4119 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4120 break; 4121 } else { 4122 // Verify middle of the chain's prev points to a valid item. 4123 if (cur.mPrevAffiliate == null) { 4124 Slog.wtf(TAG, "Bad chain @" + endIndex 4125 + ": task " + cur + " has previous affiliate " 4126 + cur.mPrevAffiliate + " but should be id " 4127 + cur.mPrevAffiliate); 4128 sane = false; 4129 break; 4130 } 4131 } 4132 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4133 Slog.wtf(TAG, "Bad chain @" + endIndex 4134 + ": task " + cur + " has affiliated id " 4135 + cur.mAffiliatedTaskId + " but should be " 4136 + task.mAffiliatedTaskId); 4137 sane = false; 4138 break; 4139 } 4140 prev = cur; 4141 endIndex++; 4142 if (endIndex >= N) { 4143 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4144 + ": last task " + prev); 4145 sane = false; 4146 break; 4147 } 4148 } 4149 if (sane) { 4150 if (endIndex < taskIndex) { 4151 Slog.wtf(TAG, "Bad chain @" + endIndex 4152 + ": did not extend to task " + task + " @" + taskIndex); 4153 sane = false; 4154 } 4155 } 4156 if (sane) { 4157 // All looks good, we can just move all of the affiliated tasks 4158 // to the top. 4159 for (int i=topIndex; i<=endIndex; i++) { 4160 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4161 + " from " + i + " to " + (i-topIndex)); 4162 TaskRecord cur = mRecentTasks.remove(i); 4163 mRecentTasks.add(i-topIndex, cur); 4164 } 4165 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4166 + " to " + endIndex); 4167 return true; 4168 } 4169 4170 // Whoops, couldn't do it. 4171 return false; 4172 } 4173 4174 final void addRecentTaskLocked(TaskRecord task) { 4175 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4176 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4177 4178 int N = mRecentTasks.size(); 4179 // Quick case: check if the top-most recent task is the same. 4180 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4182 return; 4183 } 4184 // Another quick case: check if this is part of a set of affiliated 4185 // tasks that are at the top. 4186 if (isAffiliated && N > 0 && task.inRecents 4187 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4188 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4189 + " at top when adding " + task); 4190 return; 4191 } 4192 // Another quick case: never add voice sessions. 4193 if (task.voiceSession != null) { 4194 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4195 return; 4196 } 4197 4198 boolean needAffiliationFix = false; 4199 4200 // Slightly less quick case: the task is already in recents, so all we need 4201 // to do is move it. 4202 if (task.inRecents) { 4203 int taskIndex = mRecentTasks.indexOf(task); 4204 if (taskIndex >= 0) { 4205 if (!isAffiliated) { 4206 // Simple case: this is not an affiliated task, so we just move it to the front. 4207 mRecentTasks.remove(taskIndex); 4208 mRecentTasks.add(0, task); 4209 notifyTaskPersisterLocked(task, false); 4210 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4211 + " from " + taskIndex); 4212 return; 4213 } else { 4214 // More complicated: need to keep all affiliated tasks together. 4215 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4216 // All went well. 4217 return; 4218 } 4219 4220 // Uh oh... something bad in the affiliation chain, try to rebuild 4221 // everything and then go through our general path of adding a new task. 4222 needAffiliationFix = true; 4223 } 4224 } else { 4225 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4226 needAffiliationFix = true; 4227 } 4228 } 4229 4230 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4231 trimRecentsForTask(task, true); 4232 4233 N = mRecentTasks.size(); 4234 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4235 final TaskRecord tr = mRecentTasks.remove(N - 1); 4236 tr.removedFromRecents(mTaskPersister); 4237 N--; 4238 } 4239 task.inRecents = true; 4240 if (!isAffiliated || needAffiliationFix) { 4241 // If this is a simple non-affiliated task, or we had some failure trying to 4242 // handle it as part of an affilated task, then just place it at the top. 4243 mRecentTasks.add(0, task); 4244 } else if (isAffiliated) { 4245 // If this is a new affiliated task, then move all of the affiliated tasks 4246 // to the front and insert this new one. 4247 TaskRecord other = task.mNextAffiliate; 4248 if (other == null) { 4249 other = task.mPrevAffiliate; 4250 } 4251 if (other != null) { 4252 int otherIndex = mRecentTasks.indexOf(other); 4253 if (otherIndex >= 0) { 4254 // Insert new task at appropriate location. 4255 int taskIndex; 4256 if (other == task.mNextAffiliate) { 4257 // We found the index of our next affiliation, which is who is 4258 // before us in the list, so add after that point. 4259 taskIndex = otherIndex+1; 4260 } else { 4261 // We found the index of our previous affiliation, which is who is 4262 // after us in the list, so add at their position. 4263 taskIndex = otherIndex; 4264 } 4265 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4266 + taskIndex + ": " + task); 4267 mRecentTasks.add(taskIndex, task); 4268 4269 // Now move everything to the front. 4270 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4271 // All went well. 4272 return; 4273 } 4274 4275 // Uh oh... something bad in the affiliation chain, try to rebuild 4276 // everything and then go through our general path of adding a new task. 4277 needAffiliationFix = true; 4278 } else { 4279 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4280 + other); 4281 needAffiliationFix = true; 4282 } 4283 } else { 4284 if (DEBUG_RECENTS) Slog.d(TAG, 4285 "addRecent: adding affiliated task without next/prev:" + task); 4286 needAffiliationFix = true; 4287 } 4288 } 4289 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4290 4291 if (needAffiliationFix) { 4292 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4293 cleanupRecentTasksLocked(task.userId); 4294 } 4295 } 4296 4297 /** 4298 * If needed, remove oldest existing entries in recents that are for the same kind 4299 * of task as the given one. 4300 */ 4301 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4302 int N = mRecentTasks.size(); 4303 final Intent intent = task.intent; 4304 final boolean document = intent != null && intent.isDocument(); 4305 4306 int maxRecents = task.maxRecents - 1; 4307 for (int i=0; i<N; i++) { 4308 final TaskRecord tr = mRecentTasks.get(i); 4309 if (task != tr) { 4310 if (task.userId != tr.userId) { 4311 continue; 4312 } 4313 if (i > MAX_RECENT_BITMAPS) { 4314 tr.freeLastThumbnail(); 4315 } 4316 final Intent trIntent = tr.intent; 4317 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4318 (intent == null || !intent.filterEquals(trIntent))) { 4319 continue; 4320 } 4321 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4322 if (document && trIsDocument) { 4323 // These are the same document activity (not necessarily the same doc). 4324 if (maxRecents > 0) { 4325 --maxRecents; 4326 continue; 4327 } 4328 // Hit the maximum number of documents for this task. Fall through 4329 // and remove this document from recents. 4330 } else if (document || trIsDocument) { 4331 // Only one of these is a document. Not the droid we're looking for. 4332 continue; 4333 } 4334 } 4335 4336 if (!doTrim) { 4337 // If the caller is not actually asking for a trim, just tell them we reached 4338 // a point where the trim would happen. 4339 return i; 4340 } 4341 4342 // Either task and tr are the same or, their affinities match or their intents match 4343 // and neither of them is a document, or they are documents using the same activity 4344 // and their maxRecents has been reached. 4345 tr.disposeThumbnail(); 4346 mRecentTasks.remove(i); 4347 if (task != tr) { 4348 tr.removedFromRecents(mTaskPersister); 4349 } 4350 i--; 4351 N--; 4352 if (task.intent == null) { 4353 // If the new recent task we are adding is not fully 4354 // specified, then replace it with the existing recent task. 4355 task = tr; 4356 } 4357 notifyTaskPersisterLocked(tr, false); 4358 } 4359 4360 return -1; 4361 } 4362 4363 @Override 4364 public void reportActivityFullyDrawn(IBinder token) { 4365 synchronized (this) { 4366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4367 if (r == null) { 4368 return; 4369 } 4370 r.reportFullyDrawnLocked(); 4371 } 4372 } 4373 4374 @Override 4375 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4376 synchronized (this) { 4377 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4378 if (r == null) { 4379 return; 4380 } 4381 final long origId = Binder.clearCallingIdentity(); 4382 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4383 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4384 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4385 if (config != null) { 4386 r.frozenBeforeDestroy = true; 4387 if (!updateConfigurationLocked(config, r, false, false)) { 4388 mStackSupervisor.resumeTopActivitiesLocked(); 4389 } 4390 } 4391 Binder.restoreCallingIdentity(origId); 4392 } 4393 } 4394 4395 @Override 4396 public int getRequestedOrientation(IBinder token) { 4397 synchronized (this) { 4398 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4399 if (r == null) { 4400 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4401 } 4402 return mWindowManager.getAppOrientation(r.appToken); 4403 } 4404 } 4405 4406 /** 4407 * This is the internal entry point for handling Activity.finish(). 4408 * 4409 * @param token The Binder token referencing the Activity we want to finish. 4410 * @param resultCode Result code, if any, from this Activity. 4411 * @param resultData Result data (Intent), if any, from this Activity. 4412 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4413 * the root Activity in the task. 4414 * 4415 * @return Returns true if the activity successfully finished, or false if it is still running. 4416 */ 4417 @Override 4418 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4419 boolean finishTask) { 4420 // Refuse possible leaked file descriptors 4421 if (resultData != null && resultData.hasFileDescriptors() == true) { 4422 throw new IllegalArgumentException("File descriptors passed in Intent"); 4423 } 4424 4425 synchronized(this) { 4426 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4427 if (r == null) { 4428 return true; 4429 } 4430 // Keep track of the root activity of the task before we finish it 4431 TaskRecord tr = r.task; 4432 ActivityRecord rootR = tr.getRootActivity(); 4433 // Do not allow task to finish in Lock Task mode. 4434 if (tr == mStackSupervisor.mLockTaskModeTask) { 4435 if (rootR == r) { 4436 mStackSupervisor.showLockTaskToast(); 4437 return false; 4438 } 4439 } 4440 if (mController != null) { 4441 // Find the first activity that is not finishing. 4442 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4443 if (next != null) { 4444 // ask watcher if this is allowed 4445 boolean resumeOK = true; 4446 try { 4447 resumeOK = mController.activityResuming(next.packageName); 4448 } catch (RemoteException e) { 4449 mController = null; 4450 Watchdog.getInstance().setActivityController(null); 4451 } 4452 4453 if (!resumeOK) { 4454 return false; 4455 } 4456 } 4457 } 4458 final long origId = Binder.clearCallingIdentity(); 4459 try { 4460 boolean res; 4461 if (finishTask && r == rootR) { 4462 // If requested, remove the task that is associated to this activity only if it 4463 // was the root activity in the task. The result code and data is ignored because 4464 // we don't support returning them across task boundaries. 4465 res = removeTaskByIdLocked(tr.taskId, 0); 4466 } else { 4467 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4468 resultData, "app-request", true); 4469 } 4470 return res; 4471 } finally { 4472 Binder.restoreCallingIdentity(origId); 4473 } 4474 } 4475 } 4476 4477 @Override 4478 public final void finishHeavyWeightApp() { 4479 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4480 != PackageManager.PERMISSION_GRANTED) { 4481 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4482 + Binder.getCallingPid() 4483 + ", uid=" + Binder.getCallingUid() 4484 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4485 Slog.w(TAG, msg); 4486 throw new SecurityException(msg); 4487 } 4488 4489 synchronized(this) { 4490 if (mHeavyWeightProcess == null) { 4491 return; 4492 } 4493 4494 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4495 mHeavyWeightProcess.activities); 4496 for (int i=0; i<activities.size(); i++) { 4497 ActivityRecord r = activities.get(i); 4498 if (!r.finishing) { 4499 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4500 null, "finish-heavy", true); 4501 } 4502 } 4503 4504 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4505 mHeavyWeightProcess.userId, 0)); 4506 mHeavyWeightProcess = null; 4507 } 4508 } 4509 4510 @Override 4511 public void crashApplication(int uid, int initialPid, String packageName, 4512 String message) { 4513 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4514 != PackageManager.PERMISSION_GRANTED) { 4515 String msg = "Permission Denial: crashApplication() from pid=" 4516 + Binder.getCallingPid() 4517 + ", uid=" + Binder.getCallingUid() 4518 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4519 Slog.w(TAG, msg); 4520 throw new SecurityException(msg); 4521 } 4522 4523 synchronized(this) { 4524 ProcessRecord proc = null; 4525 4526 // Figure out which process to kill. We don't trust that initialPid 4527 // still has any relation to current pids, so must scan through the 4528 // list. 4529 synchronized (mPidsSelfLocked) { 4530 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4531 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4532 if (p.uid != uid) { 4533 continue; 4534 } 4535 if (p.pid == initialPid) { 4536 proc = p; 4537 break; 4538 } 4539 if (p.pkgList.containsKey(packageName)) { 4540 proc = p; 4541 } 4542 } 4543 } 4544 4545 if (proc == null) { 4546 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4547 + " initialPid=" + initialPid 4548 + " packageName=" + packageName); 4549 return; 4550 } 4551 4552 if (proc.thread != null) { 4553 if (proc.pid == Process.myPid()) { 4554 Log.w(TAG, "crashApplication: trying to crash self!"); 4555 return; 4556 } 4557 long ident = Binder.clearCallingIdentity(); 4558 try { 4559 proc.thread.scheduleCrash(message); 4560 } catch (RemoteException e) { 4561 } 4562 Binder.restoreCallingIdentity(ident); 4563 } 4564 } 4565 } 4566 4567 @Override 4568 public final void finishSubActivity(IBinder token, String resultWho, 4569 int requestCode) { 4570 synchronized(this) { 4571 final long origId = Binder.clearCallingIdentity(); 4572 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4573 if (r != null) { 4574 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4575 } 4576 Binder.restoreCallingIdentity(origId); 4577 } 4578 } 4579 4580 @Override 4581 public boolean finishActivityAffinity(IBinder token) { 4582 synchronized(this) { 4583 final long origId = Binder.clearCallingIdentity(); 4584 try { 4585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4586 4587 ActivityRecord rootR = r.task.getRootActivity(); 4588 // Do not allow task to finish in Lock Task mode. 4589 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4590 if (rootR == r) { 4591 mStackSupervisor.showLockTaskToast(); 4592 return false; 4593 } 4594 } 4595 boolean res = false; 4596 if (r != null) { 4597 res = r.task.stack.finishActivityAffinityLocked(r); 4598 } 4599 return res; 4600 } finally { 4601 Binder.restoreCallingIdentity(origId); 4602 } 4603 } 4604 } 4605 4606 @Override 4607 public void finishVoiceTask(IVoiceInteractionSession session) { 4608 synchronized(this) { 4609 final long origId = Binder.clearCallingIdentity(); 4610 try { 4611 mStackSupervisor.finishVoiceTask(session); 4612 } finally { 4613 Binder.restoreCallingIdentity(origId); 4614 } 4615 } 4616 4617 } 4618 4619 @Override 4620 public boolean releaseActivityInstance(IBinder token) { 4621 synchronized(this) { 4622 final long origId = Binder.clearCallingIdentity(); 4623 try { 4624 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4625 if (r.task == null || r.task.stack == null) { 4626 return false; 4627 } 4628 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4629 } finally { 4630 Binder.restoreCallingIdentity(origId); 4631 } 4632 } 4633 } 4634 4635 @Override 4636 public void releaseSomeActivities(IApplicationThread appInt) { 4637 synchronized(this) { 4638 final long origId = Binder.clearCallingIdentity(); 4639 try { 4640 ProcessRecord app = getRecordForAppLocked(appInt); 4641 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4642 } finally { 4643 Binder.restoreCallingIdentity(origId); 4644 } 4645 } 4646 } 4647 4648 @Override 4649 public boolean willActivityBeVisible(IBinder token) { 4650 synchronized(this) { 4651 ActivityStack stack = ActivityRecord.getStackLocked(token); 4652 if (stack != null) { 4653 return stack.willActivityBeVisibleLocked(token); 4654 } 4655 return false; 4656 } 4657 } 4658 4659 @Override 4660 public void overridePendingTransition(IBinder token, String packageName, 4661 int enterAnim, int exitAnim) { 4662 synchronized(this) { 4663 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4664 if (self == null) { 4665 return; 4666 } 4667 4668 final long origId = Binder.clearCallingIdentity(); 4669 4670 if (self.state == ActivityState.RESUMED 4671 || self.state == ActivityState.PAUSING) { 4672 mWindowManager.overridePendingAppTransition(packageName, 4673 enterAnim, exitAnim, null); 4674 } 4675 4676 Binder.restoreCallingIdentity(origId); 4677 } 4678 } 4679 4680 /** 4681 * Main function for removing an existing process from the activity manager 4682 * as a result of that process going away. Clears out all connections 4683 * to the process. 4684 */ 4685 private final void handleAppDiedLocked(ProcessRecord app, 4686 boolean restarting, boolean allowRestart) { 4687 int pid = app.pid; 4688 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4689 if (!restarting) { 4690 removeLruProcessLocked(app); 4691 if (pid > 0) { 4692 ProcessList.remove(pid); 4693 } 4694 } 4695 4696 if (mProfileProc == app) { 4697 clearProfilerLocked(); 4698 } 4699 4700 // Remove this application's activities from active lists. 4701 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4702 4703 app.activities.clear(); 4704 4705 if (app.instrumentationClass != null) { 4706 Slog.w(TAG, "Crash of app " + app.processName 4707 + " running instrumentation " + app.instrumentationClass); 4708 Bundle info = new Bundle(); 4709 info.putString("shortMsg", "Process crashed."); 4710 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4711 } 4712 4713 if (!restarting) { 4714 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4715 // If there was nothing to resume, and we are not already 4716 // restarting this process, but there is a visible activity that 4717 // is hosted by the process... then make sure all visible 4718 // activities are running, taking care of restarting this 4719 // process. 4720 if (hasVisibleActivities) { 4721 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4722 } 4723 } 4724 } 4725 } 4726 4727 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4728 IBinder threadBinder = thread.asBinder(); 4729 // Find the application record. 4730 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4731 ProcessRecord rec = mLruProcesses.get(i); 4732 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4733 return i; 4734 } 4735 } 4736 return -1; 4737 } 4738 4739 final ProcessRecord getRecordForAppLocked( 4740 IApplicationThread thread) { 4741 if (thread == null) { 4742 return null; 4743 } 4744 4745 int appIndex = getLRURecordIndexForAppLocked(thread); 4746 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4747 } 4748 4749 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4750 // If there are no longer any background processes running, 4751 // and the app that died was not running instrumentation, 4752 // then tell everyone we are now low on memory. 4753 boolean haveBg = false; 4754 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4755 ProcessRecord rec = mLruProcesses.get(i); 4756 if (rec.thread != null 4757 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4758 haveBg = true; 4759 break; 4760 } 4761 } 4762 4763 if (!haveBg) { 4764 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4765 if (doReport) { 4766 long now = SystemClock.uptimeMillis(); 4767 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4768 doReport = false; 4769 } else { 4770 mLastMemUsageReportTime = now; 4771 } 4772 } 4773 final ArrayList<ProcessMemInfo> memInfos 4774 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4775 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4776 long now = SystemClock.uptimeMillis(); 4777 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4778 ProcessRecord rec = mLruProcesses.get(i); 4779 if (rec == dyingProc || rec.thread == null) { 4780 continue; 4781 } 4782 if (doReport) { 4783 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4784 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4785 } 4786 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4787 // The low memory report is overriding any current 4788 // state for a GC request. Make sure to do 4789 // heavy/important/visible/foreground processes first. 4790 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4791 rec.lastRequestedGc = 0; 4792 } else { 4793 rec.lastRequestedGc = rec.lastLowMemory; 4794 } 4795 rec.reportLowMemory = true; 4796 rec.lastLowMemory = now; 4797 mProcessesToGc.remove(rec); 4798 addProcessToGcListLocked(rec); 4799 } 4800 } 4801 if (doReport) { 4802 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4803 mHandler.sendMessage(msg); 4804 } 4805 scheduleAppGcsLocked(); 4806 } 4807 } 4808 4809 final void appDiedLocked(ProcessRecord app) { 4810 appDiedLocked(app, app.pid, app.thread); 4811 } 4812 4813 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4814 4815 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4816 synchronized (stats) { 4817 stats.noteProcessDiedLocked(app.info.uid, pid); 4818 } 4819 4820 Process.killProcessQuiet(pid); 4821 Process.killProcessGroup(app.info.uid, pid); 4822 app.killed = true; 4823 4824 // Clean up already done if the process has been re-started. 4825 if (app.pid == pid && app.thread != null && 4826 app.thread.asBinder() == thread.asBinder()) { 4827 boolean doLowMem = app.instrumentationClass == null; 4828 boolean doOomAdj = doLowMem; 4829 if (!app.killedByAm) { 4830 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4831 + ") has died."); 4832 mAllowLowerMemLevel = true; 4833 } else { 4834 // Note that we always want to do oom adj to update our state with the 4835 // new number of procs. 4836 mAllowLowerMemLevel = false; 4837 doLowMem = false; 4838 } 4839 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4840 if (DEBUG_CLEANUP) Slog.v( 4841 TAG, "Dying app: " + app + ", pid: " + pid 4842 + ", thread: " + thread.asBinder()); 4843 handleAppDiedLocked(app, false, true); 4844 4845 if (doOomAdj) { 4846 updateOomAdjLocked(); 4847 } 4848 if (doLowMem) { 4849 doLowMemReportIfNeededLocked(app); 4850 } 4851 } else if (app.pid != pid) { 4852 // A new process has already been started. 4853 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4854 + ") has died and restarted (pid " + app.pid + ")."); 4855 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4856 } else if (DEBUG_PROCESSES) { 4857 Slog.d(TAG, "Received spurious death notification for thread " 4858 + thread.asBinder()); 4859 } 4860 } 4861 4862 /** 4863 * If a stack trace dump file is configured, dump process stack traces. 4864 * @param clearTraces causes the dump file to be erased prior to the new 4865 * traces being written, if true; when false, the new traces will be 4866 * appended to any existing file content. 4867 * @param firstPids of dalvik VM processes to dump stack traces for first 4868 * @param lastPids of dalvik VM processes to dump stack traces for last 4869 * @param nativeProcs optional list of native process names to dump stack crawls 4870 * @return file containing stack traces, or null if no dump file is configured 4871 */ 4872 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4873 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4874 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4875 if (tracesPath == null || tracesPath.length() == 0) { 4876 return null; 4877 } 4878 4879 File tracesFile = new File(tracesPath); 4880 try { 4881 File tracesDir = tracesFile.getParentFile(); 4882 if (!tracesDir.exists()) { 4883 tracesDir.mkdirs(); 4884 if (!SELinux.restorecon(tracesDir)) { 4885 return null; 4886 } 4887 } 4888 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4889 4890 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4891 tracesFile.createNewFile(); 4892 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4893 } catch (IOException e) { 4894 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4895 return null; 4896 } 4897 4898 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4899 return tracesFile; 4900 } 4901 4902 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4903 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4904 // Use a FileObserver to detect when traces finish writing. 4905 // The order of traces is considered important to maintain for legibility. 4906 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4907 @Override 4908 public synchronized void onEvent(int event, String path) { notify(); } 4909 }; 4910 4911 try { 4912 observer.startWatching(); 4913 4914 // First collect all of the stacks of the most important pids. 4915 if (firstPids != null) { 4916 try { 4917 int num = firstPids.size(); 4918 for (int i = 0; i < num; i++) { 4919 synchronized (observer) { 4920 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4921 observer.wait(200); // Wait for write-close, give up after 200msec 4922 } 4923 } 4924 } catch (InterruptedException e) { 4925 Log.wtf(TAG, e); 4926 } 4927 } 4928 4929 // Next collect the stacks of the native pids 4930 if (nativeProcs != null) { 4931 int[] pids = Process.getPidsForCommands(nativeProcs); 4932 if (pids != null) { 4933 for (int pid : pids) { 4934 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4935 } 4936 } 4937 } 4938 4939 // Lastly, measure CPU usage. 4940 if (processCpuTracker != null) { 4941 processCpuTracker.init(); 4942 System.gc(); 4943 processCpuTracker.update(); 4944 try { 4945 synchronized (processCpuTracker) { 4946 processCpuTracker.wait(500); // measure over 1/2 second. 4947 } 4948 } catch (InterruptedException e) { 4949 } 4950 processCpuTracker.update(); 4951 4952 // We'll take the stack crawls of just the top apps using CPU. 4953 final int N = processCpuTracker.countWorkingStats(); 4954 int numProcs = 0; 4955 for (int i=0; i<N && numProcs<5; i++) { 4956 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4957 if (lastPids.indexOfKey(stats.pid) >= 0) { 4958 numProcs++; 4959 try { 4960 synchronized (observer) { 4961 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4962 observer.wait(200); // Wait for write-close, give up after 200msec 4963 } 4964 } catch (InterruptedException e) { 4965 Log.wtf(TAG, e); 4966 } 4967 4968 } 4969 } 4970 } 4971 } finally { 4972 observer.stopWatching(); 4973 } 4974 } 4975 4976 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4977 if (true || IS_USER_BUILD) { 4978 return; 4979 } 4980 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4981 if (tracesPath == null || tracesPath.length() == 0) { 4982 return; 4983 } 4984 4985 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4986 StrictMode.allowThreadDiskWrites(); 4987 try { 4988 final File tracesFile = new File(tracesPath); 4989 final File tracesDir = tracesFile.getParentFile(); 4990 final File tracesTmp = new File(tracesDir, "__tmp__"); 4991 try { 4992 if (!tracesDir.exists()) { 4993 tracesDir.mkdirs(); 4994 if (!SELinux.restorecon(tracesDir.getPath())) { 4995 return; 4996 } 4997 } 4998 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4999 5000 if (tracesFile.exists()) { 5001 tracesTmp.delete(); 5002 tracesFile.renameTo(tracesTmp); 5003 } 5004 StringBuilder sb = new StringBuilder(); 5005 Time tobj = new Time(); 5006 tobj.set(System.currentTimeMillis()); 5007 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5008 sb.append(": "); 5009 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5010 sb.append(" since "); 5011 sb.append(msg); 5012 FileOutputStream fos = new FileOutputStream(tracesFile); 5013 fos.write(sb.toString().getBytes()); 5014 if (app == null) { 5015 fos.write("\n*** No application process!".getBytes()); 5016 } 5017 fos.close(); 5018 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5019 } catch (IOException e) { 5020 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5021 return; 5022 } 5023 5024 if (app != null) { 5025 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5026 firstPids.add(app.pid); 5027 dumpStackTraces(tracesPath, firstPids, null, null, null); 5028 } 5029 5030 File lastTracesFile = null; 5031 File curTracesFile = null; 5032 for (int i=9; i>=0; i--) { 5033 String name = String.format(Locale.US, "slow%02d.txt", i); 5034 curTracesFile = new File(tracesDir, name); 5035 if (curTracesFile.exists()) { 5036 if (lastTracesFile != null) { 5037 curTracesFile.renameTo(lastTracesFile); 5038 } else { 5039 curTracesFile.delete(); 5040 } 5041 } 5042 lastTracesFile = curTracesFile; 5043 } 5044 tracesFile.renameTo(curTracesFile); 5045 if (tracesTmp.exists()) { 5046 tracesTmp.renameTo(tracesFile); 5047 } 5048 } finally { 5049 StrictMode.setThreadPolicy(oldPolicy); 5050 } 5051 } 5052 5053 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5054 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5055 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5056 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5057 5058 if (mController != null) { 5059 try { 5060 // 0 == continue, -1 = kill process immediately 5061 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5062 if (res < 0 && app.pid != MY_PID) { 5063 app.kill("anr", true); 5064 } 5065 } catch (RemoteException e) { 5066 mController = null; 5067 Watchdog.getInstance().setActivityController(null); 5068 } 5069 } 5070 5071 long anrTime = SystemClock.uptimeMillis(); 5072 if (MONITOR_CPU_USAGE) { 5073 updateCpuStatsNow(); 5074 } 5075 5076 synchronized (this) { 5077 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5078 if (mShuttingDown) { 5079 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5080 return; 5081 } else if (app.notResponding) { 5082 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5083 return; 5084 } else if (app.crashing) { 5085 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5086 return; 5087 } 5088 5089 // In case we come through here for the same app before completing 5090 // this one, mark as anring now so we will bail out. 5091 app.notResponding = true; 5092 5093 // Log the ANR to the event log. 5094 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5095 app.processName, app.info.flags, annotation); 5096 5097 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5098 firstPids.add(app.pid); 5099 5100 int parentPid = app.pid; 5101 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5102 if (parentPid != app.pid) firstPids.add(parentPid); 5103 5104 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5105 5106 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5107 ProcessRecord r = mLruProcesses.get(i); 5108 if (r != null && r.thread != null) { 5109 int pid = r.pid; 5110 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5111 if (r.persistent) { 5112 firstPids.add(pid); 5113 } else { 5114 lastPids.put(pid, Boolean.TRUE); 5115 } 5116 } 5117 } 5118 } 5119 } 5120 5121 // Log the ANR to the main log. 5122 StringBuilder info = new StringBuilder(); 5123 info.setLength(0); 5124 info.append("ANR in ").append(app.processName); 5125 if (activity != null && activity.shortComponentName != null) { 5126 info.append(" (").append(activity.shortComponentName).append(")"); 5127 } 5128 info.append("\n"); 5129 info.append("PID: ").append(app.pid).append("\n"); 5130 if (annotation != null) { 5131 info.append("Reason: ").append(annotation).append("\n"); 5132 } 5133 if (parent != null && parent != activity) { 5134 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5135 } 5136 5137 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5138 5139 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5140 NATIVE_STACKS_OF_INTEREST); 5141 5142 String cpuInfo = null; 5143 if (MONITOR_CPU_USAGE) { 5144 updateCpuStatsNow(); 5145 synchronized (mProcessCpuTracker) { 5146 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5147 } 5148 info.append(processCpuTracker.printCurrentLoad()); 5149 info.append(cpuInfo); 5150 } 5151 5152 info.append(processCpuTracker.printCurrentState(anrTime)); 5153 5154 Slog.e(TAG, info.toString()); 5155 if (tracesFile == null) { 5156 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5157 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5158 } 5159 5160 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5161 cpuInfo, tracesFile, null); 5162 5163 if (mController != null) { 5164 try { 5165 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5166 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5167 if (res != 0) { 5168 if (res < 0 && app.pid != MY_PID) { 5169 app.kill("anr", true); 5170 } else { 5171 synchronized (this) { 5172 mServices.scheduleServiceTimeoutLocked(app); 5173 } 5174 } 5175 return; 5176 } 5177 } catch (RemoteException e) { 5178 mController = null; 5179 Watchdog.getInstance().setActivityController(null); 5180 } 5181 } 5182 5183 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5184 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5185 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5186 5187 synchronized (this) { 5188 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5189 app.kill("bg anr", true); 5190 return; 5191 } 5192 5193 // Set the app's notResponding state, and look up the errorReportReceiver 5194 makeAppNotRespondingLocked(app, 5195 activity != null ? activity.shortComponentName : null, 5196 annotation != null ? "ANR " + annotation : "ANR", 5197 info.toString()); 5198 5199 // Bring up the infamous App Not Responding dialog 5200 Message msg = Message.obtain(); 5201 HashMap<String, Object> map = new HashMap<String, Object>(); 5202 msg.what = SHOW_NOT_RESPONDING_MSG; 5203 msg.obj = map; 5204 msg.arg1 = aboveSystem ? 1 : 0; 5205 map.put("app", app); 5206 if (activity != null) { 5207 map.put("activity", activity); 5208 } 5209 5210 mHandler.sendMessage(msg); 5211 } 5212 } 5213 5214 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5215 if (!mLaunchWarningShown) { 5216 mLaunchWarningShown = true; 5217 mHandler.post(new Runnable() { 5218 @Override 5219 public void run() { 5220 synchronized (ActivityManagerService.this) { 5221 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5222 d.show(); 5223 mHandler.postDelayed(new Runnable() { 5224 @Override 5225 public void run() { 5226 synchronized (ActivityManagerService.this) { 5227 d.dismiss(); 5228 mLaunchWarningShown = false; 5229 } 5230 } 5231 }, 4000); 5232 } 5233 } 5234 }); 5235 } 5236 } 5237 5238 @Override 5239 public boolean clearApplicationUserData(final String packageName, 5240 final IPackageDataObserver observer, int userId) { 5241 enforceNotIsolatedCaller("clearApplicationUserData"); 5242 int uid = Binder.getCallingUid(); 5243 int pid = Binder.getCallingPid(); 5244 userId = handleIncomingUser(pid, uid, 5245 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5246 long callingId = Binder.clearCallingIdentity(); 5247 try { 5248 IPackageManager pm = AppGlobals.getPackageManager(); 5249 int pkgUid = -1; 5250 synchronized(this) { 5251 try { 5252 pkgUid = pm.getPackageUid(packageName, userId); 5253 } catch (RemoteException e) { 5254 } 5255 if (pkgUid == -1) { 5256 Slog.w(TAG, "Invalid packageName: " + packageName); 5257 if (observer != null) { 5258 try { 5259 observer.onRemoveCompleted(packageName, false); 5260 } catch (RemoteException e) { 5261 Slog.i(TAG, "Observer no longer exists."); 5262 } 5263 } 5264 return false; 5265 } 5266 if (uid == pkgUid || checkComponentPermission( 5267 android.Manifest.permission.CLEAR_APP_USER_DATA, 5268 pid, uid, -1, true) 5269 == PackageManager.PERMISSION_GRANTED) { 5270 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5271 } else { 5272 throw new SecurityException("PID " + pid + " does not have permission " 5273 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5274 + " of package " + packageName); 5275 } 5276 5277 // Remove all tasks match the cleared application package and user 5278 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5279 final TaskRecord tr = mRecentTasks.get(i); 5280 final String taskPackageName = 5281 tr.getBaseIntent().getComponent().getPackageName(); 5282 if (tr.userId != userId) continue; 5283 if (!taskPackageName.equals(packageName)) continue; 5284 removeTaskByIdLocked(tr.taskId, 0); 5285 } 5286 } 5287 5288 try { 5289 // Clear application user data 5290 pm.clearApplicationUserData(packageName, observer, userId); 5291 5292 synchronized(this) { 5293 // Remove all permissions granted from/to this package 5294 removeUriPermissionsForPackageLocked(packageName, userId, true); 5295 } 5296 5297 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5298 Uri.fromParts("package", packageName, null)); 5299 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5300 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5301 null, null, 0, null, null, null, false, false, userId); 5302 } catch (RemoteException e) { 5303 } 5304 } finally { 5305 Binder.restoreCallingIdentity(callingId); 5306 } 5307 return true; 5308 } 5309 5310 @Override 5311 public void killBackgroundProcesses(final String packageName, int userId) { 5312 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5313 != PackageManager.PERMISSION_GRANTED && 5314 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5315 != PackageManager.PERMISSION_GRANTED) { 5316 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5317 + Binder.getCallingPid() 5318 + ", uid=" + Binder.getCallingUid() 5319 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5320 Slog.w(TAG, msg); 5321 throw new SecurityException(msg); 5322 } 5323 5324 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5325 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5326 long callingId = Binder.clearCallingIdentity(); 5327 try { 5328 IPackageManager pm = AppGlobals.getPackageManager(); 5329 synchronized(this) { 5330 int appId = -1; 5331 try { 5332 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5333 } catch (RemoteException e) { 5334 } 5335 if (appId == -1) { 5336 Slog.w(TAG, "Invalid packageName: " + packageName); 5337 return; 5338 } 5339 killPackageProcessesLocked(packageName, appId, userId, 5340 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5341 } 5342 } finally { 5343 Binder.restoreCallingIdentity(callingId); 5344 } 5345 } 5346 5347 @Override 5348 public void killAllBackgroundProcesses() { 5349 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5350 != PackageManager.PERMISSION_GRANTED) { 5351 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5352 + Binder.getCallingPid() 5353 + ", uid=" + Binder.getCallingUid() 5354 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5355 Slog.w(TAG, msg); 5356 throw new SecurityException(msg); 5357 } 5358 5359 long callingId = Binder.clearCallingIdentity(); 5360 try { 5361 synchronized(this) { 5362 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5363 final int NP = mProcessNames.getMap().size(); 5364 for (int ip=0; ip<NP; ip++) { 5365 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5366 final int NA = apps.size(); 5367 for (int ia=0; ia<NA; ia++) { 5368 ProcessRecord app = apps.valueAt(ia); 5369 if (app.persistent) { 5370 // we don't kill persistent processes 5371 continue; 5372 } 5373 if (app.removed) { 5374 procs.add(app); 5375 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5376 app.removed = true; 5377 procs.add(app); 5378 } 5379 } 5380 } 5381 5382 int N = procs.size(); 5383 for (int i=0; i<N; i++) { 5384 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5385 } 5386 mAllowLowerMemLevel = true; 5387 updateOomAdjLocked(); 5388 doLowMemReportIfNeededLocked(null); 5389 } 5390 } finally { 5391 Binder.restoreCallingIdentity(callingId); 5392 } 5393 } 5394 5395 @Override 5396 public void forceStopPackage(final String packageName, int userId) { 5397 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5398 != PackageManager.PERMISSION_GRANTED) { 5399 String msg = "Permission Denial: forceStopPackage() from pid=" 5400 + Binder.getCallingPid() 5401 + ", uid=" + Binder.getCallingUid() 5402 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5403 Slog.w(TAG, msg); 5404 throw new SecurityException(msg); 5405 } 5406 final int callingPid = Binder.getCallingPid(); 5407 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5408 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5409 long callingId = Binder.clearCallingIdentity(); 5410 try { 5411 IPackageManager pm = AppGlobals.getPackageManager(); 5412 synchronized(this) { 5413 int[] users = userId == UserHandle.USER_ALL 5414 ? getUsersLocked() : new int[] { userId }; 5415 for (int user : users) { 5416 int pkgUid = -1; 5417 try { 5418 pkgUid = pm.getPackageUid(packageName, user); 5419 } catch (RemoteException e) { 5420 } 5421 if (pkgUid == -1) { 5422 Slog.w(TAG, "Invalid packageName: " + packageName); 5423 continue; 5424 } 5425 try { 5426 pm.setPackageStoppedState(packageName, true, user); 5427 } catch (RemoteException e) { 5428 } catch (IllegalArgumentException e) { 5429 Slog.w(TAG, "Failed trying to unstop package " 5430 + packageName + ": " + e); 5431 } 5432 if (isUserRunningLocked(user, false)) { 5433 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5434 } 5435 } 5436 } 5437 } finally { 5438 Binder.restoreCallingIdentity(callingId); 5439 } 5440 } 5441 5442 @Override 5443 public void addPackageDependency(String packageName) { 5444 synchronized (this) { 5445 int callingPid = Binder.getCallingPid(); 5446 if (callingPid == Process.myPid()) { 5447 // Yeah, um, no. 5448 Slog.w(TAG, "Can't addPackageDependency on system process"); 5449 return; 5450 } 5451 ProcessRecord proc; 5452 synchronized (mPidsSelfLocked) { 5453 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5454 } 5455 if (proc != null) { 5456 if (proc.pkgDeps == null) { 5457 proc.pkgDeps = new ArraySet<String>(1); 5458 } 5459 proc.pkgDeps.add(packageName); 5460 } 5461 } 5462 } 5463 5464 /* 5465 * The pkg name and app id have to be specified. 5466 */ 5467 @Override 5468 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5469 if (pkg == null) { 5470 return; 5471 } 5472 // Make sure the uid is valid. 5473 if (appid < 0) { 5474 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5475 return; 5476 } 5477 int callerUid = Binder.getCallingUid(); 5478 // Only the system server can kill an application 5479 if (callerUid == Process.SYSTEM_UID) { 5480 // Post an aysnc message to kill the application 5481 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5482 msg.arg1 = appid; 5483 msg.arg2 = 0; 5484 Bundle bundle = new Bundle(); 5485 bundle.putString("pkg", pkg); 5486 bundle.putString("reason", reason); 5487 msg.obj = bundle; 5488 mHandler.sendMessage(msg); 5489 } else { 5490 throw new SecurityException(callerUid + " cannot kill pkg: " + 5491 pkg); 5492 } 5493 } 5494 5495 @Override 5496 public void closeSystemDialogs(String reason) { 5497 enforceNotIsolatedCaller("closeSystemDialogs"); 5498 5499 final int pid = Binder.getCallingPid(); 5500 final int uid = Binder.getCallingUid(); 5501 final long origId = Binder.clearCallingIdentity(); 5502 try { 5503 synchronized (this) { 5504 // Only allow this from foreground processes, so that background 5505 // applications can't abuse it to prevent system UI from being shown. 5506 if (uid >= Process.FIRST_APPLICATION_UID) { 5507 ProcessRecord proc; 5508 synchronized (mPidsSelfLocked) { 5509 proc = mPidsSelfLocked.get(pid); 5510 } 5511 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5512 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5513 + " from background process " + proc); 5514 return; 5515 } 5516 } 5517 closeSystemDialogsLocked(reason); 5518 } 5519 } finally { 5520 Binder.restoreCallingIdentity(origId); 5521 } 5522 } 5523 5524 void closeSystemDialogsLocked(String reason) { 5525 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5527 | Intent.FLAG_RECEIVER_FOREGROUND); 5528 if (reason != null) { 5529 intent.putExtra("reason", reason); 5530 } 5531 mWindowManager.closeSystemDialogs(reason); 5532 5533 mStackSupervisor.closeSystemDialogsLocked(); 5534 5535 broadcastIntentLocked(null, null, intent, null, 5536 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5537 Process.SYSTEM_UID, UserHandle.USER_ALL); 5538 } 5539 5540 @Override 5541 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5542 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5543 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5544 for (int i=pids.length-1; i>=0; i--) { 5545 ProcessRecord proc; 5546 int oomAdj; 5547 synchronized (this) { 5548 synchronized (mPidsSelfLocked) { 5549 proc = mPidsSelfLocked.get(pids[i]); 5550 oomAdj = proc != null ? proc.setAdj : 0; 5551 } 5552 } 5553 infos[i] = new Debug.MemoryInfo(); 5554 Debug.getMemoryInfo(pids[i], infos[i]); 5555 if (proc != null) { 5556 synchronized (this) { 5557 if (proc.thread != null && proc.setAdj == oomAdj) { 5558 // Record this for posterity if the process has been stable. 5559 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5560 infos[i].getTotalUss(), false, proc.pkgList); 5561 } 5562 } 5563 } 5564 } 5565 return infos; 5566 } 5567 5568 @Override 5569 public long[] getProcessPss(int[] pids) { 5570 enforceNotIsolatedCaller("getProcessPss"); 5571 long[] pss = new long[pids.length]; 5572 for (int i=pids.length-1; i>=0; i--) { 5573 ProcessRecord proc; 5574 int oomAdj; 5575 synchronized (this) { 5576 synchronized (mPidsSelfLocked) { 5577 proc = mPidsSelfLocked.get(pids[i]); 5578 oomAdj = proc != null ? proc.setAdj : 0; 5579 } 5580 } 5581 long[] tmpUss = new long[1]; 5582 pss[i] = Debug.getPss(pids[i], tmpUss); 5583 if (proc != null) { 5584 synchronized (this) { 5585 if (proc.thread != null && proc.setAdj == oomAdj) { 5586 // Record this for posterity if the process has been stable. 5587 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5588 } 5589 } 5590 } 5591 } 5592 return pss; 5593 } 5594 5595 @Override 5596 public void killApplicationProcess(String processName, int uid) { 5597 if (processName == null) { 5598 return; 5599 } 5600 5601 int callerUid = Binder.getCallingUid(); 5602 // Only the system server can kill an application 5603 if (callerUid == Process.SYSTEM_UID) { 5604 synchronized (this) { 5605 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5606 if (app != null && app.thread != null) { 5607 try { 5608 app.thread.scheduleSuicide(); 5609 } catch (RemoteException e) { 5610 // If the other end already died, then our work here is done. 5611 } 5612 } else { 5613 Slog.w(TAG, "Process/uid not found attempting kill of " 5614 + processName + " / " + uid); 5615 } 5616 } 5617 } else { 5618 throw new SecurityException(callerUid + " cannot kill app process: " + 5619 processName); 5620 } 5621 } 5622 5623 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5624 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5625 false, true, false, false, UserHandle.getUserId(uid), reason); 5626 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5627 Uri.fromParts("package", packageName, null)); 5628 if (!mProcessesReady) { 5629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5630 | Intent.FLAG_RECEIVER_FOREGROUND); 5631 } 5632 intent.putExtra(Intent.EXTRA_UID, uid); 5633 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5634 broadcastIntentLocked(null, null, intent, 5635 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5636 false, false, 5637 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5638 } 5639 5640 private void forceStopUserLocked(int userId, String reason) { 5641 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5642 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5644 | Intent.FLAG_RECEIVER_FOREGROUND); 5645 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5646 broadcastIntentLocked(null, null, intent, 5647 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5648 false, false, 5649 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5650 } 5651 5652 private final boolean killPackageProcessesLocked(String packageName, int appId, 5653 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5654 boolean doit, boolean evenPersistent, String reason) { 5655 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5656 5657 // Remove all processes this package may have touched: all with the 5658 // same UID (except for the system or root user), and all whose name 5659 // matches the package name. 5660 final int NP = mProcessNames.getMap().size(); 5661 for (int ip=0; ip<NP; ip++) { 5662 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5663 final int NA = apps.size(); 5664 for (int ia=0; ia<NA; ia++) { 5665 ProcessRecord app = apps.valueAt(ia); 5666 if (app.persistent && !evenPersistent) { 5667 // we don't kill persistent processes 5668 continue; 5669 } 5670 if (app.removed) { 5671 if (doit) { 5672 procs.add(app); 5673 } 5674 continue; 5675 } 5676 5677 // Skip process if it doesn't meet our oom adj requirement. 5678 if (app.setAdj < minOomAdj) { 5679 continue; 5680 } 5681 5682 // If no package is specified, we call all processes under the 5683 // give user id. 5684 if (packageName == null) { 5685 if (app.userId != userId) { 5686 continue; 5687 } 5688 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5689 continue; 5690 } 5691 // Package has been specified, we want to hit all processes 5692 // that match it. We need to qualify this by the processes 5693 // that are running under the specified app and user ID. 5694 } else { 5695 final boolean isDep = app.pkgDeps != null 5696 && app.pkgDeps.contains(packageName); 5697 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5698 continue; 5699 } 5700 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5701 continue; 5702 } 5703 if (!app.pkgList.containsKey(packageName) && !isDep) { 5704 continue; 5705 } 5706 } 5707 5708 // Process has passed all conditions, kill it! 5709 if (!doit) { 5710 return true; 5711 } 5712 app.removed = true; 5713 procs.add(app); 5714 } 5715 } 5716 5717 int N = procs.size(); 5718 for (int i=0; i<N; i++) { 5719 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5720 } 5721 updateOomAdjLocked(); 5722 return N > 0; 5723 } 5724 5725 private final boolean forceStopPackageLocked(String name, int appId, 5726 boolean callerWillRestart, boolean purgeCache, boolean doit, 5727 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5728 int i; 5729 int N; 5730 5731 if (userId == UserHandle.USER_ALL && name == null) { 5732 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5733 } 5734 5735 if (appId < 0 && name != null) { 5736 try { 5737 appId = UserHandle.getAppId( 5738 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5739 } catch (RemoteException e) { 5740 } 5741 } 5742 5743 if (doit) { 5744 if (name != null) { 5745 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5746 + " user=" + userId + ": " + reason); 5747 } else { 5748 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5749 } 5750 5751 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5752 for (int ip=pmap.size()-1; ip>=0; ip--) { 5753 SparseArray<Long> ba = pmap.valueAt(ip); 5754 for (i=ba.size()-1; i>=0; i--) { 5755 boolean remove = false; 5756 final int entUid = ba.keyAt(i); 5757 if (name != null) { 5758 if (userId == UserHandle.USER_ALL) { 5759 if (UserHandle.getAppId(entUid) == appId) { 5760 remove = true; 5761 } 5762 } else { 5763 if (entUid == UserHandle.getUid(userId, appId)) { 5764 remove = true; 5765 } 5766 } 5767 } else if (UserHandle.getUserId(entUid) == userId) { 5768 remove = true; 5769 } 5770 if (remove) { 5771 ba.removeAt(i); 5772 } 5773 } 5774 if (ba.size() == 0) { 5775 pmap.removeAt(ip); 5776 } 5777 } 5778 } 5779 5780 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5781 -100, callerWillRestart, true, doit, evenPersistent, 5782 name == null ? ("stop user " + userId) : ("stop " + name)); 5783 5784 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5785 if (!doit) { 5786 return true; 5787 } 5788 didSomething = true; 5789 } 5790 5791 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5792 if (!doit) { 5793 return true; 5794 } 5795 didSomething = true; 5796 } 5797 5798 if (name == null) { 5799 // Remove all sticky broadcasts from this user. 5800 mStickyBroadcasts.remove(userId); 5801 } 5802 5803 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5804 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5805 userId, providers)) { 5806 if (!doit) { 5807 return true; 5808 } 5809 didSomething = true; 5810 } 5811 N = providers.size(); 5812 for (i=0; i<N; i++) { 5813 removeDyingProviderLocked(null, providers.get(i), true); 5814 } 5815 5816 // Remove transient permissions granted from/to this package/user 5817 removeUriPermissionsForPackageLocked(name, userId, false); 5818 5819 if (name == null || uninstalling) { 5820 // Remove pending intents. For now we only do this when force 5821 // stopping users, because we have some problems when doing this 5822 // for packages -- app widgets are not currently cleaned up for 5823 // such packages, so they can be left with bad pending intents. 5824 if (mIntentSenderRecords.size() > 0) { 5825 Iterator<WeakReference<PendingIntentRecord>> it 5826 = mIntentSenderRecords.values().iterator(); 5827 while (it.hasNext()) { 5828 WeakReference<PendingIntentRecord> wpir = it.next(); 5829 if (wpir == null) { 5830 it.remove(); 5831 continue; 5832 } 5833 PendingIntentRecord pir = wpir.get(); 5834 if (pir == null) { 5835 it.remove(); 5836 continue; 5837 } 5838 if (name == null) { 5839 // Stopping user, remove all objects for the user. 5840 if (pir.key.userId != userId) { 5841 // Not the same user, skip it. 5842 continue; 5843 } 5844 } else { 5845 if (UserHandle.getAppId(pir.uid) != appId) { 5846 // Different app id, skip it. 5847 continue; 5848 } 5849 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5850 // Different user, skip it. 5851 continue; 5852 } 5853 if (!pir.key.packageName.equals(name)) { 5854 // Different package, skip it. 5855 continue; 5856 } 5857 } 5858 if (!doit) { 5859 return true; 5860 } 5861 didSomething = true; 5862 it.remove(); 5863 pir.canceled = true; 5864 if (pir.key.activity != null) { 5865 pir.key.activity.pendingResults.remove(pir.ref); 5866 } 5867 } 5868 } 5869 } 5870 5871 if (doit) { 5872 if (purgeCache && name != null) { 5873 AttributeCache ac = AttributeCache.instance(); 5874 if (ac != null) { 5875 ac.removePackage(name); 5876 } 5877 } 5878 if (mBooted) { 5879 mStackSupervisor.resumeTopActivitiesLocked(); 5880 mStackSupervisor.scheduleIdleLocked(); 5881 } 5882 } 5883 5884 return didSomething; 5885 } 5886 5887 private final boolean removeProcessLocked(ProcessRecord app, 5888 boolean callerWillRestart, boolean allowRestart, String reason) { 5889 final String name = app.processName; 5890 final int uid = app.uid; 5891 if (DEBUG_PROCESSES) Slog.d( 5892 TAG, "Force removing proc " + app.toShortString() + " (" + name 5893 + "/" + uid + ")"); 5894 5895 mProcessNames.remove(name, uid); 5896 mIsolatedProcesses.remove(app.uid); 5897 if (mHeavyWeightProcess == app) { 5898 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5899 mHeavyWeightProcess.userId, 0)); 5900 mHeavyWeightProcess = null; 5901 } 5902 boolean needRestart = false; 5903 if (app.pid > 0 && app.pid != MY_PID) { 5904 int pid = app.pid; 5905 synchronized (mPidsSelfLocked) { 5906 mPidsSelfLocked.remove(pid); 5907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5908 } 5909 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5910 if (app.isolated) { 5911 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5912 } 5913 app.kill(reason, true); 5914 handleAppDiedLocked(app, true, allowRestart); 5915 removeLruProcessLocked(app); 5916 5917 if (app.persistent && !app.isolated) { 5918 if (!callerWillRestart) { 5919 addAppLocked(app.info, false, null /* ABI override */); 5920 } else { 5921 needRestart = true; 5922 } 5923 } 5924 } else { 5925 mRemovedProcesses.add(app); 5926 } 5927 5928 return needRestart; 5929 } 5930 5931 private final void processStartTimedOutLocked(ProcessRecord app) { 5932 final int pid = app.pid; 5933 boolean gone = false; 5934 synchronized (mPidsSelfLocked) { 5935 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5936 if (knownApp != null && knownApp.thread == null) { 5937 mPidsSelfLocked.remove(pid); 5938 gone = true; 5939 } 5940 } 5941 5942 if (gone) { 5943 Slog.w(TAG, "Process " + app + " failed to attach"); 5944 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5945 pid, app.uid, app.processName); 5946 mProcessNames.remove(app.processName, app.uid); 5947 mIsolatedProcesses.remove(app.uid); 5948 if (mHeavyWeightProcess == app) { 5949 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5950 mHeavyWeightProcess.userId, 0)); 5951 mHeavyWeightProcess = null; 5952 } 5953 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5954 if (app.isolated) { 5955 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5956 } 5957 // Take care of any launching providers waiting for this process. 5958 checkAppInLaunchingProvidersLocked(app, true); 5959 // Take care of any services that are waiting for the process. 5960 mServices.processStartTimedOutLocked(app); 5961 app.kill("start timeout", true); 5962 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5963 Slog.w(TAG, "Unattached app died before backup, skipping"); 5964 try { 5965 IBackupManager bm = IBackupManager.Stub.asInterface( 5966 ServiceManager.getService(Context.BACKUP_SERVICE)); 5967 bm.agentDisconnected(app.info.packageName); 5968 } catch (RemoteException e) { 5969 // Can't happen; the backup manager is local 5970 } 5971 } 5972 if (isPendingBroadcastProcessLocked(pid)) { 5973 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5974 skipPendingBroadcastLocked(pid); 5975 } 5976 } else { 5977 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5978 } 5979 } 5980 5981 private final boolean attachApplicationLocked(IApplicationThread thread, 5982 int pid) { 5983 5984 // Find the application record that is being attached... either via 5985 // the pid if we are running in multiple processes, or just pull the 5986 // next app record if we are emulating process with anonymous threads. 5987 ProcessRecord app; 5988 if (pid != MY_PID && pid >= 0) { 5989 synchronized (mPidsSelfLocked) { 5990 app = mPidsSelfLocked.get(pid); 5991 } 5992 } else { 5993 app = null; 5994 } 5995 5996 if (app == null) { 5997 Slog.w(TAG, "No pending application record for pid " + pid 5998 + " (IApplicationThread " + thread + "); dropping process"); 5999 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6000 if (pid > 0 && pid != MY_PID) { 6001 Process.killProcessQuiet(pid); 6002 //TODO: Process.killProcessGroup(app.info.uid, pid); 6003 } else { 6004 try { 6005 thread.scheduleExit(); 6006 } catch (Exception e) { 6007 // Ignore exceptions. 6008 } 6009 } 6010 return false; 6011 } 6012 6013 // If this application record is still attached to a previous 6014 // process, clean it up now. 6015 if (app.thread != null) { 6016 handleAppDiedLocked(app, true, true); 6017 } 6018 6019 // Tell the process all about itself. 6020 6021 if (localLOGV) Slog.v( 6022 TAG, "Binding process pid " + pid + " to record " + app); 6023 6024 final String processName = app.processName; 6025 try { 6026 AppDeathRecipient adr = new AppDeathRecipient( 6027 app, pid, thread); 6028 thread.asBinder().linkToDeath(adr, 0); 6029 app.deathRecipient = adr; 6030 } catch (RemoteException e) { 6031 app.resetPackageList(mProcessStats); 6032 startProcessLocked(app, "link fail", processName); 6033 return false; 6034 } 6035 6036 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6037 6038 app.makeActive(thread, mProcessStats); 6039 app.curAdj = app.setAdj = -100; 6040 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6041 app.forcingToForeground = null; 6042 updateProcessForegroundLocked(app, false, false); 6043 app.hasShownUi = false; 6044 app.debugging = false; 6045 app.cached = false; 6046 6047 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6048 6049 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6050 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6051 6052 if (!normalMode) { 6053 Slog.i(TAG, "Launching preboot mode app: " + app); 6054 } 6055 6056 if (localLOGV) Slog.v( 6057 TAG, "New app record " + app 6058 + " thread=" + thread.asBinder() + " pid=" + pid); 6059 try { 6060 int testMode = IApplicationThread.DEBUG_OFF; 6061 if (mDebugApp != null && mDebugApp.equals(processName)) { 6062 testMode = mWaitForDebugger 6063 ? IApplicationThread.DEBUG_WAIT 6064 : IApplicationThread.DEBUG_ON; 6065 app.debugging = true; 6066 if (mDebugTransient) { 6067 mDebugApp = mOrigDebugApp; 6068 mWaitForDebugger = mOrigWaitForDebugger; 6069 } 6070 } 6071 String profileFile = app.instrumentationProfileFile; 6072 ParcelFileDescriptor profileFd = null; 6073 int samplingInterval = 0; 6074 boolean profileAutoStop = false; 6075 if (mProfileApp != null && mProfileApp.equals(processName)) { 6076 mProfileProc = app; 6077 profileFile = mProfileFile; 6078 profileFd = mProfileFd; 6079 samplingInterval = mSamplingInterval; 6080 profileAutoStop = mAutoStopProfiler; 6081 } 6082 boolean enableOpenGlTrace = false; 6083 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6084 enableOpenGlTrace = true; 6085 mOpenGlTraceApp = null; 6086 } 6087 6088 // If the app is being launched for restore or full backup, set it up specially 6089 boolean isRestrictedBackupMode = false; 6090 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6091 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6092 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6093 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6094 } 6095 6096 ensurePackageDexOpt(app.instrumentationInfo != null 6097 ? app.instrumentationInfo.packageName 6098 : app.info.packageName); 6099 if (app.instrumentationClass != null) { 6100 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6101 } 6102 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6103 + processName + " with config " + mConfiguration); 6104 ApplicationInfo appInfo = app.instrumentationInfo != null 6105 ? app.instrumentationInfo : app.info; 6106 app.compat = compatibilityInfoForPackageLocked(appInfo); 6107 if (profileFd != null) { 6108 profileFd = profileFd.dup(); 6109 } 6110 ProfilerInfo profilerInfo = profileFile == null ? null 6111 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6112 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6113 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6114 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6115 isRestrictedBackupMode || !normalMode, app.persistent, 6116 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6117 mCoreSettingsObserver.getCoreSettingsLocked()); 6118 updateLruProcessLocked(app, false, null); 6119 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6120 } catch (Exception e) { 6121 // todo: Yikes! What should we do? For now we will try to 6122 // start another process, but that could easily get us in 6123 // an infinite loop of restarting processes... 6124 Slog.w(TAG, "Exception thrown during bind!", e); 6125 6126 app.resetPackageList(mProcessStats); 6127 app.unlinkDeathRecipient(); 6128 startProcessLocked(app, "bind fail", processName); 6129 return false; 6130 } 6131 6132 // Remove this record from the list of starting applications. 6133 mPersistentStartingProcesses.remove(app); 6134 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6135 "Attach application locked removing on hold: " + app); 6136 mProcessesOnHold.remove(app); 6137 6138 boolean badApp = false; 6139 boolean didSomething = false; 6140 6141 // See if the top visible activity is waiting to run in this process... 6142 if (normalMode) { 6143 try { 6144 if (mStackSupervisor.attachApplicationLocked(app)) { 6145 didSomething = true; 6146 } 6147 } catch (Exception e) { 6148 badApp = true; 6149 } 6150 } 6151 6152 // Find any services that should be running in this process... 6153 if (!badApp) { 6154 try { 6155 didSomething |= mServices.attachApplicationLocked(app, processName); 6156 } catch (Exception e) { 6157 badApp = true; 6158 } 6159 } 6160 6161 // Check if a next-broadcast receiver is in this process... 6162 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6163 try { 6164 didSomething |= sendPendingBroadcastsLocked(app); 6165 } catch (Exception e) { 6166 // If the app died trying to launch the receiver we declare it 'bad' 6167 badApp = true; 6168 } 6169 } 6170 6171 // Check whether the next backup agent is in this process... 6172 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6173 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6174 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6175 try { 6176 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6177 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6178 mBackupTarget.backupMode); 6179 } catch (Exception e) { 6180 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6181 e.printStackTrace(); 6182 } 6183 } 6184 6185 if (badApp) { 6186 // todo: Also need to kill application to deal with all 6187 // kinds of exceptions. 6188 handleAppDiedLocked(app, false, true); 6189 return false; 6190 } 6191 6192 if (!didSomething) { 6193 updateOomAdjLocked(); 6194 } 6195 6196 return true; 6197 } 6198 6199 @Override 6200 public final void attachApplication(IApplicationThread thread) { 6201 synchronized (this) { 6202 int callingPid = Binder.getCallingPid(); 6203 final long origId = Binder.clearCallingIdentity(); 6204 attachApplicationLocked(thread, callingPid); 6205 Binder.restoreCallingIdentity(origId); 6206 } 6207 } 6208 6209 @Override 6210 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6211 final long origId = Binder.clearCallingIdentity(); 6212 synchronized (this) { 6213 ActivityStack stack = ActivityRecord.getStackLocked(token); 6214 if (stack != null) { 6215 ActivityRecord r = 6216 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6217 if (stopProfiling) { 6218 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6219 try { 6220 mProfileFd.close(); 6221 } catch (IOException e) { 6222 } 6223 clearProfilerLocked(); 6224 } 6225 } 6226 } 6227 } 6228 Binder.restoreCallingIdentity(origId); 6229 } 6230 6231 void postEnableScreenAfterBootLocked() { 6232 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6233 } 6234 6235 void enableScreenAfterBoot() { 6236 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6237 SystemClock.uptimeMillis()); 6238 mWindowManager.enableScreenAfterBoot(); 6239 6240 synchronized (this) { 6241 updateEventDispatchingLocked(); 6242 } 6243 } 6244 6245 @Override 6246 public void showBootMessage(final CharSequence msg, final boolean always) { 6247 enforceNotIsolatedCaller("showBootMessage"); 6248 mWindowManager.showBootMessage(msg, always); 6249 } 6250 6251 @Override 6252 public void keyguardWaitingForActivityDrawn() { 6253 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6254 final long token = Binder.clearCallingIdentity(); 6255 try { 6256 synchronized (this) { 6257 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6258 mWindowManager.keyguardWaitingForActivityDrawn(); 6259 mKeyguardWaitingForDraw = true; 6260 } 6261 } finally { 6262 Binder.restoreCallingIdentity(token); 6263 } 6264 } 6265 6266 final void finishBooting() { 6267 synchronized (this) { 6268 if (!mBootAnimationComplete) { 6269 mCallFinishBooting = true; 6270 return; 6271 } 6272 mCallFinishBooting = false; 6273 } 6274 6275 // Register receivers to handle package update events 6276 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6277 6278 // Let system services know. 6279 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6280 6281 synchronized (this) { 6282 // Ensure that any processes we had put on hold are now started 6283 // up. 6284 final int NP = mProcessesOnHold.size(); 6285 if (NP > 0) { 6286 ArrayList<ProcessRecord> procs = 6287 new ArrayList<ProcessRecord>(mProcessesOnHold); 6288 for (int ip=0; ip<NP; ip++) { 6289 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6290 + procs.get(ip)); 6291 startProcessLocked(procs.get(ip), "on-hold", null); 6292 } 6293 } 6294 6295 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6296 // Start looking for apps that are abusing wake locks. 6297 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6298 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6299 // Tell anyone interested that we are done booting! 6300 SystemProperties.set("sys.boot_completed", "1"); 6301 SystemProperties.set("dev.bootcomplete", "1"); 6302 for (int i=0; i<mStartedUsers.size(); i++) { 6303 UserStartedState uss = mStartedUsers.valueAt(i); 6304 if (uss.mState == UserStartedState.STATE_BOOTING) { 6305 uss.mState = UserStartedState.STATE_RUNNING; 6306 final int userId = mStartedUsers.keyAt(i); 6307 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6308 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6309 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6310 broadcastIntentLocked(null, null, intent, null, 6311 new IIntentReceiver.Stub() { 6312 @Override 6313 public void performReceive(Intent intent, int resultCode, 6314 String data, Bundle extras, boolean ordered, 6315 boolean sticky, int sendingUser) { 6316 synchronized (ActivityManagerService.this) { 6317 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6318 true, false); 6319 } 6320 } 6321 }, 6322 0, null, null, 6323 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6324 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6325 userId); 6326 } 6327 } 6328 scheduleStartProfilesLocked(); 6329 } 6330 } 6331 } 6332 6333 @Override 6334 public void bootAnimationComplete() { 6335 final boolean callFinishBooting; 6336 synchronized (this) { 6337 callFinishBooting = mCallFinishBooting; 6338 mBootAnimationComplete = true; 6339 } 6340 if (callFinishBooting) { 6341 finishBooting(); 6342 } 6343 } 6344 6345 final void ensureBootCompleted() { 6346 boolean booting; 6347 boolean enableScreen; 6348 synchronized (this) { 6349 booting = mBooting; 6350 mBooting = false; 6351 enableScreen = !mBooted; 6352 mBooted = true; 6353 } 6354 6355 if (booting) { 6356 finishBooting(); 6357 } 6358 6359 if (enableScreen) { 6360 enableScreenAfterBoot(); 6361 } 6362 } 6363 6364 @Override 6365 public final void activityResumed(IBinder token) { 6366 final long origId = Binder.clearCallingIdentity(); 6367 synchronized(this) { 6368 ActivityStack stack = ActivityRecord.getStackLocked(token); 6369 if (stack != null) { 6370 ActivityRecord.activityResumedLocked(token); 6371 } 6372 } 6373 Binder.restoreCallingIdentity(origId); 6374 } 6375 6376 @Override 6377 public final void activityPaused(IBinder token) { 6378 final long origId = Binder.clearCallingIdentity(); 6379 synchronized(this) { 6380 ActivityStack stack = ActivityRecord.getStackLocked(token); 6381 if (stack != null) { 6382 stack.activityPausedLocked(token, false); 6383 } 6384 } 6385 Binder.restoreCallingIdentity(origId); 6386 } 6387 6388 @Override 6389 public final void activityStopped(IBinder token, Bundle icicle, 6390 PersistableBundle persistentState, CharSequence description) { 6391 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6392 6393 // Refuse possible leaked file descriptors 6394 if (icicle != null && icicle.hasFileDescriptors()) { 6395 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6396 } 6397 6398 final long origId = Binder.clearCallingIdentity(); 6399 6400 synchronized (this) { 6401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6402 if (r != null) { 6403 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6404 } 6405 } 6406 6407 trimApplications(); 6408 6409 Binder.restoreCallingIdentity(origId); 6410 } 6411 6412 @Override 6413 public final void activityDestroyed(IBinder token) { 6414 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6415 synchronized (this) { 6416 ActivityStack stack = ActivityRecord.getStackLocked(token); 6417 if (stack != null) { 6418 stack.activityDestroyedLocked(token); 6419 } 6420 } 6421 } 6422 6423 @Override 6424 public final void backgroundResourcesReleased(IBinder token) { 6425 final long origId = Binder.clearCallingIdentity(); 6426 try { 6427 synchronized (this) { 6428 ActivityStack stack = ActivityRecord.getStackLocked(token); 6429 if (stack != null) { 6430 stack.backgroundResourcesReleased(token); 6431 } 6432 } 6433 } finally { 6434 Binder.restoreCallingIdentity(origId); 6435 } 6436 } 6437 6438 @Override 6439 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6440 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6441 } 6442 6443 @Override 6444 public final void notifyEnterAnimationComplete(IBinder token) { 6445 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6446 } 6447 6448 @Override 6449 public String getCallingPackage(IBinder token) { 6450 synchronized (this) { 6451 ActivityRecord r = getCallingRecordLocked(token); 6452 return r != null ? r.info.packageName : null; 6453 } 6454 } 6455 6456 @Override 6457 public ComponentName getCallingActivity(IBinder token) { 6458 synchronized (this) { 6459 ActivityRecord r = getCallingRecordLocked(token); 6460 return r != null ? r.intent.getComponent() : null; 6461 } 6462 } 6463 6464 private ActivityRecord getCallingRecordLocked(IBinder token) { 6465 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6466 if (r == null) { 6467 return null; 6468 } 6469 return r.resultTo; 6470 } 6471 6472 @Override 6473 public ComponentName getActivityClassForToken(IBinder token) { 6474 synchronized(this) { 6475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6476 if (r == null) { 6477 return null; 6478 } 6479 return r.intent.getComponent(); 6480 } 6481 } 6482 6483 @Override 6484 public String getPackageForToken(IBinder token) { 6485 synchronized(this) { 6486 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6487 if (r == null) { 6488 return null; 6489 } 6490 return r.packageName; 6491 } 6492 } 6493 6494 @Override 6495 public IIntentSender getIntentSender(int type, 6496 String packageName, IBinder token, String resultWho, 6497 int requestCode, Intent[] intents, String[] resolvedTypes, 6498 int flags, Bundle options, int userId) { 6499 enforceNotIsolatedCaller("getIntentSender"); 6500 // Refuse possible leaked file descriptors 6501 if (intents != null) { 6502 if (intents.length < 1) { 6503 throw new IllegalArgumentException("Intents array length must be >= 1"); 6504 } 6505 for (int i=0; i<intents.length; i++) { 6506 Intent intent = intents[i]; 6507 if (intent != null) { 6508 if (intent.hasFileDescriptors()) { 6509 throw new IllegalArgumentException("File descriptors passed in Intent"); 6510 } 6511 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6512 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6513 throw new IllegalArgumentException( 6514 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6515 } 6516 intents[i] = new Intent(intent); 6517 } 6518 } 6519 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6520 throw new IllegalArgumentException( 6521 "Intent array length does not match resolvedTypes length"); 6522 } 6523 } 6524 if (options != null) { 6525 if (options.hasFileDescriptors()) { 6526 throw new IllegalArgumentException("File descriptors passed in options"); 6527 } 6528 } 6529 6530 synchronized(this) { 6531 int callingUid = Binder.getCallingUid(); 6532 int origUserId = userId; 6533 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6534 type == ActivityManager.INTENT_SENDER_BROADCAST, 6535 ALLOW_NON_FULL, "getIntentSender", null); 6536 if (origUserId == UserHandle.USER_CURRENT) { 6537 // We don't want to evaluate this until the pending intent is 6538 // actually executed. However, we do want to always do the 6539 // security checking for it above. 6540 userId = UserHandle.USER_CURRENT; 6541 } 6542 try { 6543 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6544 int uid = AppGlobals.getPackageManager() 6545 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6546 if (!UserHandle.isSameApp(callingUid, uid)) { 6547 String msg = "Permission Denial: getIntentSender() from pid=" 6548 + Binder.getCallingPid() 6549 + ", uid=" + Binder.getCallingUid() 6550 + ", (need uid=" + uid + ")" 6551 + " is not allowed to send as package " + packageName; 6552 Slog.w(TAG, msg); 6553 throw new SecurityException(msg); 6554 } 6555 } 6556 6557 return getIntentSenderLocked(type, packageName, callingUid, userId, 6558 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6559 6560 } catch (RemoteException e) { 6561 throw new SecurityException(e); 6562 } 6563 } 6564 } 6565 6566 IIntentSender getIntentSenderLocked(int type, String packageName, 6567 int callingUid, int userId, IBinder token, String resultWho, 6568 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6569 Bundle options) { 6570 if (DEBUG_MU) 6571 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6572 ActivityRecord activity = null; 6573 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6574 activity = ActivityRecord.isInStackLocked(token); 6575 if (activity == null) { 6576 return null; 6577 } 6578 if (activity.finishing) { 6579 return null; 6580 } 6581 } 6582 6583 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6584 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6585 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6586 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6587 |PendingIntent.FLAG_UPDATE_CURRENT); 6588 6589 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6590 type, packageName, activity, resultWho, 6591 requestCode, intents, resolvedTypes, flags, options, userId); 6592 WeakReference<PendingIntentRecord> ref; 6593 ref = mIntentSenderRecords.get(key); 6594 PendingIntentRecord rec = ref != null ? ref.get() : null; 6595 if (rec != null) { 6596 if (!cancelCurrent) { 6597 if (updateCurrent) { 6598 if (rec.key.requestIntent != null) { 6599 rec.key.requestIntent.replaceExtras(intents != null ? 6600 intents[intents.length - 1] : null); 6601 } 6602 if (intents != null) { 6603 intents[intents.length-1] = rec.key.requestIntent; 6604 rec.key.allIntents = intents; 6605 rec.key.allResolvedTypes = resolvedTypes; 6606 } else { 6607 rec.key.allIntents = null; 6608 rec.key.allResolvedTypes = null; 6609 } 6610 } 6611 return rec; 6612 } 6613 rec.canceled = true; 6614 mIntentSenderRecords.remove(key); 6615 } 6616 if (noCreate) { 6617 return rec; 6618 } 6619 rec = new PendingIntentRecord(this, key, callingUid); 6620 mIntentSenderRecords.put(key, rec.ref); 6621 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6622 if (activity.pendingResults == null) { 6623 activity.pendingResults 6624 = new HashSet<WeakReference<PendingIntentRecord>>(); 6625 } 6626 activity.pendingResults.add(rec.ref); 6627 } 6628 return rec; 6629 } 6630 6631 @Override 6632 public void cancelIntentSender(IIntentSender sender) { 6633 if (!(sender instanceof PendingIntentRecord)) { 6634 return; 6635 } 6636 synchronized(this) { 6637 PendingIntentRecord rec = (PendingIntentRecord)sender; 6638 try { 6639 int uid = AppGlobals.getPackageManager() 6640 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6641 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6642 String msg = "Permission Denial: cancelIntentSender() from pid=" 6643 + Binder.getCallingPid() 6644 + ", uid=" + Binder.getCallingUid() 6645 + " is not allowed to cancel packges " 6646 + rec.key.packageName; 6647 Slog.w(TAG, msg); 6648 throw new SecurityException(msg); 6649 } 6650 } catch (RemoteException e) { 6651 throw new SecurityException(e); 6652 } 6653 cancelIntentSenderLocked(rec, true); 6654 } 6655 } 6656 6657 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6658 rec.canceled = true; 6659 mIntentSenderRecords.remove(rec.key); 6660 if (cleanActivity && rec.key.activity != null) { 6661 rec.key.activity.pendingResults.remove(rec.ref); 6662 } 6663 } 6664 6665 @Override 6666 public String getPackageForIntentSender(IIntentSender pendingResult) { 6667 if (!(pendingResult instanceof PendingIntentRecord)) { 6668 return null; 6669 } 6670 try { 6671 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6672 return res.key.packageName; 6673 } catch (ClassCastException e) { 6674 } 6675 return null; 6676 } 6677 6678 @Override 6679 public int getUidForIntentSender(IIntentSender sender) { 6680 if (sender instanceof PendingIntentRecord) { 6681 try { 6682 PendingIntentRecord res = (PendingIntentRecord)sender; 6683 return res.uid; 6684 } catch (ClassCastException e) { 6685 } 6686 } 6687 return -1; 6688 } 6689 6690 @Override 6691 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6692 if (!(pendingResult instanceof PendingIntentRecord)) { 6693 return false; 6694 } 6695 try { 6696 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6697 if (res.key.allIntents == null) { 6698 return false; 6699 } 6700 for (int i=0; i<res.key.allIntents.length; i++) { 6701 Intent intent = res.key.allIntents[i]; 6702 if (intent.getPackage() != null && intent.getComponent() != null) { 6703 return false; 6704 } 6705 } 6706 return true; 6707 } catch (ClassCastException e) { 6708 } 6709 return false; 6710 } 6711 6712 @Override 6713 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6714 if (!(pendingResult instanceof PendingIntentRecord)) { 6715 return false; 6716 } 6717 try { 6718 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6719 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6720 return true; 6721 } 6722 return false; 6723 } catch (ClassCastException e) { 6724 } 6725 return false; 6726 } 6727 6728 @Override 6729 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6730 if (!(pendingResult instanceof PendingIntentRecord)) { 6731 return null; 6732 } 6733 try { 6734 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6735 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6736 } catch (ClassCastException e) { 6737 } 6738 return null; 6739 } 6740 6741 @Override 6742 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6743 if (!(pendingResult instanceof PendingIntentRecord)) { 6744 return null; 6745 } 6746 try { 6747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6748 Intent intent = res.key.requestIntent; 6749 if (intent != null) { 6750 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6751 || res.lastTagPrefix.equals(prefix))) { 6752 return res.lastTag; 6753 } 6754 res.lastTagPrefix = prefix; 6755 StringBuilder sb = new StringBuilder(128); 6756 if (prefix != null) { 6757 sb.append(prefix); 6758 } 6759 if (intent.getAction() != null) { 6760 sb.append(intent.getAction()); 6761 } else if (intent.getComponent() != null) { 6762 intent.getComponent().appendShortString(sb); 6763 } else { 6764 sb.append("?"); 6765 } 6766 return res.lastTag = sb.toString(); 6767 } 6768 } catch (ClassCastException e) { 6769 } 6770 return null; 6771 } 6772 6773 @Override 6774 public void setProcessLimit(int max) { 6775 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6776 "setProcessLimit()"); 6777 synchronized (this) { 6778 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6779 mProcessLimitOverride = max; 6780 } 6781 trimApplications(); 6782 } 6783 6784 @Override 6785 public int getProcessLimit() { 6786 synchronized (this) { 6787 return mProcessLimitOverride; 6788 } 6789 } 6790 6791 void foregroundTokenDied(ForegroundToken token) { 6792 synchronized (ActivityManagerService.this) { 6793 synchronized (mPidsSelfLocked) { 6794 ForegroundToken cur 6795 = mForegroundProcesses.get(token.pid); 6796 if (cur != token) { 6797 return; 6798 } 6799 mForegroundProcesses.remove(token.pid); 6800 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6801 if (pr == null) { 6802 return; 6803 } 6804 pr.forcingToForeground = null; 6805 updateProcessForegroundLocked(pr, false, false); 6806 } 6807 updateOomAdjLocked(); 6808 } 6809 } 6810 6811 @Override 6812 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6813 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6814 "setProcessForeground()"); 6815 synchronized(this) { 6816 boolean changed = false; 6817 6818 synchronized (mPidsSelfLocked) { 6819 ProcessRecord pr = mPidsSelfLocked.get(pid); 6820 if (pr == null && isForeground) { 6821 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6822 return; 6823 } 6824 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6825 if (oldToken != null) { 6826 oldToken.token.unlinkToDeath(oldToken, 0); 6827 mForegroundProcesses.remove(pid); 6828 if (pr != null) { 6829 pr.forcingToForeground = null; 6830 } 6831 changed = true; 6832 } 6833 if (isForeground && token != null) { 6834 ForegroundToken newToken = new ForegroundToken() { 6835 @Override 6836 public void binderDied() { 6837 foregroundTokenDied(this); 6838 } 6839 }; 6840 newToken.pid = pid; 6841 newToken.token = token; 6842 try { 6843 token.linkToDeath(newToken, 0); 6844 mForegroundProcesses.put(pid, newToken); 6845 pr.forcingToForeground = token; 6846 changed = true; 6847 } catch (RemoteException e) { 6848 // If the process died while doing this, we will later 6849 // do the cleanup with the process death link. 6850 } 6851 } 6852 } 6853 6854 if (changed) { 6855 updateOomAdjLocked(); 6856 } 6857 } 6858 } 6859 6860 // ========================================================= 6861 // PERMISSIONS 6862 // ========================================================= 6863 6864 static class PermissionController extends IPermissionController.Stub { 6865 ActivityManagerService mActivityManagerService; 6866 PermissionController(ActivityManagerService activityManagerService) { 6867 mActivityManagerService = activityManagerService; 6868 } 6869 6870 @Override 6871 public boolean checkPermission(String permission, int pid, int uid) { 6872 return mActivityManagerService.checkPermission(permission, pid, 6873 uid) == PackageManager.PERMISSION_GRANTED; 6874 } 6875 } 6876 6877 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6878 @Override 6879 public int checkComponentPermission(String permission, int pid, int uid, 6880 int owningUid, boolean exported) { 6881 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6882 owningUid, exported); 6883 } 6884 6885 @Override 6886 public Object getAMSLock() { 6887 return ActivityManagerService.this; 6888 } 6889 } 6890 6891 /** 6892 * This can be called with or without the global lock held. 6893 */ 6894 int checkComponentPermission(String permission, int pid, int uid, 6895 int owningUid, boolean exported) { 6896 // We might be performing an operation on behalf of an indirect binder 6897 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6898 // client identity accordingly before proceeding. 6899 Identity tlsIdentity = sCallerIdentity.get(); 6900 if (tlsIdentity != null) { 6901 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6902 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6903 uid = tlsIdentity.uid; 6904 pid = tlsIdentity.pid; 6905 } 6906 6907 if (pid == MY_PID) { 6908 return PackageManager.PERMISSION_GRANTED; 6909 } 6910 6911 return ActivityManager.checkComponentPermission(permission, uid, 6912 owningUid, exported); 6913 } 6914 6915 /** 6916 * As the only public entry point for permissions checking, this method 6917 * can enforce the semantic that requesting a check on a null global 6918 * permission is automatically denied. (Internally a null permission 6919 * string is used when calling {@link #checkComponentPermission} in cases 6920 * when only uid-based security is needed.) 6921 * 6922 * This can be called with or without the global lock held. 6923 */ 6924 @Override 6925 public int checkPermission(String permission, int pid, int uid) { 6926 if (permission == null) { 6927 return PackageManager.PERMISSION_DENIED; 6928 } 6929 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6930 } 6931 6932 /** 6933 * Binder IPC calls go through the public entry point. 6934 * This can be called with or without the global lock held. 6935 */ 6936 int checkCallingPermission(String permission) { 6937 return checkPermission(permission, 6938 Binder.getCallingPid(), 6939 UserHandle.getAppId(Binder.getCallingUid())); 6940 } 6941 6942 /** 6943 * This can be called with or without the global lock held. 6944 */ 6945 void enforceCallingPermission(String permission, String func) { 6946 if (checkCallingPermission(permission) 6947 == PackageManager.PERMISSION_GRANTED) { 6948 return; 6949 } 6950 6951 String msg = "Permission Denial: " + func + " from pid=" 6952 + Binder.getCallingPid() 6953 + ", uid=" + Binder.getCallingUid() 6954 + " requires " + permission; 6955 Slog.w(TAG, msg); 6956 throw new SecurityException(msg); 6957 } 6958 6959 /** 6960 * Determine if UID is holding permissions required to access {@link Uri} in 6961 * the given {@link ProviderInfo}. Final permission checking is always done 6962 * in {@link ContentProvider}. 6963 */ 6964 private final boolean checkHoldingPermissionsLocked( 6965 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6966 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6967 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6968 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6969 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6970 != PERMISSION_GRANTED) { 6971 return false; 6972 } 6973 } 6974 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6975 } 6976 6977 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6978 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6979 if (pi.applicationInfo.uid == uid) { 6980 return true; 6981 } else if (!pi.exported) { 6982 return false; 6983 } 6984 6985 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6986 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6987 try { 6988 // check if target holds top-level <provider> permissions 6989 if (!readMet && pi.readPermission != null && considerUidPermissions 6990 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6991 readMet = true; 6992 } 6993 if (!writeMet && pi.writePermission != null && considerUidPermissions 6994 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6995 writeMet = true; 6996 } 6997 6998 // track if unprotected read/write is allowed; any denied 6999 // <path-permission> below removes this ability 7000 boolean allowDefaultRead = pi.readPermission == null; 7001 boolean allowDefaultWrite = pi.writePermission == null; 7002 7003 // check if target holds any <path-permission> that match uri 7004 final PathPermission[] pps = pi.pathPermissions; 7005 if (pps != null) { 7006 final String path = grantUri.uri.getPath(); 7007 int i = pps.length; 7008 while (i > 0 && (!readMet || !writeMet)) { 7009 i--; 7010 PathPermission pp = pps[i]; 7011 if (pp.match(path)) { 7012 if (!readMet) { 7013 final String pprperm = pp.getReadPermission(); 7014 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7015 + pprperm + " for " + pp.getPath() 7016 + ": match=" + pp.match(path) 7017 + " check=" + pm.checkUidPermission(pprperm, uid)); 7018 if (pprperm != null) { 7019 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7020 == PERMISSION_GRANTED) { 7021 readMet = true; 7022 } else { 7023 allowDefaultRead = false; 7024 } 7025 } 7026 } 7027 if (!writeMet) { 7028 final String ppwperm = pp.getWritePermission(); 7029 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7030 + ppwperm + " for " + pp.getPath() 7031 + ": match=" + pp.match(path) 7032 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7033 if (ppwperm != null) { 7034 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7035 == PERMISSION_GRANTED) { 7036 writeMet = true; 7037 } else { 7038 allowDefaultWrite = false; 7039 } 7040 } 7041 } 7042 } 7043 } 7044 } 7045 7046 // grant unprotected <provider> read/write, if not blocked by 7047 // <path-permission> above 7048 if (allowDefaultRead) readMet = true; 7049 if (allowDefaultWrite) writeMet = true; 7050 7051 } catch (RemoteException e) { 7052 return false; 7053 } 7054 7055 return readMet && writeMet; 7056 } 7057 7058 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7059 ProviderInfo pi = null; 7060 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7061 if (cpr != null) { 7062 pi = cpr.info; 7063 } else { 7064 try { 7065 pi = AppGlobals.getPackageManager().resolveContentProvider( 7066 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7067 } catch (RemoteException ex) { 7068 } 7069 } 7070 return pi; 7071 } 7072 7073 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7074 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7075 if (targetUris != null) { 7076 return targetUris.get(grantUri); 7077 } 7078 return null; 7079 } 7080 7081 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7082 String targetPkg, int targetUid, GrantUri grantUri) { 7083 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7084 if (targetUris == null) { 7085 targetUris = Maps.newArrayMap(); 7086 mGrantedUriPermissions.put(targetUid, targetUris); 7087 } 7088 7089 UriPermission perm = targetUris.get(grantUri); 7090 if (perm == null) { 7091 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7092 targetUris.put(grantUri, perm); 7093 } 7094 7095 return perm; 7096 } 7097 7098 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7099 final int modeFlags) { 7100 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7101 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7102 : UriPermission.STRENGTH_OWNED; 7103 7104 // Root gets to do everything. 7105 if (uid == 0) { 7106 return true; 7107 } 7108 7109 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7110 if (perms == null) return false; 7111 7112 // First look for exact match 7113 final UriPermission exactPerm = perms.get(grantUri); 7114 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7115 return true; 7116 } 7117 7118 // No exact match, look for prefixes 7119 final int N = perms.size(); 7120 for (int i = 0; i < N; i++) { 7121 final UriPermission perm = perms.valueAt(i); 7122 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7123 && perm.getStrength(modeFlags) >= minStrength) { 7124 return true; 7125 } 7126 } 7127 7128 return false; 7129 } 7130 7131 /** 7132 * @param uri This uri must NOT contain an embedded userId. 7133 * @param userId The userId in which the uri is to be resolved. 7134 */ 7135 @Override 7136 public int checkUriPermission(Uri uri, int pid, int uid, 7137 final int modeFlags, int userId) { 7138 enforceNotIsolatedCaller("checkUriPermission"); 7139 7140 // Another redirected-binder-call permissions check as in 7141 // {@link checkComponentPermission}. 7142 Identity tlsIdentity = sCallerIdentity.get(); 7143 if (tlsIdentity != null) { 7144 uid = tlsIdentity.uid; 7145 pid = tlsIdentity.pid; 7146 } 7147 7148 // Our own process gets to do everything. 7149 if (pid == MY_PID) { 7150 return PackageManager.PERMISSION_GRANTED; 7151 } 7152 synchronized (this) { 7153 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7154 ? PackageManager.PERMISSION_GRANTED 7155 : PackageManager.PERMISSION_DENIED; 7156 } 7157 } 7158 7159 /** 7160 * Check if the targetPkg can be granted permission to access uri by 7161 * the callingUid using the given modeFlags. Throws a security exception 7162 * if callingUid is not allowed to do this. Returns the uid of the target 7163 * if the URI permission grant should be performed; returns -1 if it is not 7164 * needed (for example targetPkg already has permission to access the URI). 7165 * If you already know the uid of the target, you can supply it in 7166 * lastTargetUid else set that to -1. 7167 */ 7168 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7169 final int modeFlags, int lastTargetUid) { 7170 if (!Intent.isAccessUriMode(modeFlags)) { 7171 return -1; 7172 } 7173 7174 if (targetPkg != null) { 7175 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7176 "Checking grant " + targetPkg + " permission to " + grantUri); 7177 } 7178 7179 final IPackageManager pm = AppGlobals.getPackageManager(); 7180 7181 // If this is not a content: uri, we can't do anything with it. 7182 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7183 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7184 "Can't grant URI permission for non-content URI: " + grantUri); 7185 return -1; 7186 } 7187 7188 final String authority = grantUri.uri.getAuthority(); 7189 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7190 if (pi == null) { 7191 Slog.w(TAG, "No content provider found for permission check: " + 7192 grantUri.uri.toSafeString()); 7193 return -1; 7194 } 7195 7196 int targetUid = lastTargetUid; 7197 if (targetUid < 0 && targetPkg != null) { 7198 try { 7199 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7200 if (targetUid < 0) { 7201 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7202 "Can't grant URI permission no uid for: " + targetPkg); 7203 return -1; 7204 } 7205 } catch (RemoteException ex) { 7206 return -1; 7207 } 7208 } 7209 7210 if (targetUid >= 0) { 7211 // First... does the target actually need this permission? 7212 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7213 // No need to grant the target this permission. 7214 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7215 "Target " + targetPkg + " already has full permission to " + grantUri); 7216 return -1; 7217 } 7218 } else { 7219 // First... there is no target package, so can anyone access it? 7220 boolean allowed = pi.exported; 7221 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7222 if (pi.readPermission != null) { 7223 allowed = false; 7224 } 7225 } 7226 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7227 if (pi.writePermission != null) { 7228 allowed = false; 7229 } 7230 } 7231 if (allowed) { 7232 return -1; 7233 } 7234 } 7235 7236 /* There is a special cross user grant if: 7237 * - The target is on another user. 7238 * - Apps on the current user can access the uri without any uid permissions. 7239 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7240 * grant uri permissions. 7241 */ 7242 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7243 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7244 modeFlags, false /*without considering the uid permissions*/); 7245 7246 // Second... is the provider allowing granting of URI permissions? 7247 if (!specialCrossUserGrant) { 7248 if (!pi.grantUriPermissions) { 7249 throw new SecurityException("Provider " + pi.packageName 7250 + "/" + pi.name 7251 + " does not allow granting of Uri permissions (uri " 7252 + grantUri + ")"); 7253 } 7254 if (pi.uriPermissionPatterns != null) { 7255 final int N = pi.uriPermissionPatterns.length; 7256 boolean allowed = false; 7257 for (int i=0; i<N; i++) { 7258 if (pi.uriPermissionPatterns[i] != null 7259 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7260 allowed = true; 7261 break; 7262 } 7263 } 7264 if (!allowed) { 7265 throw new SecurityException("Provider " + pi.packageName 7266 + "/" + pi.name 7267 + " does not allow granting of permission to path of Uri " 7268 + grantUri); 7269 } 7270 } 7271 } 7272 7273 // Third... does the caller itself have permission to access 7274 // this uri? 7275 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7276 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7277 // Require they hold a strong enough Uri permission 7278 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7279 throw new SecurityException("Uid " + callingUid 7280 + " does not have permission to uri " + grantUri); 7281 } 7282 } 7283 } 7284 return targetUid; 7285 } 7286 7287 /** 7288 * @param uri This uri must NOT contain an embedded userId. 7289 * @param userId The userId in which the uri is to be resolved. 7290 */ 7291 @Override 7292 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7293 final int modeFlags, int userId) { 7294 enforceNotIsolatedCaller("checkGrantUriPermission"); 7295 synchronized(this) { 7296 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7297 new GrantUri(userId, uri, false), modeFlags, -1); 7298 } 7299 } 7300 7301 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7302 final int modeFlags, UriPermissionOwner owner) { 7303 if (!Intent.isAccessUriMode(modeFlags)) { 7304 return; 7305 } 7306 7307 // So here we are: the caller has the assumed permission 7308 // to the uri, and the target doesn't. Let's now give this to 7309 // the target. 7310 7311 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7312 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7313 7314 final String authority = grantUri.uri.getAuthority(); 7315 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7316 if (pi == null) { 7317 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7318 return; 7319 } 7320 7321 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7322 grantUri.prefix = true; 7323 } 7324 final UriPermission perm = findOrCreateUriPermissionLocked( 7325 pi.packageName, targetPkg, targetUid, grantUri); 7326 perm.grantModes(modeFlags, owner); 7327 } 7328 7329 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7330 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7331 if (targetPkg == null) { 7332 throw new NullPointerException("targetPkg"); 7333 } 7334 int targetUid; 7335 final IPackageManager pm = AppGlobals.getPackageManager(); 7336 try { 7337 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7338 } catch (RemoteException ex) { 7339 return; 7340 } 7341 7342 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7343 targetUid); 7344 if (targetUid < 0) { 7345 return; 7346 } 7347 7348 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7349 owner); 7350 } 7351 7352 static class NeededUriGrants extends ArrayList<GrantUri> { 7353 final String targetPkg; 7354 final int targetUid; 7355 final int flags; 7356 7357 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7358 this.targetPkg = targetPkg; 7359 this.targetUid = targetUid; 7360 this.flags = flags; 7361 } 7362 } 7363 7364 /** 7365 * Like checkGrantUriPermissionLocked, but takes an Intent. 7366 */ 7367 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7368 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7369 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7370 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7371 + " clip=" + (intent != null ? intent.getClipData() : null) 7372 + " from " + intent + "; flags=0x" 7373 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7374 7375 if (targetPkg == null) { 7376 throw new NullPointerException("targetPkg"); 7377 } 7378 7379 if (intent == null) { 7380 return null; 7381 } 7382 Uri data = intent.getData(); 7383 ClipData clip = intent.getClipData(); 7384 if (data == null && clip == null) { 7385 return null; 7386 } 7387 // Default userId for uris in the intent (if they don't specify it themselves) 7388 int contentUserHint = intent.getContentUserHint(); 7389 if (contentUserHint == UserHandle.USER_CURRENT) { 7390 contentUserHint = UserHandle.getUserId(callingUid); 7391 } 7392 final IPackageManager pm = AppGlobals.getPackageManager(); 7393 int targetUid; 7394 if (needed != null) { 7395 targetUid = needed.targetUid; 7396 } else { 7397 try { 7398 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7399 } catch (RemoteException ex) { 7400 return null; 7401 } 7402 if (targetUid < 0) { 7403 if (DEBUG_URI_PERMISSION) { 7404 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7405 + " on user " + targetUserId); 7406 } 7407 return null; 7408 } 7409 } 7410 if (data != null) { 7411 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7412 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7413 targetUid); 7414 if (targetUid > 0) { 7415 if (needed == null) { 7416 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7417 } 7418 needed.add(grantUri); 7419 } 7420 } 7421 if (clip != null) { 7422 for (int i=0; i<clip.getItemCount(); i++) { 7423 Uri uri = clip.getItemAt(i).getUri(); 7424 if (uri != null) { 7425 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7426 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7427 targetUid); 7428 if (targetUid > 0) { 7429 if (needed == null) { 7430 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7431 } 7432 needed.add(grantUri); 7433 } 7434 } else { 7435 Intent clipIntent = clip.getItemAt(i).getIntent(); 7436 if (clipIntent != null) { 7437 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7438 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7439 if (newNeeded != null) { 7440 needed = newNeeded; 7441 } 7442 } 7443 } 7444 } 7445 } 7446 7447 return needed; 7448 } 7449 7450 /** 7451 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7452 */ 7453 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7454 UriPermissionOwner owner) { 7455 if (needed != null) { 7456 for (int i=0; i<needed.size(); i++) { 7457 GrantUri grantUri = needed.get(i); 7458 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7459 grantUri, needed.flags, owner); 7460 } 7461 } 7462 } 7463 7464 void grantUriPermissionFromIntentLocked(int callingUid, 7465 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7466 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7467 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7468 if (needed == null) { 7469 return; 7470 } 7471 7472 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7473 } 7474 7475 /** 7476 * @param uri This uri must NOT contain an embedded userId. 7477 * @param userId The userId in which the uri is to be resolved. 7478 */ 7479 @Override 7480 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7481 final int modeFlags, int userId) { 7482 enforceNotIsolatedCaller("grantUriPermission"); 7483 GrantUri grantUri = new GrantUri(userId, uri, false); 7484 synchronized(this) { 7485 final ProcessRecord r = getRecordForAppLocked(caller); 7486 if (r == null) { 7487 throw new SecurityException("Unable to find app for caller " 7488 + caller 7489 + " when granting permission to uri " + grantUri); 7490 } 7491 if (targetPkg == null) { 7492 throw new IllegalArgumentException("null target"); 7493 } 7494 if (grantUri == null) { 7495 throw new IllegalArgumentException("null uri"); 7496 } 7497 7498 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7499 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7500 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7501 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7502 7503 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7504 UserHandle.getUserId(r.uid)); 7505 } 7506 } 7507 7508 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7509 if (perm.modeFlags == 0) { 7510 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7511 perm.targetUid); 7512 if (perms != null) { 7513 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7514 "Removing " + perm.targetUid + " permission to " + perm.uri); 7515 7516 perms.remove(perm.uri); 7517 if (perms.isEmpty()) { 7518 mGrantedUriPermissions.remove(perm.targetUid); 7519 } 7520 } 7521 } 7522 } 7523 7524 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7525 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7526 7527 final IPackageManager pm = AppGlobals.getPackageManager(); 7528 final String authority = grantUri.uri.getAuthority(); 7529 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7530 if (pi == null) { 7531 Slog.w(TAG, "No content provider found for permission revoke: " 7532 + grantUri.toSafeString()); 7533 return; 7534 } 7535 7536 // Does the caller have this permission on the URI? 7537 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7538 // If they don't have direct access to the URI, then revoke any 7539 // ownerless URI permissions that have been granted to them. 7540 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7541 if (perms != null) { 7542 boolean persistChanged = false; 7543 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7544 final UriPermission perm = it.next(); 7545 if (perm.uri.sourceUserId == grantUri.sourceUserId 7546 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7547 if (DEBUG_URI_PERMISSION) 7548 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7549 " permission to " + perm.uri); 7550 persistChanged |= perm.revokeModes( 7551 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7552 if (perm.modeFlags == 0) { 7553 it.remove(); 7554 } 7555 } 7556 } 7557 if (perms.isEmpty()) { 7558 mGrantedUriPermissions.remove(callingUid); 7559 } 7560 if (persistChanged) { 7561 schedulePersistUriGrants(); 7562 } 7563 } 7564 return; 7565 } 7566 7567 boolean persistChanged = false; 7568 7569 // Go through all of the permissions and remove any that match. 7570 int N = mGrantedUriPermissions.size(); 7571 for (int i = 0; i < N; i++) { 7572 final int targetUid = mGrantedUriPermissions.keyAt(i); 7573 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7574 7575 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7576 final UriPermission perm = it.next(); 7577 if (perm.uri.sourceUserId == grantUri.sourceUserId 7578 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7579 if (DEBUG_URI_PERMISSION) 7580 Slog.v(TAG, 7581 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7582 persistChanged |= perm.revokeModes( 7583 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7584 if (perm.modeFlags == 0) { 7585 it.remove(); 7586 } 7587 } 7588 } 7589 7590 if (perms.isEmpty()) { 7591 mGrantedUriPermissions.remove(targetUid); 7592 N--; 7593 i--; 7594 } 7595 } 7596 7597 if (persistChanged) { 7598 schedulePersistUriGrants(); 7599 } 7600 } 7601 7602 /** 7603 * @param uri This uri must NOT contain an embedded userId. 7604 * @param userId The userId in which the uri is to be resolved. 7605 */ 7606 @Override 7607 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7608 int userId) { 7609 enforceNotIsolatedCaller("revokeUriPermission"); 7610 synchronized(this) { 7611 final ProcessRecord r = getRecordForAppLocked(caller); 7612 if (r == null) { 7613 throw new SecurityException("Unable to find app for caller " 7614 + caller 7615 + " when revoking permission to uri " + uri); 7616 } 7617 if (uri == null) { 7618 Slog.w(TAG, "revokeUriPermission: null uri"); 7619 return; 7620 } 7621 7622 if (!Intent.isAccessUriMode(modeFlags)) { 7623 return; 7624 } 7625 7626 final IPackageManager pm = AppGlobals.getPackageManager(); 7627 final String authority = uri.getAuthority(); 7628 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7629 if (pi == null) { 7630 Slog.w(TAG, "No content provider found for permission revoke: " 7631 + uri.toSafeString()); 7632 return; 7633 } 7634 7635 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7636 } 7637 } 7638 7639 /** 7640 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7641 * given package. 7642 * 7643 * @param packageName Package name to match, or {@code null} to apply to all 7644 * packages. 7645 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7646 * to all users. 7647 * @param persistable If persistable grants should be removed. 7648 */ 7649 private void removeUriPermissionsForPackageLocked( 7650 String packageName, int userHandle, boolean persistable) { 7651 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7652 throw new IllegalArgumentException("Must narrow by either package or user"); 7653 } 7654 7655 boolean persistChanged = false; 7656 7657 int N = mGrantedUriPermissions.size(); 7658 for (int i = 0; i < N; i++) { 7659 final int targetUid = mGrantedUriPermissions.keyAt(i); 7660 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7661 7662 // Only inspect grants matching user 7663 if (userHandle == UserHandle.USER_ALL 7664 || userHandle == UserHandle.getUserId(targetUid)) { 7665 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7666 final UriPermission perm = it.next(); 7667 7668 // Only inspect grants matching package 7669 if (packageName == null || perm.sourcePkg.equals(packageName) 7670 || perm.targetPkg.equals(packageName)) { 7671 persistChanged |= perm.revokeModes(persistable 7672 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7673 7674 // Only remove when no modes remain; any persisted grants 7675 // will keep this alive. 7676 if (perm.modeFlags == 0) { 7677 it.remove(); 7678 } 7679 } 7680 } 7681 7682 if (perms.isEmpty()) { 7683 mGrantedUriPermissions.remove(targetUid); 7684 N--; 7685 i--; 7686 } 7687 } 7688 } 7689 7690 if (persistChanged) { 7691 schedulePersistUriGrants(); 7692 } 7693 } 7694 7695 @Override 7696 public IBinder newUriPermissionOwner(String name) { 7697 enforceNotIsolatedCaller("newUriPermissionOwner"); 7698 synchronized(this) { 7699 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7700 return owner.getExternalTokenLocked(); 7701 } 7702 } 7703 7704 /** 7705 * @param uri This uri must NOT contain an embedded userId. 7706 * @param sourceUserId The userId in which the uri is to be resolved. 7707 * @param targetUserId The userId of the app that receives the grant. 7708 */ 7709 @Override 7710 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7711 final int modeFlags, int sourceUserId, int targetUserId) { 7712 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7713 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7714 synchronized(this) { 7715 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7716 if (owner == null) { 7717 throw new IllegalArgumentException("Unknown owner: " + token); 7718 } 7719 if (fromUid != Binder.getCallingUid()) { 7720 if (Binder.getCallingUid() != Process.myUid()) { 7721 // Only system code can grant URI permissions on behalf 7722 // of other users. 7723 throw new SecurityException("nice try"); 7724 } 7725 } 7726 if (targetPkg == null) { 7727 throw new IllegalArgumentException("null target"); 7728 } 7729 if (uri == null) { 7730 throw new IllegalArgumentException("null uri"); 7731 } 7732 7733 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7734 modeFlags, owner, targetUserId); 7735 } 7736 } 7737 7738 /** 7739 * @param uri This uri must NOT contain an embedded userId. 7740 * @param userId The userId in which the uri is to be resolved. 7741 */ 7742 @Override 7743 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7744 synchronized(this) { 7745 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7746 if (owner == null) { 7747 throw new IllegalArgumentException("Unknown owner: " + token); 7748 } 7749 7750 if (uri == null) { 7751 owner.removeUriPermissionsLocked(mode); 7752 } else { 7753 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7754 } 7755 } 7756 } 7757 7758 private void schedulePersistUriGrants() { 7759 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7760 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7761 10 * DateUtils.SECOND_IN_MILLIS); 7762 } 7763 } 7764 7765 private void writeGrantedUriPermissions() { 7766 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7767 7768 // Snapshot permissions so we can persist without lock 7769 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7770 synchronized (this) { 7771 final int size = mGrantedUriPermissions.size(); 7772 for (int i = 0; i < size; i++) { 7773 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7774 for (UriPermission perm : perms.values()) { 7775 if (perm.persistedModeFlags != 0) { 7776 persist.add(perm.snapshot()); 7777 } 7778 } 7779 } 7780 } 7781 7782 FileOutputStream fos = null; 7783 try { 7784 fos = mGrantFile.startWrite(); 7785 7786 XmlSerializer out = new FastXmlSerializer(); 7787 out.setOutput(fos, "utf-8"); 7788 out.startDocument(null, true); 7789 out.startTag(null, TAG_URI_GRANTS); 7790 for (UriPermission.Snapshot perm : persist) { 7791 out.startTag(null, TAG_URI_GRANT); 7792 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7793 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7794 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7795 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7796 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7797 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7798 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7799 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7800 out.endTag(null, TAG_URI_GRANT); 7801 } 7802 out.endTag(null, TAG_URI_GRANTS); 7803 out.endDocument(); 7804 7805 mGrantFile.finishWrite(fos); 7806 } catch (IOException e) { 7807 if (fos != null) { 7808 mGrantFile.failWrite(fos); 7809 } 7810 } 7811 } 7812 7813 private void readGrantedUriPermissionsLocked() { 7814 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7815 7816 final long now = System.currentTimeMillis(); 7817 7818 FileInputStream fis = null; 7819 try { 7820 fis = mGrantFile.openRead(); 7821 final XmlPullParser in = Xml.newPullParser(); 7822 in.setInput(fis, null); 7823 7824 int type; 7825 while ((type = in.next()) != END_DOCUMENT) { 7826 final String tag = in.getName(); 7827 if (type == START_TAG) { 7828 if (TAG_URI_GRANT.equals(tag)) { 7829 final int sourceUserId; 7830 final int targetUserId; 7831 final int userHandle = readIntAttribute(in, 7832 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7833 if (userHandle != UserHandle.USER_NULL) { 7834 // For backwards compatibility. 7835 sourceUserId = userHandle; 7836 targetUserId = userHandle; 7837 } else { 7838 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7839 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7840 } 7841 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7842 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7843 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7844 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7845 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7846 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7847 7848 // Sanity check that provider still belongs to source package 7849 final ProviderInfo pi = getProviderInfoLocked( 7850 uri.getAuthority(), sourceUserId); 7851 if (pi != null && sourcePkg.equals(pi.packageName)) { 7852 int targetUid = -1; 7853 try { 7854 targetUid = AppGlobals.getPackageManager() 7855 .getPackageUid(targetPkg, targetUserId); 7856 } catch (RemoteException e) { 7857 } 7858 if (targetUid != -1) { 7859 final UriPermission perm = findOrCreateUriPermissionLocked( 7860 sourcePkg, targetPkg, targetUid, 7861 new GrantUri(sourceUserId, uri, prefix)); 7862 perm.initPersistedModes(modeFlags, createdTime); 7863 } 7864 } else { 7865 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7866 + " but instead found " + pi); 7867 } 7868 } 7869 } 7870 } 7871 } catch (FileNotFoundException e) { 7872 // Missing grants is okay 7873 } catch (IOException e) { 7874 Log.wtf(TAG, "Failed reading Uri grants", e); 7875 } catch (XmlPullParserException e) { 7876 Log.wtf(TAG, "Failed reading Uri grants", e); 7877 } finally { 7878 IoUtils.closeQuietly(fis); 7879 } 7880 } 7881 7882 /** 7883 * @param uri This uri must NOT contain an embedded userId. 7884 * @param userId The userId in which the uri is to be resolved. 7885 */ 7886 @Override 7887 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7888 enforceNotIsolatedCaller("takePersistableUriPermission"); 7889 7890 Preconditions.checkFlagsArgument(modeFlags, 7891 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7892 7893 synchronized (this) { 7894 final int callingUid = Binder.getCallingUid(); 7895 boolean persistChanged = false; 7896 GrantUri grantUri = new GrantUri(userId, uri, false); 7897 7898 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7899 new GrantUri(userId, uri, false)); 7900 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7901 new GrantUri(userId, uri, true)); 7902 7903 final boolean exactValid = (exactPerm != null) 7904 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7905 final boolean prefixValid = (prefixPerm != null) 7906 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7907 7908 if (!(exactValid || prefixValid)) { 7909 throw new SecurityException("No persistable permission grants found for UID " 7910 + callingUid + " and Uri " + grantUri.toSafeString()); 7911 } 7912 7913 if (exactValid) { 7914 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7915 } 7916 if (prefixValid) { 7917 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7918 } 7919 7920 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7921 7922 if (persistChanged) { 7923 schedulePersistUriGrants(); 7924 } 7925 } 7926 } 7927 7928 /** 7929 * @param uri This uri must NOT contain an embedded userId. 7930 * @param userId The userId in which the uri is to be resolved. 7931 */ 7932 @Override 7933 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7934 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7935 7936 Preconditions.checkFlagsArgument(modeFlags, 7937 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7938 7939 synchronized (this) { 7940 final int callingUid = Binder.getCallingUid(); 7941 boolean persistChanged = false; 7942 7943 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7944 new GrantUri(userId, uri, false)); 7945 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7946 new GrantUri(userId, uri, true)); 7947 if (exactPerm == null && prefixPerm == null) { 7948 throw new SecurityException("No permission grants found for UID " + callingUid 7949 + " and Uri " + uri.toSafeString()); 7950 } 7951 7952 if (exactPerm != null) { 7953 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7954 removeUriPermissionIfNeededLocked(exactPerm); 7955 } 7956 if (prefixPerm != null) { 7957 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7958 removeUriPermissionIfNeededLocked(prefixPerm); 7959 } 7960 7961 if (persistChanged) { 7962 schedulePersistUriGrants(); 7963 } 7964 } 7965 } 7966 7967 /** 7968 * Prune any older {@link UriPermission} for the given UID until outstanding 7969 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7970 * 7971 * @return if any mutations occured that require persisting. 7972 */ 7973 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7974 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7975 if (perms == null) return false; 7976 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7977 7978 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7979 for (UriPermission perm : perms.values()) { 7980 if (perm.persistedModeFlags != 0) { 7981 persisted.add(perm); 7982 } 7983 } 7984 7985 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7986 if (trimCount <= 0) return false; 7987 7988 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7989 for (int i = 0; i < trimCount; i++) { 7990 final UriPermission perm = persisted.get(i); 7991 7992 if (DEBUG_URI_PERMISSION) { 7993 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7994 } 7995 7996 perm.releasePersistableModes(~0); 7997 removeUriPermissionIfNeededLocked(perm); 7998 } 7999 8000 return true; 8001 } 8002 8003 @Override 8004 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8005 String packageName, boolean incoming) { 8006 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8007 Preconditions.checkNotNull(packageName, "packageName"); 8008 8009 final int callingUid = Binder.getCallingUid(); 8010 final IPackageManager pm = AppGlobals.getPackageManager(); 8011 try { 8012 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8013 if (packageUid != callingUid) { 8014 throw new SecurityException( 8015 "Package " + packageName + " does not belong to calling UID " + callingUid); 8016 } 8017 } catch (RemoteException e) { 8018 throw new SecurityException("Failed to verify package name ownership"); 8019 } 8020 8021 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8022 synchronized (this) { 8023 if (incoming) { 8024 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8025 callingUid); 8026 if (perms == null) { 8027 Slog.w(TAG, "No permission grants found for " + packageName); 8028 } else { 8029 for (UriPermission perm : perms.values()) { 8030 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8031 result.add(perm.buildPersistedPublicApiObject()); 8032 } 8033 } 8034 } 8035 } else { 8036 final int size = mGrantedUriPermissions.size(); 8037 for (int i = 0; i < size; i++) { 8038 final ArrayMap<GrantUri, UriPermission> perms = 8039 mGrantedUriPermissions.valueAt(i); 8040 for (UriPermission perm : perms.values()) { 8041 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8042 result.add(perm.buildPersistedPublicApiObject()); 8043 } 8044 } 8045 } 8046 } 8047 } 8048 return new ParceledListSlice<android.content.UriPermission>(result); 8049 } 8050 8051 @Override 8052 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8053 synchronized (this) { 8054 ProcessRecord app = 8055 who != null ? getRecordForAppLocked(who) : null; 8056 if (app == null) return; 8057 8058 Message msg = Message.obtain(); 8059 msg.what = WAIT_FOR_DEBUGGER_MSG; 8060 msg.obj = app; 8061 msg.arg1 = waiting ? 1 : 0; 8062 mHandler.sendMessage(msg); 8063 } 8064 } 8065 8066 @Override 8067 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8068 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8069 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8070 outInfo.availMem = Process.getFreeMemory(); 8071 outInfo.totalMem = Process.getTotalMemory(); 8072 outInfo.threshold = homeAppMem; 8073 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8074 outInfo.hiddenAppThreshold = cachedAppMem; 8075 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8076 ProcessList.SERVICE_ADJ); 8077 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8078 ProcessList.VISIBLE_APP_ADJ); 8079 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8080 ProcessList.FOREGROUND_APP_ADJ); 8081 } 8082 8083 // ========================================================= 8084 // TASK MANAGEMENT 8085 // ========================================================= 8086 8087 @Override 8088 public List<IAppTask> getAppTasks(String callingPackage) { 8089 int callingUid = Binder.getCallingUid(); 8090 long ident = Binder.clearCallingIdentity(); 8091 8092 synchronized(this) { 8093 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8094 try { 8095 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8096 8097 final int N = mRecentTasks.size(); 8098 for (int i = 0; i < N; i++) { 8099 TaskRecord tr = mRecentTasks.get(i); 8100 // Skip tasks that do not match the caller. We don't need to verify 8101 // callingPackage, because we are also limiting to callingUid and know 8102 // that will limit to the correct security sandbox. 8103 if (tr.effectiveUid != callingUid) { 8104 continue; 8105 } 8106 Intent intent = tr.getBaseIntent(); 8107 if (intent == null || 8108 !callingPackage.equals(intent.getComponent().getPackageName())) { 8109 continue; 8110 } 8111 ActivityManager.RecentTaskInfo taskInfo = 8112 createRecentTaskInfoFromTaskRecord(tr); 8113 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8114 list.add(taskImpl); 8115 } 8116 } finally { 8117 Binder.restoreCallingIdentity(ident); 8118 } 8119 return list; 8120 } 8121 } 8122 8123 @Override 8124 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8125 final int callingUid = Binder.getCallingUid(); 8126 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8127 8128 synchronized(this) { 8129 if (localLOGV) Slog.v( 8130 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8131 8132 final boolean allowed = checkCallingPermission( 8133 android.Manifest.permission.GET_TASKS) 8134 == PackageManager.PERMISSION_GRANTED; 8135 if (!allowed) { 8136 Slog.w(TAG, "getTasks: caller " + callingUid 8137 + " does not hold GET_TASKS; limiting output"); 8138 } 8139 8140 // TODO: Improve with MRU list from all ActivityStacks. 8141 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8142 } 8143 8144 return list; 8145 } 8146 8147 TaskRecord getMostRecentTask() { 8148 return mRecentTasks.get(0); 8149 } 8150 8151 /** 8152 * Creates a new RecentTaskInfo from a TaskRecord. 8153 */ 8154 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8155 // Update the task description to reflect any changes in the task stack 8156 tr.updateTaskDescription(); 8157 8158 // Compose the recent task info 8159 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8160 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8161 rti.persistentId = tr.taskId; 8162 rti.baseIntent = new Intent(tr.getBaseIntent()); 8163 rti.origActivity = tr.origActivity; 8164 rti.description = tr.lastDescription; 8165 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8166 rti.userId = tr.userId; 8167 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8168 rti.firstActiveTime = tr.firstActiveTime; 8169 rti.lastActiveTime = tr.lastActiveTime; 8170 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8171 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8172 return rti; 8173 } 8174 8175 @Override 8176 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8177 final int callingUid = Binder.getCallingUid(); 8178 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8179 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8180 8181 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8182 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8183 synchronized (this) { 8184 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8185 == PackageManager.PERMISSION_GRANTED; 8186 if (!allowed) { 8187 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8188 + " does not hold GET_TASKS; limiting output"); 8189 } 8190 final boolean detailed = checkCallingPermission( 8191 android.Manifest.permission.GET_DETAILED_TASKS) 8192 == PackageManager.PERMISSION_GRANTED; 8193 8194 final int N = mRecentTasks.size(); 8195 ArrayList<ActivityManager.RecentTaskInfo> res 8196 = new ArrayList<ActivityManager.RecentTaskInfo>( 8197 maxNum < N ? maxNum : N); 8198 8199 final Set<Integer> includedUsers; 8200 if (includeProfiles) { 8201 includedUsers = getProfileIdsLocked(userId); 8202 } else { 8203 includedUsers = new HashSet<Integer>(); 8204 } 8205 includedUsers.add(Integer.valueOf(userId)); 8206 8207 for (int i=0; i<N && maxNum > 0; i++) { 8208 TaskRecord tr = mRecentTasks.get(i); 8209 // Only add calling user or related users recent tasks 8210 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8211 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8212 continue; 8213 } 8214 8215 // Return the entry if desired by the caller. We always return 8216 // the first entry, because callers always expect this to be the 8217 // foreground app. We may filter others if the caller has 8218 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8219 // we should exclude the entry. 8220 8221 if (i == 0 8222 || withExcluded 8223 || (tr.intent == null) 8224 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8225 == 0)) { 8226 if (!allowed) { 8227 // If the caller doesn't have the GET_TASKS permission, then only 8228 // allow them to see a small subset of tasks -- their own and home. 8229 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8230 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8231 continue; 8232 } 8233 } 8234 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8235 if (tr.stack != null && tr.stack.isHomeStack()) { 8236 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8237 continue; 8238 } 8239 } 8240 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8241 // Don't include auto remove tasks that are finished or finishing. 8242 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8243 + tr); 8244 continue; 8245 } 8246 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8247 && !tr.isAvailable) { 8248 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8249 continue; 8250 } 8251 8252 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8253 if (!detailed) { 8254 rti.baseIntent.replaceExtras((Bundle)null); 8255 } 8256 8257 res.add(rti); 8258 maxNum--; 8259 } 8260 } 8261 return res; 8262 } 8263 } 8264 8265 private TaskRecord recentTaskForIdLocked(int id) { 8266 final int N = mRecentTasks.size(); 8267 for (int i=0; i<N; i++) { 8268 TaskRecord tr = mRecentTasks.get(i); 8269 if (tr.taskId == id) { 8270 return tr; 8271 } 8272 } 8273 return null; 8274 } 8275 8276 @Override 8277 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8278 synchronized (this) { 8279 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8280 "getTaskThumbnail()"); 8281 TaskRecord tr = recentTaskForIdLocked(id); 8282 if (tr != null) { 8283 return tr.getTaskThumbnailLocked(); 8284 } 8285 } 8286 return null; 8287 } 8288 8289 @Override 8290 public int addAppTask(IBinder activityToken, Intent intent, 8291 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8292 final int callingUid = Binder.getCallingUid(); 8293 final long callingIdent = Binder.clearCallingIdentity(); 8294 8295 try { 8296 synchronized (this) { 8297 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8298 if (r == null) { 8299 throw new IllegalArgumentException("Activity does not exist; token=" 8300 + activityToken); 8301 } 8302 ComponentName comp = intent.getComponent(); 8303 if (comp == null) { 8304 throw new IllegalArgumentException("Intent " + intent 8305 + " must specify explicit component"); 8306 } 8307 if (thumbnail.getWidth() != mThumbnailWidth 8308 || thumbnail.getHeight() != mThumbnailHeight) { 8309 throw new IllegalArgumentException("Bad thumbnail size: got " 8310 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8311 + mThumbnailWidth + "x" + mThumbnailHeight); 8312 } 8313 if (intent.getSelector() != null) { 8314 intent.setSelector(null); 8315 } 8316 if (intent.getSourceBounds() != null) { 8317 intent.setSourceBounds(null); 8318 } 8319 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8320 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8321 // The caller has added this as an auto-remove task... that makes no 8322 // sense, so turn off auto-remove. 8323 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8324 } 8325 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8326 // Must be a new task. 8327 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8328 } 8329 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8330 mLastAddedTaskActivity = null; 8331 } 8332 ActivityInfo ainfo = mLastAddedTaskActivity; 8333 if (ainfo == null) { 8334 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8335 comp, 0, UserHandle.getUserId(callingUid)); 8336 if (ainfo.applicationInfo.uid != callingUid) { 8337 throw new SecurityException( 8338 "Can't add task for another application: target uid=" 8339 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8340 } 8341 } 8342 8343 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8344 intent, description); 8345 8346 int trimIdx = trimRecentsForTask(task, false); 8347 if (trimIdx >= 0) { 8348 // If this would have caused a trim, then we'll abort because that 8349 // means it would be added at the end of the list but then just removed. 8350 return -1; 8351 } 8352 8353 final int N = mRecentTasks.size(); 8354 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8355 final TaskRecord tr = mRecentTasks.remove(N - 1); 8356 tr.removedFromRecents(mTaskPersister); 8357 } 8358 8359 task.inRecents = true; 8360 mRecentTasks.add(task); 8361 r.task.stack.addTask(task, false, false); 8362 8363 task.setLastThumbnail(thumbnail); 8364 task.freeLastThumbnail(); 8365 8366 return task.taskId; 8367 } 8368 } finally { 8369 Binder.restoreCallingIdentity(callingIdent); 8370 } 8371 } 8372 8373 @Override 8374 public Point getAppTaskThumbnailSize() { 8375 synchronized (this) { 8376 return new Point(mThumbnailWidth, mThumbnailHeight); 8377 } 8378 } 8379 8380 @Override 8381 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8382 synchronized (this) { 8383 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8384 if (r != null) { 8385 r.setTaskDescription(td); 8386 r.task.updateTaskDescription(); 8387 } 8388 } 8389 } 8390 8391 @Override 8392 public Bitmap getTaskDescriptionIcon(String filename) { 8393 return mTaskPersister.getTaskDescriptionIcon(filename); 8394 } 8395 8396 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8397 mRecentTasks.remove(tr); 8398 tr.removedFromRecents(mTaskPersister); 8399 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8400 Intent baseIntent = new Intent( 8401 tr.intent != null ? tr.intent : tr.affinityIntent); 8402 ComponentName component = baseIntent.getComponent(); 8403 if (component == null) { 8404 Slog.w(TAG, "Now component for base intent of task: " + tr); 8405 return; 8406 } 8407 8408 // Find any running services associated with this app. 8409 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8410 8411 if (killProcesses) { 8412 // Find any running processes associated with this app. 8413 final String pkg = component.getPackageName(); 8414 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8415 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8416 for (int i=0; i<pmap.size(); i++) { 8417 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8418 for (int j=0; j<uids.size(); j++) { 8419 ProcessRecord proc = uids.valueAt(j); 8420 if (proc.userId != tr.userId) { 8421 continue; 8422 } 8423 if (!proc.pkgList.containsKey(pkg)) { 8424 continue; 8425 } 8426 procs.add(proc); 8427 } 8428 } 8429 8430 // Kill the running processes. 8431 for (int i=0; i<procs.size(); i++) { 8432 ProcessRecord pr = procs.get(i); 8433 if (pr == mHomeProcess) { 8434 // Don't kill the home process along with tasks from the same package. 8435 continue; 8436 } 8437 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8438 pr.kill("remove task", true); 8439 } else { 8440 pr.waitingToKill = "remove task"; 8441 } 8442 } 8443 } 8444 } 8445 8446 /** 8447 * Removes the task with the specified task id. 8448 * 8449 * @param taskId Identifier of the task to be removed. 8450 * @param flags Additional operational flags. May be 0 or 8451 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8452 * @return Returns true if the given task was found and removed. 8453 */ 8454 private boolean removeTaskByIdLocked(int taskId, int flags) { 8455 TaskRecord tr = recentTaskForIdLocked(taskId); 8456 if (tr != null) { 8457 tr.removeTaskActivitiesLocked(); 8458 cleanUpRemovedTaskLocked(tr, flags); 8459 if (tr.isPersistable) { 8460 notifyTaskPersisterLocked(null, true); 8461 } 8462 return true; 8463 } 8464 return false; 8465 } 8466 8467 @Override 8468 public boolean removeTask(int taskId, int flags) { 8469 synchronized (this) { 8470 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8471 "removeTask()"); 8472 long ident = Binder.clearCallingIdentity(); 8473 try { 8474 return removeTaskByIdLocked(taskId, flags); 8475 } finally { 8476 Binder.restoreCallingIdentity(ident); 8477 } 8478 } 8479 } 8480 8481 /** 8482 * TODO: Add mController hook 8483 */ 8484 @Override 8485 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8486 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8487 "moveTaskToFront()"); 8488 8489 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8490 synchronized(this) { 8491 moveTaskToFrontLocked(taskId, flags, options); 8492 } 8493 } 8494 8495 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8496 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8497 Binder.getCallingUid(), -1, -1, "Task to front")) { 8498 ActivityOptions.abort(options); 8499 return; 8500 } 8501 final long origId = Binder.clearCallingIdentity(); 8502 try { 8503 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8504 if (task == null) { 8505 return; 8506 } 8507 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8508 mStackSupervisor.showLockTaskToast(); 8509 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8510 return; 8511 } 8512 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8513 if (prev != null && prev.isRecentsActivity()) { 8514 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8515 } 8516 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8517 } finally { 8518 Binder.restoreCallingIdentity(origId); 8519 } 8520 ActivityOptions.abort(options); 8521 } 8522 8523 @Override 8524 public void moveTaskToBack(int taskId) { 8525 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8526 "moveTaskToBack()"); 8527 8528 synchronized(this) { 8529 TaskRecord tr = recentTaskForIdLocked(taskId); 8530 if (tr != null) { 8531 if (tr == mStackSupervisor.mLockTaskModeTask) { 8532 mStackSupervisor.showLockTaskToast(); 8533 return; 8534 } 8535 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8536 ActivityStack stack = tr.stack; 8537 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8538 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8539 Binder.getCallingUid(), -1, -1, "Task to back")) { 8540 return; 8541 } 8542 } 8543 final long origId = Binder.clearCallingIdentity(); 8544 try { 8545 stack.moveTaskToBackLocked(taskId, null); 8546 } finally { 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 } 8551 } 8552 8553 /** 8554 * Moves an activity, and all of the other activities within the same task, to the bottom 8555 * of the history stack. The activity's order within the task is unchanged. 8556 * 8557 * @param token A reference to the activity we wish to move 8558 * @param nonRoot If false then this only works if the activity is the root 8559 * of a task; if true it will work for any activity in a task. 8560 * @return Returns true if the move completed, false if not. 8561 */ 8562 @Override 8563 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8564 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8565 synchronized(this) { 8566 final long origId = Binder.clearCallingIdentity(); 8567 try { 8568 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8569 if (taskId >= 0) { 8570 if ((mStackSupervisor.mLockTaskModeTask != null) 8571 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8572 mStackSupervisor.showLockTaskToast(); 8573 return false; 8574 } 8575 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8576 } 8577 } finally { 8578 Binder.restoreCallingIdentity(origId); 8579 } 8580 } 8581 return false; 8582 } 8583 8584 @Override 8585 public void moveTaskBackwards(int task) { 8586 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8587 "moveTaskBackwards()"); 8588 8589 synchronized(this) { 8590 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8591 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8592 return; 8593 } 8594 final long origId = Binder.clearCallingIdentity(); 8595 moveTaskBackwardsLocked(task); 8596 Binder.restoreCallingIdentity(origId); 8597 } 8598 } 8599 8600 private final void moveTaskBackwardsLocked(int task) { 8601 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8602 } 8603 8604 @Override 8605 public IBinder getHomeActivityToken() throws RemoteException { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getHomeActivityToken()"); 8608 synchronized (this) { 8609 return mStackSupervisor.getHomeActivityToken(); 8610 } 8611 } 8612 8613 @Override 8614 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8615 IActivityContainerCallback callback) throws RemoteException { 8616 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8617 "createActivityContainer()"); 8618 synchronized (this) { 8619 if (parentActivityToken == null) { 8620 throw new IllegalArgumentException("parent token must not be null"); 8621 } 8622 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8623 if (r == null) { 8624 return null; 8625 } 8626 if (callback == null) { 8627 throw new IllegalArgumentException("callback must not be null"); 8628 } 8629 return mStackSupervisor.createActivityContainer(r, callback); 8630 } 8631 } 8632 8633 @Override 8634 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8635 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8636 "deleteActivityContainer()"); 8637 synchronized (this) { 8638 mStackSupervisor.deleteActivityContainer(container); 8639 } 8640 } 8641 8642 @Override 8643 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8644 throws RemoteException { 8645 synchronized (this) { 8646 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8647 if (stack != null) { 8648 return stack.mActivityContainer; 8649 } 8650 return null; 8651 } 8652 } 8653 8654 @Override 8655 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8656 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8657 "moveTaskToStack()"); 8658 if (stackId == HOME_STACK_ID) { 8659 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8660 new RuntimeException("here").fillInStackTrace()); 8661 } 8662 synchronized (this) { 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8666 + stackId + " toTop=" + toTop); 8667 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8668 } finally { 8669 Binder.restoreCallingIdentity(ident); 8670 } 8671 } 8672 } 8673 8674 @Override 8675 public void resizeStack(int stackBoxId, Rect bounds) { 8676 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8677 "resizeStackBox()"); 8678 long ident = Binder.clearCallingIdentity(); 8679 try { 8680 mWindowManager.resizeStack(stackBoxId, bounds); 8681 } finally { 8682 Binder.restoreCallingIdentity(ident); 8683 } 8684 } 8685 8686 @Override 8687 public List<StackInfo> getAllStackInfos() { 8688 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8689 "getAllStackInfos()"); 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 synchronized (this) { 8693 return mStackSupervisor.getAllStackInfosLocked(); 8694 } 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 8700 @Override 8701 public StackInfo getStackInfo(int stackId) { 8702 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8703 "getStackInfo()"); 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 return mStackSupervisor.getStackInfoLocked(stackId); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public boolean isInHomeStack(int taskId) { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "getStackInfo()"); 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 TaskRecord tr = recentTaskForIdLocked(taskId); 8722 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8723 } 8724 } finally { 8725 Binder.restoreCallingIdentity(ident); 8726 } 8727 } 8728 8729 @Override 8730 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8731 synchronized(this) { 8732 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8733 } 8734 } 8735 8736 private boolean isLockTaskAuthorized(String pkg) { 8737 final DevicePolicyManager dpm = (DevicePolicyManager) 8738 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8739 try { 8740 int uid = mContext.getPackageManager().getPackageUid(pkg, 8741 Binder.getCallingUserHandle().getIdentifier()); 8742 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8743 } catch (NameNotFoundException e) { 8744 return false; 8745 } 8746 } 8747 8748 void startLockTaskMode(TaskRecord task) { 8749 final String pkg; 8750 synchronized (this) { 8751 pkg = task.intent.getComponent().getPackageName(); 8752 } 8753 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8754 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8755 final TaskRecord taskRecord = task; 8756 mHandler.post(new Runnable() { 8757 @Override 8758 public void run() { 8759 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8760 } 8761 }); 8762 return; 8763 } 8764 long ident = Binder.clearCallingIdentity(); 8765 try { 8766 synchronized (this) { 8767 // Since we lost lock on task, make sure it is still there. 8768 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8769 if (task != null) { 8770 if (!isSystemInitiated 8771 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8772 throw new IllegalArgumentException("Invalid task, not in foreground"); 8773 } 8774 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8775 } 8776 } 8777 } finally { 8778 Binder.restoreCallingIdentity(ident); 8779 } 8780 } 8781 8782 @Override 8783 public void startLockTaskMode(int taskId) { 8784 final TaskRecord task; 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 if (task != null) { 8794 startLockTaskMode(task); 8795 } 8796 } 8797 8798 @Override 8799 public void startLockTaskMode(IBinder token) { 8800 final TaskRecord task; 8801 long ident = Binder.clearCallingIdentity(); 8802 try { 8803 synchronized (this) { 8804 final ActivityRecord r = ActivityRecord.forToken(token); 8805 if (r == null) { 8806 return; 8807 } 8808 task = r.task; 8809 } 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 if (task != null) { 8814 startLockTaskMode(task); 8815 } 8816 } 8817 8818 @Override 8819 public void startLockTaskModeOnCurrent() throws RemoteException { 8820 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8821 "startLockTaskModeOnCurrent"); 8822 ActivityRecord r = null; 8823 synchronized (this) { 8824 r = mStackSupervisor.topRunningActivityLocked(); 8825 } 8826 startLockTaskMode(r.task); 8827 } 8828 8829 @Override 8830 public void stopLockTaskMode() { 8831 // Verify that the user matches the package of the intent for the TaskRecord 8832 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8833 // and stopLockTaskMode. 8834 final int callingUid = Binder.getCallingUid(); 8835 if (callingUid != Process.SYSTEM_UID) { 8836 try { 8837 String pkg = 8838 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8839 int uid = mContext.getPackageManager().getPackageUid(pkg, 8840 Binder.getCallingUserHandle().getIdentifier()); 8841 if (uid != callingUid) { 8842 throw new SecurityException("Invalid uid, expected " + uid); 8843 } 8844 } catch (NameNotFoundException e) { 8845 Log.d(TAG, "stopLockTaskMode " + e); 8846 return; 8847 } 8848 } 8849 long ident = Binder.clearCallingIdentity(); 8850 try { 8851 Log.d(TAG, "stopLockTaskMode"); 8852 // Stop lock task 8853 synchronized (this) { 8854 mStackSupervisor.setLockTaskModeLocked(null, false); 8855 } 8856 } finally { 8857 Binder.restoreCallingIdentity(ident); 8858 } 8859 } 8860 8861 @Override 8862 public void stopLockTaskModeOnCurrent() throws RemoteException { 8863 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8864 "stopLockTaskModeOnCurrent"); 8865 long ident = Binder.clearCallingIdentity(); 8866 try { 8867 stopLockTaskMode(); 8868 } finally { 8869 Binder.restoreCallingIdentity(ident); 8870 } 8871 } 8872 8873 @Override 8874 public boolean isInLockTaskMode() { 8875 synchronized (this) { 8876 return mStackSupervisor.isInLockTaskMode(); 8877 } 8878 } 8879 8880 // ========================================================= 8881 // CONTENT PROVIDERS 8882 // ========================================================= 8883 8884 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8885 List<ProviderInfo> providers = null; 8886 try { 8887 providers = AppGlobals.getPackageManager(). 8888 queryContentProviders(app.processName, app.uid, 8889 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8890 } catch (RemoteException ex) { 8891 } 8892 if (DEBUG_MU) 8893 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8894 int userId = app.userId; 8895 if (providers != null) { 8896 int N = providers.size(); 8897 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8898 for (int i=0; i<N; i++) { 8899 ProviderInfo cpi = 8900 (ProviderInfo)providers.get(i); 8901 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8902 cpi.name, cpi.flags); 8903 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8904 // This is a singleton provider, but a user besides the 8905 // default user is asking to initialize a process it runs 8906 // in... well, no, it doesn't actually run in this process, 8907 // it runs in the process of the default user. Get rid of it. 8908 providers.remove(i); 8909 N--; 8910 i--; 8911 continue; 8912 } 8913 8914 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8915 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8916 if (cpr == null) { 8917 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8918 mProviderMap.putProviderByClass(comp, cpr); 8919 } 8920 if (DEBUG_MU) 8921 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8922 app.pubProviders.put(cpi.name, cpr); 8923 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8924 // Don't add this if it is a platform component that is marked 8925 // to run in multiple processes, because this is actually 8926 // part of the framework so doesn't make sense to track as a 8927 // separate apk in the process. 8928 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8929 mProcessStats); 8930 } 8931 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8932 } 8933 } 8934 return providers; 8935 } 8936 8937 /** 8938 * Check if {@link ProcessRecord} has a possible chance at accessing the 8939 * given {@link ProviderInfo}. Final permission checking is always done 8940 * in {@link ContentProvider}. 8941 */ 8942 private final String checkContentProviderPermissionLocked( 8943 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8944 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8945 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8946 boolean checkedGrants = false; 8947 if (checkUser) { 8948 // Looking for cross-user grants before enforcing the typical cross-users permissions 8949 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8950 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8951 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8952 return null; 8953 } 8954 checkedGrants = true; 8955 } 8956 userId = handleIncomingUser(callingPid, callingUid, userId, 8957 false, ALLOW_NON_FULL, 8958 "checkContentProviderPermissionLocked " + cpi.authority, null); 8959 if (userId != tmpTargetUserId) { 8960 // When we actually went to determine the final targer user ID, this ended 8961 // up different than our initial check for the authority. This is because 8962 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8963 // SELF. So we need to re-check the grants again. 8964 checkedGrants = false; 8965 } 8966 } 8967 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8968 cpi.applicationInfo.uid, cpi.exported) 8969 == PackageManager.PERMISSION_GRANTED) { 8970 return null; 8971 } 8972 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8973 cpi.applicationInfo.uid, cpi.exported) 8974 == PackageManager.PERMISSION_GRANTED) { 8975 return null; 8976 } 8977 8978 PathPermission[] pps = cpi.pathPermissions; 8979 if (pps != null) { 8980 int i = pps.length; 8981 while (i > 0) { 8982 i--; 8983 PathPermission pp = pps[i]; 8984 String pprperm = pp.getReadPermission(); 8985 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8986 cpi.applicationInfo.uid, cpi.exported) 8987 == PackageManager.PERMISSION_GRANTED) { 8988 return null; 8989 } 8990 String ppwperm = pp.getWritePermission(); 8991 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8992 cpi.applicationInfo.uid, cpi.exported) 8993 == PackageManager.PERMISSION_GRANTED) { 8994 return null; 8995 } 8996 } 8997 } 8998 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8999 return null; 9000 } 9001 9002 String msg; 9003 if (!cpi.exported) { 9004 msg = "Permission Denial: opening provider " + cpi.name 9005 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9006 + ", uid=" + callingUid + ") that is not exported from uid " 9007 + cpi.applicationInfo.uid; 9008 } else { 9009 msg = "Permission Denial: opening provider " + cpi.name 9010 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9011 + ", uid=" + callingUid + ") requires " 9012 + cpi.readPermission + " or " + cpi.writePermission; 9013 } 9014 Slog.w(TAG, msg); 9015 return msg; 9016 } 9017 9018 /** 9019 * Returns if the ContentProvider has granted a uri to callingUid 9020 */ 9021 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9022 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9023 if (perms != null) { 9024 for (int i=perms.size()-1; i>=0; i--) { 9025 GrantUri grantUri = perms.keyAt(i); 9026 if (grantUri.sourceUserId == userId || !checkUser) { 9027 if (matchesProvider(grantUri.uri, cpi)) { 9028 return true; 9029 } 9030 } 9031 } 9032 } 9033 return false; 9034 } 9035 9036 /** 9037 * Returns true if the uri authority is one of the authorities specified in the provider. 9038 */ 9039 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9040 String uriAuth = uri.getAuthority(); 9041 String cpiAuth = cpi.authority; 9042 if (cpiAuth.indexOf(';') == -1) { 9043 return cpiAuth.equals(uriAuth); 9044 } 9045 String[] cpiAuths = cpiAuth.split(";"); 9046 int length = cpiAuths.length; 9047 for (int i = 0; i < length; i++) { 9048 if (cpiAuths[i].equals(uriAuth)) return true; 9049 } 9050 return false; 9051 } 9052 9053 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9054 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9055 if (r != null) { 9056 for (int i=0; i<r.conProviders.size(); i++) { 9057 ContentProviderConnection conn = r.conProviders.get(i); 9058 if (conn.provider == cpr) { 9059 if (DEBUG_PROVIDER) Slog.v(TAG, 9060 "Adding provider requested by " 9061 + r.processName + " from process " 9062 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9063 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9064 if (stable) { 9065 conn.stableCount++; 9066 conn.numStableIncs++; 9067 } else { 9068 conn.unstableCount++; 9069 conn.numUnstableIncs++; 9070 } 9071 return conn; 9072 } 9073 } 9074 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9075 if (stable) { 9076 conn.stableCount = 1; 9077 conn.numStableIncs = 1; 9078 } else { 9079 conn.unstableCount = 1; 9080 conn.numUnstableIncs = 1; 9081 } 9082 cpr.connections.add(conn); 9083 r.conProviders.add(conn); 9084 return conn; 9085 } 9086 cpr.addExternalProcessHandleLocked(externalProcessToken); 9087 return null; 9088 } 9089 9090 boolean decProviderCountLocked(ContentProviderConnection conn, 9091 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9092 if (conn != null) { 9093 cpr = conn.provider; 9094 if (DEBUG_PROVIDER) Slog.v(TAG, 9095 "Removing provider requested by " 9096 + conn.client.processName + " from process " 9097 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9098 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9099 if (stable) { 9100 conn.stableCount--; 9101 } else { 9102 conn.unstableCount--; 9103 } 9104 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9105 cpr.connections.remove(conn); 9106 conn.client.conProviders.remove(conn); 9107 return true; 9108 } 9109 return false; 9110 } 9111 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9112 return false; 9113 } 9114 9115 private void checkTime(long startTime, String where) { 9116 long now = SystemClock.elapsedRealtime(); 9117 if ((now-startTime) > 1000) { 9118 // If we are taking more than a second, log about it. 9119 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9120 } 9121 } 9122 9123 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9124 String name, IBinder token, boolean stable, int userId) { 9125 ContentProviderRecord cpr; 9126 ContentProviderConnection conn = null; 9127 ProviderInfo cpi = null; 9128 9129 synchronized(this) { 9130 long startTime = SystemClock.elapsedRealtime(); 9131 9132 ProcessRecord r = null; 9133 if (caller != null) { 9134 r = getRecordForAppLocked(caller); 9135 if (r == null) { 9136 throw new SecurityException( 9137 "Unable to find app for caller " + caller 9138 + " (pid=" + Binder.getCallingPid() 9139 + ") when getting content provider " + name); 9140 } 9141 } 9142 9143 boolean checkCrossUser = true; 9144 9145 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9146 9147 // First check if this content provider has been published... 9148 cpr = mProviderMap.getProviderByName(name, userId); 9149 // If that didn't work, check if it exists for user 0 and then 9150 // verify that it's a singleton provider before using it. 9151 if (cpr == null && userId != UserHandle.USER_OWNER) { 9152 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9153 if (cpr != null) { 9154 cpi = cpr.info; 9155 if (isSingleton(cpi.processName, cpi.applicationInfo, 9156 cpi.name, cpi.flags) 9157 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9158 userId = UserHandle.USER_OWNER; 9159 checkCrossUser = false; 9160 } else { 9161 cpr = null; 9162 cpi = null; 9163 } 9164 } 9165 } 9166 9167 boolean providerRunning = cpr != null; 9168 if (providerRunning) { 9169 cpi = cpr.info; 9170 String msg; 9171 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9172 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9173 != null) { 9174 throw new SecurityException(msg); 9175 } 9176 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9177 9178 if (r != null && cpr.canRunHere(r)) { 9179 // This provider has been published or is in the process 9180 // of being published... but it is also allowed to run 9181 // in the caller's process, so don't make a connection 9182 // and just let the caller instantiate its own instance. 9183 ContentProviderHolder holder = cpr.newHolder(null); 9184 // don't give caller the provider object, it needs 9185 // to make its own. 9186 holder.provider = null; 9187 return holder; 9188 } 9189 9190 final long origId = Binder.clearCallingIdentity(); 9191 9192 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9193 9194 // In this case the provider instance already exists, so we can 9195 // return it right away. 9196 conn = incProviderCountLocked(r, cpr, token, stable); 9197 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9198 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9199 // If this is a perceptible app accessing the provider, 9200 // make sure to count it as being accessed and thus 9201 // back up on the LRU list. This is good because 9202 // content providers are often expensive to start. 9203 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9204 updateLruProcessLocked(cpr.proc, false, null); 9205 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9206 } 9207 } 9208 9209 if (cpr.proc != null) { 9210 if (false) { 9211 if (cpr.name.flattenToShortString().equals( 9212 "com.android.providers.calendar/.CalendarProvider2")) { 9213 Slog.v(TAG, "****************** KILLING " 9214 + cpr.name.flattenToShortString()); 9215 Process.killProcess(cpr.proc.pid); 9216 } 9217 } 9218 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9219 boolean success = updateOomAdjLocked(cpr.proc); 9220 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9221 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9222 // NOTE: there is still a race here where a signal could be 9223 // pending on the process even though we managed to update its 9224 // adj level. Not sure what to do about this, but at least 9225 // the race is now smaller. 9226 if (!success) { 9227 // Uh oh... it looks like the provider's process 9228 // has been killed on us. We need to wait for a new 9229 // process to be started, and make sure its death 9230 // doesn't kill our process. 9231 Slog.i(TAG, 9232 "Existing provider " + cpr.name.flattenToShortString() 9233 + " is crashing; detaching " + r); 9234 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9235 checkTime(startTime, "getContentProviderImpl: before appDied"); 9236 appDiedLocked(cpr.proc); 9237 checkTime(startTime, "getContentProviderImpl: after appDied"); 9238 if (!lastRef) { 9239 // This wasn't the last ref our process had on 9240 // the provider... we have now been killed, bail. 9241 return null; 9242 } 9243 providerRunning = false; 9244 conn = null; 9245 } 9246 } 9247 9248 Binder.restoreCallingIdentity(origId); 9249 } 9250 9251 boolean singleton; 9252 if (!providerRunning) { 9253 try { 9254 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9255 cpi = AppGlobals.getPackageManager(). 9256 resolveContentProvider(name, 9257 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9258 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9259 } catch (RemoteException ex) { 9260 } 9261 if (cpi == null) { 9262 return null; 9263 } 9264 // If the provider is a singleton AND 9265 // (it's a call within the same user || the provider is a 9266 // privileged app) 9267 // Then allow connecting to the singleton provider 9268 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9269 cpi.name, cpi.flags) 9270 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9271 if (singleton) { 9272 userId = UserHandle.USER_OWNER; 9273 } 9274 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9275 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9276 9277 String msg; 9278 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9279 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9280 != null) { 9281 throw new SecurityException(msg); 9282 } 9283 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9284 9285 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9286 && !cpi.processName.equals("system")) { 9287 // If this content provider does not run in the system 9288 // process, and the system is not yet ready to run other 9289 // processes, then fail fast instead of hanging. 9290 throw new IllegalArgumentException( 9291 "Attempt to launch content provider before system ready"); 9292 } 9293 9294 // Make sure that the user who owns this provider is started. If not, 9295 // we don't want to allow it to run. 9296 if (mStartedUsers.get(userId) == null) { 9297 Slog.w(TAG, "Unable to launch app " 9298 + cpi.applicationInfo.packageName + "/" 9299 + cpi.applicationInfo.uid + " for provider " 9300 + name + ": user " + userId + " is stopped"); 9301 return null; 9302 } 9303 9304 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9305 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9306 cpr = mProviderMap.getProviderByClass(comp, userId); 9307 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9308 final boolean firstClass = cpr == null; 9309 if (firstClass) { 9310 try { 9311 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9312 ApplicationInfo ai = 9313 AppGlobals.getPackageManager(). 9314 getApplicationInfo( 9315 cpi.applicationInfo.packageName, 9316 STOCK_PM_FLAGS, userId); 9317 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9318 if (ai == null) { 9319 Slog.w(TAG, "No package info for content provider " 9320 + cpi.name); 9321 return null; 9322 } 9323 ai = getAppInfoForUser(ai, userId); 9324 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9325 } catch (RemoteException ex) { 9326 // pm is in same process, this will never happen. 9327 } 9328 } 9329 9330 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9331 9332 if (r != null && cpr.canRunHere(r)) { 9333 // If this is a multiprocess provider, then just return its 9334 // info and allow the caller to instantiate it. Only do 9335 // this if the provider is the same user as the caller's 9336 // process, or can run as root (so can be in any process). 9337 return cpr.newHolder(null); 9338 } 9339 9340 if (DEBUG_PROVIDER) { 9341 RuntimeException e = new RuntimeException("here"); 9342 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9343 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9344 } 9345 9346 // This is single process, and our app is now connecting to it. 9347 // See if we are already in the process of launching this 9348 // provider. 9349 final int N = mLaunchingProviders.size(); 9350 int i; 9351 for (i=0; i<N; i++) { 9352 if (mLaunchingProviders.get(i) == cpr) { 9353 break; 9354 } 9355 } 9356 9357 // If the provider is not already being launched, then get it 9358 // started. 9359 if (i >= N) { 9360 final long origId = Binder.clearCallingIdentity(); 9361 9362 try { 9363 // Content provider is now in use, its package can't be stopped. 9364 try { 9365 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9366 AppGlobals.getPackageManager().setPackageStoppedState( 9367 cpr.appInfo.packageName, false, userId); 9368 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9369 } catch (RemoteException e) { 9370 } catch (IllegalArgumentException e) { 9371 Slog.w(TAG, "Failed trying to unstop package " 9372 + cpr.appInfo.packageName + ": " + e); 9373 } 9374 9375 // Use existing process if already started 9376 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9377 ProcessRecord proc = getProcessRecordLocked( 9378 cpi.processName, cpr.appInfo.uid, false); 9379 if (proc != null && proc.thread != null) { 9380 if (DEBUG_PROVIDER) { 9381 Slog.d(TAG, "Installing in existing process " + proc); 9382 } 9383 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9384 proc.pubProviders.put(cpi.name, cpr); 9385 try { 9386 proc.thread.scheduleInstallProvider(cpi); 9387 } catch (RemoteException e) { 9388 } 9389 } else { 9390 checkTime(startTime, "getContentProviderImpl: before start process"); 9391 proc = startProcessLocked(cpi.processName, 9392 cpr.appInfo, false, 0, "content provider", 9393 new ComponentName(cpi.applicationInfo.packageName, 9394 cpi.name), false, false, false); 9395 checkTime(startTime, "getContentProviderImpl: after start process"); 9396 if (proc == null) { 9397 Slog.w(TAG, "Unable to launch app " 9398 + cpi.applicationInfo.packageName + "/" 9399 + cpi.applicationInfo.uid + " for provider " 9400 + name + ": process is bad"); 9401 return null; 9402 } 9403 } 9404 cpr.launchingApp = proc; 9405 mLaunchingProviders.add(cpr); 9406 } finally { 9407 Binder.restoreCallingIdentity(origId); 9408 } 9409 } 9410 9411 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9412 9413 // Make sure the provider is published (the same provider class 9414 // may be published under multiple names). 9415 if (firstClass) { 9416 mProviderMap.putProviderByClass(comp, cpr); 9417 } 9418 9419 mProviderMap.putProviderByName(name, cpr); 9420 conn = incProviderCountLocked(r, cpr, token, stable); 9421 if (conn != null) { 9422 conn.waiting = true; 9423 } 9424 } 9425 checkTime(startTime, "getContentProviderImpl: done!"); 9426 } 9427 9428 // Wait for the provider to be published... 9429 synchronized (cpr) { 9430 while (cpr.provider == null) { 9431 if (cpr.launchingApp == null) { 9432 Slog.w(TAG, "Unable to launch app " 9433 + cpi.applicationInfo.packageName + "/" 9434 + cpi.applicationInfo.uid + " for provider " 9435 + name + ": launching app became null"); 9436 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9437 UserHandle.getUserId(cpi.applicationInfo.uid), 9438 cpi.applicationInfo.packageName, 9439 cpi.applicationInfo.uid, name); 9440 return null; 9441 } 9442 try { 9443 if (DEBUG_MU) { 9444 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9445 + cpr.launchingApp); 9446 } 9447 if (conn != null) { 9448 conn.waiting = true; 9449 } 9450 cpr.wait(); 9451 } catch (InterruptedException ex) { 9452 } finally { 9453 if (conn != null) { 9454 conn.waiting = false; 9455 } 9456 } 9457 } 9458 } 9459 return cpr != null ? cpr.newHolder(conn) : null; 9460 } 9461 9462 @Override 9463 public final ContentProviderHolder getContentProvider( 9464 IApplicationThread caller, String name, int userId, boolean stable) { 9465 enforceNotIsolatedCaller("getContentProvider"); 9466 if (caller == null) { 9467 String msg = "null IApplicationThread when getting content provider " 9468 + name; 9469 Slog.w(TAG, msg); 9470 throw new SecurityException(msg); 9471 } 9472 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9473 // with cross-user grant. 9474 return getContentProviderImpl(caller, name, null, stable, userId); 9475 } 9476 9477 public ContentProviderHolder getContentProviderExternal( 9478 String name, int userId, IBinder token) { 9479 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9480 "Do not have permission in call getContentProviderExternal()"); 9481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9482 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9483 return getContentProviderExternalUnchecked(name, token, userId); 9484 } 9485 9486 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9487 IBinder token, int userId) { 9488 return getContentProviderImpl(null, name, token, true, userId); 9489 } 9490 9491 /** 9492 * Drop a content provider from a ProcessRecord's bookkeeping 9493 */ 9494 public void removeContentProvider(IBinder connection, boolean stable) { 9495 enforceNotIsolatedCaller("removeContentProvider"); 9496 long ident = Binder.clearCallingIdentity(); 9497 try { 9498 synchronized (this) { 9499 ContentProviderConnection conn; 9500 try { 9501 conn = (ContentProviderConnection)connection; 9502 } catch (ClassCastException e) { 9503 String msg ="removeContentProvider: " + connection 9504 + " not a ContentProviderConnection"; 9505 Slog.w(TAG, msg); 9506 throw new IllegalArgumentException(msg); 9507 } 9508 if (conn == null) { 9509 throw new NullPointerException("connection is null"); 9510 } 9511 if (decProviderCountLocked(conn, null, null, stable)) { 9512 updateOomAdjLocked(); 9513 } 9514 } 9515 } finally { 9516 Binder.restoreCallingIdentity(ident); 9517 } 9518 } 9519 9520 public void removeContentProviderExternal(String name, IBinder token) { 9521 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9522 "Do not have permission in call removeContentProviderExternal()"); 9523 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9524 } 9525 9526 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9527 synchronized (this) { 9528 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9529 if(cpr == null) { 9530 //remove from mProvidersByClass 9531 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9532 return; 9533 } 9534 9535 //update content provider record entry info 9536 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9537 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9538 if (localCpr.hasExternalProcessHandles()) { 9539 if (localCpr.removeExternalProcessHandleLocked(token)) { 9540 updateOomAdjLocked(); 9541 } else { 9542 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9543 + " with no external reference for token: " 9544 + token + "."); 9545 } 9546 } else { 9547 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9548 + " with no external references."); 9549 } 9550 } 9551 } 9552 9553 public final void publishContentProviders(IApplicationThread caller, 9554 List<ContentProviderHolder> providers) { 9555 if (providers == null) { 9556 return; 9557 } 9558 9559 enforceNotIsolatedCaller("publishContentProviders"); 9560 synchronized (this) { 9561 final ProcessRecord r = getRecordForAppLocked(caller); 9562 if (DEBUG_MU) 9563 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9564 if (r == null) { 9565 throw new SecurityException( 9566 "Unable to find app for caller " + caller 9567 + " (pid=" + Binder.getCallingPid() 9568 + ") when publishing content providers"); 9569 } 9570 9571 final long origId = Binder.clearCallingIdentity(); 9572 9573 final int N = providers.size(); 9574 for (int i=0; i<N; i++) { 9575 ContentProviderHolder src = providers.get(i); 9576 if (src == null || src.info == null || src.provider == null) { 9577 continue; 9578 } 9579 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9580 if (DEBUG_MU) 9581 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9582 if (dst != null) { 9583 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9584 mProviderMap.putProviderByClass(comp, dst); 9585 String names[] = dst.info.authority.split(";"); 9586 for (int j = 0; j < names.length; j++) { 9587 mProviderMap.putProviderByName(names[j], dst); 9588 } 9589 9590 int NL = mLaunchingProviders.size(); 9591 int j; 9592 for (j=0; j<NL; j++) { 9593 if (mLaunchingProviders.get(j) == dst) { 9594 mLaunchingProviders.remove(j); 9595 j--; 9596 NL--; 9597 } 9598 } 9599 synchronized (dst) { 9600 dst.provider = src.provider; 9601 dst.proc = r; 9602 dst.notifyAll(); 9603 } 9604 updateOomAdjLocked(r); 9605 } 9606 } 9607 9608 Binder.restoreCallingIdentity(origId); 9609 } 9610 } 9611 9612 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9613 ContentProviderConnection conn; 9614 try { 9615 conn = (ContentProviderConnection)connection; 9616 } catch (ClassCastException e) { 9617 String msg ="refContentProvider: " + connection 9618 + " not a ContentProviderConnection"; 9619 Slog.w(TAG, msg); 9620 throw new IllegalArgumentException(msg); 9621 } 9622 if (conn == null) { 9623 throw new NullPointerException("connection is null"); 9624 } 9625 9626 synchronized (this) { 9627 if (stable > 0) { 9628 conn.numStableIncs += stable; 9629 } 9630 stable = conn.stableCount + stable; 9631 if (stable < 0) { 9632 throw new IllegalStateException("stableCount < 0: " + stable); 9633 } 9634 9635 if (unstable > 0) { 9636 conn.numUnstableIncs += unstable; 9637 } 9638 unstable = conn.unstableCount + unstable; 9639 if (unstable < 0) { 9640 throw new IllegalStateException("unstableCount < 0: " + unstable); 9641 } 9642 9643 if ((stable+unstable) <= 0) { 9644 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9645 + stable + " unstable=" + unstable); 9646 } 9647 conn.stableCount = stable; 9648 conn.unstableCount = unstable; 9649 return !conn.dead; 9650 } 9651 } 9652 9653 public void unstableProviderDied(IBinder connection) { 9654 ContentProviderConnection conn; 9655 try { 9656 conn = (ContentProviderConnection)connection; 9657 } catch (ClassCastException e) { 9658 String msg ="refContentProvider: " + connection 9659 + " not a ContentProviderConnection"; 9660 Slog.w(TAG, msg); 9661 throw new IllegalArgumentException(msg); 9662 } 9663 if (conn == null) { 9664 throw new NullPointerException("connection is null"); 9665 } 9666 9667 // Safely retrieve the content provider associated with the connection. 9668 IContentProvider provider; 9669 synchronized (this) { 9670 provider = conn.provider.provider; 9671 } 9672 9673 if (provider == null) { 9674 // Um, yeah, we're way ahead of you. 9675 return; 9676 } 9677 9678 // Make sure the caller is being honest with us. 9679 if (provider.asBinder().pingBinder()) { 9680 // Er, no, still looks good to us. 9681 synchronized (this) { 9682 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9683 + " says " + conn + " died, but we don't agree"); 9684 return; 9685 } 9686 } 9687 9688 // Well look at that! It's dead! 9689 synchronized (this) { 9690 if (conn.provider.provider != provider) { 9691 // But something changed... good enough. 9692 return; 9693 } 9694 9695 ProcessRecord proc = conn.provider.proc; 9696 if (proc == null || proc.thread == null) { 9697 // Seems like the process is already cleaned up. 9698 return; 9699 } 9700 9701 // As far as we're concerned, this is just like receiving a 9702 // death notification... just a bit prematurely. 9703 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9704 + ") early provider death"); 9705 final long ident = Binder.clearCallingIdentity(); 9706 try { 9707 appDiedLocked(proc); 9708 } finally { 9709 Binder.restoreCallingIdentity(ident); 9710 } 9711 } 9712 } 9713 9714 @Override 9715 public void appNotRespondingViaProvider(IBinder connection) { 9716 enforceCallingPermission( 9717 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9718 9719 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9720 if (conn == null) { 9721 Slog.w(TAG, "ContentProviderConnection is null"); 9722 return; 9723 } 9724 9725 final ProcessRecord host = conn.provider.proc; 9726 if (host == null) { 9727 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9728 return; 9729 } 9730 9731 final long token = Binder.clearCallingIdentity(); 9732 try { 9733 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9734 } finally { 9735 Binder.restoreCallingIdentity(token); 9736 } 9737 } 9738 9739 public final void installSystemProviders() { 9740 List<ProviderInfo> providers; 9741 synchronized (this) { 9742 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9743 providers = generateApplicationProvidersLocked(app); 9744 if (providers != null) { 9745 for (int i=providers.size()-1; i>=0; i--) { 9746 ProviderInfo pi = (ProviderInfo)providers.get(i); 9747 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9748 Slog.w(TAG, "Not installing system proc provider " + pi.name 9749 + ": not system .apk"); 9750 providers.remove(i); 9751 } 9752 } 9753 } 9754 } 9755 if (providers != null) { 9756 mSystemThread.installSystemProviders(providers); 9757 } 9758 9759 mCoreSettingsObserver = new CoreSettingsObserver(this); 9760 9761 //mUsageStatsService.monitorPackages(); 9762 } 9763 9764 /** 9765 * Allows apps to retrieve the MIME type of a URI. 9766 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9767 * users, then it does not need permission to access the ContentProvider. 9768 * Either, it needs cross-user uri grants. 9769 * 9770 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9771 * 9772 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9773 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9774 */ 9775 public String getProviderMimeType(Uri uri, int userId) { 9776 enforceNotIsolatedCaller("getProviderMimeType"); 9777 final String name = uri.getAuthority(); 9778 int callingUid = Binder.getCallingUid(); 9779 int callingPid = Binder.getCallingPid(); 9780 long ident = 0; 9781 boolean clearedIdentity = false; 9782 userId = unsafeConvertIncomingUser(userId); 9783 if (canClearIdentity(callingPid, callingUid, userId)) { 9784 clearedIdentity = true; 9785 ident = Binder.clearCallingIdentity(); 9786 } 9787 ContentProviderHolder holder = null; 9788 try { 9789 holder = getContentProviderExternalUnchecked(name, null, userId); 9790 if (holder != null) { 9791 return holder.provider.getType(uri); 9792 } 9793 } catch (RemoteException e) { 9794 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9795 return null; 9796 } finally { 9797 // We need to clear the identity to call removeContentProviderExternalUnchecked 9798 if (!clearedIdentity) { 9799 ident = Binder.clearCallingIdentity(); 9800 } 9801 try { 9802 if (holder != null) { 9803 removeContentProviderExternalUnchecked(name, null, userId); 9804 } 9805 } finally { 9806 Binder.restoreCallingIdentity(ident); 9807 } 9808 } 9809 9810 return null; 9811 } 9812 9813 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9814 if (UserHandle.getUserId(callingUid) == userId) { 9815 return true; 9816 } 9817 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9818 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9819 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9820 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9821 return true; 9822 } 9823 return false; 9824 } 9825 9826 // ========================================================= 9827 // GLOBAL MANAGEMENT 9828 // ========================================================= 9829 9830 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9831 boolean isolated, int isolatedUid) { 9832 String proc = customProcess != null ? customProcess : info.processName; 9833 BatteryStatsImpl.Uid.Proc ps = null; 9834 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9835 int uid = info.uid; 9836 if (isolated) { 9837 if (isolatedUid == 0) { 9838 int userId = UserHandle.getUserId(uid); 9839 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9840 while (true) { 9841 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9842 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9843 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9844 } 9845 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9846 mNextIsolatedProcessUid++; 9847 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9848 // No process for this uid, use it. 9849 break; 9850 } 9851 stepsLeft--; 9852 if (stepsLeft <= 0) { 9853 return null; 9854 } 9855 } 9856 } else { 9857 // Special case for startIsolatedProcess (internal only), where 9858 // the uid of the isolated process is specified by the caller. 9859 uid = isolatedUid; 9860 } 9861 } 9862 return new ProcessRecord(stats, info, proc, uid); 9863 } 9864 9865 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9866 String abiOverride) { 9867 ProcessRecord app; 9868 if (!isolated) { 9869 app = getProcessRecordLocked(info.processName, info.uid, true); 9870 } else { 9871 app = null; 9872 } 9873 9874 if (app == null) { 9875 app = newProcessRecordLocked(info, null, isolated, 0); 9876 mProcessNames.put(info.processName, app.uid, app); 9877 if (isolated) { 9878 mIsolatedProcesses.put(app.uid, app); 9879 } 9880 updateLruProcessLocked(app, false, null); 9881 updateOomAdjLocked(); 9882 } 9883 9884 // This package really, really can not be stopped. 9885 try { 9886 AppGlobals.getPackageManager().setPackageStoppedState( 9887 info.packageName, false, UserHandle.getUserId(app.uid)); 9888 } catch (RemoteException e) { 9889 } catch (IllegalArgumentException e) { 9890 Slog.w(TAG, "Failed trying to unstop package " 9891 + info.packageName + ": " + e); 9892 } 9893 9894 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9895 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9896 app.persistent = true; 9897 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9898 } 9899 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9900 mPersistentStartingProcesses.add(app); 9901 startProcessLocked(app, "added application", app.processName, abiOverride, 9902 null /* entryPoint */, null /* entryPointArgs */); 9903 } 9904 9905 return app; 9906 } 9907 9908 public void unhandledBack() { 9909 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9910 "unhandledBack()"); 9911 9912 synchronized(this) { 9913 final long origId = Binder.clearCallingIdentity(); 9914 try { 9915 getFocusedStack().unhandledBackLocked(); 9916 } finally { 9917 Binder.restoreCallingIdentity(origId); 9918 } 9919 } 9920 } 9921 9922 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9923 enforceNotIsolatedCaller("openContentUri"); 9924 final int userId = UserHandle.getCallingUserId(); 9925 String name = uri.getAuthority(); 9926 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9927 ParcelFileDescriptor pfd = null; 9928 if (cph != null) { 9929 // We record the binder invoker's uid in thread-local storage before 9930 // going to the content provider to open the file. Later, in the code 9931 // that handles all permissions checks, we look for this uid and use 9932 // that rather than the Activity Manager's own uid. The effect is that 9933 // we do the check against the caller's permissions even though it looks 9934 // to the content provider like the Activity Manager itself is making 9935 // the request. 9936 sCallerIdentity.set(new Identity( 9937 Binder.getCallingPid(), Binder.getCallingUid())); 9938 try { 9939 pfd = cph.provider.openFile(null, uri, "r", null); 9940 } catch (FileNotFoundException e) { 9941 // do nothing; pfd will be returned null 9942 } finally { 9943 // Ensure that whatever happens, we clean up the identity state 9944 sCallerIdentity.remove(); 9945 } 9946 9947 // We've got the fd now, so we're done with the provider. 9948 removeContentProviderExternalUnchecked(name, null, userId); 9949 } else { 9950 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9951 } 9952 return pfd; 9953 } 9954 9955 // Actually is sleeping or shutting down or whatever else in the future 9956 // is an inactive state. 9957 public boolean isSleepingOrShuttingDown() { 9958 return isSleeping() || mShuttingDown; 9959 } 9960 9961 public boolean isSleeping() { 9962 return mSleeping && !mKeyguardWaitingForDraw; 9963 } 9964 9965 void goingToSleep() { 9966 synchronized(this) { 9967 mWentToSleep = true; 9968 updateEventDispatchingLocked(); 9969 goToSleepIfNeededLocked(); 9970 } 9971 } 9972 9973 void finishRunningVoiceLocked() { 9974 if (mRunningVoice) { 9975 mRunningVoice = false; 9976 goToSleepIfNeededLocked(); 9977 } 9978 } 9979 9980 void goToSleepIfNeededLocked() { 9981 if (mWentToSleep && !mRunningVoice) { 9982 if (!mSleeping) { 9983 mSleeping = true; 9984 mKeyguardWaitingForDraw = false; 9985 mStackSupervisor.goingToSleepLocked(); 9986 9987 // Initialize the wake times of all processes. 9988 checkExcessivePowerUsageLocked(false); 9989 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9990 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9991 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9992 } 9993 } 9994 } 9995 9996 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9997 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9998 // Never persist the home stack. 9999 return; 10000 } 10001 mTaskPersister.wakeup(task, flush); 10002 } 10003 10004 @Override 10005 public boolean shutdown(int timeout) { 10006 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10007 != PackageManager.PERMISSION_GRANTED) { 10008 throw new SecurityException("Requires permission " 10009 + android.Manifest.permission.SHUTDOWN); 10010 } 10011 10012 boolean timedout = false; 10013 10014 synchronized(this) { 10015 mShuttingDown = true; 10016 updateEventDispatchingLocked(); 10017 timedout = mStackSupervisor.shutdownLocked(timeout); 10018 } 10019 10020 mAppOpsService.shutdown(); 10021 if (mUsageStatsService != null) { 10022 mUsageStatsService.prepareShutdown(); 10023 } 10024 mBatteryStatsService.shutdown(); 10025 synchronized (this) { 10026 mProcessStats.shutdownLocked(); 10027 } 10028 notifyTaskPersisterLocked(null, true); 10029 10030 return timedout; 10031 } 10032 10033 public final void activitySlept(IBinder token) { 10034 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10035 10036 final long origId = Binder.clearCallingIdentity(); 10037 10038 synchronized (this) { 10039 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10040 if (r != null) { 10041 mStackSupervisor.activitySleptLocked(r); 10042 } 10043 } 10044 10045 Binder.restoreCallingIdentity(origId); 10046 } 10047 10048 void logLockScreen(String msg) { 10049 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10050 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10051 mWentToSleep + " mSleeping=" + mSleeping); 10052 } 10053 10054 private void comeOutOfSleepIfNeededLocked() { 10055 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10056 if (mSleeping) { 10057 mSleeping = false; 10058 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10059 } 10060 } 10061 } 10062 10063 void wakingUp() { 10064 synchronized(this) { 10065 mWentToSleep = false; 10066 updateEventDispatchingLocked(); 10067 comeOutOfSleepIfNeededLocked(); 10068 } 10069 } 10070 10071 void startRunningVoiceLocked() { 10072 if (!mRunningVoice) { 10073 mRunningVoice = true; 10074 comeOutOfSleepIfNeededLocked(); 10075 } 10076 } 10077 10078 private void updateEventDispatchingLocked() { 10079 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10080 } 10081 10082 public void setLockScreenShown(boolean shown) { 10083 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10084 != PackageManager.PERMISSION_GRANTED) { 10085 throw new SecurityException("Requires permission " 10086 + android.Manifest.permission.DEVICE_POWER); 10087 } 10088 10089 synchronized(this) { 10090 long ident = Binder.clearCallingIdentity(); 10091 try { 10092 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10093 mLockScreenShown = shown; 10094 mKeyguardWaitingForDraw = false; 10095 comeOutOfSleepIfNeededLocked(); 10096 } finally { 10097 Binder.restoreCallingIdentity(ident); 10098 } 10099 } 10100 } 10101 10102 @Override 10103 public void stopAppSwitches() { 10104 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10105 != PackageManager.PERMISSION_GRANTED) { 10106 throw new SecurityException("Requires permission " 10107 + android.Manifest.permission.STOP_APP_SWITCHES); 10108 } 10109 10110 synchronized(this) { 10111 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10112 + APP_SWITCH_DELAY_TIME; 10113 mDidAppSwitch = false; 10114 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10115 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10116 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10117 } 10118 } 10119 10120 public void resumeAppSwitches() { 10121 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10122 != PackageManager.PERMISSION_GRANTED) { 10123 throw new SecurityException("Requires permission " 10124 + android.Manifest.permission.STOP_APP_SWITCHES); 10125 } 10126 10127 synchronized(this) { 10128 // Note that we don't execute any pending app switches... we will 10129 // let those wait until either the timeout, or the next start 10130 // activity request. 10131 mAppSwitchesAllowedTime = 0; 10132 } 10133 } 10134 10135 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10136 int callingPid, int callingUid, String name) { 10137 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10138 return true; 10139 } 10140 10141 int perm = checkComponentPermission( 10142 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10143 sourceUid, -1, true); 10144 if (perm == PackageManager.PERMISSION_GRANTED) { 10145 return true; 10146 } 10147 10148 // If the actual IPC caller is different from the logical source, then 10149 // also see if they are allowed to control app switches. 10150 if (callingUid != -1 && callingUid != sourceUid) { 10151 perm = checkComponentPermission( 10152 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10153 callingUid, -1, true); 10154 if (perm == PackageManager.PERMISSION_GRANTED) { 10155 return true; 10156 } 10157 } 10158 10159 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10160 return false; 10161 } 10162 10163 public void setDebugApp(String packageName, boolean waitForDebugger, 10164 boolean persistent) { 10165 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10166 "setDebugApp()"); 10167 10168 long ident = Binder.clearCallingIdentity(); 10169 try { 10170 // Note that this is not really thread safe if there are multiple 10171 // callers into it at the same time, but that's not a situation we 10172 // care about. 10173 if (persistent) { 10174 final ContentResolver resolver = mContext.getContentResolver(); 10175 Settings.Global.putString( 10176 resolver, Settings.Global.DEBUG_APP, 10177 packageName); 10178 Settings.Global.putInt( 10179 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10180 waitForDebugger ? 1 : 0); 10181 } 10182 10183 synchronized (this) { 10184 if (!persistent) { 10185 mOrigDebugApp = mDebugApp; 10186 mOrigWaitForDebugger = mWaitForDebugger; 10187 } 10188 mDebugApp = packageName; 10189 mWaitForDebugger = waitForDebugger; 10190 mDebugTransient = !persistent; 10191 if (packageName != null) { 10192 forceStopPackageLocked(packageName, -1, false, false, true, true, 10193 false, UserHandle.USER_ALL, "set debug app"); 10194 } 10195 } 10196 } finally { 10197 Binder.restoreCallingIdentity(ident); 10198 } 10199 } 10200 10201 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10202 synchronized (this) { 10203 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10204 if (!isDebuggable) { 10205 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10206 throw new SecurityException("Process not debuggable: " + app.packageName); 10207 } 10208 } 10209 10210 mOpenGlTraceApp = processName; 10211 } 10212 } 10213 10214 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10215 synchronized (this) { 10216 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10217 if (!isDebuggable) { 10218 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10219 throw new SecurityException("Process not debuggable: " + app.packageName); 10220 } 10221 } 10222 mProfileApp = processName; 10223 mProfileFile = profilerInfo.profileFile; 10224 if (mProfileFd != null) { 10225 try { 10226 mProfileFd.close(); 10227 } catch (IOException e) { 10228 } 10229 mProfileFd = null; 10230 } 10231 mProfileFd = profilerInfo.profileFd; 10232 mSamplingInterval = profilerInfo.samplingInterval; 10233 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10234 mProfileType = 0; 10235 } 10236 } 10237 10238 @Override 10239 public void setAlwaysFinish(boolean enabled) { 10240 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10241 "setAlwaysFinish()"); 10242 10243 Settings.Global.putInt( 10244 mContext.getContentResolver(), 10245 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10246 10247 synchronized (this) { 10248 mAlwaysFinishActivities = enabled; 10249 } 10250 } 10251 10252 @Override 10253 public void setActivityController(IActivityController controller) { 10254 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10255 "setActivityController()"); 10256 synchronized (this) { 10257 mController = controller; 10258 Watchdog.getInstance().setActivityController(controller); 10259 } 10260 } 10261 10262 @Override 10263 public void setUserIsMonkey(boolean userIsMonkey) { 10264 synchronized (this) { 10265 synchronized (mPidsSelfLocked) { 10266 final int callingPid = Binder.getCallingPid(); 10267 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10268 if (precessRecord == null) { 10269 throw new SecurityException("Unknown process: " + callingPid); 10270 } 10271 if (precessRecord.instrumentationUiAutomationConnection == null) { 10272 throw new SecurityException("Only an instrumentation process " 10273 + "with a UiAutomation can call setUserIsMonkey"); 10274 } 10275 } 10276 mUserIsMonkey = userIsMonkey; 10277 } 10278 } 10279 10280 @Override 10281 public boolean isUserAMonkey() { 10282 synchronized (this) { 10283 // If there is a controller also implies the user is a monkey. 10284 return (mUserIsMonkey || mController != null); 10285 } 10286 } 10287 10288 public void requestBugReport() { 10289 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10290 SystemProperties.set("ctl.start", "bugreport"); 10291 } 10292 10293 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10294 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10295 } 10296 10297 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10298 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10299 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10300 } 10301 return KEY_DISPATCHING_TIMEOUT; 10302 } 10303 10304 @Override 10305 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10306 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10307 != PackageManager.PERMISSION_GRANTED) { 10308 throw new SecurityException("Requires permission " 10309 + android.Manifest.permission.FILTER_EVENTS); 10310 } 10311 ProcessRecord proc; 10312 long timeout; 10313 synchronized (this) { 10314 synchronized (mPidsSelfLocked) { 10315 proc = mPidsSelfLocked.get(pid); 10316 } 10317 timeout = getInputDispatchingTimeoutLocked(proc); 10318 } 10319 10320 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10321 return -1; 10322 } 10323 10324 return timeout; 10325 } 10326 10327 /** 10328 * Handle input dispatching timeouts. 10329 * Returns whether input dispatching should be aborted or not. 10330 */ 10331 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10332 final ActivityRecord activity, final ActivityRecord parent, 10333 final boolean aboveSystem, String reason) { 10334 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10335 != PackageManager.PERMISSION_GRANTED) { 10336 throw new SecurityException("Requires permission " 10337 + android.Manifest.permission.FILTER_EVENTS); 10338 } 10339 10340 final String annotation; 10341 if (reason == null) { 10342 annotation = "Input dispatching timed out"; 10343 } else { 10344 annotation = "Input dispatching timed out (" + reason + ")"; 10345 } 10346 10347 if (proc != null) { 10348 synchronized (this) { 10349 if (proc.debugging) { 10350 return false; 10351 } 10352 10353 if (mDidDexOpt) { 10354 // Give more time since we were dexopting. 10355 mDidDexOpt = false; 10356 return false; 10357 } 10358 10359 if (proc.instrumentationClass != null) { 10360 Bundle info = new Bundle(); 10361 info.putString("shortMsg", "keyDispatchingTimedOut"); 10362 info.putString("longMsg", annotation); 10363 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10364 return true; 10365 } 10366 } 10367 mHandler.post(new Runnable() { 10368 @Override 10369 public void run() { 10370 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10371 } 10372 }); 10373 } 10374 10375 return true; 10376 } 10377 10378 public Bundle getAssistContextExtras(int requestType) { 10379 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10380 "getAssistContextExtras()"); 10381 PendingAssistExtras pae; 10382 Bundle extras = new Bundle(); 10383 synchronized (this) { 10384 ActivityRecord activity = getFocusedStack().mResumedActivity; 10385 if (activity == null) { 10386 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10387 return null; 10388 } 10389 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10390 if (activity.app == null || activity.app.thread == null) { 10391 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10392 return extras; 10393 } 10394 if (activity.app.pid == Binder.getCallingPid()) { 10395 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10396 return extras; 10397 } 10398 pae = new PendingAssistExtras(activity); 10399 try { 10400 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10401 requestType); 10402 mPendingAssistExtras.add(pae); 10403 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10404 } catch (RemoteException e) { 10405 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10406 return extras; 10407 } 10408 } 10409 synchronized (pae) { 10410 while (!pae.haveResult) { 10411 try { 10412 pae.wait(); 10413 } catch (InterruptedException e) { 10414 } 10415 } 10416 if (pae.result != null) { 10417 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10418 } 10419 } 10420 synchronized (this) { 10421 mPendingAssistExtras.remove(pae); 10422 mHandler.removeCallbacks(pae); 10423 } 10424 return extras; 10425 } 10426 10427 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10428 PendingAssistExtras pae = (PendingAssistExtras)token; 10429 synchronized (pae) { 10430 pae.result = extras; 10431 pae.haveResult = true; 10432 pae.notifyAll(); 10433 } 10434 } 10435 10436 public void registerProcessObserver(IProcessObserver observer) { 10437 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10438 "registerProcessObserver()"); 10439 synchronized (this) { 10440 mProcessObservers.register(observer); 10441 } 10442 } 10443 10444 @Override 10445 public void unregisterProcessObserver(IProcessObserver observer) { 10446 synchronized (this) { 10447 mProcessObservers.unregister(observer); 10448 } 10449 } 10450 10451 @Override 10452 public boolean convertFromTranslucent(IBinder token) { 10453 final long origId = Binder.clearCallingIdentity(); 10454 try { 10455 synchronized (this) { 10456 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10457 if (r == null) { 10458 return false; 10459 } 10460 final boolean translucentChanged = r.changeWindowTranslucency(true); 10461 if (translucentChanged) { 10462 r.task.stack.releaseBackgroundResources(); 10463 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10464 } 10465 mWindowManager.setAppFullscreen(token, true); 10466 return translucentChanged; 10467 } 10468 } finally { 10469 Binder.restoreCallingIdentity(origId); 10470 } 10471 } 10472 10473 @Override 10474 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10475 final long origId = Binder.clearCallingIdentity(); 10476 try { 10477 synchronized (this) { 10478 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10479 if (r == null) { 10480 return false; 10481 } 10482 int index = r.task.mActivities.lastIndexOf(r); 10483 if (index > 0) { 10484 ActivityRecord under = r.task.mActivities.get(index - 1); 10485 under.returningOptions = options; 10486 } 10487 final boolean translucentChanged = r.changeWindowTranslucency(false); 10488 if (translucentChanged) { 10489 r.task.stack.convertToTranslucent(r); 10490 } 10491 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10492 mWindowManager.setAppFullscreen(token, false); 10493 return translucentChanged; 10494 } 10495 } finally { 10496 Binder.restoreCallingIdentity(origId); 10497 } 10498 } 10499 10500 @Override 10501 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10502 final long origId = Binder.clearCallingIdentity(); 10503 try { 10504 synchronized (this) { 10505 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10506 if (r != null) { 10507 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10508 } 10509 } 10510 return false; 10511 } finally { 10512 Binder.restoreCallingIdentity(origId); 10513 } 10514 } 10515 10516 @Override 10517 public boolean isBackgroundVisibleBehind(IBinder token) { 10518 final long origId = Binder.clearCallingIdentity(); 10519 try { 10520 synchronized (this) { 10521 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10522 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10523 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10524 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10525 return visible; 10526 } 10527 } finally { 10528 Binder.restoreCallingIdentity(origId); 10529 } 10530 } 10531 10532 @Override 10533 public ActivityOptions getActivityOptions(IBinder token) { 10534 final long origId = Binder.clearCallingIdentity(); 10535 try { 10536 synchronized (this) { 10537 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10538 if (r != null) { 10539 final ActivityOptions activityOptions = r.pendingOptions; 10540 r.pendingOptions = null; 10541 return activityOptions; 10542 } 10543 return null; 10544 } 10545 } finally { 10546 Binder.restoreCallingIdentity(origId); 10547 } 10548 } 10549 10550 @Override 10551 public void setImmersive(IBinder token, boolean immersive) { 10552 synchronized(this) { 10553 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10554 if (r == null) { 10555 throw new IllegalArgumentException(); 10556 } 10557 r.immersive = immersive; 10558 10559 // update associated state if we're frontmost 10560 if (r == mFocusedActivity) { 10561 if (DEBUG_IMMERSIVE) { 10562 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10563 } 10564 applyUpdateLockStateLocked(r); 10565 } 10566 } 10567 } 10568 10569 @Override 10570 public boolean isImmersive(IBinder token) { 10571 synchronized (this) { 10572 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10573 if (r == null) { 10574 throw new IllegalArgumentException(); 10575 } 10576 return r.immersive; 10577 } 10578 } 10579 10580 public boolean isTopActivityImmersive() { 10581 enforceNotIsolatedCaller("startActivity"); 10582 synchronized (this) { 10583 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10584 return (r != null) ? r.immersive : false; 10585 } 10586 } 10587 10588 @Override 10589 public boolean isTopOfTask(IBinder token) { 10590 synchronized (this) { 10591 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10592 if (r == null) { 10593 throw new IllegalArgumentException(); 10594 } 10595 return r.task.getTopActivity() == r; 10596 } 10597 } 10598 10599 public final void enterSafeMode() { 10600 synchronized(this) { 10601 // It only makes sense to do this before the system is ready 10602 // and started launching other packages. 10603 if (!mSystemReady) { 10604 try { 10605 AppGlobals.getPackageManager().enterSafeMode(); 10606 } catch (RemoteException e) { 10607 } 10608 } 10609 10610 mSafeMode = true; 10611 } 10612 } 10613 10614 public final void showSafeModeOverlay() { 10615 View v = LayoutInflater.from(mContext).inflate( 10616 com.android.internal.R.layout.safe_mode, null); 10617 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10618 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10619 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10620 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10621 lp.gravity = Gravity.BOTTOM | Gravity.START; 10622 lp.format = v.getBackground().getOpacity(); 10623 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10624 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10625 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10626 ((WindowManager)mContext.getSystemService( 10627 Context.WINDOW_SERVICE)).addView(v, lp); 10628 } 10629 10630 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10631 if (!(sender instanceof PendingIntentRecord)) { 10632 return; 10633 } 10634 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10635 synchronized (stats) { 10636 if (mBatteryStatsService.isOnBattery()) { 10637 mBatteryStatsService.enforceCallingPermission(); 10638 PendingIntentRecord rec = (PendingIntentRecord)sender; 10639 int MY_UID = Binder.getCallingUid(); 10640 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10641 BatteryStatsImpl.Uid.Pkg pkg = 10642 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10643 sourcePkg != null ? sourcePkg : rec.key.packageName); 10644 pkg.incWakeupsLocked(); 10645 } 10646 } 10647 } 10648 10649 public boolean killPids(int[] pids, String pReason, boolean secure) { 10650 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10651 throw new SecurityException("killPids only available to the system"); 10652 } 10653 String reason = (pReason == null) ? "Unknown" : pReason; 10654 // XXX Note: don't acquire main activity lock here, because the window 10655 // manager calls in with its locks held. 10656 10657 boolean killed = false; 10658 synchronized (mPidsSelfLocked) { 10659 int[] types = new int[pids.length]; 10660 int worstType = 0; 10661 for (int i=0; i<pids.length; i++) { 10662 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10663 if (proc != null) { 10664 int type = proc.setAdj; 10665 types[i] = type; 10666 if (type > worstType) { 10667 worstType = type; 10668 } 10669 } 10670 } 10671 10672 // If the worst oom_adj is somewhere in the cached proc LRU range, 10673 // then constrain it so we will kill all cached procs. 10674 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10675 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10676 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10677 } 10678 10679 // If this is not a secure call, don't let it kill processes that 10680 // are important. 10681 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10682 worstType = ProcessList.SERVICE_ADJ; 10683 } 10684 10685 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10686 for (int i=0; i<pids.length; i++) { 10687 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10688 if (proc == null) { 10689 continue; 10690 } 10691 int adj = proc.setAdj; 10692 if (adj >= worstType && !proc.killedByAm) { 10693 proc.kill(reason, true); 10694 killed = true; 10695 } 10696 } 10697 } 10698 return killed; 10699 } 10700 10701 @Override 10702 public void killUid(int uid, String reason) { 10703 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10704 throw new SecurityException("killUid only available to the system"); 10705 } 10706 synchronized (this) { 10707 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10708 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10709 reason != null ? reason : "kill uid"); 10710 } 10711 } 10712 10713 @Override 10714 public boolean killProcessesBelowForeground(String reason) { 10715 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10716 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10717 } 10718 10719 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10720 } 10721 10722 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10723 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10724 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10725 } 10726 10727 boolean killed = false; 10728 synchronized (mPidsSelfLocked) { 10729 final int size = mPidsSelfLocked.size(); 10730 for (int i = 0; i < size; i++) { 10731 final int pid = mPidsSelfLocked.keyAt(i); 10732 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10733 if (proc == null) continue; 10734 10735 final int adj = proc.setAdj; 10736 if (adj > belowAdj && !proc.killedByAm) { 10737 proc.kill(reason, true); 10738 killed = true; 10739 } 10740 } 10741 } 10742 return killed; 10743 } 10744 10745 @Override 10746 public void hang(final IBinder who, boolean allowRestart) { 10747 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10748 != PackageManager.PERMISSION_GRANTED) { 10749 throw new SecurityException("Requires permission " 10750 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10751 } 10752 10753 final IBinder.DeathRecipient death = new DeathRecipient() { 10754 @Override 10755 public void binderDied() { 10756 synchronized (this) { 10757 notifyAll(); 10758 } 10759 } 10760 }; 10761 10762 try { 10763 who.linkToDeath(death, 0); 10764 } catch (RemoteException e) { 10765 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10766 return; 10767 } 10768 10769 synchronized (this) { 10770 Watchdog.getInstance().setAllowRestart(allowRestart); 10771 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10772 synchronized (death) { 10773 while (who.isBinderAlive()) { 10774 try { 10775 death.wait(); 10776 } catch (InterruptedException e) { 10777 } 10778 } 10779 } 10780 Watchdog.getInstance().setAllowRestart(true); 10781 } 10782 } 10783 10784 @Override 10785 public void restart() { 10786 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10787 != PackageManager.PERMISSION_GRANTED) { 10788 throw new SecurityException("Requires permission " 10789 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10790 } 10791 10792 Log.i(TAG, "Sending shutdown broadcast..."); 10793 10794 BroadcastReceiver br = new BroadcastReceiver() { 10795 @Override public void onReceive(Context context, Intent intent) { 10796 // Now the broadcast is done, finish up the low-level shutdown. 10797 Log.i(TAG, "Shutting down activity manager..."); 10798 shutdown(10000); 10799 Log.i(TAG, "Shutdown complete, restarting!"); 10800 Process.killProcess(Process.myPid()); 10801 System.exit(10); 10802 } 10803 }; 10804 10805 // First send the high-level shut down broadcast. 10806 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10807 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10808 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10809 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10810 mContext.sendOrderedBroadcastAsUser(intent, 10811 UserHandle.ALL, null, br, mHandler, 0, null, null); 10812 */ 10813 br.onReceive(mContext, intent); 10814 } 10815 10816 private long getLowRamTimeSinceIdle(long now) { 10817 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10818 } 10819 10820 @Override 10821 public void performIdleMaintenance() { 10822 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10823 != PackageManager.PERMISSION_GRANTED) { 10824 throw new SecurityException("Requires permission " 10825 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10826 } 10827 10828 synchronized (this) { 10829 final long now = SystemClock.uptimeMillis(); 10830 final long timeSinceLastIdle = now - mLastIdleTime; 10831 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10832 mLastIdleTime = now; 10833 mLowRamTimeSinceLastIdle = 0; 10834 if (mLowRamStartTime != 0) { 10835 mLowRamStartTime = now; 10836 } 10837 10838 StringBuilder sb = new StringBuilder(128); 10839 sb.append("Idle maintenance over "); 10840 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10841 sb.append(" low RAM for "); 10842 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10843 Slog.i(TAG, sb.toString()); 10844 10845 // If at least 1/3 of our time since the last idle period has been spent 10846 // with RAM low, then we want to kill processes. 10847 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10848 10849 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10850 ProcessRecord proc = mLruProcesses.get(i); 10851 if (proc.notCachedSinceIdle) { 10852 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10853 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10854 if (doKilling && proc.initialIdlePss != 0 10855 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10856 proc.kill("idle maint (pss " + proc.lastPss 10857 + " from " + proc.initialIdlePss + ")", true); 10858 } 10859 } 10860 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10861 proc.notCachedSinceIdle = true; 10862 proc.initialIdlePss = 0; 10863 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10864 isSleeping(), now); 10865 } 10866 } 10867 10868 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10869 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10870 } 10871 } 10872 10873 private void retrieveSettings() { 10874 final ContentResolver resolver = mContext.getContentResolver(); 10875 String debugApp = Settings.Global.getString( 10876 resolver, Settings.Global.DEBUG_APP); 10877 boolean waitForDebugger = Settings.Global.getInt( 10878 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10879 boolean alwaysFinishActivities = Settings.Global.getInt( 10880 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10881 boolean forceRtl = Settings.Global.getInt( 10882 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10883 // Transfer any global setting for forcing RTL layout, into a System Property 10884 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10885 10886 Configuration configuration = new Configuration(); 10887 Settings.System.getConfiguration(resolver, configuration); 10888 if (forceRtl) { 10889 // This will take care of setting the correct layout direction flags 10890 configuration.setLayoutDirection(configuration.locale); 10891 } 10892 10893 synchronized (this) { 10894 mDebugApp = mOrigDebugApp = debugApp; 10895 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10896 mAlwaysFinishActivities = alwaysFinishActivities; 10897 // This happens before any activities are started, so we can 10898 // change mConfiguration in-place. 10899 updateConfigurationLocked(configuration, null, false, true); 10900 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10901 } 10902 } 10903 10904 /** Loads resources after the current configuration has been set. */ 10905 private void loadResourcesOnSystemReady() { 10906 final Resources res = mContext.getResources(); 10907 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10908 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10909 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10910 } 10911 10912 public boolean testIsSystemReady() { 10913 // no need to synchronize(this) just to read & return the value 10914 return mSystemReady; 10915 } 10916 10917 private static File getCalledPreBootReceiversFile() { 10918 File dataDir = Environment.getDataDirectory(); 10919 File systemDir = new File(dataDir, "system"); 10920 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10921 return fname; 10922 } 10923 10924 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10925 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10926 File file = getCalledPreBootReceiversFile(); 10927 FileInputStream fis = null; 10928 try { 10929 fis = new FileInputStream(file); 10930 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10931 int fvers = dis.readInt(); 10932 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10933 String vers = dis.readUTF(); 10934 String codename = dis.readUTF(); 10935 String build = dis.readUTF(); 10936 if (android.os.Build.VERSION.RELEASE.equals(vers) 10937 && android.os.Build.VERSION.CODENAME.equals(codename) 10938 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10939 int num = dis.readInt(); 10940 while (num > 0) { 10941 num--; 10942 String pkg = dis.readUTF(); 10943 String cls = dis.readUTF(); 10944 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10945 } 10946 } 10947 } 10948 } catch (FileNotFoundException e) { 10949 } catch (IOException e) { 10950 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10951 } finally { 10952 if (fis != null) { 10953 try { 10954 fis.close(); 10955 } catch (IOException e) { 10956 } 10957 } 10958 } 10959 return lastDoneReceivers; 10960 } 10961 10962 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10963 File file = getCalledPreBootReceiversFile(); 10964 FileOutputStream fos = null; 10965 DataOutputStream dos = null; 10966 try { 10967 fos = new FileOutputStream(file); 10968 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10969 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10970 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10971 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10972 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10973 dos.writeInt(list.size()); 10974 for (int i=0; i<list.size(); i++) { 10975 dos.writeUTF(list.get(i).getPackageName()); 10976 dos.writeUTF(list.get(i).getClassName()); 10977 } 10978 } catch (IOException e) { 10979 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10980 file.delete(); 10981 } finally { 10982 FileUtils.sync(fos); 10983 if (dos != null) { 10984 try { 10985 dos.close(); 10986 } catch (IOException e) { 10987 // TODO Auto-generated catch block 10988 e.printStackTrace(); 10989 } 10990 } 10991 } 10992 } 10993 10994 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10995 ArrayList<ComponentName> doneReceivers, int userId) { 10996 boolean waitingUpdate = false; 10997 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10998 List<ResolveInfo> ris = null; 10999 try { 11000 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11001 intent, null, 0, userId); 11002 } catch (RemoteException e) { 11003 } 11004 if (ris != null) { 11005 for (int i=ris.size()-1; i>=0; i--) { 11006 if ((ris.get(i).activityInfo.applicationInfo.flags 11007 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11008 ris.remove(i); 11009 } 11010 } 11011 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11012 11013 // For User 0, load the version number. When delivering to a new user, deliver 11014 // to all receivers. 11015 if (userId == UserHandle.USER_OWNER) { 11016 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11017 for (int i=0; i<ris.size(); i++) { 11018 ActivityInfo ai = ris.get(i).activityInfo; 11019 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11020 if (lastDoneReceivers.contains(comp)) { 11021 // We already did the pre boot receiver for this app with the current 11022 // platform version, so don't do it again... 11023 ris.remove(i); 11024 i--; 11025 // ...however, do keep it as one that has been done, so we don't 11026 // forget about it when rewriting the file of last done receivers. 11027 doneReceivers.add(comp); 11028 } 11029 } 11030 } 11031 11032 // If primary user, send broadcast to all available users, else just to userId 11033 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11034 : new int[] { userId }; 11035 for (int i = 0; i < ris.size(); i++) { 11036 ActivityInfo ai = ris.get(i).activityInfo; 11037 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11038 doneReceivers.add(comp); 11039 intent.setComponent(comp); 11040 for (int j=0; j<users.length; j++) { 11041 IIntentReceiver finisher = null; 11042 // On last receiver and user, set up a completion callback 11043 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11044 finisher = new IIntentReceiver.Stub() { 11045 public void performReceive(Intent intent, int resultCode, 11046 String data, Bundle extras, boolean ordered, 11047 boolean sticky, int sendingUser) { 11048 // The raw IIntentReceiver interface is called 11049 // with the AM lock held, so redispatch to 11050 // execute our code without the lock. 11051 mHandler.post(onFinishCallback); 11052 } 11053 }; 11054 } 11055 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11056 + " for user " + users[j]); 11057 broadcastIntentLocked(null, null, intent, null, finisher, 11058 0, null, null, null, AppOpsManager.OP_NONE, 11059 true, false, MY_PID, Process.SYSTEM_UID, 11060 users[j]); 11061 if (finisher != null) { 11062 waitingUpdate = true; 11063 } 11064 } 11065 } 11066 } 11067 11068 return waitingUpdate; 11069 } 11070 11071 public void systemReady(final Runnable goingCallback) { 11072 synchronized(this) { 11073 if (mSystemReady) { 11074 // If we're done calling all the receivers, run the next "boot phase" passed in 11075 // by the SystemServer 11076 if (goingCallback != null) { 11077 goingCallback.run(); 11078 } 11079 return; 11080 } 11081 11082 // Make sure we have the current profile info, since it is needed for 11083 // security checks. 11084 updateCurrentProfileIdsLocked(); 11085 11086 if (mRecentTasks == null) { 11087 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11088 if (!mRecentTasks.isEmpty()) { 11089 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11090 } 11091 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11092 mTaskPersister.startPersisting(); 11093 } 11094 11095 // Check to see if there are any update receivers to run. 11096 if (!mDidUpdate) { 11097 if (mWaitingUpdate) { 11098 return; 11099 } 11100 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11101 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11102 public void run() { 11103 synchronized (ActivityManagerService.this) { 11104 mDidUpdate = true; 11105 } 11106 writeLastDonePreBootReceivers(doneReceivers); 11107 showBootMessage(mContext.getText( 11108 R.string.android_upgrading_complete), 11109 false); 11110 systemReady(goingCallback); 11111 } 11112 }, doneReceivers, UserHandle.USER_OWNER); 11113 11114 if (mWaitingUpdate) { 11115 return; 11116 } 11117 mDidUpdate = true; 11118 } 11119 11120 mAppOpsService.systemReady(); 11121 mSystemReady = true; 11122 } 11123 11124 ArrayList<ProcessRecord> procsToKill = null; 11125 synchronized(mPidsSelfLocked) { 11126 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11127 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11128 if (!isAllowedWhileBooting(proc.info)){ 11129 if (procsToKill == null) { 11130 procsToKill = new ArrayList<ProcessRecord>(); 11131 } 11132 procsToKill.add(proc); 11133 } 11134 } 11135 } 11136 11137 synchronized(this) { 11138 if (procsToKill != null) { 11139 for (int i=procsToKill.size()-1; i>=0; i--) { 11140 ProcessRecord proc = procsToKill.get(i); 11141 Slog.i(TAG, "Removing system update proc: " + proc); 11142 removeProcessLocked(proc, true, false, "system update done"); 11143 } 11144 } 11145 11146 // Now that we have cleaned up any update processes, we 11147 // are ready to start launching real processes and know that 11148 // we won't trample on them any more. 11149 mProcessesReady = true; 11150 } 11151 11152 Slog.i(TAG, "System now ready"); 11153 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11154 SystemClock.uptimeMillis()); 11155 11156 synchronized(this) { 11157 // Make sure we have no pre-ready processes sitting around. 11158 11159 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11160 ResolveInfo ri = mContext.getPackageManager() 11161 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11162 STOCK_PM_FLAGS); 11163 CharSequence errorMsg = null; 11164 if (ri != null) { 11165 ActivityInfo ai = ri.activityInfo; 11166 ApplicationInfo app = ai.applicationInfo; 11167 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11168 mTopAction = Intent.ACTION_FACTORY_TEST; 11169 mTopData = null; 11170 mTopComponent = new ComponentName(app.packageName, 11171 ai.name); 11172 } else { 11173 errorMsg = mContext.getResources().getText( 11174 com.android.internal.R.string.factorytest_not_system); 11175 } 11176 } else { 11177 errorMsg = mContext.getResources().getText( 11178 com.android.internal.R.string.factorytest_no_action); 11179 } 11180 if (errorMsg != null) { 11181 mTopAction = null; 11182 mTopData = null; 11183 mTopComponent = null; 11184 Message msg = Message.obtain(); 11185 msg.what = SHOW_FACTORY_ERROR_MSG; 11186 msg.getData().putCharSequence("msg", errorMsg); 11187 mHandler.sendMessage(msg); 11188 } 11189 } 11190 } 11191 11192 retrieveSettings(); 11193 loadResourcesOnSystemReady(); 11194 11195 synchronized (this) { 11196 readGrantedUriPermissionsLocked(); 11197 } 11198 11199 if (goingCallback != null) goingCallback.run(); 11200 11201 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11202 Integer.toString(mCurrentUserId), mCurrentUserId); 11203 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11204 Integer.toString(mCurrentUserId), mCurrentUserId); 11205 mSystemServiceManager.startUser(mCurrentUserId); 11206 11207 synchronized (this) { 11208 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11209 try { 11210 List apps = AppGlobals.getPackageManager(). 11211 getPersistentApplications(STOCK_PM_FLAGS); 11212 if (apps != null) { 11213 int N = apps.size(); 11214 int i; 11215 for (i=0; i<N; i++) { 11216 ApplicationInfo info 11217 = (ApplicationInfo)apps.get(i); 11218 if (info != null && 11219 !info.packageName.equals("android")) { 11220 addAppLocked(info, false, null /* ABI override */); 11221 } 11222 } 11223 } 11224 } catch (RemoteException ex) { 11225 // pm is in same process, this will never happen. 11226 } 11227 } 11228 11229 // Start up initial activity. 11230 mBooting = true; 11231 11232 try { 11233 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11234 Message msg = Message.obtain(); 11235 msg.what = SHOW_UID_ERROR_MSG; 11236 mHandler.sendMessage(msg); 11237 } 11238 } catch (RemoteException e) { 11239 } 11240 11241 long ident = Binder.clearCallingIdentity(); 11242 try { 11243 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11245 | Intent.FLAG_RECEIVER_FOREGROUND); 11246 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11247 broadcastIntentLocked(null, null, intent, 11248 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11249 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11250 intent = new Intent(Intent.ACTION_USER_STARTING); 11251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11252 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11253 broadcastIntentLocked(null, null, intent, 11254 null, new IIntentReceiver.Stub() { 11255 @Override 11256 public void performReceive(Intent intent, int resultCode, String data, 11257 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11258 throws RemoteException { 11259 } 11260 }, 0, null, null, 11261 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11262 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11263 } catch (Throwable t) { 11264 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11265 } finally { 11266 Binder.restoreCallingIdentity(ident); 11267 } 11268 mStackSupervisor.resumeTopActivitiesLocked(); 11269 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11270 } 11271 } 11272 11273 private boolean makeAppCrashingLocked(ProcessRecord app, 11274 String shortMsg, String longMsg, String stackTrace) { 11275 app.crashing = true; 11276 app.crashingReport = generateProcessError(app, 11277 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11278 startAppProblemLocked(app); 11279 app.stopFreezingAllLocked(); 11280 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11281 } 11282 11283 private void makeAppNotRespondingLocked(ProcessRecord app, 11284 String activity, String shortMsg, String longMsg) { 11285 app.notResponding = true; 11286 app.notRespondingReport = generateProcessError(app, 11287 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11288 activity, shortMsg, longMsg, null); 11289 startAppProblemLocked(app); 11290 app.stopFreezingAllLocked(); 11291 } 11292 11293 /** 11294 * Generate a process error record, suitable for attachment to a ProcessRecord. 11295 * 11296 * @param app The ProcessRecord in which the error occurred. 11297 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11298 * ActivityManager.AppErrorStateInfo 11299 * @param activity The activity associated with the crash, if known. 11300 * @param shortMsg Short message describing the crash. 11301 * @param longMsg Long message describing the crash. 11302 * @param stackTrace Full crash stack trace, may be null. 11303 * 11304 * @return Returns a fully-formed AppErrorStateInfo record. 11305 */ 11306 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11307 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11308 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11309 11310 report.condition = condition; 11311 report.processName = app.processName; 11312 report.pid = app.pid; 11313 report.uid = app.info.uid; 11314 report.tag = activity; 11315 report.shortMsg = shortMsg; 11316 report.longMsg = longMsg; 11317 report.stackTrace = stackTrace; 11318 11319 return report; 11320 } 11321 11322 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11323 synchronized (this) { 11324 app.crashing = false; 11325 app.crashingReport = null; 11326 app.notResponding = false; 11327 app.notRespondingReport = null; 11328 if (app.anrDialog == fromDialog) { 11329 app.anrDialog = null; 11330 } 11331 if (app.waitDialog == fromDialog) { 11332 app.waitDialog = null; 11333 } 11334 if (app.pid > 0 && app.pid != MY_PID) { 11335 handleAppCrashLocked(app, null, null, null); 11336 app.kill("user request after error", true); 11337 } 11338 } 11339 } 11340 11341 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11342 String stackTrace) { 11343 long now = SystemClock.uptimeMillis(); 11344 11345 Long crashTime; 11346 if (!app.isolated) { 11347 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11348 } else { 11349 crashTime = null; 11350 } 11351 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11352 // This process loses! 11353 Slog.w(TAG, "Process " + app.info.processName 11354 + " has crashed too many times: killing!"); 11355 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11356 app.userId, app.info.processName, app.uid); 11357 mStackSupervisor.handleAppCrashLocked(app); 11358 if (!app.persistent) { 11359 // We don't want to start this process again until the user 11360 // explicitly does so... but for persistent process, we really 11361 // need to keep it running. If a persistent process is actually 11362 // repeatedly crashing, then badness for everyone. 11363 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11364 app.info.processName); 11365 if (!app.isolated) { 11366 // XXX We don't have a way to mark isolated processes 11367 // as bad, since they don't have a peristent identity. 11368 mBadProcesses.put(app.info.processName, app.uid, 11369 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11370 mProcessCrashTimes.remove(app.info.processName, app.uid); 11371 } 11372 app.bad = true; 11373 app.removed = true; 11374 // Don't let services in this process be restarted and potentially 11375 // annoy the user repeatedly. Unless it is persistent, since those 11376 // processes run critical code. 11377 removeProcessLocked(app, false, false, "crash"); 11378 mStackSupervisor.resumeTopActivitiesLocked(); 11379 return false; 11380 } 11381 mStackSupervisor.resumeTopActivitiesLocked(); 11382 } else { 11383 mStackSupervisor.finishTopRunningActivityLocked(app); 11384 } 11385 11386 // Bump up the crash count of any services currently running in the proc. 11387 for (int i=app.services.size()-1; i>=0; i--) { 11388 // Any services running in the application need to be placed 11389 // back in the pending list. 11390 ServiceRecord sr = app.services.valueAt(i); 11391 sr.crashCount++; 11392 } 11393 11394 // If the crashing process is what we consider to be the "home process" and it has been 11395 // replaced by a third-party app, clear the package preferred activities from packages 11396 // with a home activity running in the process to prevent a repeatedly crashing app 11397 // from blocking the user to manually clear the list. 11398 final ArrayList<ActivityRecord> activities = app.activities; 11399 if (app == mHomeProcess && activities.size() > 0 11400 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11401 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11402 final ActivityRecord r = activities.get(activityNdx); 11403 if (r.isHomeActivity()) { 11404 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11405 try { 11406 ActivityThread.getPackageManager() 11407 .clearPackagePreferredActivities(r.packageName); 11408 } catch (RemoteException c) { 11409 // pm is in same process, this will never happen. 11410 } 11411 } 11412 } 11413 } 11414 11415 if (!app.isolated) { 11416 // XXX Can't keep track of crash times for isolated processes, 11417 // because they don't have a perisistent identity. 11418 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11419 } 11420 11421 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11422 return true; 11423 } 11424 11425 void startAppProblemLocked(ProcessRecord app) { 11426 // If this app is not running under the current user, then we 11427 // can't give it a report button because that would require 11428 // launching the report UI under a different user. 11429 app.errorReportReceiver = null; 11430 11431 for (int userId : mCurrentProfileIds) { 11432 if (app.userId == userId) { 11433 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11434 mContext, app.info.packageName, app.info.flags); 11435 } 11436 } 11437 skipCurrentReceiverLocked(app); 11438 } 11439 11440 void skipCurrentReceiverLocked(ProcessRecord app) { 11441 for (BroadcastQueue queue : mBroadcastQueues) { 11442 queue.skipCurrentReceiverLocked(app); 11443 } 11444 } 11445 11446 /** 11447 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11448 * The application process will exit immediately after this call returns. 11449 * @param app object of the crashing app, null for the system server 11450 * @param crashInfo describing the exception 11451 */ 11452 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11453 ProcessRecord r = findAppProcess(app, "Crash"); 11454 final String processName = app == null ? "system_server" 11455 : (r == null ? "unknown" : r.processName); 11456 11457 handleApplicationCrashInner("crash", r, processName, crashInfo); 11458 } 11459 11460 /* Native crash reporting uses this inner version because it needs to be somewhat 11461 * decoupled from the AM-managed cleanup lifecycle 11462 */ 11463 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11464 ApplicationErrorReport.CrashInfo crashInfo) { 11465 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11466 UserHandle.getUserId(Binder.getCallingUid()), processName, 11467 r == null ? -1 : r.info.flags, 11468 crashInfo.exceptionClassName, 11469 crashInfo.exceptionMessage, 11470 crashInfo.throwFileName, 11471 crashInfo.throwLineNumber); 11472 11473 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11474 11475 crashApplication(r, crashInfo); 11476 } 11477 11478 public void handleApplicationStrictModeViolation( 11479 IBinder app, 11480 int violationMask, 11481 StrictMode.ViolationInfo info) { 11482 ProcessRecord r = findAppProcess(app, "StrictMode"); 11483 if (r == null) { 11484 return; 11485 } 11486 11487 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11488 Integer stackFingerprint = info.hashCode(); 11489 boolean logIt = true; 11490 synchronized (mAlreadyLoggedViolatedStacks) { 11491 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11492 logIt = false; 11493 // TODO: sub-sample into EventLog for these, with 11494 // the info.durationMillis? Then we'd get 11495 // the relative pain numbers, without logging all 11496 // the stack traces repeatedly. We'd want to do 11497 // likewise in the client code, which also does 11498 // dup suppression, before the Binder call. 11499 } else { 11500 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11501 mAlreadyLoggedViolatedStacks.clear(); 11502 } 11503 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11504 } 11505 } 11506 if (logIt) { 11507 logStrictModeViolationToDropBox(r, info); 11508 } 11509 } 11510 11511 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11512 AppErrorResult result = new AppErrorResult(); 11513 synchronized (this) { 11514 final long origId = Binder.clearCallingIdentity(); 11515 11516 Message msg = Message.obtain(); 11517 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11518 HashMap<String, Object> data = new HashMap<String, Object>(); 11519 data.put("result", result); 11520 data.put("app", r); 11521 data.put("violationMask", violationMask); 11522 data.put("info", info); 11523 msg.obj = data; 11524 mHandler.sendMessage(msg); 11525 11526 Binder.restoreCallingIdentity(origId); 11527 } 11528 int res = result.get(); 11529 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11530 } 11531 } 11532 11533 // Depending on the policy in effect, there could be a bunch of 11534 // these in quick succession so we try to batch these together to 11535 // minimize disk writes, number of dropbox entries, and maximize 11536 // compression, by having more fewer, larger records. 11537 private void logStrictModeViolationToDropBox( 11538 ProcessRecord process, 11539 StrictMode.ViolationInfo info) { 11540 if (info == null) { 11541 return; 11542 } 11543 final boolean isSystemApp = process == null || 11544 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11545 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11546 final String processName = process == null ? "unknown" : process.processName; 11547 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11548 final DropBoxManager dbox = (DropBoxManager) 11549 mContext.getSystemService(Context.DROPBOX_SERVICE); 11550 11551 // Exit early if the dropbox isn't configured to accept this report type. 11552 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11553 11554 boolean bufferWasEmpty; 11555 boolean needsFlush; 11556 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11557 synchronized (sb) { 11558 bufferWasEmpty = sb.length() == 0; 11559 appendDropBoxProcessHeaders(process, processName, sb); 11560 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11561 sb.append("System-App: ").append(isSystemApp).append("\n"); 11562 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11563 if (info.violationNumThisLoop != 0) { 11564 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11565 } 11566 if (info.numAnimationsRunning != 0) { 11567 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11568 } 11569 if (info.broadcastIntentAction != null) { 11570 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11571 } 11572 if (info.durationMillis != -1) { 11573 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11574 } 11575 if (info.numInstances != -1) { 11576 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11577 } 11578 if (info.tags != null) { 11579 for (String tag : info.tags) { 11580 sb.append("Span-Tag: ").append(tag).append("\n"); 11581 } 11582 } 11583 sb.append("\n"); 11584 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11585 sb.append(info.crashInfo.stackTrace); 11586 } 11587 sb.append("\n"); 11588 11589 // Only buffer up to ~64k. Various logging bits truncate 11590 // things at 128k. 11591 needsFlush = (sb.length() > 64 * 1024); 11592 } 11593 11594 // Flush immediately if the buffer's grown too large, or this 11595 // is a non-system app. Non-system apps are isolated with a 11596 // different tag & policy and not batched. 11597 // 11598 // Batching is useful during internal testing with 11599 // StrictMode settings turned up high. Without batching, 11600 // thousands of separate files could be created on boot. 11601 if (!isSystemApp || needsFlush) { 11602 new Thread("Error dump: " + dropboxTag) { 11603 @Override 11604 public void run() { 11605 String report; 11606 synchronized (sb) { 11607 report = sb.toString(); 11608 sb.delete(0, sb.length()); 11609 sb.trimToSize(); 11610 } 11611 if (report.length() != 0) { 11612 dbox.addText(dropboxTag, report); 11613 } 11614 } 11615 }.start(); 11616 return; 11617 } 11618 11619 // System app batching: 11620 if (!bufferWasEmpty) { 11621 // An existing dropbox-writing thread is outstanding, so 11622 // we don't need to start it up. The existing thread will 11623 // catch the buffer appends we just did. 11624 return; 11625 } 11626 11627 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11628 // (After this point, we shouldn't access AMS internal data structures.) 11629 new Thread("Error dump: " + dropboxTag) { 11630 @Override 11631 public void run() { 11632 // 5 second sleep to let stacks arrive and be batched together 11633 try { 11634 Thread.sleep(5000); // 5 seconds 11635 } catch (InterruptedException e) {} 11636 11637 String errorReport; 11638 synchronized (mStrictModeBuffer) { 11639 errorReport = mStrictModeBuffer.toString(); 11640 if (errorReport.length() == 0) { 11641 return; 11642 } 11643 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11644 mStrictModeBuffer.trimToSize(); 11645 } 11646 dbox.addText(dropboxTag, errorReport); 11647 } 11648 }.start(); 11649 } 11650 11651 /** 11652 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11653 * @param app object of the crashing app, null for the system server 11654 * @param tag reported by the caller 11655 * @param system whether this wtf is coming from the system 11656 * @param crashInfo describing the context of the error 11657 * @return true if the process should exit immediately (WTF is fatal) 11658 */ 11659 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11660 final ApplicationErrorReport.CrashInfo crashInfo) { 11661 final ProcessRecord r = findAppProcess(app, "WTF"); 11662 final String processName = app == null ? "system_server" 11663 : (r == null ? "unknown" : r.processName); 11664 11665 EventLog.writeEvent(EventLogTags.AM_WTF, 11666 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11667 processName, 11668 r == null ? -1 : r.info.flags, 11669 tag, crashInfo.exceptionMessage); 11670 11671 if (system) { 11672 // If this is coming from the system, we could very well have low-level 11673 // system locks held, so we want to do this all asynchronously. And we 11674 // never want this to become fatal, so there is that too. 11675 mHandler.post(new Runnable() { 11676 @Override public void run() { 11677 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11678 crashInfo); 11679 } 11680 }); 11681 return false; 11682 } 11683 11684 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11685 11686 if (r != null && r.pid != Process.myPid() && 11687 Settings.Global.getInt(mContext.getContentResolver(), 11688 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11689 crashApplication(r, crashInfo); 11690 return true; 11691 } else { 11692 return false; 11693 } 11694 } 11695 11696 /** 11697 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11698 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11699 */ 11700 private ProcessRecord findAppProcess(IBinder app, String reason) { 11701 if (app == null) { 11702 return null; 11703 } 11704 11705 synchronized (this) { 11706 final int NP = mProcessNames.getMap().size(); 11707 for (int ip=0; ip<NP; ip++) { 11708 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11709 final int NA = apps.size(); 11710 for (int ia=0; ia<NA; ia++) { 11711 ProcessRecord p = apps.valueAt(ia); 11712 if (p.thread != null && p.thread.asBinder() == app) { 11713 return p; 11714 } 11715 } 11716 } 11717 11718 Slog.w(TAG, "Can't find mystery application for " + reason 11719 + " from pid=" + Binder.getCallingPid() 11720 + " uid=" + Binder.getCallingUid() + ": " + app); 11721 return null; 11722 } 11723 } 11724 11725 /** 11726 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11727 * to append various headers to the dropbox log text. 11728 */ 11729 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11730 StringBuilder sb) { 11731 // Watchdog thread ends up invoking this function (with 11732 // a null ProcessRecord) to add the stack file to dropbox. 11733 // Do not acquire a lock on this (am) in such cases, as it 11734 // could cause a potential deadlock, if and when watchdog 11735 // is invoked due to unavailability of lock on am and it 11736 // would prevent watchdog from killing system_server. 11737 if (process == null) { 11738 sb.append("Process: ").append(processName).append("\n"); 11739 return; 11740 } 11741 // Note: ProcessRecord 'process' is guarded by the service 11742 // instance. (notably process.pkgList, which could otherwise change 11743 // concurrently during execution of this method) 11744 synchronized (this) { 11745 sb.append("Process: ").append(processName).append("\n"); 11746 int flags = process.info.flags; 11747 IPackageManager pm = AppGlobals.getPackageManager(); 11748 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11749 for (int ip=0; ip<process.pkgList.size(); ip++) { 11750 String pkg = process.pkgList.keyAt(ip); 11751 sb.append("Package: ").append(pkg); 11752 try { 11753 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11754 if (pi != null) { 11755 sb.append(" v").append(pi.versionCode); 11756 if (pi.versionName != null) { 11757 sb.append(" (").append(pi.versionName).append(")"); 11758 } 11759 } 11760 } catch (RemoteException e) { 11761 Slog.e(TAG, "Error getting package info: " + pkg, e); 11762 } 11763 sb.append("\n"); 11764 } 11765 } 11766 } 11767 11768 private static String processClass(ProcessRecord process) { 11769 if (process == null || process.pid == MY_PID) { 11770 return "system_server"; 11771 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11772 return "system_app"; 11773 } else { 11774 return "data_app"; 11775 } 11776 } 11777 11778 /** 11779 * Write a description of an error (crash, WTF, ANR) to the drop box. 11780 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11781 * @param process which caused the error, null means the system server 11782 * @param activity which triggered the error, null if unknown 11783 * @param parent activity related to the error, null if unknown 11784 * @param subject line related to the error, null if absent 11785 * @param report in long form describing the error, null if absent 11786 * @param logFile to include in the report, null if none 11787 * @param crashInfo giving an application stack trace, null if absent 11788 */ 11789 public void addErrorToDropBox(String eventType, 11790 ProcessRecord process, String processName, ActivityRecord activity, 11791 ActivityRecord parent, String subject, 11792 final String report, final File logFile, 11793 final ApplicationErrorReport.CrashInfo crashInfo) { 11794 // NOTE -- this must never acquire the ActivityManagerService lock, 11795 // otherwise the watchdog may be prevented from resetting the system. 11796 11797 final String dropboxTag = processClass(process) + "_" + eventType; 11798 final DropBoxManager dbox = (DropBoxManager) 11799 mContext.getSystemService(Context.DROPBOX_SERVICE); 11800 11801 // Exit early if the dropbox isn't configured to accept this report type. 11802 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11803 11804 final StringBuilder sb = new StringBuilder(1024); 11805 appendDropBoxProcessHeaders(process, processName, sb); 11806 if (activity != null) { 11807 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11808 } 11809 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11810 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11811 } 11812 if (parent != null && parent != activity) { 11813 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11814 } 11815 if (subject != null) { 11816 sb.append("Subject: ").append(subject).append("\n"); 11817 } 11818 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11819 if (Debug.isDebuggerConnected()) { 11820 sb.append("Debugger: Connected\n"); 11821 } 11822 sb.append("\n"); 11823 11824 // Do the rest in a worker thread to avoid blocking the caller on I/O 11825 // (After this point, we shouldn't access AMS internal data structures.) 11826 Thread worker = new Thread("Error dump: " + dropboxTag) { 11827 @Override 11828 public void run() { 11829 if (report != null) { 11830 sb.append(report); 11831 } 11832 if (logFile != null) { 11833 try { 11834 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11835 "\n\n[[TRUNCATED]]")); 11836 } catch (IOException e) { 11837 Slog.e(TAG, "Error reading " + logFile, e); 11838 } 11839 } 11840 if (crashInfo != null && crashInfo.stackTrace != null) { 11841 sb.append(crashInfo.stackTrace); 11842 } 11843 11844 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11845 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11846 if (lines > 0) { 11847 sb.append("\n"); 11848 11849 // Merge several logcat streams, and take the last N lines 11850 InputStreamReader input = null; 11851 try { 11852 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11853 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11854 "-b", "crash", 11855 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11856 11857 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11858 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11859 input = new InputStreamReader(logcat.getInputStream()); 11860 11861 int num; 11862 char[] buf = new char[8192]; 11863 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11864 } catch (IOException e) { 11865 Slog.e(TAG, "Error running logcat", e); 11866 } finally { 11867 if (input != null) try { input.close(); } catch (IOException e) {} 11868 } 11869 } 11870 11871 dbox.addText(dropboxTag, sb.toString()); 11872 } 11873 }; 11874 11875 if (process == null) { 11876 // If process is null, we are being called from some internal code 11877 // and may be about to die -- run this synchronously. 11878 worker.run(); 11879 } else { 11880 worker.start(); 11881 } 11882 } 11883 11884 /** 11885 * Bring up the "unexpected error" dialog box for a crashing app. 11886 * Deal with edge cases (intercepts from instrumented applications, 11887 * ActivityController, error intent receivers, that sort of thing). 11888 * @param r the application crashing 11889 * @param crashInfo describing the failure 11890 */ 11891 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11892 long timeMillis = System.currentTimeMillis(); 11893 String shortMsg = crashInfo.exceptionClassName; 11894 String longMsg = crashInfo.exceptionMessage; 11895 String stackTrace = crashInfo.stackTrace; 11896 if (shortMsg != null && longMsg != null) { 11897 longMsg = shortMsg + ": " + longMsg; 11898 } else if (shortMsg != null) { 11899 longMsg = shortMsg; 11900 } 11901 11902 AppErrorResult result = new AppErrorResult(); 11903 synchronized (this) { 11904 if (mController != null) { 11905 try { 11906 String name = r != null ? r.processName : null; 11907 int pid = r != null ? r.pid : Binder.getCallingPid(); 11908 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11909 if (!mController.appCrashed(name, pid, 11910 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11911 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11912 && "Native crash".equals(crashInfo.exceptionClassName)) { 11913 Slog.w(TAG, "Skip killing native crashed app " + name 11914 + "(" + pid + ") during testing"); 11915 } else { 11916 Slog.w(TAG, "Force-killing crashed app " + name 11917 + " at watcher's request"); 11918 if (r != null) { 11919 r.kill("crash", true); 11920 } else { 11921 // Huh. 11922 Process.killProcess(pid); 11923 Process.killProcessGroup(uid, pid); 11924 } 11925 } 11926 return; 11927 } 11928 } catch (RemoteException e) { 11929 mController = null; 11930 Watchdog.getInstance().setActivityController(null); 11931 } 11932 } 11933 11934 final long origId = Binder.clearCallingIdentity(); 11935 11936 // If this process is running instrumentation, finish it. 11937 if (r != null && r.instrumentationClass != null) { 11938 Slog.w(TAG, "Error in app " + r.processName 11939 + " running instrumentation " + r.instrumentationClass + ":"); 11940 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11941 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11942 Bundle info = new Bundle(); 11943 info.putString("shortMsg", shortMsg); 11944 info.putString("longMsg", longMsg); 11945 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11946 Binder.restoreCallingIdentity(origId); 11947 return; 11948 } 11949 11950 // If we can't identify the process or it's already exceeded its crash quota, 11951 // quit right away without showing a crash dialog. 11952 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11953 Binder.restoreCallingIdentity(origId); 11954 return; 11955 } 11956 11957 Message msg = Message.obtain(); 11958 msg.what = SHOW_ERROR_MSG; 11959 HashMap data = new HashMap(); 11960 data.put("result", result); 11961 data.put("app", r); 11962 msg.obj = data; 11963 mHandler.sendMessage(msg); 11964 11965 Binder.restoreCallingIdentity(origId); 11966 } 11967 11968 int res = result.get(); 11969 11970 Intent appErrorIntent = null; 11971 synchronized (this) { 11972 if (r != null && !r.isolated) { 11973 // XXX Can't keep track of crash time for isolated processes, 11974 // since they don't have a persistent identity. 11975 mProcessCrashTimes.put(r.info.processName, r.uid, 11976 SystemClock.uptimeMillis()); 11977 } 11978 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11979 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11980 } 11981 } 11982 11983 if (appErrorIntent != null) { 11984 try { 11985 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11986 } catch (ActivityNotFoundException e) { 11987 Slog.w(TAG, "bug report receiver dissappeared", e); 11988 } 11989 } 11990 } 11991 11992 Intent createAppErrorIntentLocked(ProcessRecord r, 11993 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11994 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11995 if (report == null) { 11996 return null; 11997 } 11998 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11999 result.setComponent(r.errorReportReceiver); 12000 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12001 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12002 return result; 12003 } 12004 12005 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12006 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12007 if (r.errorReportReceiver == null) { 12008 return null; 12009 } 12010 12011 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12012 return null; 12013 } 12014 12015 ApplicationErrorReport report = new ApplicationErrorReport(); 12016 report.packageName = r.info.packageName; 12017 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12018 report.processName = r.processName; 12019 report.time = timeMillis; 12020 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12021 12022 if (r.crashing || r.forceCrashReport) { 12023 report.type = ApplicationErrorReport.TYPE_CRASH; 12024 report.crashInfo = crashInfo; 12025 } else if (r.notResponding) { 12026 report.type = ApplicationErrorReport.TYPE_ANR; 12027 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12028 12029 report.anrInfo.activity = r.notRespondingReport.tag; 12030 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12031 report.anrInfo.info = r.notRespondingReport.longMsg; 12032 } 12033 12034 return report; 12035 } 12036 12037 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12038 enforceNotIsolatedCaller("getProcessesInErrorState"); 12039 // assume our apps are happy - lazy create the list 12040 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12041 12042 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12043 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12044 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12045 12046 synchronized (this) { 12047 12048 // iterate across all processes 12049 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12050 ProcessRecord app = mLruProcesses.get(i); 12051 if (!allUsers && app.userId != userId) { 12052 continue; 12053 } 12054 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12055 // This one's in trouble, so we'll generate a report for it 12056 // crashes are higher priority (in case there's a crash *and* an anr) 12057 ActivityManager.ProcessErrorStateInfo report = null; 12058 if (app.crashing) { 12059 report = app.crashingReport; 12060 } else if (app.notResponding) { 12061 report = app.notRespondingReport; 12062 } 12063 12064 if (report != null) { 12065 if (errList == null) { 12066 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12067 } 12068 errList.add(report); 12069 } else { 12070 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12071 " crashing = " + app.crashing + 12072 " notResponding = " + app.notResponding); 12073 } 12074 } 12075 } 12076 } 12077 12078 return errList; 12079 } 12080 12081 static int procStateToImportance(int procState, int memAdj, 12082 ActivityManager.RunningAppProcessInfo currApp) { 12083 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12084 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12085 currApp.lru = memAdj; 12086 } else { 12087 currApp.lru = 0; 12088 } 12089 return imp; 12090 } 12091 12092 private void fillInProcMemInfo(ProcessRecord app, 12093 ActivityManager.RunningAppProcessInfo outInfo) { 12094 outInfo.pid = app.pid; 12095 outInfo.uid = app.info.uid; 12096 if (mHeavyWeightProcess == app) { 12097 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12098 } 12099 if (app.persistent) { 12100 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12101 } 12102 if (app.activities.size() > 0) { 12103 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12104 } 12105 outInfo.lastTrimLevel = app.trimMemoryLevel; 12106 int adj = app.curAdj; 12107 int procState = app.curProcState; 12108 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12109 outInfo.importanceReasonCode = app.adjTypeCode; 12110 outInfo.processState = app.curProcState; 12111 } 12112 12113 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12114 enforceNotIsolatedCaller("getRunningAppProcesses"); 12115 // Lazy instantiation of list 12116 List<ActivityManager.RunningAppProcessInfo> runList = null; 12117 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12118 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12119 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12120 synchronized (this) { 12121 // Iterate across all processes 12122 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12123 ProcessRecord app = mLruProcesses.get(i); 12124 if (!allUsers && app.userId != userId) { 12125 continue; 12126 } 12127 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12128 // Generate process state info for running application 12129 ActivityManager.RunningAppProcessInfo currApp = 12130 new ActivityManager.RunningAppProcessInfo(app.processName, 12131 app.pid, app.getPackageList()); 12132 fillInProcMemInfo(app, currApp); 12133 if (app.adjSource instanceof ProcessRecord) { 12134 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12135 currApp.importanceReasonImportance = 12136 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12137 app.adjSourceProcState); 12138 } else if (app.adjSource instanceof ActivityRecord) { 12139 ActivityRecord r = (ActivityRecord)app.adjSource; 12140 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12141 } 12142 if (app.adjTarget instanceof ComponentName) { 12143 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12144 } 12145 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12146 // + " lru=" + currApp.lru); 12147 if (runList == null) { 12148 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12149 } 12150 runList.add(currApp); 12151 } 12152 } 12153 } 12154 return runList; 12155 } 12156 12157 public List<ApplicationInfo> getRunningExternalApplications() { 12158 enforceNotIsolatedCaller("getRunningExternalApplications"); 12159 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12160 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12161 if (runningApps != null && runningApps.size() > 0) { 12162 Set<String> extList = new HashSet<String>(); 12163 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12164 if (app.pkgList != null) { 12165 for (String pkg : app.pkgList) { 12166 extList.add(pkg); 12167 } 12168 } 12169 } 12170 IPackageManager pm = AppGlobals.getPackageManager(); 12171 for (String pkg : extList) { 12172 try { 12173 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12174 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12175 retList.add(info); 12176 } 12177 } catch (RemoteException e) { 12178 } 12179 } 12180 } 12181 return retList; 12182 } 12183 12184 @Override 12185 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12186 enforceNotIsolatedCaller("getMyMemoryState"); 12187 synchronized (this) { 12188 ProcessRecord proc; 12189 synchronized (mPidsSelfLocked) { 12190 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12191 } 12192 fillInProcMemInfo(proc, outInfo); 12193 } 12194 } 12195 12196 @Override 12197 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12198 if (checkCallingPermission(android.Manifest.permission.DUMP) 12199 != PackageManager.PERMISSION_GRANTED) { 12200 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12201 + Binder.getCallingPid() 12202 + ", uid=" + Binder.getCallingUid() 12203 + " without permission " 12204 + android.Manifest.permission.DUMP); 12205 return; 12206 } 12207 12208 boolean dumpAll = false; 12209 boolean dumpClient = false; 12210 String dumpPackage = null; 12211 12212 int opti = 0; 12213 while (opti < args.length) { 12214 String opt = args[opti]; 12215 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12216 break; 12217 } 12218 opti++; 12219 if ("-a".equals(opt)) { 12220 dumpAll = true; 12221 } else if ("-c".equals(opt)) { 12222 dumpClient = true; 12223 } else if ("-h".equals(opt)) { 12224 pw.println("Activity manager dump options:"); 12225 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12226 pw.println(" cmd may be one of:"); 12227 pw.println(" a[ctivities]: activity stack state"); 12228 pw.println(" r[recents]: recent activities state"); 12229 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12230 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12231 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12232 pw.println(" o[om]: out of memory management"); 12233 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12234 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12235 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12236 pw.println(" service [COMP_SPEC]: service client-side state"); 12237 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12238 pw.println(" all: dump all activities"); 12239 pw.println(" top: dump the top activity"); 12240 pw.println(" write: write all pending state to storage"); 12241 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12242 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12243 pw.println(" a partial substring in a component name, a"); 12244 pw.println(" hex object identifier."); 12245 pw.println(" -a: include all available server state."); 12246 pw.println(" -c: include client state."); 12247 return; 12248 } else { 12249 pw.println("Unknown argument: " + opt + "; use -h for help"); 12250 } 12251 } 12252 12253 long origId = Binder.clearCallingIdentity(); 12254 boolean more = false; 12255 // Is the caller requesting to dump a particular piece of data? 12256 if (opti < args.length) { 12257 String cmd = args[opti]; 12258 opti++; 12259 if ("activities".equals(cmd) || "a".equals(cmd)) { 12260 synchronized (this) { 12261 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12262 } 12263 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12264 synchronized (this) { 12265 dumpRecentsLocked(fd, pw, args, opti, true, null); 12266 } 12267 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12268 String[] newArgs; 12269 String name; 12270 if (opti >= args.length) { 12271 name = null; 12272 newArgs = EMPTY_STRING_ARRAY; 12273 } else { 12274 name = args[opti]; 12275 opti++; 12276 newArgs = new String[args.length - opti]; 12277 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12278 args.length - opti); 12279 } 12280 synchronized (this) { 12281 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12282 } 12283 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12284 String[] newArgs; 12285 String name; 12286 if (opti >= args.length) { 12287 name = null; 12288 newArgs = EMPTY_STRING_ARRAY; 12289 } else { 12290 name = args[opti]; 12291 opti++; 12292 newArgs = new String[args.length - opti]; 12293 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12294 args.length - opti); 12295 } 12296 synchronized (this) { 12297 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12298 } 12299 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12300 String[] newArgs; 12301 String name; 12302 if (opti >= args.length) { 12303 name = null; 12304 newArgs = EMPTY_STRING_ARRAY; 12305 } else { 12306 name = args[opti]; 12307 opti++; 12308 newArgs = new String[args.length - opti]; 12309 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12310 args.length - opti); 12311 } 12312 synchronized (this) { 12313 dumpProcessesLocked(fd, pw, args, opti, true, name); 12314 } 12315 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12316 synchronized (this) { 12317 dumpOomLocked(fd, pw, args, opti, true); 12318 } 12319 } else if ("provider".equals(cmd)) { 12320 String[] newArgs; 12321 String name; 12322 if (opti >= args.length) { 12323 name = null; 12324 newArgs = EMPTY_STRING_ARRAY; 12325 } else { 12326 name = args[opti]; 12327 opti++; 12328 newArgs = new String[args.length - opti]; 12329 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12330 } 12331 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12332 pw.println("No providers match: " + name); 12333 pw.println("Use -h for help."); 12334 } 12335 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12336 synchronized (this) { 12337 dumpProvidersLocked(fd, pw, args, opti, true, null); 12338 } 12339 } else if ("service".equals(cmd)) { 12340 String[] newArgs; 12341 String name; 12342 if (opti >= args.length) { 12343 name = null; 12344 newArgs = EMPTY_STRING_ARRAY; 12345 } else { 12346 name = args[opti]; 12347 opti++; 12348 newArgs = new String[args.length - opti]; 12349 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12350 args.length - opti); 12351 } 12352 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12353 pw.println("No services match: " + name); 12354 pw.println("Use -h for help."); 12355 } 12356 } else if ("package".equals(cmd)) { 12357 String[] newArgs; 12358 if (opti >= args.length) { 12359 pw.println("package: no package name specified"); 12360 pw.println("Use -h for help."); 12361 } else { 12362 dumpPackage = args[opti]; 12363 opti++; 12364 newArgs = new String[args.length - opti]; 12365 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12366 args.length - opti); 12367 args = newArgs; 12368 opti = 0; 12369 more = true; 12370 } 12371 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12372 synchronized (this) { 12373 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12374 } 12375 } else if ("write".equals(cmd)) { 12376 mTaskPersister.flush(); 12377 pw.println("All tasks persisted."); 12378 return; 12379 } else { 12380 // Dumping a single activity? 12381 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12382 pw.println("Bad activity command, or no activities match: " + cmd); 12383 pw.println("Use -h for help."); 12384 } 12385 } 12386 if (!more) { 12387 Binder.restoreCallingIdentity(origId); 12388 return; 12389 } 12390 } 12391 12392 // No piece of data specified, dump everything. 12393 synchronized (this) { 12394 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12395 pw.println(); 12396 if (dumpAll) { 12397 pw.println("-------------------------------------------------------------------------------"); 12398 } 12399 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12400 pw.println(); 12401 if (dumpAll) { 12402 pw.println("-------------------------------------------------------------------------------"); 12403 } 12404 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12405 pw.println(); 12406 if (dumpAll) { 12407 pw.println("-------------------------------------------------------------------------------"); 12408 } 12409 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12410 pw.println(); 12411 if (dumpAll) { 12412 pw.println("-------------------------------------------------------------------------------"); 12413 } 12414 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12415 pw.println(); 12416 if (dumpAll) { 12417 pw.println("-------------------------------------------------------------------------------"); 12418 } 12419 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12420 pw.println(); 12421 if (dumpAll) { 12422 pw.println("-------------------------------------------------------------------------------"); 12423 } 12424 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12425 } 12426 Binder.restoreCallingIdentity(origId); 12427 } 12428 12429 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12430 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12431 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12432 12433 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12434 dumpPackage); 12435 boolean needSep = printedAnything; 12436 12437 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12438 dumpPackage, needSep, " mFocusedActivity: "); 12439 if (printed) { 12440 printedAnything = true; 12441 needSep = false; 12442 } 12443 12444 if (dumpPackage == null) { 12445 if (needSep) { 12446 pw.println(); 12447 } 12448 needSep = true; 12449 printedAnything = true; 12450 mStackSupervisor.dump(pw, " "); 12451 } 12452 12453 if (!printedAnything) { 12454 pw.println(" (nothing)"); 12455 } 12456 } 12457 12458 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12459 int opti, boolean dumpAll, String dumpPackage) { 12460 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12461 12462 boolean printedAnything = false; 12463 12464 if (mRecentTasks.size() > 0) { 12465 boolean printedHeader = false; 12466 12467 final int N = mRecentTasks.size(); 12468 for (int i=0; i<N; i++) { 12469 TaskRecord tr = mRecentTasks.get(i); 12470 if (dumpPackage != null) { 12471 if (tr.realActivity == null || 12472 !dumpPackage.equals(tr.realActivity)) { 12473 continue; 12474 } 12475 } 12476 if (!printedHeader) { 12477 pw.println(" Recent tasks:"); 12478 printedHeader = true; 12479 printedAnything = true; 12480 } 12481 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12482 pw.println(tr); 12483 if (dumpAll) { 12484 mRecentTasks.get(i).dump(pw, " "); 12485 } 12486 } 12487 } 12488 12489 if (!printedAnything) { 12490 pw.println(" (nothing)"); 12491 } 12492 } 12493 12494 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12495 int opti, boolean dumpAll, String dumpPackage) { 12496 boolean needSep = false; 12497 boolean printedAnything = false; 12498 int numPers = 0; 12499 12500 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12501 12502 if (dumpAll) { 12503 final int NP = mProcessNames.getMap().size(); 12504 for (int ip=0; ip<NP; ip++) { 12505 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12506 final int NA = procs.size(); 12507 for (int ia=0; ia<NA; ia++) { 12508 ProcessRecord r = procs.valueAt(ia); 12509 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12510 continue; 12511 } 12512 if (!needSep) { 12513 pw.println(" All known processes:"); 12514 needSep = true; 12515 printedAnything = true; 12516 } 12517 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12518 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12519 pw.print(" "); pw.println(r); 12520 r.dump(pw, " "); 12521 if (r.persistent) { 12522 numPers++; 12523 } 12524 } 12525 } 12526 } 12527 12528 if (mIsolatedProcesses.size() > 0) { 12529 boolean printed = false; 12530 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12531 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12532 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12533 continue; 12534 } 12535 if (!printed) { 12536 if (needSep) { 12537 pw.println(); 12538 } 12539 pw.println(" Isolated process list (sorted by uid):"); 12540 printedAnything = true; 12541 printed = true; 12542 needSep = true; 12543 } 12544 pw.println(String.format("%sIsolated #%2d: %s", 12545 " ", i, r.toString())); 12546 } 12547 } 12548 12549 if (mLruProcesses.size() > 0) { 12550 if (needSep) { 12551 pw.println(); 12552 } 12553 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12554 pw.print(" total, non-act at "); 12555 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12556 pw.print(", non-svc at "); 12557 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12558 pw.println("):"); 12559 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12560 needSep = true; 12561 printedAnything = true; 12562 } 12563 12564 if (dumpAll || dumpPackage != null) { 12565 synchronized (mPidsSelfLocked) { 12566 boolean printed = false; 12567 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12568 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12569 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12570 continue; 12571 } 12572 if (!printed) { 12573 if (needSep) pw.println(); 12574 needSep = true; 12575 pw.println(" PID mappings:"); 12576 printed = true; 12577 printedAnything = true; 12578 } 12579 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12580 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12581 } 12582 } 12583 } 12584 12585 if (mForegroundProcesses.size() > 0) { 12586 synchronized (mPidsSelfLocked) { 12587 boolean printed = false; 12588 for (int i=0; i<mForegroundProcesses.size(); i++) { 12589 ProcessRecord r = mPidsSelfLocked.get( 12590 mForegroundProcesses.valueAt(i).pid); 12591 if (dumpPackage != null && (r == null 12592 || !r.pkgList.containsKey(dumpPackage))) { 12593 continue; 12594 } 12595 if (!printed) { 12596 if (needSep) pw.println(); 12597 needSep = true; 12598 pw.println(" Foreground Processes:"); 12599 printed = true; 12600 printedAnything = true; 12601 } 12602 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12603 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12604 } 12605 } 12606 } 12607 12608 if (mPersistentStartingProcesses.size() > 0) { 12609 if (needSep) pw.println(); 12610 needSep = true; 12611 printedAnything = true; 12612 pw.println(" Persisent processes that are starting:"); 12613 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12614 "Starting Norm", "Restarting PERS", dumpPackage); 12615 } 12616 12617 if (mRemovedProcesses.size() > 0) { 12618 if (needSep) pw.println(); 12619 needSep = true; 12620 printedAnything = true; 12621 pw.println(" Processes that are being removed:"); 12622 dumpProcessList(pw, this, mRemovedProcesses, " ", 12623 "Removed Norm", "Removed PERS", dumpPackage); 12624 } 12625 12626 if (mProcessesOnHold.size() > 0) { 12627 if (needSep) pw.println(); 12628 needSep = true; 12629 printedAnything = true; 12630 pw.println(" Processes that are on old until the system is ready:"); 12631 dumpProcessList(pw, this, mProcessesOnHold, " ", 12632 "OnHold Norm", "OnHold PERS", dumpPackage); 12633 } 12634 12635 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12636 12637 if (mProcessCrashTimes.getMap().size() > 0) { 12638 boolean printed = false; 12639 long now = SystemClock.uptimeMillis(); 12640 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12641 final int NP = pmap.size(); 12642 for (int ip=0; ip<NP; ip++) { 12643 String pname = pmap.keyAt(ip); 12644 SparseArray<Long> uids = pmap.valueAt(ip); 12645 final int N = uids.size(); 12646 for (int i=0; i<N; i++) { 12647 int puid = uids.keyAt(i); 12648 ProcessRecord r = mProcessNames.get(pname, puid); 12649 if (dumpPackage != null && (r == null 12650 || !r.pkgList.containsKey(dumpPackage))) { 12651 continue; 12652 } 12653 if (!printed) { 12654 if (needSep) pw.println(); 12655 needSep = true; 12656 pw.println(" Time since processes crashed:"); 12657 printed = true; 12658 printedAnything = true; 12659 } 12660 pw.print(" Process "); pw.print(pname); 12661 pw.print(" uid "); pw.print(puid); 12662 pw.print(": last crashed "); 12663 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12664 pw.println(" ago"); 12665 } 12666 } 12667 } 12668 12669 if (mBadProcesses.getMap().size() > 0) { 12670 boolean printed = false; 12671 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12672 final int NP = pmap.size(); 12673 for (int ip=0; ip<NP; ip++) { 12674 String pname = pmap.keyAt(ip); 12675 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12676 final int N = uids.size(); 12677 for (int i=0; i<N; i++) { 12678 int puid = uids.keyAt(i); 12679 ProcessRecord r = mProcessNames.get(pname, puid); 12680 if (dumpPackage != null && (r == null 12681 || !r.pkgList.containsKey(dumpPackage))) { 12682 continue; 12683 } 12684 if (!printed) { 12685 if (needSep) pw.println(); 12686 needSep = true; 12687 pw.println(" Bad processes:"); 12688 printedAnything = true; 12689 } 12690 BadProcessInfo info = uids.valueAt(i); 12691 pw.print(" Bad process "); pw.print(pname); 12692 pw.print(" uid "); pw.print(puid); 12693 pw.print(": crashed at time "); pw.println(info.time); 12694 if (info.shortMsg != null) { 12695 pw.print(" Short msg: "); pw.println(info.shortMsg); 12696 } 12697 if (info.longMsg != null) { 12698 pw.print(" Long msg: "); pw.println(info.longMsg); 12699 } 12700 if (info.stack != null) { 12701 pw.println(" Stack:"); 12702 int lastPos = 0; 12703 for (int pos=0; pos<info.stack.length(); pos++) { 12704 if (info.stack.charAt(pos) == '\n') { 12705 pw.print(" "); 12706 pw.write(info.stack, lastPos, pos-lastPos); 12707 pw.println(); 12708 lastPos = pos+1; 12709 } 12710 } 12711 if (lastPos < info.stack.length()) { 12712 pw.print(" "); 12713 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12714 pw.println(); 12715 } 12716 } 12717 } 12718 } 12719 } 12720 12721 if (dumpPackage == null) { 12722 pw.println(); 12723 needSep = false; 12724 pw.println(" mStartedUsers:"); 12725 for (int i=0; i<mStartedUsers.size(); i++) { 12726 UserStartedState uss = mStartedUsers.valueAt(i); 12727 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12728 pw.print(": "); uss.dump("", pw); 12729 } 12730 pw.print(" mStartedUserArray: ["); 12731 for (int i=0; i<mStartedUserArray.length; i++) { 12732 if (i > 0) pw.print(", "); 12733 pw.print(mStartedUserArray[i]); 12734 } 12735 pw.println("]"); 12736 pw.print(" mUserLru: ["); 12737 for (int i=0; i<mUserLru.size(); i++) { 12738 if (i > 0) pw.print(", "); 12739 pw.print(mUserLru.get(i)); 12740 } 12741 pw.println("]"); 12742 if (dumpAll) { 12743 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12744 } 12745 synchronized (mUserProfileGroupIdsSelfLocked) { 12746 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12747 pw.println(" mUserProfileGroupIds:"); 12748 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12749 pw.print(" User #"); 12750 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12751 pw.print(" -> profile #"); 12752 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12753 } 12754 } 12755 } 12756 } 12757 if (mHomeProcess != null && (dumpPackage == null 12758 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12759 if (needSep) { 12760 pw.println(); 12761 needSep = false; 12762 } 12763 pw.println(" mHomeProcess: " + mHomeProcess); 12764 } 12765 if (mPreviousProcess != null && (dumpPackage == null 12766 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12767 if (needSep) { 12768 pw.println(); 12769 needSep = false; 12770 } 12771 pw.println(" mPreviousProcess: " + mPreviousProcess); 12772 } 12773 if (dumpAll) { 12774 StringBuilder sb = new StringBuilder(128); 12775 sb.append(" mPreviousProcessVisibleTime: "); 12776 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12777 pw.println(sb); 12778 } 12779 if (mHeavyWeightProcess != null && (dumpPackage == null 12780 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12781 if (needSep) { 12782 pw.println(); 12783 needSep = false; 12784 } 12785 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12786 } 12787 if (dumpPackage == null) { 12788 pw.println(" mConfiguration: " + mConfiguration); 12789 } 12790 if (dumpAll) { 12791 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12792 if (mCompatModePackages.getPackages().size() > 0) { 12793 boolean printed = false; 12794 for (Map.Entry<String, Integer> entry 12795 : mCompatModePackages.getPackages().entrySet()) { 12796 String pkg = entry.getKey(); 12797 int mode = entry.getValue(); 12798 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12799 continue; 12800 } 12801 if (!printed) { 12802 pw.println(" mScreenCompatPackages:"); 12803 printed = true; 12804 } 12805 pw.print(" "); pw.print(pkg); pw.print(": "); 12806 pw.print(mode); pw.println(); 12807 } 12808 } 12809 } 12810 if (dumpPackage == null) { 12811 if (mSleeping || mWentToSleep || mLockScreenShown) { 12812 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12813 + " mLockScreenShown " + mLockScreenShown); 12814 } 12815 if (mShuttingDown || mRunningVoice) { 12816 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12817 } 12818 } 12819 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12820 || mOrigWaitForDebugger) { 12821 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12822 || dumpPackage.equals(mOrigDebugApp)) { 12823 if (needSep) { 12824 pw.println(); 12825 needSep = false; 12826 } 12827 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12828 + " mDebugTransient=" + mDebugTransient 12829 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12830 } 12831 } 12832 if (mOpenGlTraceApp != null) { 12833 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12834 if (needSep) { 12835 pw.println(); 12836 needSep = false; 12837 } 12838 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12839 } 12840 } 12841 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12842 || mProfileFd != null) { 12843 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12844 if (needSep) { 12845 pw.println(); 12846 needSep = false; 12847 } 12848 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12849 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12850 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12851 + mAutoStopProfiler); 12852 pw.println(" mProfileType=" + mProfileType); 12853 } 12854 } 12855 if (dumpPackage == null) { 12856 if (mAlwaysFinishActivities || mController != null) { 12857 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12858 + " mController=" + mController); 12859 } 12860 if (dumpAll) { 12861 pw.println(" Total persistent processes: " + numPers); 12862 pw.println(" mProcessesReady=" + mProcessesReady 12863 + " mSystemReady=" + mSystemReady); 12864 pw.println(" mBooting=" + mBooting 12865 + " mBooted=" + mBooted 12866 + " mFactoryTest=" + mFactoryTest); 12867 pw.print(" mLastPowerCheckRealtime="); 12868 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12869 pw.println(""); 12870 pw.print(" mLastPowerCheckUptime="); 12871 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12872 pw.println(""); 12873 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12874 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12875 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12876 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12877 + " (" + mLruProcesses.size() + " total)" 12878 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12879 + " mNumServiceProcs=" + mNumServiceProcs 12880 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12881 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12882 + " mLastMemoryLevel" + mLastMemoryLevel 12883 + " mLastNumProcesses" + mLastNumProcesses); 12884 long now = SystemClock.uptimeMillis(); 12885 pw.print(" mLastIdleTime="); 12886 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12887 pw.print(" mLowRamSinceLastIdle="); 12888 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12889 pw.println(); 12890 } 12891 } 12892 12893 if (!printedAnything) { 12894 pw.println(" (nothing)"); 12895 } 12896 } 12897 12898 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12899 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12900 if (mProcessesToGc.size() > 0) { 12901 boolean printed = false; 12902 long now = SystemClock.uptimeMillis(); 12903 for (int i=0; i<mProcessesToGc.size(); i++) { 12904 ProcessRecord proc = mProcessesToGc.get(i); 12905 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12906 continue; 12907 } 12908 if (!printed) { 12909 if (needSep) pw.println(); 12910 needSep = true; 12911 pw.println(" Processes that are waiting to GC:"); 12912 printed = true; 12913 } 12914 pw.print(" Process "); pw.println(proc); 12915 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12916 pw.print(", last gced="); 12917 pw.print(now-proc.lastRequestedGc); 12918 pw.print(" ms ago, last lowMem="); 12919 pw.print(now-proc.lastLowMemory); 12920 pw.println(" ms ago"); 12921 12922 } 12923 } 12924 return needSep; 12925 } 12926 12927 void printOomLevel(PrintWriter pw, String name, int adj) { 12928 pw.print(" "); 12929 if (adj >= 0) { 12930 pw.print(' '); 12931 if (adj < 10) pw.print(' '); 12932 } else { 12933 if (adj > -10) pw.print(' '); 12934 } 12935 pw.print(adj); 12936 pw.print(": "); 12937 pw.print(name); 12938 pw.print(" ("); 12939 pw.print(mProcessList.getMemLevel(adj)/1024); 12940 pw.println(" kB)"); 12941 } 12942 12943 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12944 int opti, boolean dumpAll) { 12945 boolean needSep = false; 12946 12947 if (mLruProcesses.size() > 0) { 12948 if (needSep) pw.println(); 12949 needSep = true; 12950 pw.println(" OOM levels:"); 12951 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12952 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12953 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12954 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12955 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12956 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12957 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12958 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12959 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12960 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12961 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12962 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12963 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12964 12965 if (needSep) pw.println(); 12966 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12967 pw.print(" total, non-act at "); 12968 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12969 pw.print(", non-svc at "); 12970 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12971 pw.println("):"); 12972 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12973 needSep = true; 12974 } 12975 12976 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12977 12978 pw.println(); 12979 pw.println(" mHomeProcess: " + mHomeProcess); 12980 pw.println(" mPreviousProcess: " + mPreviousProcess); 12981 if (mHeavyWeightProcess != null) { 12982 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12983 } 12984 12985 return true; 12986 } 12987 12988 /** 12989 * There are three ways to call this: 12990 * - no provider specified: dump all the providers 12991 * - a flattened component name that matched an existing provider was specified as the 12992 * first arg: dump that one provider 12993 * - the first arg isn't the flattened component name of an existing provider: 12994 * dump all providers whose component contains the first arg as a substring 12995 */ 12996 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12997 int opti, boolean dumpAll) { 12998 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12999 } 13000 13001 static class ItemMatcher { 13002 ArrayList<ComponentName> components; 13003 ArrayList<String> strings; 13004 ArrayList<Integer> objects; 13005 boolean all; 13006 13007 ItemMatcher() { 13008 all = true; 13009 } 13010 13011 void build(String name) { 13012 ComponentName componentName = ComponentName.unflattenFromString(name); 13013 if (componentName != null) { 13014 if (components == null) { 13015 components = new ArrayList<ComponentName>(); 13016 } 13017 components.add(componentName); 13018 all = false; 13019 } else { 13020 int objectId = 0; 13021 // Not a '/' separated full component name; maybe an object ID? 13022 try { 13023 objectId = Integer.parseInt(name, 16); 13024 if (objects == null) { 13025 objects = new ArrayList<Integer>(); 13026 } 13027 objects.add(objectId); 13028 all = false; 13029 } catch (RuntimeException e) { 13030 // Not an integer; just do string match. 13031 if (strings == null) { 13032 strings = new ArrayList<String>(); 13033 } 13034 strings.add(name); 13035 all = false; 13036 } 13037 } 13038 } 13039 13040 int build(String[] args, int opti) { 13041 for (; opti<args.length; opti++) { 13042 String name = args[opti]; 13043 if ("--".equals(name)) { 13044 return opti+1; 13045 } 13046 build(name); 13047 } 13048 return opti; 13049 } 13050 13051 boolean match(Object object, ComponentName comp) { 13052 if (all) { 13053 return true; 13054 } 13055 if (components != null) { 13056 for (int i=0; i<components.size(); i++) { 13057 if (components.get(i).equals(comp)) { 13058 return true; 13059 } 13060 } 13061 } 13062 if (objects != null) { 13063 for (int i=0; i<objects.size(); i++) { 13064 if (System.identityHashCode(object) == objects.get(i)) { 13065 return true; 13066 } 13067 } 13068 } 13069 if (strings != null) { 13070 String flat = comp.flattenToString(); 13071 for (int i=0; i<strings.size(); i++) { 13072 if (flat.contains(strings.get(i))) { 13073 return true; 13074 } 13075 } 13076 } 13077 return false; 13078 } 13079 } 13080 13081 /** 13082 * There are three things that cmd can be: 13083 * - a flattened component name that matches an existing activity 13084 * - the cmd arg isn't the flattened component name of an existing activity: 13085 * dump all activity whose component contains the cmd as a substring 13086 * - A hex number of the ActivityRecord object instance. 13087 */ 13088 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13089 int opti, boolean dumpAll) { 13090 ArrayList<ActivityRecord> activities; 13091 13092 synchronized (this) { 13093 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13094 } 13095 13096 if (activities.size() <= 0) { 13097 return false; 13098 } 13099 13100 String[] newArgs = new String[args.length - opti]; 13101 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13102 13103 TaskRecord lastTask = null; 13104 boolean needSep = false; 13105 for (int i=activities.size()-1; i>=0; i--) { 13106 ActivityRecord r = activities.get(i); 13107 if (needSep) { 13108 pw.println(); 13109 } 13110 needSep = true; 13111 synchronized (this) { 13112 if (lastTask != r.task) { 13113 lastTask = r.task; 13114 pw.print("TASK "); pw.print(lastTask.affinity); 13115 pw.print(" id="); pw.println(lastTask.taskId); 13116 if (dumpAll) { 13117 lastTask.dump(pw, " "); 13118 } 13119 } 13120 } 13121 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13122 } 13123 return true; 13124 } 13125 13126 /** 13127 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13128 * there is a thread associated with the activity. 13129 */ 13130 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13131 final ActivityRecord r, String[] args, boolean dumpAll) { 13132 String innerPrefix = prefix + " "; 13133 synchronized (this) { 13134 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13135 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13136 pw.print(" pid="); 13137 if (r.app != null) pw.println(r.app.pid); 13138 else pw.println("(not running)"); 13139 if (dumpAll) { 13140 r.dump(pw, innerPrefix); 13141 } 13142 } 13143 if (r.app != null && r.app.thread != null) { 13144 // flush anything that is already in the PrintWriter since the thread is going 13145 // to write to the file descriptor directly 13146 pw.flush(); 13147 try { 13148 TransferPipe tp = new TransferPipe(); 13149 try { 13150 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13151 r.appToken, innerPrefix, args); 13152 tp.go(fd); 13153 } finally { 13154 tp.kill(); 13155 } 13156 } catch (IOException e) { 13157 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13158 } catch (RemoteException e) { 13159 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13160 } 13161 } 13162 } 13163 13164 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13165 int opti, boolean dumpAll, String dumpPackage) { 13166 boolean needSep = false; 13167 boolean onlyHistory = false; 13168 boolean printedAnything = false; 13169 13170 if ("history".equals(dumpPackage)) { 13171 if (opti < args.length && "-s".equals(args[opti])) { 13172 dumpAll = false; 13173 } 13174 onlyHistory = true; 13175 dumpPackage = null; 13176 } 13177 13178 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13179 if (!onlyHistory && dumpAll) { 13180 if (mRegisteredReceivers.size() > 0) { 13181 boolean printed = false; 13182 Iterator it = mRegisteredReceivers.values().iterator(); 13183 while (it.hasNext()) { 13184 ReceiverList r = (ReceiverList)it.next(); 13185 if (dumpPackage != null && (r.app == null || 13186 !dumpPackage.equals(r.app.info.packageName))) { 13187 continue; 13188 } 13189 if (!printed) { 13190 pw.println(" Registered Receivers:"); 13191 needSep = true; 13192 printed = true; 13193 printedAnything = true; 13194 } 13195 pw.print(" * "); pw.println(r); 13196 r.dump(pw, " "); 13197 } 13198 } 13199 13200 if (mReceiverResolver.dump(pw, needSep ? 13201 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13202 " ", dumpPackage, false)) { 13203 needSep = true; 13204 printedAnything = true; 13205 } 13206 } 13207 13208 for (BroadcastQueue q : mBroadcastQueues) { 13209 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13210 printedAnything |= needSep; 13211 } 13212 13213 needSep = true; 13214 13215 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13216 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13217 if (needSep) { 13218 pw.println(); 13219 } 13220 needSep = true; 13221 printedAnything = true; 13222 pw.print(" Sticky broadcasts for user "); 13223 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13224 StringBuilder sb = new StringBuilder(128); 13225 for (Map.Entry<String, ArrayList<Intent>> ent 13226 : mStickyBroadcasts.valueAt(user).entrySet()) { 13227 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13228 if (dumpAll) { 13229 pw.println(":"); 13230 ArrayList<Intent> intents = ent.getValue(); 13231 final int N = intents.size(); 13232 for (int i=0; i<N; i++) { 13233 sb.setLength(0); 13234 sb.append(" Intent: "); 13235 intents.get(i).toShortString(sb, false, true, false, false); 13236 pw.println(sb.toString()); 13237 Bundle bundle = intents.get(i).getExtras(); 13238 if (bundle != null) { 13239 pw.print(" "); 13240 pw.println(bundle.toString()); 13241 } 13242 } 13243 } else { 13244 pw.println(""); 13245 } 13246 } 13247 } 13248 } 13249 13250 if (!onlyHistory && dumpAll) { 13251 pw.println(); 13252 for (BroadcastQueue queue : mBroadcastQueues) { 13253 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13254 + queue.mBroadcastsScheduled); 13255 } 13256 pw.println(" mHandler:"); 13257 mHandler.dump(new PrintWriterPrinter(pw), " "); 13258 needSep = true; 13259 printedAnything = true; 13260 } 13261 13262 if (!printedAnything) { 13263 pw.println(" (nothing)"); 13264 } 13265 } 13266 13267 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13268 int opti, boolean dumpAll, String dumpPackage) { 13269 boolean needSep; 13270 boolean printedAnything = false; 13271 13272 ItemMatcher matcher = new ItemMatcher(); 13273 matcher.build(args, opti); 13274 13275 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13276 13277 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13278 printedAnything |= needSep; 13279 13280 if (mLaunchingProviders.size() > 0) { 13281 boolean printed = false; 13282 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13283 ContentProviderRecord r = mLaunchingProviders.get(i); 13284 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13285 continue; 13286 } 13287 if (!printed) { 13288 if (needSep) pw.println(); 13289 needSep = true; 13290 pw.println(" Launching content providers:"); 13291 printed = true; 13292 printedAnything = true; 13293 } 13294 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13295 pw.println(r); 13296 } 13297 } 13298 13299 if (mGrantedUriPermissions.size() > 0) { 13300 boolean printed = false; 13301 int dumpUid = -2; 13302 if (dumpPackage != null) { 13303 try { 13304 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13305 } catch (NameNotFoundException e) { 13306 dumpUid = -1; 13307 } 13308 } 13309 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13310 int uid = mGrantedUriPermissions.keyAt(i); 13311 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13312 continue; 13313 } 13314 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13315 if (!printed) { 13316 if (needSep) pw.println(); 13317 needSep = true; 13318 pw.println(" Granted Uri Permissions:"); 13319 printed = true; 13320 printedAnything = true; 13321 } 13322 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13323 for (UriPermission perm : perms.values()) { 13324 pw.print(" "); pw.println(perm); 13325 if (dumpAll) { 13326 perm.dump(pw, " "); 13327 } 13328 } 13329 } 13330 } 13331 13332 if (!printedAnything) { 13333 pw.println(" (nothing)"); 13334 } 13335 } 13336 13337 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13338 int opti, boolean dumpAll, String dumpPackage) { 13339 boolean printed = false; 13340 13341 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13342 13343 if (mIntentSenderRecords.size() > 0) { 13344 Iterator<WeakReference<PendingIntentRecord>> it 13345 = mIntentSenderRecords.values().iterator(); 13346 while (it.hasNext()) { 13347 WeakReference<PendingIntentRecord> ref = it.next(); 13348 PendingIntentRecord rec = ref != null ? ref.get(): null; 13349 if (dumpPackage != null && (rec == null 13350 || !dumpPackage.equals(rec.key.packageName))) { 13351 continue; 13352 } 13353 printed = true; 13354 if (rec != null) { 13355 pw.print(" * "); pw.println(rec); 13356 if (dumpAll) { 13357 rec.dump(pw, " "); 13358 } 13359 } else { 13360 pw.print(" * "); pw.println(ref); 13361 } 13362 } 13363 } 13364 13365 if (!printed) { 13366 pw.println(" (nothing)"); 13367 } 13368 } 13369 13370 private static final int dumpProcessList(PrintWriter pw, 13371 ActivityManagerService service, List list, 13372 String prefix, String normalLabel, String persistentLabel, 13373 String dumpPackage) { 13374 int numPers = 0; 13375 final int N = list.size()-1; 13376 for (int i=N; i>=0; i--) { 13377 ProcessRecord r = (ProcessRecord)list.get(i); 13378 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13379 continue; 13380 } 13381 pw.println(String.format("%s%s #%2d: %s", 13382 prefix, (r.persistent ? persistentLabel : normalLabel), 13383 i, r.toString())); 13384 if (r.persistent) { 13385 numPers++; 13386 } 13387 } 13388 return numPers; 13389 } 13390 13391 private static final boolean dumpProcessOomList(PrintWriter pw, 13392 ActivityManagerService service, List<ProcessRecord> origList, 13393 String prefix, String normalLabel, String persistentLabel, 13394 boolean inclDetails, String dumpPackage) { 13395 13396 ArrayList<Pair<ProcessRecord, Integer>> list 13397 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13398 for (int i=0; i<origList.size(); i++) { 13399 ProcessRecord r = origList.get(i); 13400 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13401 continue; 13402 } 13403 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13404 } 13405 13406 if (list.size() <= 0) { 13407 return false; 13408 } 13409 13410 Comparator<Pair<ProcessRecord, Integer>> comparator 13411 = new Comparator<Pair<ProcessRecord, Integer>>() { 13412 @Override 13413 public int compare(Pair<ProcessRecord, Integer> object1, 13414 Pair<ProcessRecord, Integer> object2) { 13415 if (object1.first.setAdj != object2.first.setAdj) { 13416 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13417 } 13418 if (object1.second.intValue() != object2.second.intValue()) { 13419 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13420 } 13421 return 0; 13422 } 13423 }; 13424 13425 Collections.sort(list, comparator); 13426 13427 final long curRealtime = SystemClock.elapsedRealtime(); 13428 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13429 final long curUptime = SystemClock.uptimeMillis(); 13430 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13431 13432 for (int i=list.size()-1; i>=0; i--) { 13433 ProcessRecord r = list.get(i).first; 13434 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13435 char schedGroup; 13436 switch (r.setSchedGroup) { 13437 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13438 schedGroup = 'B'; 13439 break; 13440 case Process.THREAD_GROUP_DEFAULT: 13441 schedGroup = 'F'; 13442 break; 13443 default: 13444 schedGroup = '?'; 13445 break; 13446 } 13447 char foreground; 13448 if (r.foregroundActivities) { 13449 foreground = 'A'; 13450 } else if (r.foregroundServices) { 13451 foreground = 'S'; 13452 } else { 13453 foreground = ' '; 13454 } 13455 String procState = ProcessList.makeProcStateString(r.curProcState); 13456 pw.print(prefix); 13457 pw.print(r.persistent ? persistentLabel : normalLabel); 13458 pw.print(" #"); 13459 int num = (origList.size()-1)-list.get(i).second; 13460 if (num < 10) pw.print(' '); 13461 pw.print(num); 13462 pw.print(": "); 13463 pw.print(oomAdj); 13464 pw.print(' '); 13465 pw.print(schedGroup); 13466 pw.print('/'); 13467 pw.print(foreground); 13468 pw.print('/'); 13469 pw.print(procState); 13470 pw.print(" trm:"); 13471 if (r.trimMemoryLevel < 10) pw.print(' '); 13472 pw.print(r.trimMemoryLevel); 13473 pw.print(' '); 13474 pw.print(r.toShortString()); 13475 pw.print(" ("); 13476 pw.print(r.adjType); 13477 pw.println(')'); 13478 if (r.adjSource != null || r.adjTarget != null) { 13479 pw.print(prefix); 13480 pw.print(" "); 13481 if (r.adjTarget instanceof ComponentName) { 13482 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13483 } else if (r.adjTarget != null) { 13484 pw.print(r.adjTarget.toString()); 13485 } else { 13486 pw.print("{null}"); 13487 } 13488 pw.print("<="); 13489 if (r.adjSource instanceof ProcessRecord) { 13490 pw.print("Proc{"); 13491 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13492 pw.println("}"); 13493 } else if (r.adjSource != null) { 13494 pw.println(r.adjSource.toString()); 13495 } else { 13496 pw.println("{null}"); 13497 } 13498 } 13499 if (inclDetails) { 13500 pw.print(prefix); 13501 pw.print(" "); 13502 pw.print("oom: max="); pw.print(r.maxAdj); 13503 pw.print(" curRaw="); pw.print(r.curRawAdj); 13504 pw.print(" setRaw="); pw.print(r.setRawAdj); 13505 pw.print(" cur="); pw.print(r.curAdj); 13506 pw.print(" set="); pw.println(r.setAdj); 13507 pw.print(prefix); 13508 pw.print(" "); 13509 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13510 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13511 pw.print(" lastPss="); pw.print(r.lastPss); 13512 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13513 pw.print(prefix); 13514 pw.print(" "); 13515 pw.print("cached="); pw.print(r.cached); 13516 pw.print(" empty="); pw.print(r.empty); 13517 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13518 13519 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13520 if (r.lastWakeTime != 0) { 13521 long wtime; 13522 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13523 synchronized (stats) { 13524 wtime = stats.getProcessWakeTime(r.info.uid, 13525 r.pid, curRealtime); 13526 } 13527 long timeUsed = wtime - r.lastWakeTime; 13528 pw.print(prefix); 13529 pw.print(" "); 13530 pw.print("keep awake over "); 13531 TimeUtils.formatDuration(realtimeSince, pw); 13532 pw.print(" used "); 13533 TimeUtils.formatDuration(timeUsed, pw); 13534 pw.print(" ("); 13535 pw.print((timeUsed*100)/realtimeSince); 13536 pw.println("%)"); 13537 } 13538 if (r.lastCpuTime != 0) { 13539 long timeUsed = r.curCpuTime - r.lastCpuTime; 13540 pw.print(prefix); 13541 pw.print(" "); 13542 pw.print("run cpu over "); 13543 TimeUtils.formatDuration(uptimeSince, pw); 13544 pw.print(" used "); 13545 TimeUtils.formatDuration(timeUsed, pw); 13546 pw.print(" ("); 13547 pw.print((timeUsed*100)/uptimeSince); 13548 pw.println("%)"); 13549 } 13550 } 13551 } 13552 } 13553 return true; 13554 } 13555 13556 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13557 ArrayList<ProcessRecord> procs; 13558 synchronized (this) { 13559 if (args != null && args.length > start 13560 && args[start].charAt(0) != '-') { 13561 procs = new ArrayList<ProcessRecord>(); 13562 int pid = -1; 13563 try { 13564 pid = Integer.parseInt(args[start]); 13565 } catch (NumberFormatException e) { 13566 } 13567 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13568 ProcessRecord proc = mLruProcesses.get(i); 13569 if (proc.pid == pid) { 13570 procs.add(proc); 13571 } else if (proc.processName.equals(args[start])) { 13572 procs.add(proc); 13573 } 13574 } 13575 if (procs.size() <= 0) { 13576 return null; 13577 } 13578 } else { 13579 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13580 } 13581 } 13582 return procs; 13583 } 13584 13585 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13586 PrintWriter pw, String[] args) { 13587 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13588 if (procs == null) { 13589 pw.println("No process found for: " + args[0]); 13590 return; 13591 } 13592 13593 long uptime = SystemClock.uptimeMillis(); 13594 long realtime = SystemClock.elapsedRealtime(); 13595 pw.println("Applications Graphics Acceleration Info:"); 13596 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13597 13598 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13599 ProcessRecord r = procs.get(i); 13600 if (r.thread != null) { 13601 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13602 pw.flush(); 13603 try { 13604 TransferPipe tp = new TransferPipe(); 13605 try { 13606 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13607 tp.go(fd); 13608 } finally { 13609 tp.kill(); 13610 } 13611 } catch (IOException e) { 13612 pw.println("Failure while dumping the app: " + r); 13613 pw.flush(); 13614 } catch (RemoteException e) { 13615 pw.println("Got a RemoteException while dumping the app " + r); 13616 pw.flush(); 13617 } 13618 } 13619 } 13620 } 13621 13622 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13623 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13624 if (procs == null) { 13625 pw.println("No process found for: " + args[0]); 13626 return; 13627 } 13628 13629 pw.println("Applications Database Info:"); 13630 13631 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13632 ProcessRecord r = procs.get(i); 13633 if (r.thread != null) { 13634 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13635 pw.flush(); 13636 try { 13637 TransferPipe tp = new TransferPipe(); 13638 try { 13639 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13640 tp.go(fd); 13641 } finally { 13642 tp.kill(); 13643 } 13644 } catch (IOException e) { 13645 pw.println("Failure while dumping the app: " + r); 13646 pw.flush(); 13647 } catch (RemoteException e) { 13648 pw.println("Got a RemoteException while dumping the app " + r); 13649 pw.flush(); 13650 } 13651 } 13652 } 13653 } 13654 13655 final static class MemItem { 13656 final boolean isProc; 13657 final String label; 13658 final String shortLabel; 13659 final long pss; 13660 final int id; 13661 final boolean hasActivities; 13662 ArrayList<MemItem> subitems; 13663 13664 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13665 boolean _hasActivities) { 13666 isProc = true; 13667 label = _label; 13668 shortLabel = _shortLabel; 13669 pss = _pss; 13670 id = _id; 13671 hasActivities = _hasActivities; 13672 } 13673 13674 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13675 isProc = false; 13676 label = _label; 13677 shortLabel = _shortLabel; 13678 pss = _pss; 13679 id = _id; 13680 hasActivities = false; 13681 } 13682 } 13683 13684 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13685 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13686 if (sort && !isCompact) { 13687 Collections.sort(items, new Comparator<MemItem>() { 13688 @Override 13689 public int compare(MemItem lhs, MemItem rhs) { 13690 if (lhs.pss < rhs.pss) { 13691 return 1; 13692 } else if (lhs.pss > rhs.pss) { 13693 return -1; 13694 } 13695 return 0; 13696 } 13697 }); 13698 } 13699 13700 for (int i=0; i<items.size(); i++) { 13701 MemItem mi = items.get(i); 13702 if (!isCompact) { 13703 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13704 } else if (mi.isProc) { 13705 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13706 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13707 pw.println(mi.hasActivities ? ",a" : ",e"); 13708 } else { 13709 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13710 pw.println(mi.pss); 13711 } 13712 if (mi.subitems != null) { 13713 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13714 true, isCompact); 13715 } 13716 } 13717 } 13718 13719 // These are in KB. 13720 static final long[] DUMP_MEM_BUCKETS = new long[] { 13721 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13722 120*1024, 160*1024, 200*1024, 13723 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13724 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13725 }; 13726 13727 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13728 boolean stackLike) { 13729 int start = label.lastIndexOf('.'); 13730 if (start >= 0) start++; 13731 else start = 0; 13732 int end = label.length(); 13733 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13734 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13735 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13736 out.append(bucket); 13737 out.append(stackLike ? "MB." : "MB "); 13738 out.append(label, start, end); 13739 return; 13740 } 13741 } 13742 out.append(memKB/1024); 13743 out.append(stackLike ? "MB." : "MB "); 13744 out.append(label, start, end); 13745 } 13746 13747 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13748 ProcessList.NATIVE_ADJ, 13749 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13750 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13751 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13752 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13753 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13754 }; 13755 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13756 "Native", 13757 "System", "Persistent", "Foreground", 13758 "Visible", "Perceptible", 13759 "Heavy Weight", "Backup", 13760 "A Services", "Home", 13761 "Previous", "B Services", "Cached" 13762 }; 13763 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13764 "native", 13765 "sys", "pers", "fore", 13766 "vis", "percept", 13767 "heavy", "backup", 13768 "servicea", "home", 13769 "prev", "serviceb", "cached" 13770 }; 13771 13772 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13773 long realtime, boolean isCheckinRequest, boolean isCompact) { 13774 if (isCheckinRequest || isCompact) { 13775 // short checkin version 13776 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13777 } else { 13778 pw.println("Applications Memory Usage (kB):"); 13779 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13780 } 13781 } 13782 13783 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13784 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13785 boolean dumpDetails = false; 13786 boolean dumpFullDetails = false; 13787 boolean dumpDalvik = false; 13788 boolean oomOnly = false; 13789 boolean isCompact = false; 13790 boolean localOnly = false; 13791 13792 int opti = 0; 13793 while (opti < args.length) { 13794 String opt = args[opti]; 13795 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13796 break; 13797 } 13798 opti++; 13799 if ("-a".equals(opt)) { 13800 dumpDetails = true; 13801 dumpFullDetails = true; 13802 dumpDalvik = true; 13803 } else if ("-d".equals(opt)) { 13804 dumpDalvik = true; 13805 } else if ("-c".equals(opt)) { 13806 isCompact = true; 13807 } else if ("--oom".equals(opt)) { 13808 oomOnly = true; 13809 } else if ("--local".equals(opt)) { 13810 localOnly = true; 13811 } else if ("-h".equals(opt)) { 13812 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13813 pw.println(" -a: include all available information for each process."); 13814 pw.println(" -d: include dalvik details when dumping process details."); 13815 pw.println(" -c: dump in a compact machine-parseable representation."); 13816 pw.println(" --oom: only show processes organized by oom adj."); 13817 pw.println(" --local: only collect details locally, don't call process."); 13818 pw.println("If [process] is specified it can be the name or "); 13819 pw.println("pid of a specific process to dump."); 13820 return; 13821 } else { 13822 pw.println("Unknown argument: " + opt + "; use -h for help"); 13823 } 13824 } 13825 13826 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13827 long uptime = SystemClock.uptimeMillis(); 13828 long realtime = SystemClock.elapsedRealtime(); 13829 final long[] tmpLong = new long[1]; 13830 13831 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13832 if (procs == null) { 13833 // No Java processes. Maybe they want to print a native process. 13834 if (args != null && args.length > opti 13835 && args[opti].charAt(0) != '-') { 13836 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13837 = new ArrayList<ProcessCpuTracker.Stats>(); 13838 updateCpuStatsNow(); 13839 int findPid = -1; 13840 try { 13841 findPid = Integer.parseInt(args[opti]); 13842 } catch (NumberFormatException e) { 13843 } 13844 synchronized (mProcessCpuTracker) { 13845 final int N = mProcessCpuTracker.countStats(); 13846 for (int i=0; i<N; i++) { 13847 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13848 if (st.pid == findPid || (st.baseName != null 13849 && st.baseName.equals(args[opti]))) { 13850 nativeProcs.add(st); 13851 } 13852 } 13853 } 13854 if (nativeProcs.size() > 0) { 13855 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13856 isCompact); 13857 Debug.MemoryInfo mi = null; 13858 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13859 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13860 final int pid = r.pid; 13861 if (!isCheckinRequest && dumpDetails) { 13862 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13863 } 13864 if (mi == null) { 13865 mi = new Debug.MemoryInfo(); 13866 } 13867 if (dumpDetails || (!brief && !oomOnly)) { 13868 Debug.getMemoryInfo(pid, mi); 13869 } else { 13870 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13871 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13872 } 13873 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13874 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13875 if (isCheckinRequest) { 13876 pw.println(); 13877 } 13878 } 13879 return; 13880 } 13881 } 13882 pw.println("No process found for: " + args[opti]); 13883 return; 13884 } 13885 13886 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13887 dumpDetails = true; 13888 } 13889 13890 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13891 13892 String[] innerArgs = new String[args.length-opti]; 13893 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13894 13895 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13896 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13897 long nativePss=0, dalvikPss=0, otherPss=0; 13898 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13899 13900 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13901 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13902 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13903 13904 long totalPss = 0; 13905 long cachedPss = 0; 13906 13907 Debug.MemoryInfo mi = null; 13908 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13909 final ProcessRecord r = procs.get(i); 13910 final IApplicationThread thread; 13911 final int pid; 13912 final int oomAdj; 13913 final boolean hasActivities; 13914 synchronized (this) { 13915 thread = r.thread; 13916 pid = r.pid; 13917 oomAdj = r.getSetAdjWithServices(); 13918 hasActivities = r.activities.size() > 0; 13919 } 13920 if (thread != null) { 13921 if (!isCheckinRequest && dumpDetails) { 13922 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13923 } 13924 if (mi == null) { 13925 mi = new Debug.MemoryInfo(); 13926 } 13927 if (dumpDetails || (!brief && !oomOnly)) { 13928 Debug.getMemoryInfo(pid, mi); 13929 } else { 13930 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13931 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13932 } 13933 if (dumpDetails) { 13934 if (localOnly) { 13935 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13936 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13937 if (isCheckinRequest) { 13938 pw.println(); 13939 } 13940 } else { 13941 try { 13942 pw.flush(); 13943 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13944 dumpDalvik, innerArgs); 13945 } catch (RemoteException e) { 13946 if (!isCheckinRequest) { 13947 pw.println("Got RemoteException!"); 13948 pw.flush(); 13949 } 13950 } 13951 } 13952 } 13953 13954 final long myTotalPss = mi.getTotalPss(); 13955 final long myTotalUss = mi.getTotalUss(); 13956 13957 synchronized (this) { 13958 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13959 // Record this for posterity if the process has been stable. 13960 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13961 } 13962 } 13963 13964 if (!isCheckinRequest && mi != null) { 13965 totalPss += myTotalPss; 13966 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13967 (hasActivities ? " / activities)" : ")"), 13968 r.processName, myTotalPss, pid, hasActivities); 13969 procMems.add(pssItem); 13970 procMemsMap.put(pid, pssItem); 13971 13972 nativePss += mi.nativePss; 13973 dalvikPss += mi.dalvikPss; 13974 otherPss += mi.otherPss; 13975 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13976 long mem = mi.getOtherPss(j); 13977 miscPss[j] += mem; 13978 otherPss -= mem; 13979 } 13980 13981 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13982 cachedPss += myTotalPss; 13983 } 13984 13985 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13986 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13987 || oomIndex == (oomPss.length-1)) { 13988 oomPss[oomIndex] += myTotalPss; 13989 if (oomProcs[oomIndex] == null) { 13990 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13991 } 13992 oomProcs[oomIndex].add(pssItem); 13993 break; 13994 } 13995 } 13996 } 13997 } 13998 } 13999 14000 long nativeProcTotalPss = 0; 14001 14002 if (!isCheckinRequest && procs.size() > 1) { 14003 // If we are showing aggregations, also look for native processes to 14004 // include so that our aggregations are more accurate. 14005 updateCpuStatsNow(); 14006 synchronized (mProcessCpuTracker) { 14007 final int N = mProcessCpuTracker.countStats(); 14008 for (int i=0; i<N; i++) { 14009 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14010 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14011 if (mi == null) { 14012 mi = new Debug.MemoryInfo(); 14013 } 14014 if (!brief && !oomOnly) { 14015 Debug.getMemoryInfo(st.pid, mi); 14016 } else { 14017 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14018 mi.nativePrivateDirty = (int)tmpLong[0]; 14019 } 14020 14021 final long myTotalPss = mi.getTotalPss(); 14022 totalPss += myTotalPss; 14023 nativeProcTotalPss += myTotalPss; 14024 14025 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14026 st.name, myTotalPss, st.pid, false); 14027 procMems.add(pssItem); 14028 14029 nativePss += mi.nativePss; 14030 dalvikPss += mi.dalvikPss; 14031 otherPss += mi.otherPss; 14032 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14033 long mem = mi.getOtherPss(j); 14034 miscPss[j] += mem; 14035 otherPss -= mem; 14036 } 14037 oomPss[0] += myTotalPss; 14038 if (oomProcs[0] == null) { 14039 oomProcs[0] = new ArrayList<MemItem>(); 14040 } 14041 oomProcs[0].add(pssItem); 14042 } 14043 } 14044 } 14045 14046 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14047 14048 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14049 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14050 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14051 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14052 String label = Debug.MemoryInfo.getOtherLabel(j); 14053 catMems.add(new MemItem(label, label, miscPss[j], j)); 14054 } 14055 14056 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14057 for (int j=0; j<oomPss.length; j++) { 14058 if (oomPss[j] != 0) { 14059 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14060 : DUMP_MEM_OOM_LABEL[j]; 14061 MemItem item = new MemItem(label, label, oomPss[j], 14062 DUMP_MEM_OOM_ADJ[j]); 14063 item.subitems = oomProcs[j]; 14064 oomMems.add(item); 14065 } 14066 } 14067 14068 if (!brief && !oomOnly && !isCompact) { 14069 pw.println(); 14070 pw.println("Total PSS by process:"); 14071 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14072 pw.println(); 14073 } 14074 if (!isCompact) { 14075 pw.println("Total PSS by OOM adjustment:"); 14076 } 14077 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14078 if (!brief && !oomOnly) { 14079 PrintWriter out = categoryPw != null ? categoryPw : pw; 14080 if (!isCompact) { 14081 out.println(); 14082 out.println("Total PSS by category:"); 14083 } 14084 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14085 } 14086 if (!isCompact) { 14087 pw.println(); 14088 } 14089 MemInfoReader memInfo = new MemInfoReader(); 14090 memInfo.readMemInfo(); 14091 if (nativeProcTotalPss > 0) { 14092 synchronized (this) { 14093 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14094 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14095 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14096 nativeProcTotalPss); 14097 } 14098 } 14099 if (!brief) { 14100 if (!isCompact) { 14101 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14102 pw.print(" kB (status "); 14103 switch (mLastMemoryLevel) { 14104 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14105 pw.println("normal)"); 14106 break; 14107 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14108 pw.println("moderate)"); 14109 break; 14110 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14111 pw.println("low)"); 14112 break; 14113 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14114 pw.println("critical)"); 14115 break; 14116 default: 14117 pw.print(mLastMemoryLevel); 14118 pw.println(")"); 14119 break; 14120 } 14121 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14122 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14123 pw.print(cachedPss); pw.print(" cached pss + "); 14124 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14125 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14126 } else { 14127 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14128 pw.print(cachedPss + memInfo.getCachedSizeKb() 14129 + memInfo.getFreeSizeKb()); pw.print(","); 14130 pw.println(totalPss - cachedPss); 14131 } 14132 } 14133 if (!isCompact) { 14134 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14135 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14136 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14137 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14138 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14139 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14140 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14141 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14142 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14143 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14144 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14145 } 14146 if (!brief) { 14147 if (memInfo.getZramTotalSizeKb() != 0) { 14148 if (!isCompact) { 14149 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14150 pw.print(" kB physical used for "); 14151 pw.print(memInfo.getSwapTotalSizeKb() 14152 - memInfo.getSwapFreeSizeKb()); 14153 pw.print(" kB in swap ("); 14154 pw.print(memInfo.getSwapTotalSizeKb()); 14155 pw.println(" kB total swap)"); 14156 } else { 14157 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14158 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14159 pw.println(memInfo.getSwapFreeSizeKb()); 14160 } 14161 } 14162 final int[] SINGLE_LONG_FORMAT = new int[] { 14163 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14164 }; 14165 long[] longOut = new long[1]; 14166 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14167 SINGLE_LONG_FORMAT, null, longOut, null); 14168 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14169 longOut[0] = 0; 14170 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14171 SINGLE_LONG_FORMAT, null, longOut, null); 14172 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14173 longOut[0] = 0; 14174 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14175 SINGLE_LONG_FORMAT, null, longOut, null); 14176 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14177 longOut[0] = 0; 14178 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14179 SINGLE_LONG_FORMAT, null, longOut, null); 14180 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14181 if (!isCompact) { 14182 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14183 pw.print(" KSM: "); pw.print(sharing); 14184 pw.print(" kB saved from shared "); 14185 pw.print(shared); pw.println(" kB"); 14186 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14187 pw.print(voltile); pw.println(" kB volatile"); 14188 } 14189 pw.print(" Tuning: "); 14190 pw.print(ActivityManager.staticGetMemoryClass()); 14191 pw.print(" (large "); 14192 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14193 pw.print("), oom "); 14194 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14195 pw.print(" kB"); 14196 pw.print(", restore limit "); 14197 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14198 pw.print(" kB"); 14199 if (ActivityManager.isLowRamDeviceStatic()) { 14200 pw.print(" (low-ram)"); 14201 } 14202 if (ActivityManager.isHighEndGfx()) { 14203 pw.print(" (high-end-gfx)"); 14204 } 14205 pw.println(); 14206 } else { 14207 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14208 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14209 pw.println(voltile); 14210 pw.print("tuning,"); 14211 pw.print(ActivityManager.staticGetMemoryClass()); 14212 pw.print(','); 14213 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14214 pw.print(','); 14215 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14216 if (ActivityManager.isLowRamDeviceStatic()) { 14217 pw.print(",low-ram"); 14218 } 14219 if (ActivityManager.isHighEndGfx()) { 14220 pw.print(",high-end-gfx"); 14221 } 14222 pw.println(); 14223 } 14224 } 14225 } 14226 } 14227 14228 /** 14229 * Searches array of arguments for the specified string 14230 * @param args array of argument strings 14231 * @param value value to search for 14232 * @return true if the value is contained in the array 14233 */ 14234 private static boolean scanArgs(String[] args, String value) { 14235 if (args != null) { 14236 for (String arg : args) { 14237 if (value.equals(arg)) { 14238 return true; 14239 } 14240 } 14241 } 14242 return false; 14243 } 14244 14245 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14246 ContentProviderRecord cpr, boolean always) { 14247 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14248 14249 if (!inLaunching || always) { 14250 synchronized (cpr) { 14251 cpr.launchingApp = null; 14252 cpr.notifyAll(); 14253 } 14254 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14255 String names[] = cpr.info.authority.split(";"); 14256 for (int j = 0; j < names.length; j++) { 14257 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14258 } 14259 } 14260 14261 for (int i=0; i<cpr.connections.size(); i++) { 14262 ContentProviderConnection conn = cpr.connections.get(i); 14263 if (conn.waiting) { 14264 // If this connection is waiting for the provider, then we don't 14265 // need to mess with its process unless we are always removing 14266 // or for some reason the provider is not currently launching. 14267 if (inLaunching && !always) { 14268 continue; 14269 } 14270 } 14271 ProcessRecord capp = conn.client; 14272 conn.dead = true; 14273 if (conn.stableCount > 0) { 14274 if (!capp.persistent && capp.thread != null 14275 && capp.pid != 0 14276 && capp.pid != MY_PID) { 14277 capp.kill("depends on provider " 14278 + cpr.name.flattenToShortString() 14279 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14280 } 14281 } else if (capp.thread != null && conn.provider.provider != null) { 14282 try { 14283 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14284 } catch (RemoteException e) { 14285 } 14286 // In the protocol here, we don't expect the client to correctly 14287 // clean up this connection, we'll just remove it. 14288 cpr.connections.remove(i); 14289 conn.client.conProviders.remove(conn); 14290 } 14291 } 14292 14293 if (inLaunching && always) { 14294 mLaunchingProviders.remove(cpr); 14295 } 14296 return inLaunching; 14297 } 14298 14299 /** 14300 * Main code for cleaning up a process when it has gone away. This is 14301 * called both as a result of the process dying, or directly when stopping 14302 * a process when running in single process mode. 14303 */ 14304 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14305 boolean restarting, boolean allowRestart, int index) { 14306 if (index >= 0) { 14307 removeLruProcessLocked(app); 14308 ProcessList.remove(app.pid); 14309 } 14310 14311 mProcessesToGc.remove(app); 14312 mPendingPssProcesses.remove(app); 14313 14314 // Dismiss any open dialogs. 14315 if (app.crashDialog != null && !app.forceCrashReport) { 14316 app.crashDialog.dismiss(); 14317 app.crashDialog = null; 14318 } 14319 if (app.anrDialog != null) { 14320 app.anrDialog.dismiss(); 14321 app.anrDialog = null; 14322 } 14323 if (app.waitDialog != null) { 14324 app.waitDialog.dismiss(); 14325 app.waitDialog = null; 14326 } 14327 14328 app.crashing = false; 14329 app.notResponding = false; 14330 14331 app.resetPackageList(mProcessStats); 14332 app.unlinkDeathRecipient(); 14333 app.makeInactive(mProcessStats); 14334 app.waitingToKill = null; 14335 app.forcingToForeground = null; 14336 updateProcessForegroundLocked(app, false, false); 14337 app.foregroundActivities = false; 14338 app.hasShownUi = false; 14339 app.treatLikeActivity = false; 14340 app.hasAboveClient = false; 14341 app.hasClientActivities = false; 14342 14343 mServices.killServicesLocked(app, allowRestart); 14344 14345 boolean restart = false; 14346 14347 // Remove published content providers. 14348 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14349 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14350 final boolean always = app.bad || !allowRestart; 14351 if (removeDyingProviderLocked(app, cpr, always) || always) { 14352 // We left the provider in the launching list, need to 14353 // restart it. 14354 restart = true; 14355 } 14356 14357 cpr.provider = null; 14358 cpr.proc = null; 14359 } 14360 app.pubProviders.clear(); 14361 14362 // Take care of any launching providers waiting for this process. 14363 if (checkAppInLaunchingProvidersLocked(app, false)) { 14364 restart = true; 14365 } 14366 14367 // Unregister from connected content providers. 14368 if (!app.conProviders.isEmpty()) { 14369 for (int i=0; i<app.conProviders.size(); i++) { 14370 ContentProviderConnection conn = app.conProviders.get(i); 14371 conn.provider.connections.remove(conn); 14372 } 14373 app.conProviders.clear(); 14374 } 14375 14376 // At this point there may be remaining entries in mLaunchingProviders 14377 // where we were the only one waiting, so they are no longer of use. 14378 // Look for these and clean up if found. 14379 // XXX Commented out for now. Trying to figure out a way to reproduce 14380 // the actual situation to identify what is actually going on. 14381 if (false) { 14382 for (int i=0; i<mLaunchingProviders.size(); i++) { 14383 ContentProviderRecord cpr = (ContentProviderRecord) 14384 mLaunchingProviders.get(i); 14385 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14386 synchronized (cpr) { 14387 cpr.launchingApp = null; 14388 cpr.notifyAll(); 14389 } 14390 } 14391 } 14392 } 14393 14394 skipCurrentReceiverLocked(app); 14395 14396 // Unregister any receivers. 14397 for (int i=app.receivers.size()-1; i>=0; i--) { 14398 removeReceiverLocked(app.receivers.valueAt(i)); 14399 } 14400 app.receivers.clear(); 14401 14402 // If the app is undergoing backup, tell the backup manager about it 14403 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14404 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14405 + mBackupTarget.appInfo + " died during backup"); 14406 try { 14407 IBackupManager bm = IBackupManager.Stub.asInterface( 14408 ServiceManager.getService(Context.BACKUP_SERVICE)); 14409 bm.agentDisconnected(app.info.packageName); 14410 } catch (RemoteException e) { 14411 // can't happen; backup manager is local 14412 } 14413 } 14414 14415 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14416 ProcessChangeItem item = mPendingProcessChanges.get(i); 14417 if (item.pid == app.pid) { 14418 mPendingProcessChanges.remove(i); 14419 mAvailProcessChanges.add(item); 14420 } 14421 } 14422 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14423 14424 // If the caller is restarting this app, then leave it in its 14425 // current lists and let the caller take care of it. 14426 if (restarting) { 14427 return; 14428 } 14429 14430 if (!app.persistent || app.isolated) { 14431 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14432 "Removing non-persistent process during cleanup: " + app); 14433 mProcessNames.remove(app.processName, app.uid); 14434 mIsolatedProcesses.remove(app.uid); 14435 if (mHeavyWeightProcess == app) { 14436 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14437 mHeavyWeightProcess.userId, 0)); 14438 mHeavyWeightProcess = null; 14439 } 14440 } else if (!app.removed) { 14441 // This app is persistent, so we need to keep its record around. 14442 // If it is not already on the pending app list, add it there 14443 // and start a new process for it. 14444 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14445 mPersistentStartingProcesses.add(app); 14446 restart = true; 14447 } 14448 } 14449 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14450 "Clean-up removing on hold: " + app); 14451 mProcessesOnHold.remove(app); 14452 14453 if (app == mHomeProcess) { 14454 mHomeProcess = null; 14455 } 14456 if (app == mPreviousProcess) { 14457 mPreviousProcess = null; 14458 } 14459 14460 if (restart && !app.isolated) { 14461 // We have components that still need to be running in the 14462 // process, so re-launch it. 14463 mProcessNames.put(app.processName, app.uid, app); 14464 startProcessLocked(app, "restart", app.processName); 14465 } else if (app.pid > 0 && app.pid != MY_PID) { 14466 // Goodbye! 14467 boolean removed; 14468 synchronized (mPidsSelfLocked) { 14469 mPidsSelfLocked.remove(app.pid); 14470 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14471 } 14472 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14473 if (app.isolated) { 14474 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14475 } 14476 app.setPid(0); 14477 } 14478 } 14479 14480 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14481 // Look through the content providers we are waiting to have launched, 14482 // and if any run in this process then either schedule a restart of 14483 // the process or kill the client waiting for it if this process has 14484 // gone bad. 14485 int NL = mLaunchingProviders.size(); 14486 boolean restart = false; 14487 for (int i=0; i<NL; i++) { 14488 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14489 if (cpr.launchingApp == app) { 14490 if (!alwaysBad && !app.bad) { 14491 restart = true; 14492 } else { 14493 removeDyingProviderLocked(app, cpr, true); 14494 // cpr should have been removed from mLaunchingProviders 14495 NL = mLaunchingProviders.size(); 14496 i--; 14497 } 14498 } 14499 } 14500 return restart; 14501 } 14502 14503 // ========================================================= 14504 // SERVICES 14505 // ========================================================= 14506 14507 @Override 14508 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14509 int flags) { 14510 enforceNotIsolatedCaller("getServices"); 14511 synchronized (this) { 14512 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14513 } 14514 } 14515 14516 @Override 14517 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14518 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14519 synchronized (this) { 14520 return mServices.getRunningServiceControlPanelLocked(name); 14521 } 14522 } 14523 14524 @Override 14525 public ComponentName startService(IApplicationThread caller, Intent service, 14526 String resolvedType, int userId) { 14527 enforceNotIsolatedCaller("startService"); 14528 // Refuse possible leaked file descriptors 14529 if (service != null && service.hasFileDescriptors() == true) { 14530 throw new IllegalArgumentException("File descriptors passed in Intent"); 14531 } 14532 14533 if (DEBUG_SERVICE) 14534 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14535 synchronized(this) { 14536 final int callingPid = Binder.getCallingPid(); 14537 final int callingUid = Binder.getCallingUid(); 14538 final long origId = Binder.clearCallingIdentity(); 14539 ComponentName res = mServices.startServiceLocked(caller, service, 14540 resolvedType, callingPid, callingUid, userId); 14541 Binder.restoreCallingIdentity(origId); 14542 return res; 14543 } 14544 } 14545 14546 ComponentName startServiceInPackage(int uid, 14547 Intent service, String resolvedType, int userId) { 14548 synchronized(this) { 14549 if (DEBUG_SERVICE) 14550 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14551 final long origId = Binder.clearCallingIdentity(); 14552 ComponentName res = mServices.startServiceLocked(null, service, 14553 resolvedType, -1, uid, userId); 14554 Binder.restoreCallingIdentity(origId); 14555 return res; 14556 } 14557 } 14558 14559 @Override 14560 public int stopService(IApplicationThread caller, Intent service, 14561 String resolvedType, int userId) { 14562 enforceNotIsolatedCaller("stopService"); 14563 // Refuse possible leaked file descriptors 14564 if (service != null && service.hasFileDescriptors() == true) { 14565 throw new IllegalArgumentException("File descriptors passed in Intent"); 14566 } 14567 14568 synchronized(this) { 14569 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14570 } 14571 } 14572 14573 @Override 14574 public IBinder peekService(Intent service, String resolvedType) { 14575 enforceNotIsolatedCaller("peekService"); 14576 // Refuse possible leaked file descriptors 14577 if (service != null && service.hasFileDescriptors() == true) { 14578 throw new IllegalArgumentException("File descriptors passed in Intent"); 14579 } 14580 synchronized(this) { 14581 return mServices.peekServiceLocked(service, resolvedType); 14582 } 14583 } 14584 14585 @Override 14586 public boolean stopServiceToken(ComponentName className, IBinder token, 14587 int startId) { 14588 synchronized(this) { 14589 return mServices.stopServiceTokenLocked(className, token, startId); 14590 } 14591 } 14592 14593 @Override 14594 public void setServiceForeground(ComponentName className, IBinder token, 14595 int id, Notification notification, boolean removeNotification) { 14596 synchronized(this) { 14597 mServices.setServiceForegroundLocked(className, token, id, notification, 14598 removeNotification); 14599 } 14600 } 14601 14602 @Override 14603 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14604 boolean requireFull, String name, String callerPackage) { 14605 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14606 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14607 } 14608 14609 int unsafeConvertIncomingUser(int userId) { 14610 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14611 ? mCurrentUserId : userId; 14612 } 14613 14614 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14615 int allowMode, String name, String callerPackage) { 14616 final int callingUserId = UserHandle.getUserId(callingUid); 14617 if (callingUserId == userId) { 14618 return userId; 14619 } 14620 14621 // Note that we may be accessing mCurrentUserId outside of a lock... 14622 // shouldn't be a big deal, if this is being called outside 14623 // of a locked context there is intrinsically a race with 14624 // the value the caller will receive and someone else changing it. 14625 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14626 // we will switch to the calling user if access to the current user fails. 14627 int targetUserId = unsafeConvertIncomingUser(userId); 14628 14629 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14630 final boolean allow; 14631 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14632 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14633 // If the caller has this permission, they always pass go. And collect $200. 14634 allow = true; 14635 } else if (allowMode == ALLOW_FULL_ONLY) { 14636 // We require full access, sucks to be you. 14637 allow = false; 14638 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14639 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14640 // If the caller does not have either permission, they are always doomed. 14641 allow = false; 14642 } else if (allowMode == ALLOW_NON_FULL) { 14643 // We are blanket allowing non-full access, you lucky caller! 14644 allow = true; 14645 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14646 // We may or may not allow this depending on whether the two users are 14647 // in the same profile. 14648 synchronized (mUserProfileGroupIdsSelfLocked) { 14649 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14650 UserInfo.NO_PROFILE_GROUP_ID); 14651 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14652 UserInfo.NO_PROFILE_GROUP_ID); 14653 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14654 && callingProfile == targetProfile; 14655 } 14656 } else { 14657 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14658 } 14659 if (!allow) { 14660 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14661 // In this case, they would like to just execute as their 14662 // owner user instead of failing. 14663 targetUserId = callingUserId; 14664 } else { 14665 StringBuilder builder = new StringBuilder(128); 14666 builder.append("Permission Denial: "); 14667 builder.append(name); 14668 if (callerPackage != null) { 14669 builder.append(" from "); 14670 builder.append(callerPackage); 14671 } 14672 builder.append(" asks to run as user "); 14673 builder.append(userId); 14674 builder.append(" but is calling from user "); 14675 builder.append(UserHandle.getUserId(callingUid)); 14676 builder.append("; this requires "); 14677 builder.append(INTERACT_ACROSS_USERS_FULL); 14678 if (allowMode != ALLOW_FULL_ONLY) { 14679 builder.append(" or "); 14680 builder.append(INTERACT_ACROSS_USERS); 14681 } 14682 String msg = builder.toString(); 14683 Slog.w(TAG, msg); 14684 throw new SecurityException(msg); 14685 } 14686 } 14687 } 14688 if (!allowAll && targetUserId < 0) { 14689 throw new IllegalArgumentException( 14690 "Call does not support special user #" + targetUserId); 14691 } 14692 // Check shell permission 14693 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14694 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14695 targetUserId)) { 14696 throw new SecurityException("Shell does not have permission to access user " 14697 + targetUserId + "\n " + Debug.getCallers(3)); 14698 } 14699 } 14700 return targetUserId; 14701 } 14702 14703 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14704 String className, int flags) { 14705 boolean result = false; 14706 // For apps that don't have pre-defined UIDs, check for permission 14707 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14708 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14709 if (ActivityManager.checkUidPermission( 14710 INTERACT_ACROSS_USERS, 14711 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14712 ComponentName comp = new ComponentName(aInfo.packageName, className); 14713 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14714 + " requests FLAG_SINGLE_USER, but app does not hold " 14715 + INTERACT_ACROSS_USERS; 14716 Slog.w(TAG, msg); 14717 throw new SecurityException(msg); 14718 } 14719 // Permission passed 14720 result = true; 14721 } 14722 } else if ("system".equals(componentProcessName)) { 14723 result = true; 14724 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14725 // Phone app and persistent apps are allowed to export singleuser providers. 14726 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14727 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14728 } 14729 if (DEBUG_MU) { 14730 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14731 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14732 } 14733 return result; 14734 } 14735 14736 /** 14737 * Checks to see if the caller is in the same app as the singleton 14738 * component, or the component is in a special app. It allows special apps 14739 * to export singleton components but prevents exporting singleton 14740 * components for regular apps. 14741 */ 14742 boolean isValidSingletonCall(int callingUid, int componentUid) { 14743 int componentAppId = UserHandle.getAppId(componentUid); 14744 return UserHandle.isSameApp(callingUid, componentUid) 14745 || componentAppId == Process.SYSTEM_UID 14746 || componentAppId == Process.PHONE_UID 14747 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14748 == PackageManager.PERMISSION_GRANTED; 14749 } 14750 14751 public int bindService(IApplicationThread caller, IBinder token, 14752 Intent service, String resolvedType, 14753 IServiceConnection connection, int flags, int userId) { 14754 enforceNotIsolatedCaller("bindService"); 14755 14756 // Refuse possible leaked file descriptors 14757 if (service != null && service.hasFileDescriptors() == true) { 14758 throw new IllegalArgumentException("File descriptors passed in Intent"); 14759 } 14760 14761 synchronized(this) { 14762 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14763 connection, flags, userId); 14764 } 14765 } 14766 14767 public boolean unbindService(IServiceConnection connection) { 14768 synchronized (this) { 14769 return mServices.unbindServiceLocked(connection); 14770 } 14771 } 14772 14773 public void publishService(IBinder token, Intent intent, IBinder service) { 14774 // Refuse possible leaked file descriptors 14775 if (intent != null && intent.hasFileDescriptors() == true) { 14776 throw new IllegalArgumentException("File descriptors passed in Intent"); 14777 } 14778 14779 synchronized(this) { 14780 if (!(token instanceof ServiceRecord)) { 14781 throw new IllegalArgumentException("Invalid service token"); 14782 } 14783 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14784 } 14785 } 14786 14787 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14788 // Refuse possible leaked file descriptors 14789 if (intent != null && intent.hasFileDescriptors() == true) { 14790 throw new IllegalArgumentException("File descriptors passed in Intent"); 14791 } 14792 14793 synchronized(this) { 14794 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14795 } 14796 } 14797 14798 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14799 synchronized(this) { 14800 if (!(token instanceof ServiceRecord)) { 14801 throw new IllegalArgumentException("Invalid service token"); 14802 } 14803 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14804 } 14805 } 14806 14807 // ========================================================= 14808 // BACKUP AND RESTORE 14809 // ========================================================= 14810 14811 // Cause the target app to be launched if necessary and its backup agent 14812 // instantiated. The backup agent will invoke backupAgentCreated() on the 14813 // activity manager to announce its creation. 14814 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14815 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14816 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14817 14818 synchronized(this) { 14819 // !!! TODO: currently no check here that we're already bound 14820 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14821 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14822 synchronized (stats) { 14823 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14824 } 14825 14826 // Backup agent is now in use, its package can't be stopped. 14827 try { 14828 AppGlobals.getPackageManager().setPackageStoppedState( 14829 app.packageName, false, UserHandle.getUserId(app.uid)); 14830 } catch (RemoteException e) { 14831 } catch (IllegalArgumentException e) { 14832 Slog.w(TAG, "Failed trying to unstop package " 14833 + app.packageName + ": " + e); 14834 } 14835 14836 BackupRecord r = new BackupRecord(ss, app, backupMode); 14837 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14838 ? new ComponentName(app.packageName, app.backupAgentName) 14839 : new ComponentName("android", "FullBackupAgent"); 14840 // startProcessLocked() returns existing proc's record if it's already running 14841 ProcessRecord proc = startProcessLocked(app.processName, app, 14842 false, 0, "backup", hostingName, false, false, false); 14843 if (proc == null) { 14844 Slog.e(TAG, "Unable to start backup agent process " + r); 14845 return false; 14846 } 14847 14848 r.app = proc; 14849 mBackupTarget = r; 14850 mBackupAppName = app.packageName; 14851 14852 // Try not to kill the process during backup 14853 updateOomAdjLocked(proc); 14854 14855 // If the process is already attached, schedule the creation of the backup agent now. 14856 // If it is not yet live, this will be done when it attaches to the framework. 14857 if (proc.thread != null) { 14858 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14859 try { 14860 proc.thread.scheduleCreateBackupAgent(app, 14861 compatibilityInfoForPackageLocked(app), backupMode); 14862 } catch (RemoteException e) { 14863 // Will time out on the backup manager side 14864 } 14865 } else { 14866 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14867 } 14868 // Invariants: at this point, the target app process exists and the application 14869 // is either already running or in the process of coming up. mBackupTarget and 14870 // mBackupAppName describe the app, so that when it binds back to the AM we 14871 // know that it's scheduled for a backup-agent operation. 14872 } 14873 14874 return true; 14875 } 14876 14877 @Override 14878 public void clearPendingBackup() { 14879 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14880 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14881 14882 synchronized (this) { 14883 mBackupTarget = null; 14884 mBackupAppName = null; 14885 } 14886 } 14887 14888 // A backup agent has just come up 14889 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14890 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14891 + " = " + agent); 14892 14893 synchronized(this) { 14894 if (!agentPackageName.equals(mBackupAppName)) { 14895 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14896 return; 14897 } 14898 } 14899 14900 long oldIdent = Binder.clearCallingIdentity(); 14901 try { 14902 IBackupManager bm = IBackupManager.Stub.asInterface( 14903 ServiceManager.getService(Context.BACKUP_SERVICE)); 14904 bm.agentConnected(agentPackageName, agent); 14905 } catch (RemoteException e) { 14906 // can't happen; the backup manager service is local 14907 } catch (Exception e) { 14908 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14909 e.printStackTrace(); 14910 } finally { 14911 Binder.restoreCallingIdentity(oldIdent); 14912 } 14913 } 14914 14915 // done with this agent 14916 public void unbindBackupAgent(ApplicationInfo appInfo) { 14917 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14918 if (appInfo == null) { 14919 Slog.w(TAG, "unbind backup agent for null app"); 14920 return; 14921 } 14922 14923 synchronized(this) { 14924 try { 14925 if (mBackupAppName == null) { 14926 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14927 return; 14928 } 14929 14930 if (!mBackupAppName.equals(appInfo.packageName)) { 14931 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14932 return; 14933 } 14934 14935 // Not backing this app up any more; reset its OOM adjustment 14936 final ProcessRecord proc = mBackupTarget.app; 14937 updateOomAdjLocked(proc); 14938 14939 // If the app crashed during backup, 'thread' will be null here 14940 if (proc.thread != null) { 14941 try { 14942 proc.thread.scheduleDestroyBackupAgent(appInfo, 14943 compatibilityInfoForPackageLocked(appInfo)); 14944 } catch (Exception e) { 14945 Slog.e(TAG, "Exception when unbinding backup agent:"); 14946 e.printStackTrace(); 14947 } 14948 } 14949 } finally { 14950 mBackupTarget = null; 14951 mBackupAppName = null; 14952 } 14953 } 14954 } 14955 // ========================================================= 14956 // BROADCASTS 14957 // ========================================================= 14958 14959 private final List getStickiesLocked(String action, IntentFilter filter, 14960 List cur, int userId) { 14961 final ContentResolver resolver = mContext.getContentResolver(); 14962 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14963 if (stickies == null) { 14964 return cur; 14965 } 14966 final ArrayList<Intent> list = stickies.get(action); 14967 if (list == null) { 14968 return cur; 14969 } 14970 int N = list.size(); 14971 for (int i=0; i<N; i++) { 14972 Intent intent = list.get(i); 14973 if (filter.match(resolver, intent, true, TAG) >= 0) { 14974 if (cur == null) { 14975 cur = new ArrayList<Intent>(); 14976 } 14977 cur.add(intent); 14978 } 14979 } 14980 return cur; 14981 } 14982 14983 boolean isPendingBroadcastProcessLocked(int pid) { 14984 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14985 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14986 } 14987 14988 void skipPendingBroadcastLocked(int pid) { 14989 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14990 for (BroadcastQueue queue : mBroadcastQueues) { 14991 queue.skipPendingBroadcastLocked(pid); 14992 } 14993 } 14994 14995 // The app just attached; send any pending broadcasts that it should receive 14996 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14997 boolean didSomething = false; 14998 for (BroadcastQueue queue : mBroadcastQueues) { 14999 didSomething |= queue.sendPendingBroadcastsLocked(app); 15000 } 15001 return didSomething; 15002 } 15003 15004 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15005 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15006 enforceNotIsolatedCaller("registerReceiver"); 15007 int callingUid; 15008 int callingPid; 15009 synchronized(this) { 15010 ProcessRecord callerApp = null; 15011 if (caller != null) { 15012 callerApp = getRecordForAppLocked(caller); 15013 if (callerApp == null) { 15014 throw new SecurityException( 15015 "Unable to find app for caller " + caller 15016 + " (pid=" + Binder.getCallingPid() 15017 + ") when registering receiver " + receiver); 15018 } 15019 if (callerApp.info.uid != Process.SYSTEM_UID && 15020 !callerApp.pkgList.containsKey(callerPackage) && 15021 !"android".equals(callerPackage)) { 15022 throw new SecurityException("Given caller package " + callerPackage 15023 + " is not running in process " + callerApp); 15024 } 15025 callingUid = callerApp.info.uid; 15026 callingPid = callerApp.pid; 15027 } else { 15028 callerPackage = null; 15029 callingUid = Binder.getCallingUid(); 15030 callingPid = Binder.getCallingPid(); 15031 } 15032 15033 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15034 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15035 15036 List allSticky = null; 15037 15038 // Look for any matching sticky broadcasts... 15039 Iterator actions = filter.actionsIterator(); 15040 if (actions != null) { 15041 while (actions.hasNext()) { 15042 String action = (String)actions.next(); 15043 allSticky = getStickiesLocked(action, filter, allSticky, 15044 UserHandle.USER_ALL); 15045 allSticky = getStickiesLocked(action, filter, allSticky, 15046 UserHandle.getUserId(callingUid)); 15047 } 15048 } else { 15049 allSticky = getStickiesLocked(null, filter, allSticky, 15050 UserHandle.USER_ALL); 15051 allSticky = getStickiesLocked(null, filter, allSticky, 15052 UserHandle.getUserId(callingUid)); 15053 } 15054 15055 // The first sticky in the list is returned directly back to 15056 // the client. 15057 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15058 15059 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15060 + ": " + sticky); 15061 15062 if (receiver == null) { 15063 return sticky; 15064 } 15065 15066 ReceiverList rl 15067 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15068 if (rl == null) { 15069 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15070 userId, receiver); 15071 if (rl.app != null) { 15072 rl.app.receivers.add(rl); 15073 } else { 15074 try { 15075 receiver.asBinder().linkToDeath(rl, 0); 15076 } catch (RemoteException e) { 15077 return sticky; 15078 } 15079 rl.linkedToDeath = true; 15080 } 15081 mRegisteredReceivers.put(receiver.asBinder(), rl); 15082 } else if (rl.uid != callingUid) { 15083 throw new IllegalArgumentException( 15084 "Receiver requested to register for uid " + callingUid 15085 + " was previously registered for uid " + rl.uid); 15086 } else if (rl.pid != callingPid) { 15087 throw new IllegalArgumentException( 15088 "Receiver requested to register for pid " + callingPid 15089 + " was previously registered for pid " + rl.pid); 15090 } else if (rl.userId != userId) { 15091 throw new IllegalArgumentException( 15092 "Receiver requested to register for user " + userId 15093 + " was previously registered for user " + rl.userId); 15094 } 15095 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15096 permission, callingUid, userId); 15097 rl.add(bf); 15098 if (!bf.debugCheck()) { 15099 Slog.w(TAG, "==> For Dynamic broadast"); 15100 } 15101 mReceiverResolver.addFilter(bf); 15102 15103 // Enqueue broadcasts for all existing stickies that match 15104 // this filter. 15105 if (allSticky != null) { 15106 ArrayList receivers = new ArrayList(); 15107 receivers.add(bf); 15108 15109 int N = allSticky.size(); 15110 for (int i=0; i<N; i++) { 15111 Intent intent = (Intent)allSticky.get(i); 15112 BroadcastQueue queue = broadcastQueueForIntent(intent); 15113 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15114 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15115 null, null, false, true, true, -1); 15116 queue.enqueueParallelBroadcastLocked(r); 15117 queue.scheduleBroadcastsLocked(); 15118 } 15119 } 15120 15121 return sticky; 15122 } 15123 } 15124 15125 public void unregisterReceiver(IIntentReceiver receiver) { 15126 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15127 15128 final long origId = Binder.clearCallingIdentity(); 15129 try { 15130 boolean doTrim = false; 15131 15132 synchronized(this) { 15133 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15134 if (rl != null) { 15135 if (rl.curBroadcast != null) { 15136 BroadcastRecord r = rl.curBroadcast; 15137 final boolean doNext = finishReceiverLocked( 15138 receiver.asBinder(), r.resultCode, r.resultData, 15139 r.resultExtras, r.resultAbort); 15140 if (doNext) { 15141 doTrim = true; 15142 r.queue.processNextBroadcast(false); 15143 } 15144 } 15145 15146 if (rl.app != null) { 15147 rl.app.receivers.remove(rl); 15148 } 15149 removeReceiverLocked(rl); 15150 if (rl.linkedToDeath) { 15151 rl.linkedToDeath = false; 15152 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15153 } 15154 } 15155 } 15156 15157 // If we actually concluded any broadcasts, we might now be able 15158 // to trim the recipients' apps from our working set 15159 if (doTrim) { 15160 trimApplications(); 15161 return; 15162 } 15163 15164 } finally { 15165 Binder.restoreCallingIdentity(origId); 15166 } 15167 } 15168 15169 void removeReceiverLocked(ReceiverList rl) { 15170 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15171 int N = rl.size(); 15172 for (int i=0; i<N; i++) { 15173 mReceiverResolver.removeFilter(rl.get(i)); 15174 } 15175 } 15176 15177 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15178 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15179 ProcessRecord r = mLruProcesses.get(i); 15180 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15181 try { 15182 r.thread.dispatchPackageBroadcast(cmd, packages); 15183 } catch (RemoteException ex) { 15184 } 15185 } 15186 } 15187 } 15188 15189 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15190 int callingUid, int[] users) { 15191 List<ResolveInfo> receivers = null; 15192 try { 15193 HashSet<ComponentName> singleUserReceivers = null; 15194 boolean scannedFirstReceivers = false; 15195 for (int user : users) { 15196 // Skip users that have Shell restrictions 15197 if (callingUid == Process.SHELL_UID 15198 && getUserManagerLocked().hasUserRestriction( 15199 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15200 continue; 15201 } 15202 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15203 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15204 if (user != 0 && newReceivers != null) { 15205 // If this is not the primary user, we need to check for 15206 // any receivers that should be filtered out. 15207 for (int i=0; i<newReceivers.size(); i++) { 15208 ResolveInfo ri = newReceivers.get(i); 15209 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15210 newReceivers.remove(i); 15211 i--; 15212 } 15213 } 15214 } 15215 if (newReceivers != null && newReceivers.size() == 0) { 15216 newReceivers = null; 15217 } 15218 if (receivers == null) { 15219 receivers = newReceivers; 15220 } else if (newReceivers != null) { 15221 // We need to concatenate the additional receivers 15222 // found with what we have do far. This would be easy, 15223 // but we also need to de-dup any receivers that are 15224 // singleUser. 15225 if (!scannedFirstReceivers) { 15226 // Collect any single user receivers we had already retrieved. 15227 scannedFirstReceivers = true; 15228 for (int i=0; i<receivers.size(); i++) { 15229 ResolveInfo ri = receivers.get(i); 15230 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15231 ComponentName cn = new ComponentName( 15232 ri.activityInfo.packageName, ri.activityInfo.name); 15233 if (singleUserReceivers == null) { 15234 singleUserReceivers = new HashSet<ComponentName>(); 15235 } 15236 singleUserReceivers.add(cn); 15237 } 15238 } 15239 } 15240 // Add the new results to the existing results, tracking 15241 // and de-dupping single user receivers. 15242 for (int i=0; i<newReceivers.size(); i++) { 15243 ResolveInfo ri = newReceivers.get(i); 15244 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15245 ComponentName cn = new ComponentName( 15246 ri.activityInfo.packageName, ri.activityInfo.name); 15247 if (singleUserReceivers == null) { 15248 singleUserReceivers = new HashSet<ComponentName>(); 15249 } 15250 if (!singleUserReceivers.contains(cn)) { 15251 singleUserReceivers.add(cn); 15252 receivers.add(ri); 15253 } 15254 } else { 15255 receivers.add(ri); 15256 } 15257 } 15258 } 15259 } 15260 } catch (RemoteException ex) { 15261 // pm is in same process, this will never happen. 15262 } 15263 return receivers; 15264 } 15265 15266 private final int broadcastIntentLocked(ProcessRecord callerApp, 15267 String callerPackage, Intent intent, String resolvedType, 15268 IIntentReceiver resultTo, int resultCode, String resultData, 15269 Bundle map, String requiredPermission, int appOp, 15270 boolean ordered, boolean sticky, int callingPid, int callingUid, 15271 int userId) { 15272 intent = new Intent(intent); 15273 15274 // By default broadcasts do not go to stopped apps. 15275 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15276 15277 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15278 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15279 + " ordered=" + ordered + " userid=" + userId); 15280 if ((resultTo != null) && !ordered) { 15281 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15282 } 15283 15284 userId = handleIncomingUser(callingPid, callingUid, userId, 15285 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15286 15287 // Make sure that the user who is receiving this broadcast is started. 15288 // If not, we will just skip it. 15289 15290 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15291 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15292 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15293 Slog.w(TAG, "Skipping broadcast of " + intent 15294 + ": user " + userId + " is stopped"); 15295 return ActivityManager.BROADCAST_SUCCESS; 15296 } 15297 } 15298 15299 /* 15300 * Prevent non-system code (defined here to be non-persistent 15301 * processes) from sending protected broadcasts. 15302 */ 15303 int callingAppId = UserHandle.getAppId(callingUid); 15304 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15305 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15306 || callingAppId == Process.NFC_UID || callingUid == 0) { 15307 // Always okay. 15308 } else if (callerApp == null || !callerApp.persistent) { 15309 try { 15310 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15311 intent.getAction())) { 15312 String msg = "Permission Denial: not allowed to send broadcast " 15313 + intent.getAction() + " from pid=" 15314 + callingPid + ", uid=" + callingUid; 15315 Slog.w(TAG, msg); 15316 throw new SecurityException(msg); 15317 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15318 // Special case for compatibility: we don't want apps to send this, 15319 // but historically it has not been protected and apps may be using it 15320 // to poke their own app widget. So, instead of making it protected, 15321 // just limit it to the caller. 15322 if (callerApp == null) { 15323 String msg = "Permission Denial: not allowed to send broadcast " 15324 + intent.getAction() + " from unknown caller."; 15325 Slog.w(TAG, msg); 15326 throw new SecurityException(msg); 15327 } else if (intent.getComponent() != null) { 15328 // They are good enough to send to an explicit component... verify 15329 // it is being sent to the calling app. 15330 if (!intent.getComponent().getPackageName().equals( 15331 callerApp.info.packageName)) { 15332 String msg = "Permission Denial: not allowed to send broadcast " 15333 + intent.getAction() + " to " 15334 + intent.getComponent().getPackageName() + " from " 15335 + callerApp.info.packageName; 15336 Slog.w(TAG, msg); 15337 throw new SecurityException(msg); 15338 } 15339 } else { 15340 // Limit broadcast to their own package. 15341 intent.setPackage(callerApp.info.packageName); 15342 } 15343 } 15344 } catch (RemoteException e) { 15345 Slog.w(TAG, "Remote exception", e); 15346 return ActivityManager.BROADCAST_SUCCESS; 15347 } 15348 } 15349 15350 // Handle special intents: if this broadcast is from the package 15351 // manager about a package being removed, we need to remove all of 15352 // its activities from the history stack. 15353 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15354 intent.getAction()); 15355 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15356 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15357 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15358 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15359 || uidRemoved) { 15360 if (checkComponentPermission( 15361 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15362 callingPid, callingUid, -1, true) 15363 == PackageManager.PERMISSION_GRANTED) { 15364 if (uidRemoved) { 15365 final Bundle intentExtras = intent.getExtras(); 15366 final int uid = intentExtras != null 15367 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15368 if (uid >= 0) { 15369 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15370 synchronized (bs) { 15371 bs.removeUidStatsLocked(uid); 15372 } 15373 mAppOpsService.uidRemoved(uid); 15374 } 15375 } else { 15376 // If resources are unavailable just force stop all 15377 // those packages and flush the attribute cache as well. 15378 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15379 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15380 if (list != null && (list.length > 0)) { 15381 for (String pkg : list) { 15382 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15383 "storage unmount"); 15384 } 15385 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15386 sendPackageBroadcastLocked( 15387 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15388 } 15389 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15390 intent.getAction())) { 15391 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15392 } else { 15393 Uri data = intent.getData(); 15394 String ssp; 15395 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15396 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15397 intent.getAction()); 15398 boolean fullUninstall = removed && 15399 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15400 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15401 forceStopPackageLocked(ssp, UserHandle.getAppId( 15402 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15403 false, fullUninstall, userId, 15404 removed ? "pkg removed" : "pkg changed"); 15405 } 15406 if (removed) { 15407 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15408 new String[] {ssp}, userId); 15409 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15410 mAppOpsService.packageRemoved( 15411 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15412 15413 // Remove all permissions granted from/to this package 15414 removeUriPermissionsForPackageLocked(ssp, userId, true); 15415 } 15416 } 15417 } 15418 } 15419 } 15420 } else { 15421 String msg = "Permission Denial: " + intent.getAction() 15422 + " broadcast from " + callerPackage + " (pid=" + callingPid 15423 + ", uid=" + callingUid + ")" 15424 + " requires " 15425 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15426 Slog.w(TAG, msg); 15427 throw new SecurityException(msg); 15428 } 15429 15430 // Special case for adding a package: by default turn on compatibility 15431 // mode. 15432 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15433 Uri data = intent.getData(); 15434 String ssp; 15435 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15436 mCompatModePackages.handlePackageAddedLocked(ssp, 15437 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15438 } 15439 } 15440 15441 /* 15442 * If this is the time zone changed action, queue up a message that will reset the timezone 15443 * of all currently running processes. This message will get queued up before the broadcast 15444 * happens. 15445 */ 15446 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15447 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15448 } 15449 15450 /* 15451 * If the user set the time, let all running processes know. 15452 */ 15453 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15454 final int is24Hour = intent.getBooleanExtra( 15455 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15456 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15457 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15458 synchronized (stats) { 15459 stats.noteCurrentTimeChangedLocked(); 15460 } 15461 } 15462 15463 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15464 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15465 } 15466 15467 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15468 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15469 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15470 } 15471 15472 // Add to the sticky list if requested. 15473 if (sticky) { 15474 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15475 callingPid, callingUid) 15476 != PackageManager.PERMISSION_GRANTED) { 15477 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15478 + callingPid + ", uid=" + callingUid 15479 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15480 Slog.w(TAG, msg); 15481 throw new SecurityException(msg); 15482 } 15483 if (requiredPermission != null) { 15484 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15485 + " and enforce permission " + requiredPermission); 15486 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15487 } 15488 if (intent.getComponent() != null) { 15489 throw new SecurityException( 15490 "Sticky broadcasts can't target a specific component"); 15491 } 15492 // We use userId directly here, since the "all" target is maintained 15493 // as a separate set of sticky broadcasts. 15494 if (userId != UserHandle.USER_ALL) { 15495 // But first, if this is not a broadcast to all users, then 15496 // make sure it doesn't conflict with an existing broadcast to 15497 // all users. 15498 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15499 UserHandle.USER_ALL); 15500 if (stickies != null) { 15501 ArrayList<Intent> list = stickies.get(intent.getAction()); 15502 if (list != null) { 15503 int N = list.size(); 15504 int i; 15505 for (i=0; i<N; i++) { 15506 if (intent.filterEquals(list.get(i))) { 15507 throw new IllegalArgumentException( 15508 "Sticky broadcast " + intent + " for user " 15509 + userId + " conflicts with existing global broadcast"); 15510 } 15511 } 15512 } 15513 } 15514 } 15515 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15516 if (stickies == null) { 15517 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15518 mStickyBroadcasts.put(userId, stickies); 15519 } 15520 ArrayList<Intent> list = stickies.get(intent.getAction()); 15521 if (list == null) { 15522 list = new ArrayList<Intent>(); 15523 stickies.put(intent.getAction(), list); 15524 } 15525 int N = list.size(); 15526 int i; 15527 for (i=0; i<N; i++) { 15528 if (intent.filterEquals(list.get(i))) { 15529 // This sticky already exists, replace it. 15530 list.set(i, new Intent(intent)); 15531 break; 15532 } 15533 } 15534 if (i >= N) { 15535 list.add(new Intent(intent)); 15536 } 15537 } 15538 15539 int[] users; 15540 if (userId == UserHandle.USER_ALL) { 15541 // Caller wants broadcast to go to all started users. 15542 users = mStartedUserArray; 15543 } else { 15544 // Caller wants broadcast to go to one specific user. 15545 users = new int[] {userId}; 15546 } 15547 15548 // Figure out who all will receive this broadcast. 15549 List receivers = null; 15550 List<BroadcastFilter> registeredReceivers = null; 15551 // Need to resolve the intent to interested receivers... 15552 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15553 == 0) { 15554 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15555 } 15556 if (intent.getComponent() == null) { 15557 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15558 // Query one target user at a time, excluding shell-restricted users 15559 UserManagerService ums = getUserManagerLocked(); 15560 for (int i = 0; i < users.length; i++) { 15561 if (ums.hasUserRestriction( 15562 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15563 continue; 15564 } 15565 List<BroadcastFilter> registeredReceiversForUser = 15566 mReceiverResolver.queryIntent(intent, 15567 resolvedType, false, users[i]); 15568 if (registeredReceivers == null) { 15569 registeredReceivers = registeredReceiversForUser; 15570 } else if (registeredReceiversForUser != null) { 15571 registeredReceivers.addAll(registeredReceiversForUser); 15572 } 15573 } 15574 } else { 15575 registeredReceivers = mReceiverResolver.queryIntent(intent, 15576 resolvedType, false, userId); 15577 } 15578 } 15579 15580 final boolean replacePending = 15581 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15582 15583 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15584 + " replacePending=" + replacePending); 15585 15586 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15587 if (!ordered && NR > 0) { 15588 // If we are not serializing this broadcast, then send the 15589 // registered receivers separately so they don't wait for the 15590 // components to be launched. 15591 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15592 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15593 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15594 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15595 ordered, sticky, false, userId); 15596 if (DEBUG_BROADCAST) Slog.v( 15597 TAG, "Enqueueing parallel broadcast " + r); 15598 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15599 if (!replaced) { 15600 queue.enqueueParallelBroadcastLocked(r); 15601 queue.scheduleBroadcastsLocked(); 15602 } 15603 registeredReceivers = null; 15604 NR = 0; 15605 } 15606 15607 // Merge into one list. 15608 int ir = 0; 15609 if (receivers != null) { 15610 // A special case for PACKAGE_ADDED: do not allow the package 15611 // being added to see this broadcast. This prevents them from 15612 // using this as a back door to get run as soon as they are 15613 // installed. Maybe in the future we want to have a special install 15614 // broadcast or such for apps, but we'd like to deliberately make 15615 // this decision. 15616 String skipPackages[] = null; 15617 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15618 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15619 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15620 Uri data = intent.getData(); 15621 if (data != null) { 15622 String pkgName = data.getSchemeSpecificPart(); 15623 if (pkgName != null) { 15624 skipPackages = new String[] { pkgName }; 15625 } 15626 } 15627 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15628 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15629 } 15630 if (skipPackages != null && (skipPackages.length > 0)) { 15631 for (String skipPackage : skipPackages) { 15632 if (skipPackage != null) { 15633 int NT = receivers.size(); 15634 for (int it=0; it<NT; it++) { 15635 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15636 if (curt.activityInfo.packageName.equals(skipPackage)) { 15637 receivers.remove(it); 15638 it--; 15639 NT--; 15640 } 15641 } 15642 } 15643 } 15644 } 15645 15646 int NT = receivers != null ? receivers.size() : 0; 15647 int it = 0; 15648 ResolveInfo curt = null; 15649 BroadcastFilter curr = null; 15650 while (it < NT && ir < NR) { 15651 if (curt == null) { 15652 curt = (ResolveInfo)receivers.get(it); 15653 } 15654 if (curr == null) { 15655 curr = registeredReceivers.get(ir); 15656 } 15657 if (curr.getPriority() >= curt.priority) { 15658 // Insert this broadcast record into the final list. 15659 receivers.add(it, curr); 15660 ir++; 15661 curr = null; 15662 it++; 15663 NT++; 15664 } else { 15665 // Skip to the next ResolveInfo in the final list. 15666 it++; 15667 curt = null; 15668 } 15669 } 15670 } 15671 while (ir < NR) { 15672 if (receivers == null) { 15673 receivers = new ArrayList(); 15674 } 15675 receivers.add(registeredReceivers.get(ir)); 15676 ir++; 15677 } 15678 15679 if ((receivers != null && receivers.size() > 0) 15680 || resultTo != null) { 15681 BroadcastQueue queue = broadcastQueueForIntent(intent); 15682 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15683 callerPackage, callingPid, callingUid, resolvedType, 15684 requiredPermission, appOp, receivers, resultTo, resultCode, 15685 resultData, map, ordered, sticky, false, userId); 15686 if (DEBUG_BROADCAST) Slog.v( 15687 TAG, "Enqueueing ordered broadcast " + r 15688 + ": prev had " + queue.mOrderedBroadcasts.size()); 15689 if (DEBUG_BROADCAST) { 15690 int seq = r.intent.getIntExtra("seq", -1); 15691 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15692 } 15693 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15694 if (!replaced) { 15695 queue.enqueueOrderedBroadcastLocked(r); 15696 queue.scheduleBroadcastsLocked(); 15697 } 15698 } 15699 15700 return ActivityManager.BROADCAST_SUCCESS; 15701 } 15702 15703 final Intent verifyBroadcastLocked(Intent intent) { 15704 // Refuse possible leaked file descriptors 15705 if (intent != null && intent.hasFileDescriptors() == true) { 15706 throw new IllegalArgumentException("File descriptors passed in Intent"); 15707 } 15708 15709 int flags = intent.getFlags(); 15710 15711 if (!mProcessesReady) { 15712 // if the caller really truly claims to know what they're doing, go 15713 // ahead and allow the broadcast without launching any receivers 15714 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15715 intent = new Intent(intent); 15716 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15717 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15718 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15719 + " before boot completion"); 15720 throw new IllegalStateException("Cannot broadcast before boot completed"); 15721 } 15722 } 15723 15724 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15725 throw new IllegalArgumentException( 15726 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15727 } 15728 15729 return intent; 15730 } 15731 15732 public final int broadcastIntent(IApplicationThread caller, 15733 Intent intent, String resolvedType, IIntentReceiver resultTo, 15734 int resultCode, String resultData, Bundle map, 15735 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15736 enforceNotIsolatedCaller("broadcastIntent"); 15737 synchronized(this) { 15738 intent = verifyBroadcastLocked(intent); 15739 15740 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15741 final int callingPid = Binder.getCallingPid(); 15742 final int callingUid = Binder.getCallingUid(); 15743 final long origId = Binder.clearCallingIdentity(); 15744 int res = broadcastIntentLocked(callerApp, 15745 callerApp != null ? callerApp.info.packageName : null, 15746 intent, resolvedType, resultTo, 15747 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15748 callingPid, callingUid, userId); 15749 Binder.restoreCallingIdentity(origId); 15750 return res; 15751 } 15752 } 15753 15754 int broadcastIntentInPackage(String packageName, int uid, 15755 Intent intent, String resolvedType, IIntentReceiver resultTo, 15756 int resultCode, String resultData, Bundle map, 15757 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15758 synchronized(this) { 15759 intent = verifyBroadcastLocked(intent); 15760 15761 final long origId = Binder.clearCallingIdentity(); 15762 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15763 resultTo, resultCode, resultData, map, requiredPermission, 15764 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15765 Binder.restoreCallingIdentity(origId); 15766 return res; 15767 } 15768 } 15769 15770 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15771 // Refuse possible leaked file descriptors 15772 if (intent != null && intent.hasFileDescriptors() == true) { 15773 throw new IllegalArgumentException("File descriptors passed in Intent"); 15774 } 15775 15776 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15777 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15778 15779 synchronized(this) { 15780 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15781 != PackageManager.PERMISSION_GRANTED) { 15782 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15783 + Binder.getCallingPid() 15784 + ", uid=" + Binder.getCallingUid() 15785 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15786 Slog.w(TAG, msg); 15787 throw new SecurityException(msg); 15788 } 15789 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15790 if (stickies != null) { 15791 ArrayList<Intent> list = stickies.get(intent.getAction()); 15792 if (list != null) { 15793 int N = list.size(); 15794 int i; 15795 for (i=0; i<N; i++) { 15796 if (intent.filterEquals(list.get(i))) { 15797 list.remove(i); 15798 break; 15799 } 15800 } 15801 if (list.size() <= 0) { 15802 stickies.remove(intent.getAction()); 15803 } 15804 } 15805 if (stickies.size() <= 0) { 15806 mStickyBroadcasts.remove(userId); 15807 } 15808 } 15809 } 15810 } 15811 15812 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15813 String resultData, Bundle resultExtras, boolean resultAbort) { 15814 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15815 if (r == null) { 15816 Slog.w(TAG, "finishReceiver called but not found on queue"); 15817 return false; 15818 } 15819 15820 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15821 } 15822 15823 void backgroundServicesFinishedLocked(int userId) { 15824 for (BroadcastQueue queue : mBroadcastQueues) { 15825 queue.backgroundServicesFinishedLocked(userId); 15826 } 15827 } 15828 15829 public void finishReceiver(IBinder who, int resultCode, String resultData, 15830 Bundle resultExtras, boolean resultAbort) { 15831 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15832 15833 // Refuse possible leaked file descriptors 15834 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15835 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15836 } 15837 15838 final long origId = Binder.clearCallingIdentity(); 15839 try { 15840 boolean doNext = false; 15841 BroadcastRecord r; 15842 15843 synchronized(this) { 15844 r = broadcastRecordForReceiverLocked(who); 15845 if (r != null) { 15846 doNext = r.queue.finishReceiverLocked(r, resultCode, 15847 resultData, resultExtras, resultAbort, true); 15848 } 15849 } 15850 15851 if (doNext) { 15852 r.queue.processNextBroadcast(false); 15853 } 15854 trimApplications(); 15855 } finally { 15856 Binder.restoreCallingIdentity(origId); 15857 } 15858 } 15859 15860 // ========================================================= 15861 // INSTRUMENTATION 15862 // ========================================================= 15863 15864 public boolean startInstrumentation(ComponentName className, 15865 String profileFile, int flags, Bundle arguments, 15866 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15867 int userId, String abiOverride) { 15868 enforceNotIsolatedCaller("startInstrumentation"); 15869 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15870 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15871 // Refuse possible leaked file descriptors 15872 if (arguments != null && arguments.hasFileDescriptors()) { 15873 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15874 } 15875 15876 synchronized(this) { 15877 InstrumentationInfo ii = null; 15878 ApplicationInfo ai = null; 15879 try { 15880 ii = mContext.getPackageManager().getInstrumentationInfo( 15881 className, STOCK_PM_FLAGS); 15882 ai = AppGlobals.getPackageManager().getApplicationInfo( 15883 ii.targetPackage, STOCK_PM_FLAGS, userId); 15884 } catch (PackageManager.NameNotFoundException e) { 15885 } catch (RemoteException e) { 15886 } 15887 if (ii == null) { 15888 reportStartInstrumentationFailure(watcher, className, 15889 "Unable to find instrumentation info for: " + className); 15890 return false; 15891 } 15892 if (ai == null) { 15893 reportStartInstrumentationFailure(watcher, className, 15894 "Unable to find instrumentation target package: " + ii.targetPackage); 15895 return false; 15896 } 15897 15898 int match = mContext.getPackageManager().checkSignatures( 15899 ii.targetPackage, ii.packageName); 15900 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15901 String msg = "Permission Denial: starting instrumentation " 15902 + className + " from pid=" 15903 + Binder.getCallingPid() 15904 + ", uid=" + Binder.getCallingPid() 15905 + " not allowed because package " + ii.packageName 15906 + " does not have a signature matching the target " 15907 + ii.targetPackage; 15908 reportStartInstrumentationFailure(watcher, className, msg); 15909 throw new SecurityException(msg); 15910 } 15911 15912 final long origId = Binder.clearCallingIdentity(); 15913 // Instrumentation can kill and relaunch even persistent processes 15914 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15915 "start instr"); 15916 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15917 app.instrumentationClass = className; 15918 app.instrumentationInfo = ai; 15919 app.instrumentationProfileFile = profileFile; 15920 app.instrumentationArguments = arguments; 15921 app.instrumentationWatcher = watcher; 15922 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15923 app.instrumentationResultClass = className; 15924 Binder.restoreCallingIdentity(origId); 15925 } 15926 15927 return true; 15928 } 15929 15930 /** 15931 * Report errors that occur while attempting to start Instrumentation. Always writes the 15932 * error to the logs, but if somebody is watching, send the report there too. This enables 15933 * the "am" command to report errors with more information. 15934 * 15935 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15936 * @param cn The component name of the instrumentation. 15937 * @param report The error report. 15938 */ 15939 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15940 ComponentName cn, String report) { 15941 Slog.w(TAG, report); 15942 try { 15943 if (watcher != null) { 15944 Bundle results = new Bundle(); 15945 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15946 results.putString("Error", report); 15947 watcher.instrumentationStatus(cn, -1, results); 15948 } 15949 } catch (RemoteException e) { 15950 Slog.w(TAG, e); 15951 } 15952 } 15953 15954 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15955 if (app.instrumentationWatcher != null) { 15956 try { 15957 // NOTE: IInstrumentationWatcher *must* be oneway here 15958 app.instrumentationWatcher.instrumentationFinished( 15959 app.instrumentationClass, 15960 resultCode, 15961 results); 15962 } catch (RemoteException e) { 15963 } 15964 } 15965 if (app.instrumentationUiAutomationConnection != null) { 15966 try { 15967 app.instrumentationUiAutomationConnection.shutdown(); 15968 } catch (RemoteException re) { 15969 /* ignore */ 15970 } 15971 // Only a UiAutomation can set this flag and now that 15972 // it is finished we make sure it is reset to its default. 15973 mUserIsMonkey = false; 15974 } 15975 app.instrumentationWatcher = null; 15976 app.instrumentationUiAutomationConnection = null; 15977 app.instrumentationClass = null; 15978 app.instrumentationInfo = null; 15979 app.instrumentationProfileFile = null; 15980 app.instrumentationArguments = null; 15981 15982 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15983 "finished inst"); 15984 } 15985 15986 public void finishInstrumentation(IApplicationThread target, 15987 int resultCode, Bundle results) { 15988 int userId = UserHandle.getCallingUserId(); 15989 // Refuse possible leaked file descriptors 15990 if (results != null && results.hasFileDescriptors()) { 15991 throw new IllegalArgumentException("File descriptors passed in Intent"); 15992 } 15993 15994 synchronized(this) { 15995 ProcessRecord app = getRecordForAppLocked(target); 15996 if (app == null) { 15997 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15998 return; 15999 } 16000 final long origId = Binder.clearCallingIdentity(); 16001 finishInstrumentationLocked(app, resultCode, results); 16002 Binder.restoreCallingIdentity(origId); 16003 } 16004 } 16005 16006 // ========================================================= 16007 // CONFIGURATION 16008 // ========================================================= 16009 16010 public ConfigurationInfo getDeviceConfigurationInfo() { 16011 ConfigurationInfo config = new ConfigurationInfo(); 16012 synchronized (this) { 16013 config.reqTouchScreen = mConfiguration.touchscreen; 16014 config.reqKeyboardType = mConfiguration.keyboard; 16015 config.reqNavigation = mConfiguration.navigation; 16016 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16017 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16018 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16019 } 16020 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16021 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16022 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16023 } 16024 config.reqGlEsVersion = GL_ES_VERSION; 16025 } 16026 return config; 16027 } 16028 16029 ActivityStack getFocusedStack() { 16030 return mStackSupervisor.getFocusedStack(); 16031 } 16032 16033 public Configuration getConfiguration() { 16034 Configuration ci; 16035 synchronized(this) { 16036 ci = new Configuration(mConfiguration); 16037 } 16038 return ci; 16039 } 16040 16041 public void updatePersistentConfiguration(Configuration values) { 16042 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16043 "updateConfiguration()"); 16044 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16045 "updateConfiguration()"); 16046 if (values == null) { 16047 throw new NullPointerException("Configuration must not be null"); 16048 } 16049 16050 synchronized(this) { 16051 final long origId = Binder.clearCallingIdentity(); 16052 updateConfigurationLocked(values, null, true, false); 16053 Binder.restoreCallingIdentity(origId); 16054 } 16055 } 16056 16057 public void updateConfiguration(Configuration values) { 16058 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16059 "updateConfiguration()"); 16060 16061 synchronized(this) { 16062 if (values == null && mWindowManager != null) { 16063 // sentinel: fetch the current configuration from the window manager 16064 values = mWindowManager.computeNewConfiguration(); 16065 } 16066 16067 if (mWindowManager != null) { 16068 mProcessList.applyDisplaySize(mWindowManager); 16069 } 16070 16071 final long origId = Binder.clearCallingIdentity(); 16072 if (values != null) { 16073 Settings.System.clearConfiguration(values); 16074 } 16075 updateConfigurationLocked(values, null, false, false); 16076 Binder.restoreCallingIdentity(origId); 16077 } 16078 } 16079 16080 /** 16081 * Do either or both things: (1) change the current configuration, and (2) 16082 * make sure the given activity is running with the (now) current 16083 * configuration. Returns true if the activity has been left running, or 16084 * false if <var>starting</var> is being destroyed to match the new 16085 * configuration. 16086 * @param persistent TODO 16087 */ 16088 boolean updateConfigurationLocked(Configuration values, 16089 ActivityRecord starting, boolean persistent, boolean initLocale) { 16090 int changes = 0; 16091 16092 if (values != null) { 16093 Configuration newConfig = new Configuration(mConfiguration); 16094 changes = newConfig.updateFrom(values); 16095 if (changes != 0) { 16096 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16097 Slog.i(TAG, "Updating configuration to: " + values); 16098 } 16099 16100 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16101 16102 if (values.locale != null && !initLocale) { 16103 saveLocaleLocked(values.locale, 16104 !values.locale.equals(mConfiguration.locale), 16105 values.userSetLocale); 16106 } 16107 16108 mConfigurationSeq++; 16109 if (mConfigurationSeq <= 0) { 16110 mConfigurationSeq = 1; 16111 } 16112 newConfig.seq = mConfigurationSeq; 16113 mConfiguration = newConfig; 16114 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16115 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16116 //mUsageStatsService.noteStartConfig(newConfig); 16117 16118 final Configuration configCopy = new Configuration(mConfiguration); 16119 16120 // TODO: If our config changes, should we auto dismiss any currently 16121 // showing dialogs? 16122 mShowDialogs = shouldShowDialogs(newConfig); 16123 16124 AttributeCache ac = AttributeCache.instance(); 16125 if (ac != null) { 16126 ac.updateConfiguration(configCopy); 16127 } 16128 16129 // Make sure all resources in our process are updated 16130 // right now, so that anyone who is going to retrieve 16131 // resource values after we return will be sure to get 16132 // the new ones. This is especially important during 16133 // boot, where the first config change needs to guarantee 16134 // all resources have that config before following boot 16135 // code is executed. 16136 mSystemThread.applyConfigurationToResources(configCopy); 16137 16138 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16139 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16140 msg.obj = new Configuration(configCopy); 16141 mHandler.sendMessage(msg); 16142 } 16143 16144 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16145 ProcessRecord app = mLruProcesses.get(i); 16146 try { 16147 if (app.thread != null) { 16148 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16149 + app.processName + " new config " + mConfiguration); 16150 app.thread.scheduleConfigurationChanged(configCopy); 16151 } 16152 } catch (Exception e) { 16153 } 16154 } 16155 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16157 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16158 | Intent.FLAG_RECEIVER_FOREGROUND); 16159 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16160 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16161 Process.SYSTEM_UID, UserHandle.USER_ALL); 16162 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16163 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16164 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16165 broadcastIntentLocked(null, null, intent, 16166 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16167 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16168 } 16169 } 16170 } 16171 16172 boolean kept = true; 16173 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16174 // mainStack is null during startup. 16175 if (mainStack != null) { 16176 if (changes != 0 && starting == null) { 16177 // If the configuration changed, and the caller is not already 16178 // in the process of starting an activity, then find the top 16179 // activity to check if its configuration needs to change. 16180 starting = mainStack.topRunningActivityLocked(null); 16181 } 16182 16183 if (starting != null) { 16184 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16185 // And we need to make sure at this point that all other activities 16186 // are made visible with the correct configuration. 16187 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16188 } 16189 } 16190 16191 if (values != null && mWindowManager != null) { 16192 mWindowManager.setNewConfiguration(mConfiguration); 16193 } 16194 16195 return kept; 16196 } 16197 16198 /** 16199 * Decide based on the configuration whether we should shouw the ANR, 16200 * crash, etc dialogs. The idea is that if there is no affordnace to 16201 * press the on-screen buttons, we shouldn't show the dialog. 16202 * 16203 * A thought: SystemUI might also want to get told about this, the Power 16204 * dialog / global actions also might want different behaviors. 16205 */ 16206 private static final boolean shouldShowDialogs(Configuration config) { 16207 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16208 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16209 } 16210 16211 /** 16212 * Save the locale. You must be inside a synchronized (this) block. 16213 */ 16214 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16215 if(isDiff) { 16216 SystemProperties.set("user.language", l.getLanguage()); 16217 SystemProperties.set("user.region", l.getCountry()); 16218 } 16219 16220 if(isPersist) { 16221 SystemProperties.set("persist.sys.language", l.getLanguage()); 16222 SystemProperties.set("persist.sys.country", l.getCountry()); 16223 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16224 } 16225 } 16226 16227 @Override 16228 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16229 synchronized (this) { 16230 ActivityRecord srec = ActivityRecord.forToken(token); 16231 if (srec.task != null && srec.task.stack != null) { 16232 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16233 } 16234 } 16235 return false; 16236 } 16237 16238 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16239 Intent resultData) { 16240 16241 synchronized (this) { 16242 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16243 if (stack != null) { 16244 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16245 } 16246 return false; 16247 } 16248 } 16249 16250 public int getLaunchedFromUid(IBinder activityToken) { 16251 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16252 if (srec == null) { 16253 return -1; 16254 } 16255 return srec.launchedFromUid; 16256 } 16257 16258 public String getLaunchedFromPackage(IBinder activityToken) { 16259 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16260 if (srec == null) { 16261 return null; 16262 } 16263 return srec.launchedFromPackage; 16264 } 16265 16266 // ========================================================= 16267 // LIFETIME MANAGEMENT 16268 // ========================================================= 16269 16270 // Returns which broadcast queue the app is the current [or imminent] receiver 16271 // on, or 'null' if the app is not an active broadcast recipient. 16272 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16273 BroadcastRecord r = app.curReceiver; 16274 if (r != null) { 16275 return r.queue; 16276 } 16277 16278 // It's not the current receiver, but it might be starting up to become one 16279 synchronized (this) { 16280 for (BroadcastQueue queue : mBroadcastQueues) { 16281 r = queue.mPendingBroadcast; 16282 if (r != null && r.curApp == app) { 16283 // found it; report which queue it's in 16284 return queue; 16285 } 16286 } 16287 } 16288 16289 return null; 16290 } 16291 16292 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16293 boolean doingAll, long now) { 16294 if (mAdjSeq == app.adjSeq) { 16295 // This adjustment has already been computed. 16296 return app.curRawAdj; 16297 } 16298 16299 if (app.thread == null) { 16300 app.adjSeq = mAdjSeq; 16301 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16302 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16303 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16304 } 16305 16306 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16307 app.adjSource = null; 16308 app.adjTarget = null; 16309 app.empty = false; 16310 app.cached = false; 16311 16312 final int activitiesSize = app.activities.size(); 16313 16314 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16315 // The max adjustment doesn't allow this app to be anything 16316 // below foreground, so it is not worth doing work for it. 16317 app.adjType = "fixed"; 16318 app.adjSeq = mAdjSeq; 16319 app.curRawAdj = app.maxAdj; 16320 app.foregroundActivities = false; 16321 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16322 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16323 // System processes can do UI, and when they do we want to have 16324 // them trim their memory after the user leaves the UI. To 16325 // facilitate this, here we need to determine whether or not it 16326 // is currently showing UI. 16327 app.systemNoUi = true; 16328 if (app == TOP_APP) { 16329 app.systemNoUi = false; 16330 } else if (activitiesSize > 0) { 16331 for (int j = 0; j < activitiesSize; j++) { 16332 final ActivityRecord r = app.activities.get(j); 16333 if (r.visible) { 16334 app.systemNoUi = false; 16335 } 16336 } 16337 } 16338 if (!app.systemNoUi) { 16339 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16340 } 16341 return (app.curAdj=app.maxAdj); 16342 } 16343 16344 app.systemNoUi = false; 16345 16346 // Determine the importance of the process, starting with most 16347 // important to least, and assign an appropriate OOM adjustment. 16348 int adj; 16349 int schedGroup; 16350 int procState; 16351 boolean foregroundActivities = false; 16352 BroadcastQueue queue; 16353 if (app == TOP_APP) { 16354 // The last app on the list is the foreground app. 16355 adj = ProcessList.FOREGROUND_APP_ADJ; 16356 schedGroup = Process.THREAD_GROUP_DEFAULT; 16357 app.adjType = "top-activity"; 16358 foregroundActivities = true; 16359 procState = ActivityManager.PROCESS_STATE_TOP; 16360 } else if (app.instrumentationClass != null) { 16361 // Don't want to kill running instrumentation. 16362 adj = ProcessList.FOREGROUND_APP_ADJ; 16363 schedGroup = Process.THREAD_GROUP_DEFAULT; 16364 app.adjType = "instrumentation"; 16365 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16366 } else if ((queue = isReceivingBroadcast(app)) != null) { 16367 // An app that is currently receiving a broadcast also 16368 // counts as being in the foreground for OOM killer purposes. 16369 // It's placed in a sched group based on the nature of the 16370 // broadcast as reflected by which queue it's active in. 16371 adj = ProcessList.FOREGROUND_APP_ADJ; 16372 schedGroup = (queue == mFgBroadcastQueue) 16373 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16374 app.adjType = "broadcast"; 16375 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16376 } else if (app.executingServices.size() > 0) { 16377 // An app that is currently executing a service callback also 16378 // counts as being in the foreground. 16379 adj = ProcessList.FOREGROUND_APP_ADJ; 16380 schedGroup = app.execServicesFg ? 16381 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16382 app.adjType = "exec-service"; 16383 procState = ActivityManager.PROCESS_STATE_SERVICE; 16384 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16385 } else { 16386 // As far as we know the process is empty. We may change our mind later. 16387 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16388 // At this point we don't actually know the adjustment. Use the cached adj 16389 // value that the caller wants us to. 16390 adj = cachedAdj; 16391 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16392 app.cached = true; 16393 app.empty = true; 16394 app.adjType = "cch-empty"; 16395 } 16396 16397 // Examine all activities if not already foreground. 16398 if (!foregroundActivities && activitiesSize > 0) { 16399 for (int j = 0; j < activitiesSize; j++) { 16400 final ActivityRecord r = app.activities.get(j); 16401 if (r.app != app) { 16402 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16403 + app + "?!?"); 16404 continue; 16405 } 16406 if (r.visible) { 16407 // App has a visible activity; only upgrade adjustment. 16408 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16409 adj = ProcessList.VISIBLE_APP_ADJ; 16410 app.adjType = "visible"; 16411 } 16412 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16413 procState = ActivityManager.PROCESS_STATE_TOP; 16414 } 16415 schedGroup = Process.THREAD_GROUP_DEFAULT; 16416 app.cached = false; 16417 app.empty = false; 16418 foregroundActivities = true; 16419 break; 16420 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16421 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16422 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16423 app.adjType = "pausing"; 16424 } 16425 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16426 procState = ActivityManager.PROCESS_STATE_TOP; 16427 } 16428 schedGroup = Process.THREAD_GROUP_DEFAULT; 16429 app.cached = false; 16430 app.empty = false; 16431 foregroundActivities = true; 16432 } else if (r.state == ActivityState.STOPPING) { 16433 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16434 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16435 app.adjType = "stopping"; 16436 } 16437 // For the process state, we will at this point consider the 16438 // process to be cached. It will be cached either as an activity 16439 // or empty depending on whether the activity is finishing. We do 16440 // this so that we can treat the process as cached for purposes of 16441 // memory trimming (determing current memory level, trim command to 16442 // send to process) since there can be an arbitrary number of stopping 16443 // processes and they should soon all go into the cached state. 16444 if (!r.finishing) { 16445 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16446 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16447 } 16448 } 16449 app.cached = false; 16450 app.empty = false; 16451 foregroundActivities = true; 16452 } else { 16453 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16454 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16455 app.adjType = "cch-act"; 16456 } 16457 } 16458 } 16459 } 16460 16461 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16462 if (app.foregroundServices) { 16463 // The user is aware of this app, so make it visible. 16464 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16465 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16466 app.cached = false; 16467 app.adjType = "fg-service"; 16468 schedGroup = Process.THREAD_GROUP_DEFAULT; 16469 } else if (app.forcingToForeground != null) { 16470 // The user is aware of this app, so make it visible. 16471 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16472 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16473 app.cached = false; 16474 app.adjType = "force-fg"; 16475 app.adjSource = app.forcingToForeground; 16476 schedGroup = Process.THREAD_GROUP_DEFAULT; 16477 } 16478 } 16479 16480 if (app == mHeavyWeightProcess) { 16481 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16482 // We don't want to kill the current heavy-weight process. 16483 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16484 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16485 app.cached = false; 16486 app.adjType = "heavy"; 16487 } 16488 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16489 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16490 } 16491 } 16492 16493 if (app == mHomeProcess) { 16494 if (adj > ProcessList.HOME_APP_ADJ) { 16495 // This process is hosting what we currently consider to be the 16496 // home app, so we don't want to let it go into the background. 16497 adj = ProcessList.HOME_APP_ADJ; 16498 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16499 app.cached = false; 16500 app.adjType = "home"; 16501 } 16502 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16503 procState = ActivityManager.PROCESS_STATE_HOME; 16504 } 16505 } 16506 16507 if (app == mPreviousProcess && app.activities.size() > 0) { 16508 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16509 // This was the previous process that showed UI to the user. 16510 // We want to try to keep it around more aggressively, to give 16511 // a good experience around switching between two apps. 16512 adj = ProcessList.PREVIOUS_APP_ADJ; 16513 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16514 app.cached = false; 16515 app.adjType = "previous"; 16516 } 16517 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16518 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16519 } 16520 } 16521 16522 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16523 + " reason=" + app.adjType); 16524 16525 // By default, we use the computed adjustment. It may be changed if 16526 // there are applications dependent on our services or providers, but 16527 // this gives us a baseline and makes sure we don't get into an 16528 // infinite recursion. 16529 app.adjSeq = mAdjSeq; 16530 app.curRawAdj = adj; 16531 app.hasStartedServices = false; 16532 16533 if (mBackupTarget != null && app == mBackupTarget.app) { 16534 // If possible we want to avoid killing apps while they're being backed up 16535 if (adj > ProcessList.BACKUP_APP_ADJ) { 16536 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16537 adj = ProcessList.BACKUP_APP_ADJ; 16538 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16539 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16540 } 16541 app.adjType = "backup"; 16542 app.cached = false; 16543 } 16544 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16545 procState = ActivityManager.PROCESS_STATE_BACKUP; 16546 } 16547 } 16548 16549 boolean mayBeTop = false; 16550 16551 for (int is = app.services.size()-1; 16552 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16553 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16554 || procState > ActivityManager.PROCESS_STATE_TOP); 16555 is--) { 16556 ServiceRecord s = app.services.valueAt(is); 16557 if (s.startRequested) { 16558 app.hasStartedServices = true; 16559 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16560 procState = ActivityManager.PROCESS_STATE_SERVICE; 16561 } 16562 if (app.hasShownUi && app != mHomeProcess) { 16563 // If this process has shown some UI, let it immediately 16564 // go to the LRU list because it may be pretty heavy with 16565 // UI stuff. We'll tag it with a label just to help 16566 // debug and understand what is going on. 16567 if (adj > ProcessList.SERVICE_ADJ) { 16568 app.adjType = "cch-started-ui-services"; 16569 } 16570 } else { 16571 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16572 // This service has seen some activity within 16573 // recent memory, so we will keep its process ahead 16574 // of the background processes. 16575 if (adj > ProcessList.SERVICE_ADJ) { 16576 adj = ProcessList.SERVICE_ADJ; 16577 app.adjType = "started-services"; 16578 app.cached = false; 16579 } 16580 } 16581 // If we have let the service slide into the background 16582 // state, still have some text describing what it is doing 16583 // even though the service no longer has an impact. 16584 if (adj > ProcessList.SERVICE_ADJ) { 16585 app.adjType = "cch-started-services"; 16586 } 16587 } 16588 } 16589 for (int conni = s.connections.size()-1; 16590 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16591 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16592 || procState > ActivityManager.PROCESS_STATE_TOP); 16593 conni--) { 16594 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16595 for (int i = 0; 16596 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16597 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16598 || procState > ActivityManager.PROCESS_STATE_TOP); 16599 i++) { 16600 // XXX should compute this based on the max of 16601 // all connected clients. 16602 ConnectionRecord cr = clist.get(i); 16603 if (cr.binding.client == app) { 16604 // Binding to ourself is not interesting. 16605 continue; 16606 } 16607 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16608 ProcessRecord client = cr.binding.client; 16609 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16610 TOP_APP, doingAll, now); 16611 int clientProcState = client.curProcState; 16612 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16613 // If the other app is cached for any reason, for purposes here 16614 // we are going to consider it empty. The specific cached state 16615 // doesn't propagate except under certain conditions. 16616 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16617 } 16618 String adjType = null; 16619 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16620 // Not doing bind OOM management, so treat 16621 // this guy more like a started service. 16622 if (app.hasShownUi && app != mHomeProcess) { 16623 // If this process has shown some UI, let it immediately 16624 // go to the LRU list because it may be pretty heavy with 16625 // UI stuff. We'll tag it with a label just to help 16626 // debug and understand what is going on. 16627 if (adj > clientAdj) { 16628 adjType = "cch-bound-ui-services"; 16629 } 16630 app.cached = false; 16631 clientAdj = adj; 16632 clientProcState = procState; 16633 } else { 16634 if (now >= (s.lastActivity 16635 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16636 // This service has not seen activity within 16637 // recent memory, so allow it to drop to the 16638 // LRU list if there is no other reason to keep 16639 // it around. We'll also tag it with a label just 16640 // to help debug and undertand what is going on. 16641 if (adj > clientAdj) { 16642 adjType = "cch-bound-services"; 16643 } 16644 clientAdj = adj; 16645 } 16646 } 16647 } 16648 if (adj > clientAdj) { 16649 // If this process has recently shown UI, and 16650 // the process that is binding to it is less 16651 // important than being visible, then we don't 16652 // care about the binding as much as we care 16653 // about letting this process get into the LRU 16654 // list to be killed and restarted if needed for 16655 // memory. 16656 if (app.hasShownUi && app != mHomeProcess 16657 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16658 adjType = "cch-bound-ui-services"; 16659 } else { 16660 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16661 |Context.BIND_IMPORTANT)) != 0) { 16662 adj = clientAdj; 16663 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16664 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16665 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16666 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16667 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16668 adj = clientAdj; 16669 } else { 16670 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16671 adj = ProcessList.VISIBLE_APP_ADJ; 16672 } 16673 } 16674 if (!client.cached) { 16675 app.cached = false; 16676 } 16677 adjType = "service"; 16678 } 16679 } 16680 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16681 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16682 schedGroup = Process.THREAD_GROUP_DEFAULT; 16683 } 16684 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16685 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16686 // Special handling of clients who are in the top state. 16687 // We *may* want to consider this process to be in the 16688 // top state as well, but only if there is not another 16689 // reason for it to be running. Being on the top is a 16690 // special state, meaning you are specifically running 16691 // for the current top app. If the process is already 16692 // running in the background for some other reason, it 16693 // is more important to continue considering it to be 16694 // in the background state. 16695 mayBeTop = true; 16696 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16697 } else { 16698 // Special handling for above-top states (persistent 16699 // processes). These should not bring the current process 16700 // into the top state, since they are not on top. Instead 16701 // give them the best state after that. 16702 clientProcState = 16703 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16704 } 16705 } 16706 } else { 16707 if (clientProcState < 16708 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16709 clientProcState = 16710 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16711 } 16712 } 16713 if (procState > clientProcState) { 16714 procState = clientProcState; 16715 } 16716 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16717 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16718 app.pendingUiClean = true; 16719 } 16720 if (adjType != null) { 16721 app.adjType = adjType; 16722 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16723 .REASON_SERVICE_IN_USE; 16724 app.adjSource = cr.binding.client; 16725 app.adjSourceProcState = clientProcState; 16726 app.adjTarget = s.name; 16727 } 16728 } 16729 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16730 app.treatLikeActivity = true; 16731 } 16732 final ActivityRecord a = cr.activity; 16733 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16734 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16735 (a.visible || a.state == ActivityState.RESUMED 16736 || a.state == ActivityState.PAUSING)) { 16737 adj = ProcessList.FOREGROUND_APP_ADJ; 16738 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16739 schedGroup = Process.THREAD_GROUP_DEFAULT; 16740 } 16741 app.cached = false; 16742 app.adjType = "service"; 16743 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16744 .REASON_SERVICE_IN_USE; 16745 app.adjSource = a; 16746 app.adjSourceProcState = procState; 16747 app.adjTarget = s.name; 16748 } 16749 } 16750 } 16751 } 16752 } 16753 16754 for (int provi = app.pubProviders.size()-1; 16755 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16756 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16757 || procState > ActivityManager.PROCESS_STATE_TOP); 16758 provi--) { 16759 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16760 for (int i = cpr.connections.size()-1; 16761 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16762 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16763 || procState > ActivityManager.PROCESS_STATE_TOP); 16764 i--) { 16765 ContentProviderConnection conn = cpr.connections.get(i); 16766 ProcessRecord client = conn.client; 16767 if (client == app) { 16768 // Being our own client is not interesting. 16769 continue; 16770 } 16771 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16772 int clientProcState = client.curProcState; 16773 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16774 // If the other app is cached for any reason, for purposes here 16775 // we are going to consider it empty. 16776 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16777 } 16778 if (adj > clientAdj) { 16779 if (app.hasShownUi && app != mHomeProcess 16780 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16781 app.adjType = "cch-ui-provider"; 16782 } else { 16783 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16784 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16785 app.adjType = "provider"; 16786 } 16787 app.cached &= client.cached; 16788 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16789 .REASON_PROVIDER_IN_USE; 16790 app.adjSource = client; 16791 app.adjSourceProcState = clientProcState; 16792 app.adjTarget = cpr.name; 16793 } 16794 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16795 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16796 // Special handling of clients who are in the top state. 16797 // We *may* want to consider this process to be in the 16798 // top state as well, but only if there is not another 16799 // reason for it to be running. Being on the top is a 16800 // special state, meaning you are specifically running 16801 // for the current top app. If the process is already 16802 // running in the background for some other reason, it 16803 // is more important to continue considering it to be 16804 // in the background state. 16805 mayBeTop = true; 16806 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16807 } else { 16808 // Special handling for above-top states (persistent 16809 // processes). These should not bring the current process 16810 // into the top state, since they are not on top. Instead 16811 // give them the best state after that. 16812 clientProcState = 16813 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16814 } 16815 } 16816 if (procState > clientProcState) { 16817 procState = clientProcState; 16818 } 16819 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16820 schedGroup = Process.THREAD_GROUP_DEFAULT; 16821 } 16822 } 16823 // If the provider has external (non-framework) process 16824 // dependencies, ensure that its adjustment is at least 16825 // FOREGROUND_APP_ADJ. 16826 if (cpr.hasExternalProcessHandles()) { 16827 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16828 adj = ProcessList.FOREGROUND_APP_ADJ; 16829 schedGroup = Process.THREAD_GROUP_DEFAULT; 16830 app.cached = false; 16831 app.adjType = "provider"; 16832 app.adjTarget = cpr.name; 16833 } 16834 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16835 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16836 } 16837 } 16838 } 16839 16840 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16841 // A client of one of our services or providers is in the top state. We 16842 // *may* want to be in the top state, but not if we are already running in 16843 // the background for some other reason. For the decision here, we are going 16844 // to pick out a few specific states that we want to remain in when a client 16845 // is top (states that tend to be longer-term) and otherwise allow it to go 16846 // to the top state. 16847 switch (procState) { 16848 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16849 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16850 case ActivityManager.PROCESS_STATE_SERVICE: 16851 // These all are longer-term states, so pull them up to the top 16852 // of the background states, but not all the way to the top state. 16853 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16854 break; 16855 default: 16856 // Otherwise, top is a better choice, so take it. 16857 procState = ActivityManager.PROCESS_STATE_TOP; 16858 break; 16859 } 16860 } 16861 16862 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16863 if (app.hasClientActivities) { 16864 // This is a cached process, but with client activities. Mark it so. 16865 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16866 app.adjType = "cch-client-act"; 16867 } else if (app.treatLikeActivity) { 16868 // This is a cached process, but somebody wants us to treat it like it has 16869 // an activity, okay! 16870 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16871 app.adjType = "cch-as-act"; 16872 } 16873 } 16874 16875 if (adj == ProcessList.SERVICE_ADJ) { 16876 if (doingAll) { 16877 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16878 mNewNumServiceProcs++; 16879 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16880 if (!app.serviceb) { 16881 // This service isn't far enough down on the LRU list to 16882 // normally be a B service, but if we are low on RAM and it 16883 // is large we want to force it down since we would prefer to 16884 // keep launcher over it. 16885 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16886 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16887 app.serviceHighRam = true; 16888 app.serviceb = true; 16889 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16890 } else { 16891 mNewNumAServiceProcs++; 16892 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16893 } 16894 } else { 16895 app.serviceHighRam = false; 16896 } 16897 } 16898 if (app.serviceb) { 16899 adj = ProcessList.SERVICE_B_ADJ; 16900 } 16901 } 16902 16903 app.curRawAdj = adj; 16904 16905 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16906 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16907 if (adj > app.maxAdj) { 16908 adj = app.maxAdj; 16909 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16910 schedGroup = Process.THREAD_GROUP_DEFAULT; 16911 } 16912 } 16913 16914 // Do final modification to adj. Everything we do between here and applying 16915 // the final setAdj must be done in this function, because we will also use 16916 // it when computing the final cached adj later. Note that we don't need to 16917 // worry about this for max adj above, since max adj will always be used to 16918 // keep it out of the cached vaues. 16919 app.curAdj = app.modifyRawOomAdj(adj); 16920 app.curSchedGroup = schedGroup; 16921 app.curProcState = procState; 16922 app.foregroundActivities = foregroundActivities; 16923 16924 return app.curRawAdj; 16925 } 16926 16927 /** 16928 * Schedule PSS collection of a process. 16929 */ 16930 void requestPssLocked(ProcessRecord proc, int procState) { 16931 if (mPendingPssProcesses.contains(proc)) { 16932 return; 16933 } 16934 if (mPendingPssProcesses.size() == 0) { 16935 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16936 } 16937 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16938 proc.pssProcState = procState; 16939 mPendingPssProcesses.add(proc); 16940 } 16941 16942 /** 16943 * Schedule PSS collection of all processes. 16944 */ 16945 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16946 if (!always) { 16947 if (now < (mLastFullPssTime + 16948 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16949 return; 16950 } 16951 } 16952 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16953 mLastFullPssTime = now; 16954 mFullPssPending = true; 16955 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16956 mPendingPssProcesses.clear(); 16957 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16958 ProcessRecord app = mLruProcesses.get(i); 16959 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16960 app.pssProcState = app.setProcState; 16961 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16962 isSleeping(), now); 16963 mPendingPssProcesses.add(app); 16964 } 16965 } 16966 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16967 } 16968 16969 /** 16970 * Ask a given process to GC right now. 16971 */ 16972 final void performAppGcLocked(ProcessRecord app) { 16973 try { 16974 app.lastRequestedGc = SystemClock.uptimeMillis(); 16975 if (app.thread != null) { 16976 if (app.reportLowMemory) { 16977 app.reportLowMemory = false; 16978 app.thread.scheduleLowMemory(); 16979 } else { 16980 app.thread.processInBackground(); 16981 } 16982 } 16983 } catch (Exception e) { 16984 // whatever. 16985 } 16986 } 16987 16988 /** 16989 * Returns true if things are idle enough to perform GCs. 16990 */ 16991 private final boolean canGcNowLocked() { 16992 boolean processingBroadcasts = false; 16993 for (BroadcastQueue q : mBroadcastQueues) { 16994 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16995 processingBroadcasts = true; 16996 } 16997 } 16998 return !processingBroadcasts 16999 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17000 } 17001 17002 /** 17003 * Perform GCs on all processes that are waiting for it, but only 17004 * if things are idle. 17005 */ 17006 final void performAppGcsLocked() { 17007 final int N = mProcessesToGc.size(); 17008 if (N <= 0) { 17009 return; 17010 } 17011 if (canGcNowLocked()) { 17012 while (mProcessesToGc.size() > 0) { 17013 ProcessRecord proc = mProcessesToGc.remove(0); 17014 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17015 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17016 <= SystemClock.uptimeMillis()) { 17017 // To avoid spamming the system, we will GC processes one 17018 // at a time, waiting a few seconds between each. 17019 performAppGcLocked(proc); 17020 scheduleAppGcsLocked(); 17021 return; 17022 } else { 17023 // It hasn't been long enough since we last GCed this 17024 // process... put it in the list to wait for its time. 17025 addProcessToGcListLocked(proc); 17026 break; 17027 } 17028 } 17029 } 17030 17031 scheduleAppGcsLocked(); 17032 } 17033 } 17034 17035 /** 17036 * If all looks good, perform GCs on all processes waiting for them. 17037 */ 17038 final void performAppGcsIfAppropriateLocked() { 17039 if (canGcNowLocked()) { 17040 performAppGcsLocked(); 17041 return; 17042 } 17043 // Still not idle, wait some more. 17044 scheduleAppGcsLocked(); 17045 } 17046 17047 /** 17048 * Schedule the execution of all pending app GCs. 17049 */ 17050 final void scheduleAppGcsLocked() { 17051 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17052 17053 if (mProcessesToGc.size() > 0) { 17054 // Schedule a GC for the time to the next process. 17055 ProcessRecord proc = mProcessesToGc.get(0); 17056 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17057 17058 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17059 long now = SystemClock.uptimeMillis(); 17060 if (when < (now+GC_TIMEOUT)) { 17061 when = now + GC_TIMEOUT; 17062 } 17063 mHandler.sendMessageAtTime(msg, when); 17064 } 17065 } 17066 17067 /** 17068 * Add a process to the array of processes waiting to be GCed. Keeps the 17069 * list in sorted order by the last GC time. The process can't already be 17070 * on the list. 17071 */ 17072 final void addProcessToGcListLocked(ProcessRecord proc) { 17073 boolean added = false; 17074 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17075 if (mProcessesToGc.get(i).lastRequestedGc < 17076 proc.lastRequestedGc) { 17077 added = true; 17078 mProcessesToGc.add(i+1, proc); 17079 break; 17080 } 17081 } 17082 if (!added) { 17083 mProcessesToGc.add(0, proc); 17084 } 17085 } 17086 17087 /** 17088 * Set up to ask a process to GC itself. This will either do it 17089 * immediately, or put it on the list of processes to gc the next 17090 * time things are idle. 17091 */ 17092 final void scheduleAppGcLocked(ProcessRecord app) { 17093 long now = SystemClock.uptimeMillis(); 17094 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17095 return; 17096 } 17097 if (!mProcessesToGc.contains(app)) { 17098 addProcessToGcListLocked(app); 17099 scheduleAppGcsLocked(); 17100 } 17101 } 17102 17103 final void checkExcessivePowerUsageLocked(boolean doKills) { 17104 updateCpuStatsNow(); 17105 17106 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17107 boolean doWakeKills = doKills; 17108 boolean doCpuKills = doKills; 17109 if (mLastPowerCheckRealtime == 0) { 17110 doWakeKills = false; 17111 } 17112 if (mLastPowerCheckUptime == 0) { 17113 doCpuKills = false; 17114 } 17115 if (stats.isScreenOn()) { 17116 doWakeKills = false; 17117 } 17118 final long curRealtime = SystemClock.elapsedRealtime(); 17119 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17120 final long curUptime = SystemClock.uptimeMillis(); 17121 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17122 mLastPowerCheckRealtime = curRealtime; 17123 mLastPowerCheckUptime = curUptime; 17124 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17125 doWakeKills = false; 17126 } 17127 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17128 doCpuKills = false; 17129 } 17130 int i = mLruProcesses.size(); 17131 while (i > 0) { 17132 i--; 17133 ProcessRecord app = mLruProcesses.get(i); 17134 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17135 long wtime; 17136 synchronized (stats) { 17137 wtime = stats.getProcessWakeTime(app.info.uid, 17138 app.pid, curRealtime); 17139 } 17140 long wtimeUsed = wtime - app.lastWakeTime; 17141 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17142 if (DEBUG_POWER) { 17143 StringBuilder sb = new StringBuilder(128); 17144 sb.append("Wake for "); 17145 app.toShortString(sb); 17146 sb.append(": over "); 17147 TimeUtils.formatDuration(realtimeSince, sb); 17148 sb.append(" used "); 17149 TimeUtils.formatDuration(wtimeUsed, sb); 17150 sb.append(" ("); 17151 sb.append((wtimeUsed*100)/realtimeSince); 17152 sb.append("%)"); 17153 Slog.i(TAG, sb.toString()); 17154 sb.setLength(0); 17155 sb.append("CPU for "); 17156 app.toShortString(sb); 17157 sb.append(": over "); 17158 TimeUtils.formatDuration(uptimeSince, sb); 17159 sb.append(" used "); 17160 TimeUtils.formatDuration(cputimeUsed, sb); 17161 sb.append(" ("); 17162 sb.append((cputimeUsed*100)/uptimeSince); 17163 sb.append("%)"); 17164 Slog.i(TAG, sb.toString()); 17165 } 17166 // If a process has held a wake lock for more 17167 // than 50% of the time during this period, 17168 // that sounds bad. Kill! 17169 if (doWakeKills && realtimeSince > 0 17170 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17171 synchronized (stats) { 17172 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17173 realtimeSince, wtimeUsed); 17174 } 17175 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17176 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17177 } else if (doCpuKills && uptimeSince > 0 17178 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17179 synchronized (stats) { 17180 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17181 uptimeSince, cputimeUsed); 17182 } 17183 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17184 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17185 } else { 17186 app.lastWakeTime = wtime; 17187 app.lastCpuTime = app.curCpuTime; 17188 } 17189 } 17190 } 17191 } 17192 17193 private final boolean applyOomAdjLocked(ProcessRecord app, 17194 ProcessRecord TOP_APP, boolean doingAll, long now) { 17195 boolean success = true; 17196 17197 if (app.curRawAdj != app.setRawAdj) { 17198 app.setRawAdj = app.curRawAdj; 17199 } 17200 17201 int changes = 0; 17202 17203 if (app.curAdj != app.setAdj) { 17204 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17205 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17206 TAG, "Set " + app.pid + " " + app.processName + 17207 " adj " + app.curAdj + ": " + app.adjType); 17208 app.setAdj = app.curAdj; 17209 } 17210 17211 if (app.setSchedGroup != app.curSchedGroup) { 17212 app.setSchedGroup = app.curSchedGroup; 17213 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17214 "Setting process group of " + app.processName 17215 + " to " + app.curSchedGroup); 17216 if (app.waitingToKill != null && 17217 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17218 app.kill(app.waitingToKill, true); 17219 success = false; 17220 } else { 17221 if (true) { 17222 long oldId = Binder.clearCallingIdentity(); 17223 try { 17224 Process.setProcessGroup(app.pid, app.curSchedGroup); 17225 } catch (Exception e) { 17226 Slog.w(TAG, "Failed setting process group of " + app.pid 17227 + " to " + app.curSchedGroup); 17228 e.printStackTrace(); 17229 } finally { 17230 Binder.restoreCallingIdentity(oldId); 17231 } 17232 } else { 17233 if (app.thread != null) { 17234 try { 17235 app.thread.setSchedulingGroup(app.curSchedGroup); 17236 } catch (RemoteException e) { 17237 } 17238 } 17239 } 17240 Process.setSwappiness(app.pid, 17241 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17242 } 17243 } 17244 if (app.repForegroundActivities != app.foregroundActivities) { 17245 app.repForegroundActivities = app.foregroundActivities; 17246 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17247 } 17248 if (app.repProcState != app.curProcState) { 17249 app.repProcState = app.curProcState; 17250 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17251 if (app.thread != null) { 17252 try { 17253 if (false) { 17254 //RuntimeException h = new RuntimeException("here"); 17255 Slog.i(TAG, "Sending new process state " + app.repProcState 17256 + " to " + app /*, h*/); 17257 } 17258 app.thread.setProcessState(app.repProcState); 17259 } catch (RemoteException e) { 17260 } 17261 } 17262 } 17263 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17264 app.setProcState)) { 17265 app.lastStateTime = now; 17266 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17267 isSleeping(), now); 17268 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17269 + ProcessList.makeProcStateString(app.setProcState) + " to " 17270 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17271 + (app.nextPssTime-now) + ": " + app); 17272 } else { 17273 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17274 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17275 requestPssLocked(app, app.setProcState); 17276 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17277 isSleeping(), now); 17278 } else if (false && DEBUG_PSS) { 17279 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17280 } 17281 } 17282 if (app.setProcState != app.curProcState) { 17283 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17284 "Proc state change of " + app.processName 17285 + " to " + app.curProcState); 17286 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17287 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17288 if (setImportant && !curImportant) { 17289 // This app is no longer something we consider important enough to allow to 17290 // use arbitrary amounts of battery power. Note 17291 // its current wake lock time to later know to kill it if 17292 // it is not behaving well. 17293 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17294 synchronized (stats) { 17295 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17296 app.pid, SystemClock.elapsedRealtime()); 17297 } 17298 app.lastCpuTime = app.curCpuTime; 17299 17300 } 17301 app.setProcState = app.curProcState; 17302 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17303 app.notCachedSinceIdle = false; 17304 } 17305 if (!doingAll) { 17306 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17307 } else { 17308 app.procStateChanged = true; 17309 } 17310 } 17311 17312 if (changes != 0) { 17313 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17314 int i = mPendingProcessChanges.size()-1; 17315 ProcessChangeItem item = null; 17316 while (i >= 0) { 17317 item = mPendingProcessChanges.get(i); 17318 if (item.pid == app.pid) { 17319 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17320 break; 17321 } 17322 i--; 17323 } 17324 if (i < 0) { 17325 // No existing item in pending changes; need a new one. 17326 final int NA = mAvailProcessChanges.size(); 17327 if (NA > 0) { 17328 item = mAvailProcessChanges.remove(NA-1); 17329 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17330 } else { 17331 item = new ProcessChangeItem(); 17332 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17333 } 17334 item.changes = 0; 17335 item.pid = app.pid; 17336 item.uid = app.info.uid; 17337 if (mPendingProcessChanges.size() == 0) { 17338 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17339 "*** Enqueueing dispatch processes changed!"); 17340 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17341 } 17342 mPendingProcessChanges.add(item); 17343 } 17344 item.changes |= changes; 17345 item.processState = app.repProcState; 17346 item.foregroundActivities = app.repForegroundActivities; 17347 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17348 + Integer.toHexString(System.identityHashCode(item)) 17349 + " " + app.toShortString() + ": changes=" + item.changes 17350 + " procState=" + item.processState 17351 + " foreground=" + item.foregroundActivities 17352 + " type=" + app.adjType + " source=" + app.adjSource 17353 + " target=" + app.adjTarget); 17354 } 17355 17356 return success; 17357 } 17358 17359 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17360 if (proc.thread != null) { 17361 if (proc.baseProcessTracker != null) { 17362 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17363 } 17364 if (proc.repProcState >= 0) { 17365 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17366 proc.repProcState); 17367 } 17368 } 17369 } 17370 17371 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17372 ProcessRecord TOP_APP, boolean doingAll, long now) { 17373 if (app.thread == null) { 17374 return false; 17375 } 17376 17377 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17378 17379 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17380 } 17381 17382 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17383 boolean oomAdj) { 17384 if (isForeground != proc.foregroundServices) { 17385 proc.foregroundServices = isForeground; 17386 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17387 proc.info.uid); 17388 if (isForeground) { 17389 if (curProcs == null) { 17390 curProcs = new ArrayList<ProcessRecord>(); 17391 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17392 } 17393 if (!curProcs.contains(proc)) { 17394 curProcs.add(proc); 17395 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17396 proc.info.packageName, proc.info.uid); 17397 } 17398 } else { 17399 if (curProcs != null) { 17400 if (curProcs.remove(proc)) { 17401 mBatteryStatsService.noteEvent( 17402 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17403 proc.info.packageName, proc.info.uid); 17404 if (curProcs.size() <= 0) { 17405 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17406 } 17407 } 17408 } 17409 } 17410 if (oomAdj) { 17411 updateOomAdjLocked(); 17412 } 17413 } 17414 } 17415 17416 private final ActivityRecord resumedAppLocked() { 17417 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17418 String pkg; 17419 int uid; 17420 if (act != null) { 17421 pkg = act.packageName; 17422 uid = act.info.applicationInfo.uid; 17423 } else { 17424 pkg = null; 17425 uid = -1; 17426 } 17427 // Has the UID or resumed package name changed? 17428 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17429 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17430 if (mCurResumedPackage != null) { 17431 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17432 mCurResumedPackage, mCurResumedUid); 17433 } 17434 mCurResumedPackage = pkg; 17435 mCurResumedUid = uid; 17436 if (mCurResumedPackage != null) { 17437 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17438 mCurResumedPackage, mCurResumedUid); 17439 } 17440 } 17441 return act; 17442 } 17443 17444 final boolean updateOomAdjLocked(ProcessRecord app) { 17445 final ActivityRecord TOP_ACT = resumedAppLocked(); 17446 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17447 final boolean wasCached = app.cached; 17448 17449 mAdjSeq++; 17450 17451 // This is the desired cached adjusment we want to tell it to use. 17452 // If our app is currently cached, we know it, and that is it. Otherwise, 17453 // we don't know it yet, and it needs to now be cached we will then 17454 // need to do a complete oom adj. 17455 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17456 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17457 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17458 SystemClock.uptimeMillis()); 17459 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17460 // Changed to/from cached state, so apps after it in the LRU 17461 // list may also be changed. 17462 updateOomAdjLocked(); 17463 } 17464 return success; 17465 } 17466 17467 final void updateOomAdjLocked() { 17468 final ActivityRecord TOP_ACT = resumedAppLocked(); 17469 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17470 final long now = SystemClock.uptimeMillis(); 17471 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17472 final int N = mLruProcesses.size(); 17473 17474 if (false) { 17475 RuntimeException e = new RuntimeException(); 17476 e.fillInStackTrace(); 17477 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17478 } 17479 17480 mAdjSeq++; 17481 mNewNumServiceProcs = 0; 17482 mNewNumAServiceProcs = 0; 17483 17484 final int emptyProcessLimit; 17485 final int cachedProcessLimit; 17486 if (mProcessLimit <= 0) { 17487 emptyProcessLimit = cachedProcessLimit = 0; 17488 } else if (mProcessLimit == 1) { 17489 emptyProcessLimit = 1; 17490 cachedProcessLimit = 0; 17491 } else { 17492 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17493 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17494 } 17495 17496 // Let's determine how many processes we have running vs. 17497 // how many slots we have for background processes; we may want 17498 // to put multiple processes in a slot of there are enough of 17499 // them. 17500 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17501 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17502 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17503 if (numEmptyProcs > cachedProcessLimit) { 17504 // If there are more empty processes than our limit on cached 17505 // processes, then use the cached process limit for the factor. 17506 // This ensures that the really old empty processes get pushed 17507 // down to the bottom, so if we are running low on memory we will 17508 // have a better chance at keeping around more cached processes 17509 // instead of a gazillion empty processes. 17510 numEmptyProcs = cachedProcessLimit; 17511 } 17512 int emptyFactor = numEmptyProcs/numSlots; 17513 if (emptyFactor < 1) emptyFactor = 1; 17514 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17515 if (cachedFactor < 1) cachedFactor = 1; 17516 int stepCached = 0; 17517 int stepEmpty = 0; 17518 int numCached = 0; 17519 int numEmpty = 0; 17520 int numTrimming = 0; 17521 17522 mNumNonCachedProcs = 0; 17523 mNumCachedHiddenProcs = 0; 17524 17525 // First update the OOM adjustment for each of the 17526 // application processes based on their current state. 17527 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17528 int nextCachedAdj = curCachedAdj+1; 17529 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17530 int nextEmptyAdj = curEmptyAdj+2; 17531 for (int i=N-1; i>=0; i--) { 17532 ProcessRecord app = mLruProcesses.get(i); 17533 if (!app.killedByAm && app.thread != null) { 17534 app.procStateChanged = false; 17535 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17536 17537 // If we haven't yet assigned the final cached adj 17538 // to the process, do that now. 17539 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17540 switch (app.curProcState) { 17541 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17542 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17543 // This process is a cached process holding activities... 17544 // assign it the next cached value for that type, and then 17545 // step that cached level. 17546 app.curRawAdj = curCachedAdj; 17547 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17548 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17549 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17550 + ")"); 17551 if (curCachedAdj != nextCachedAdj) { 17552 stepCached++; 17553 if (stepCached >= cachedFactor) { 17554 stepCached = 0; 17555 curCachedAdj = nextCachedAdj; 17556 nextCachedAdj += 2; 17557 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17558 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17559 } 17560 } 17561 } 17562 break; 17563 default: 17564 // For everything else, assign next empty cached process 17565 // level and bump that up. Note that this means that 17566 // long-running services that have dropped down to the 17567 // cached level will be treated as empty (since their process 17568 // state is still as a service), which is what we want. 17569 app.curRawAdj = curEmptyAdj; 17570 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17571 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17572 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17573 + ")"); 17574 if (curEmptyAdj != nextEmptyAdj) { 17575 stepEmpty++; 17576 if (stepEmpty >= emptyFactor) { 17577 stepEmpty = 0; 17578 curEmptyAdj = nextEmptyAdj; 17579 nextEmptyAdj += 2; 17580 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17581 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17582 } 17583 } 17584 } 17585 break; 17586 } 17587 } 17588 17589 applyOomAdjLocked(app, TOP_APP, true, now); 17590 17591 // Count the number of process types. 17592 switch (app.curProcState) { 17593 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17594 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17595 mNumCachedHiddenProcs++; 17596 numCached++; 17597 if (numCached > cachedProcessLimit) { 17598 app.kill("cached #" + numCached, true); 17599 } 17600 break; 17601 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17602 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17603 && app.lastActivityTime < oldTime) { 17604 app.kill("empty for " 17605 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17606 / 1000) + "s", true); 17607 } else { 17608 numEmpty++; 17609 if (numEmpty > emptyProcessLimit) { 17610 app.kill("empty #" + numEmpty, true); 17611 } 17612 } 17613 break; 17614 default: 17615 mNumNonCachedProcs++; 17616 break; 17617 } 17618 17619 if (app.isolated && app.services.size() <= 0) { 17620 // If this is an isolated process, and there are no 17621 // services running in it, then the process is no longer 17622 // needed. We agressively kill these because we can by 17623 // definition not re-use the same process again, and it is 17624 // good to avoid having whatever code was running in them 17625 // left sitting around after no longer needed. 17626 app.kill("isolated not needed", true); 17627 } 17628 17629 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17630 && !app.killedByAm) { 17631 numTrimming++; 17632 } 17633 } 17634 } 17635 17636 mNumServiceProcs = mNewNumServiceProcs; 17637 17638 // Now determine the memory trimming level of background processes. 17639 // Unfortunately we need to start at the back of the list to do this 17640 // properly. We only do this if the number of background apps we 17641 // are managing to keep around is less than half the maximum we desire; 17642 // if we are keeping a good number around, we'll let them use whatever 17643 // memory they want. 17644 final int numCachedAndEmpty = numCached + numEmpty; 17645 int memFactor; 17646 if (numCached <= ProcessList.TRIM_CACHED_APPS 17647 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17648 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17649 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17650 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17651 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17652 } else { 17653 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17654 } 17655 } else { 17656 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17657 } 17658 // We always allow the memory level to go up (better). We only allow it to go 17659 // down if we are in a state where that is allowed, *and* the total number of processes 17660 // has gone down since last time. 17661 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17662 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17663 + " last=" + mLastNumProcesses); 17664 if (memFactor > mLastMemoryLevel) { 17665 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17666 memFactor = mLastMemoryLevel; 17667 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17668 } 17669 } 17670 mLastMemoryLevel = memFactor; 17671 mLastNumProcesses = mLruProcesses.size(); 17672 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17673 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17674 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17675 if (mLowRamStartTime == 0) { 17676 mLowRamStartTime = now; 17677 } 17678 int step = 0; 17679 int fgTrimLevel; 17680 switch (memFactor) { 17681 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17682 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17683 break; 17684 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17685 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17686 break; 17687 default: 17688 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17689 break; 17690 } 17691 int factor = numTrimming/3; 17692 int minFactor = 2; 17693 if (mHomeProcess != null) minFactor++; 17694 if (mPreviousProcess != null) minFactor++; 17695 if (factor < minFactor) factor = minFactor; 17696 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17697 for (int i=N-1; i>=0; i--) { 17698 ProcessRecord app = mLruProcesses.get(i); 17699 if (allChanged || app.procStateChanged) { 17700 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17701 app.procStateChanged = false; 17702 } 17703 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17704 && !app.killedByAm) { 17705 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17706 try { 17707 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17708 "Trimming memory of " + app.processName 17709 + " to " + curLevel); 17710 app.thread.scheduleTrimMemory(curLevel); 17711 } catch (RemoteException e) { 17712 } 17713 if (false) { 17714 // For now we won't do this; our memory trimming seems 17715 // to be good enough at this point that destroying 17716 // activities causes more harm than good. 17717 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17718 && app != mHomeProcess && app != mPreviousProcess) { 17719 // Need to do this on its own message because the stack may not 17720 // be in a consistent state at this point. 17721 // For these apps we will also finish their activities 17722 // to help them free memory. 17723 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17724 } 17725 } 17726 } 17727 app.trimMemoryLevel = curLevel; 17728 step++; 17729 if (step >= factor) { 17730 step = 0; 17731 switch (curLevel) { 17732 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17733 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17734 break; 17735 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17736 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17737 break; 17738 } 17739 } 17740 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17741 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17742 && app.thread != null) { 17743 try { 17744 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17745 "Trimming memory of heavy-weight " + app.processName 17746 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17747 app.thread.scheduleTrimMemory( 17748 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17749 } catch (RemoteException e) { 17750 } 17751 } 17752 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17753 } else { 17754 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17755 || app.systemNoUi) && app.pendingUiClean) { 17756 // If this application is now in the background and it 17757 // had done UI, then give it the special trim level to 17758 // have it free UI resources. 17759 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17760 if (app.trimMemoryLevel < level && app.thread != null) { 17761 try { 17762 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17763 "Trimming memory of bg-ui " + app.processName 17764 + " to " + level); 17765 app.thread.scheduleTrimMemory(level); 17766 } catch (RemoteException e) { 17767 } 17768 } 17769 app.pendingUiClean = false; 17770 } 17771 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17772 try { 17773 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17774 "Trimming memory of fg " + app.processName 17775 + " to " + fgTrimLevel); 17776 app.thread.scheduleTrimMemory(fgTrimLevel); 17777 } catch (RemoteException e) { 17778 } 17779 } 17780 app.trimMemoryLevel = fgTrimLevel; 17781 } 17782 } 17783 } else { 17784 if (mLowRamStartTime != 0) { 17785 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17786 mLowRamStartTime = 0; 17787 } 17788 for (int i=N-1; i>=0; i--) { 17789 ProcessRecord app = mLruProcesses.get(i); 17790 if (allChanged || app.procStateChanged) { 17791 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17792 app.procStateChanged = false; 17793 } 17794 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17795 || app.systemNoUi) && app.pendingUiClean) { 17796 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17797 && app.thread != null) { 17798 try { 17799 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17800 "Trimming memory of ui hidden " + app.processName 17801 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17802 app.thread.scheduleTrimMemory( 17803 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17804 } catch (RemoteException e) { 17805 } 17806 } 17807 app.pendingUiClean = false; 17808 } 17809 app.trimMemoryLevel = 0; 17810 } 17811 } 17812 17813 if (mAlwaysFinishActivities) { 17814 // Need to do this on its own message because the stack may not 17815 // be in a consistent state at this point. 17816 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17817 } 17818 17819 if (allChanged) { 17820 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17821 } 17822 17823 if (mProcessStats.shouldWriteNowLocked(now)) { 17824 mHandler.post(new Runnable() { 17825 @Override public void run() { 17826 synchronized (ActivityManagerService.this) { 17827 mProcessStats.writeStateAsyncLocked(); 17828 } 17829 } 17830 }); 17831 } 17832 17833 if (DEBUG_OOM_ADJ) { 17834 if (false) { 17835 RuntimeException here = new RuntimeException("here"); 17836 here.fillInStackTrace(); 17837 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17838 } else { 17839 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17840 } 17841 } 17842 } 17843 17844 final void trimApplications() { 17845 synchronized (this) { 17846 int i; 17847 17848 // First remove any unused application processes whose package 17849 // has been removed. 17850 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17851 final ProcessRecord app = mRemovedProcesses.get(i); 17852 if (app.activities.size() == 0 17853 && app.curReceiver == null && app.services.size() == 0) { 17854 Slog.i( 17855 TAG, "Exiting empty application process " 17856 + app.processName + " (" 17857 + (app.thread != null ? app.thread.asBinder() : null) 17858 + ")\n"); 17859 if (app.pid > 0 && app.pid != MY_PID) { 17860 app.kill("empty", false); 17861 } else { 17862 try { 17863 app.thread.scheduleExit(); 17864 } catch (Exception e) { 17865 // Ignore exceptions. 17866 } 17867 } 17868 cleanUpApplicationRecordLocked(app, false, true, -1); 17869 mRemovedProcesses.remove(i); 17870 17871 if (app.persistent) { 17872 addAppLocked(app.info, false, null /* ABI override */); 17873 } 17874 } 17875 } 17876 17877 // Now update the oom adj for all processes. 17878 updateOomAdjLocked(); 17879 } 17880 } 17881 17882 /** This method sends the specified signal to each of the persistent apps */ 17883 public void signalPersistentProcesses(int sig) throws RemoteException { 17884 if (sig != Process.SIGNAL_USR1) { 17885 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17886 } 17887 17888 synchronized (this) { 17889 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17890 != PackageManager.PERMISSION_GRANTED) { 17891 throw new SecurityException("Requires permission " 17892 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17893 } 17894 17895 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17896 ProcessRecord r = mLruProcesses.get(i); 17897 if (r.thread != null && r.persistent) { 17898 Process.sendSignal(r.pid, sig); 17899 } 17900 } 17901 } 17902 } 17903 17904 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17905 if (proc == null || proc == mProfileProc) { 17906 proc = mProfileProc; 17907 profileType = mProfileType; 17908 clearProfilerLocked(); 17909 } 17910 if (proc == null) { 17911 return; 17912 } 17913 try { 17914 proc.thread.profilerControl(false, null, profileType); 17915 } catch (RemoteException e) { 17916 throw new IllegalStateException("Process disappeared"); 17917 } 17918 } 17919 17920 private void clearProfilerLocked() { 17921 if (mProfileFd != null) { 17922 try { 17923 mProfileFd.close(); 17924 } catch (IOException e) { 17925 } 17926 } 17927 mProfileApp = null; 17928 mProfileProc = null; 17929 mProfileFile = null; 17930 mProfileType = 0; 17931 mAutoStopProfiler = false; 17932 mSamplingInterval = 0; 17933 } 17934 17935 public boolean profileControl(String process, int userId, boolean start, 17936 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17937 17938 try { 17939 synchronized (this) { 17940 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17941 // its own permission. 17942 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17943 != PackageManager.PERMISSION_GRANTED) { 17944 throw new SecurityException("Requires permission " 17945 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17946 } 17947 17948 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17949 throw new IllegalArgumentException("null profile info or fd"); 17950 } 17951 17952 ProcessRecord proc = null; 17953 if (process != null) { 17954 proc = findProcessLocked(process, userId, "profileControl"); 17955 } 17956 17957 if (start && (proc == null || proc.thread == null)) { 17958 throw new IllegalArgumentException("Unknown process: " + process); 17959 } 17960 17961 if (start) { 17962 stopProfilerLocked(null, 0); 17963 setProfileApp(proc.info, proc.processName, profilerInfo); 17964 mProfileProc = proc; 17965 mProfileType = profileType; 17966 ParcelFileDescriptor fd = profilerInfo.profileFd; 17967 try { 17968 fd = fd.dup(); 17969 } catch (IOException e) { 17970 fd = null; 17971 } 17972 profilerInfo.profileFd = fd; 17973 proc.thread.profilerControl(start, profilerInfo, profileType); 17974 fd = null; 17975 mProfileFd = null; 17976 } else { 17977 stopProfilerLocked(proc, profileType); 17978 if (profilerInfo != null && profilerInfo.profileFd != null) { 17979 try { 17980 profilerInfo.profileFd.close(); 17981 } catch (IOException e) { 17982 } 17983 } 17984 } 17985 17986 return true; 17987 } 17988 } catch (RemoteException e) { 17989 throw new IllegalStateException("Process disappeared"); 17990 } finally { 17991 if (profilerInfo != null && profilerInfo.profileFd != null) { 17992 try { 17993 profilerInfo.profileFd.close(); 17994 } catch (IOException e) { 17995 } 17996 } 17997 } 17998 } 17999 18000 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18001 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18002 userId, true, ALLOW_FULL_ONLY, callName, null); 18003 ProcessRecord proc = null; 18004 try { 18005 int pid = Integer.parseInt(process); 18006 synchronized (mPidsSelfLocked) { 18007 proc = mPidsSelfLocked.get(pid); 18008 } 18009 } catch (NumberFormatException e) { 18010 } 18011 18012 if (proc == null) { 18013 ArrayMap<String, SparseArray<ProcessRecord>> all 18014 = mProcessNames.getMap(); 18015 SparseArray<ProcessRecord> procs = all.get(process); 18016 if (procs != null && procs.size() > 0) { 18017 proc = procs.valueAt(0); 18018 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18019 for (int i=1; i<procs.size(); i++) { 18020 ProcessRecord thisProc = procs.valueAt(i); 18021 if (thisProc.userId == userId) { 18022 proc = thisProc; 18023 break; 18024 } 18025 } 18026 } 18027 } 18028 } 18029 18030 return proc; 18031 } 18032 18033 public boolean dumpHeap(String process, int userId, boolean managed, 18034 String path, ParcelFileDescriptor fd) throws RemoteException { 18035 18036 try { 18037 synchronized (this) { 18038 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18039 // its own permission (same as profileControl). 18040 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18041 != PackageManager.PERMISSION_GRANTED) { 18042 throw new SecurityException("Requires permission " 18043 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18044 } 18045 18046 if (fd == null) { 18047 throw new IllegalArgumentException("null fd"); 18048 } 18049 18050 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18051 if (proc == null || proc.thread == null) { 18052 throw new IllegalArgumentException("Unknown process: " + process); 18053 } 18054 18055 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18056 if (!isDebuggable) { 18057 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18058 throw new SecurityException("Process not debuggable: " + proc); 18059 } 18060 } 18061 18062 proc.thread.dumpHeap(managed, path, fd); 18063 fd = null; 18064 return true; 18065 } 18066 } catch (RemoteException e) { 18067 throw new IllegalStateException("Process disappeared"); 18068 } finally { 18069 if (fd != null) { 18070 try { 18071 fd.close(); 18072 } catch (IOException e) { 18073 } 18074 } 18075 } 18076 } 18077 18078 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18079 public void monitor() { 18080 synchronized (this) { } 18081 } 18082 18083 void onCoreSettingsChange(Bundle settings) { 18084 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18085 ProcessRecord processRecord = mLruProcesses.get(i); 18086 try { 18087 if (processRecord.thread != null) { 18088 processRecord.thread.setCoreSettings(settings); 18089 } 18090 } catch (RemoteException re) { 18091 /* ignore */ 18092 } 18093 } 18094 } 18095 18096 // Multi-user methods 18097 18098 /** 18099 * Start user, if its not already running, but don't bring it to foreground. 18100 */ 18101 @Override 18102 public boolean startUserInBackground(final int userId) { 18103 return startUser(userId, /* foreground */ false); 18104 } 18105 18106 /** 18107 * Start user, if its not already running, and bring it to foreground. 18108 */ 18109 boolean startUserInForeground(final int userId, Dialog dlg) { 18110 boolean result = startUser(userId, /* foreground */ true); 18111 dlg.dismiss(); 18112 return result; 18113 } 18114 18115 /** 18116 * Refreshes the list of users related to the current user when either a 18117 * user switch happens or when a new related user is started in the 18118 * background. 18119 */ 18120 private void updateCurrentProfileIdsLocked() { 18121 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18122 mCurrentUserId, false /* enabledOnly */); 18123 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18124 for (int i = 0; i < currentProfileIds.length; i++) { 18125 currentProfileIds[i] = profiles.get(i).id; 18126 } 18127 mCurrentProfileIds = currentProfileIds; 18128 18129 synchronized (mUserProfileGroupIdsSelfLocked) { 18130 mUserProfileGroupIdsSelfLocked.clear(); 18131 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18132 for (int i = 0; i < users.size(); i++) { 18133 UserInfo user = users.get(i); 18134 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18135 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18136 } 18137 } 18138 } 18139 } 18140 18141 private Set getProfileIdsLocked(int userId) { 18142 Set userIds = new HashSet<Integer>(); 18143 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18144 userId, false /* enabledOnly */); 18145 for (UserInfo user : profiles) { 18146 userIds.add(Integer.valueOf(user.id)); 18147 } 18148 return userIds; 18149 } 18150 18151 @Override 18152 public boolean switchUser(final int userId) { 18153 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18154 String userName; 18155 synchronized (this) { 18156 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18157 if (userInfo == null) { 18158 Slog.w(TAG, "No user info for user #" + userId); 18159 return false; 18160 } 18161 if (userInfo.isManagedProfile()) { 18162 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18163 return false; 18164 } 18165 userName = userInfo.name; 18166 mTargetUserId = userId; 18167 } 18168 mHandler.removeMessages(START_USER_SWITCH_MSG); 18169 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18170 return true; 18171 } 18172 18173 private void showUserSwitchDialog(int userId, String userName) { 18174 // The dialog will show and then initiate the user switch by calling startUserInForeground 18175 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18176 true /* above system */); 18177 d.show(); 18178 } 18179 18180 private boolean startUser(final int userId, final boolean foreground) { 18181 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18182 != PackageManager.PERMISSION_GRANTED) { 18183 String msg = "Permission Denial: switchUser() from pid=" 18184 + Binder.getCallingPid() 18185 + ", uid=" + Binder.getCallingUid() 18186 + " requires " + INTERACT_ACROSS_USERS_FULL; 18187 Slog.w(TAG, msg); 18188 throw new SecurityException(msg); 18189 } 18190 18191 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18192 18193 final long ident = Binder.clearCallingIdentity(); 18194 try { 18195 synchronized (this) { 18196 final int oldUserId = mCurrentUserId; 18197 if (oldUserId == userId) { 18198 return true; 18199 } 18200 18201 mStackSupervisor.setLockTaskModeLocked(null, false); 18202 18203 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18204 if (userInfo == null) { 18205 Slog.w(TAG, "No user info for user #" + userId); 18206 return false; 18207 } 18208 if (foreground && userInfo.isManagedProfile()) { 18209 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18210 return false; 18211 } 18212 18213 if (foreground) { 18214 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18215 R.anim.screen_user_enter); 18216 } 18217 18218 boolean needStart = false; 18219 18220 // If the user we are switching to is not currently started, then 18221 // we need to start it now. 18222 if (mStartedUsers.get(userId) == null) { 18223 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18224 updateStartedUserArrayLocked(); 18225 needStart = true; 18226 } 18227 18228 final Integer userIdInt = Integer.valueOf(userId); 18229 mUserLru.remove(userIdInt); 18230 mUserLru.add(userIdInt); 18231 18232 if (foreground) { 18233 mCurrentUserId = userId; 18234 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18235 updateCurrentProfileIdsLocked(); 18236 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18237 // Once the internal notion of the active user has switched, we lock the device 18238 // with the option to show the user switcher on the keyguard. 18239 mWindowManager.lockNow(null); 18240 } else { 18241 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18242 updateCurrentProfileIdsLocked(); 18243 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18244 mUserLru.remove(currentUserIdInt); 18245 mUserLru.add(currentUserIdInt); 18246 } 18247 18248 final UserStartedState uss = mStartedUsers.get(userId); 18249 18250 // Make sure user is in the started state. If it is currently 18251 // stopping, we need to knock that off. 18252 if (uss.mState == UserStartedState.STATE_STOPPING) { 18253 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18254 // so we can just fairly silently bring the user back from 18255 // the almost-dead. 18256 uss.mState = UserStartedState.STATE_RUNNING; 18257 updateStartedUserArrayLocked(); 18258 needStart = true; 18259 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18260 // This means ACTION_SHUTDOWN has been sent, so we will 18261 // need to treat this as a new boot of the user. 18262 uss.mState = UserStartedState.STATE_BOOTING; 18263 updateStartedUserArrayLocked(); 18264 needStart = true; 18265 } 18266 18267 if (uss.mState == UserStartedState.STATE_BOOTING) { 18268 // Booting up a new user, need to tell system services about it. 18269 // Note that this is on the same handler as scheduling of broadcasts, 18270 // which is important because it needs to go first. 18271 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18272 } 18273 18274 if (foreground) { 18275 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18276 oldUserId)); 18277 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18278 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18279 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18280 oldUserId, userId, uss)); 18281 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18282 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18283 } 18284 18285 if (needStart) { 18286 // Send USER_STARTED broadcast 18287 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18288 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18289 | Intent.FLAG_RECEIVER_FOREGROUND); 18290 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18291 broadcastIntentLocked(null, null, intent, 18292 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18293 false, false, MY_PID, Process.SYSTEM_UID, userId); 18294 } 18295 18296 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18297 if (userId != UserHandle.USER_OWNER) { 18298 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18299 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18300 broadcastIntentLocked(null, null, intent, null, 18301 new IIntentReceiver.Stub() { 18302 public void performReceive(Intent intent, int resultCode, 18303 String data, Bundle extras, boolean ordered, 18304 boolean sticky, int sendingUser) { 18305 onUserInitialized(uss, foreground, oldUserId, userId); 18306 } 18307 }, 0, null, null, null, AppOpsManager.OP_NONE, 18308 true, false, MY_PID, Process.SYSTEM_UID, 18309 userId); 18310 uss.initializing = true; 18311 } else { 18312 getUserManagerLocked().makeInitialized(userInfo.id); 18313 } 18314 } 18315 18316 if (foreground) { 18317 if (!uss.initializing) { 18318 moveUserToForeground(uss, oldUserId, userId); 18319 } 18320 } else { 18321 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18322 } 18323 18324 if (needStart) { 18325 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18326 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18327 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18328 broadcastIntentLocked(null, null, intent, 18329 null, new IIntentReceiver.Stub() { 18330 @Override 18331 public void performReceive(Intent intent, int resultCode, String data, 18332 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18333 throws RemoteException { 18334 } 18335 }, 0, null, null, 18336 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18337 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18338 } 18339 } 18340 } finally { 18341 Binder.restoreCallingIdentity(ident); 18342 } 18343 18344 return true; 18345 } 18346 18347 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18348 long ident = Binder.clearCallingIdentity(); 18349 try { 18350 Intent intent; 18351 if (oldUserId >= 0) { 18352 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18353 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18354 int count = profiles.size(); 18355 for (int i = 0; i < count; i++) { 18356 int profileUserId = profiles.get(i).id; 18357 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18358 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18359 | Intent.FLAG_RECEIVER_FOREGROUND); 18360 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18361 broadcastIntentLocked(null, null, intent, 18362 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18363 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18364 } 18365 } 18366 if (newUserId >= 0) { 18367 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18368 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18369 int count = profiles.size(); 18370 for (int i = 0; i < count; i++) { 18371 int profileUserId = profiles.get(i).id; 18372 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18373 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18374 | Intent.FLAG_RECEIVER_FOREGROUND); 18375 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18376 broadcastIntentLocked(null, null, intent, 18377 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18378 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18379 } 18380 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18381 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18382 | Intent.FLAG_RECEIVER_FOREGROUND); 18383 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18384 broadcastIntentLocked(null, null, intent, 18385 null, null, 0, null, null, 18386 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18387 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18388 } 18389 } finally { 18390 Binder.restoreCallingIdentity(ident); 18391 } 18392 } 18393 18394 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18395 final int newUserId) { 18396 final int N = mUserSwitchObservers.beginBroadcast(); 18397 if (N > 0) { 18398 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18399 int mCount = 0; 18400 @Override 18401 public void sendResult(Bundle data) throws RemoteException { 18402 synchronized (ActivityManagerService.this) { 18403 if (mCurUserSwitchCallback == this) { 18404 mCount++; 18405 if (mCount == N) { 18406 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18407 } 18408 } 18409 } 18410 } 18411 }; 18412 synchronized (this) { 18413 uss.switching = true; 18414 mCurUserSwitchCallback = callback; 18415 } 18416 for (int i=0; i<N; i++) { 18417 try { 18418 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18419 newUserId, callback); 18420 } catch (RemoteException e) { 18421 } 18422 } 18423 } else { 18424 synchronized (this) { 18425 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18426 } 18427 } 18428 mUserSwitchObservers.finishBroadcast(); 18429 } 18430 18431 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18432 synchronized (this) { 18433 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18434 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18435 } 18436 } 18437 18438 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18439 mCurUserSwitchCallback = null; 18440 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18441 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18442 oldUserId, newUserId, uss)); 18443 } 18444 18445 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18446 synchronized (this) { 18447 if (foreground) { 18448 moveUserToForeground(uss, oldUserId, newUserId); 18449 } 18450 } 18451 18452 completeSwitchAndInitalize(uss, newUserId, true, false); 18453 } 18454 18455 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18456 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18457 if (homeInFront) { 18458 startHomeActivityLocked(newUserId); 18459 } else { 18460 mStackSupervisor.resumeTopActivitiesLocked(); 18461 } 18462 EventLogTags.writeAmSwitchUser(newUserId); 18463 getUserManagerLocked().userForeground(newUserId); 18464 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18465 } 18466 18467 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18468 completeSwitchAndInitalize(uss, newUserId, false, true); 18469 } 18470 18471 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18472 boolean clearInitializing, boolean clearSwitching) { 18473 boolean unfrozen = false; 18474 synchronized (this) { 18475 if (clearInitializing) { 18476 uss.initializing = false; 18477 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18478 } 18479 if (clearSwitching) { 18480 uss.switching = false; 18481 } 18482 if (!uss.switching && !uss.initializing) { 18483 mWindowManager.stopFreezingScreen(); 18484 unfrozen = true; 18485 } 18486 } 18487 if (unfrozen) { 18488 final int N = mUserSwitchObservers.beginBroadcast(); 18489 for (int i=0; i<N; i++) { 18490 try { 18491 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18492 } catch (RemoteException e) { 18493 } 18494 } 18495 mUserSwitchObservers.finishBroadcast(); 18496 } 18497 } 18498 18499 void scheduleStartProfilesLocked() { 18500 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18501 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18502 DateUtils.SECOND_IN_MILLIS); 18503 } 18504 } 18505 18506 void startProfilesLocked() { 18507 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18508 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18509 mCurrentUserId, false /* enabledOnly */); 18510 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18511 for (UserInfo user : profiles) { 18512 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18513 && user.id != mCurrentUserId) { 18514 toStart.add(user); 18515 } 18516 } 18517 final int n = toStart.size(); 18518 int i = 0; 18519 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18520 startUserInBackground(toStart.get(i).id); 18521 } 18522 if (i < n) { 18523 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18524 } 18525 } 18526 18527 void finishUserBoot(UserStartedState uss) { 18528 synchronized (this) { 18529 if (uss.mState == UserStartedState.STATE_BOOTING 18530 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18531 uss.mState = UserStartedState.STATE_RUNNING; 18532 final int userId = uss.mHandle.getIdentifier(); 18533 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18534 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18535 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18536 broadcastIntentLocked(null, null, intent, 18537 null, null, 0, null, null, 18538 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18539 true, false, MY_PID, Process.SYSTEM_UID, userId); 18540 } 18541 } 18542 } 18543 18544 void finishUserSwitch(UserStartedState uss) { 18545 synchronized (this) { 18546 finishUserBoot(uss); 18547 18548 startProfilesLocked(); 18549 18550 int num = mUserLru.size(); 18551 int i = 0; 18552 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18553 Integer oldUserId = mUserLru.get(i); 18554 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18555 if (oldUss == null) { 18556 // Shouldn't happen, but be sane if it does. 18557 mUserLru.remove(i); 18558 num--; 18559 continue; 18560 } 18561 if (oldUss.mState == UserStartedState.STATE_STOPPING 18562 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18563 // This user is already stopping, doesn't count. 18564 num--; 18565 i++; 18566 continue; 18567 } 18568 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18569 // Owner and current can't be stopped, but count as running. 18570 i++; 18571 continue; 18572 } 18573 // This is a user to be stopped. 18574 stopUserLocked(oldUserId, null); 18575 num--; 18576 i++; 18577 } 18578 } 18579 } 18580 18581 @Override 18582 public int stopUser(final int userId, final IStopUserCallback callback) { 18583 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18584 != PackageManager.PERMISSION_GRANTED) { 18585 String msg = "Permission Denial: switchUser() from pid=" 18586 + Binder.getCallingPid() 18587 + ", uid=" + Binder.getCallingUid() 18588 + " requires " + INTERACT_ACROSS_USERS_FULL; 18589 Slog.w(TAG, msg); 18590 throw new SecurityException(msg); 18591 } 18592 if (userId <= 0) { 18593 throw new IllegalArgumentException("Can't stop primary user " + userId); 18594 } 18595 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18596 synchronized (this) { 18597 return stopUserLocked(userId, callback); 18598 } 18599 } 18600 18601 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18602 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18603 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18604 return ActivityManager.USER_OP_IS_CURRENT; 18605 } 18606 18607 final UserStartedState uss = mStartedUsers.get(userId); 18608 if (uss == null) { 18609 // User is not started, nothing to do... but we do need to 18610 // callback if requested. 18611 if (callback != null) { 18612 mHandler.post(new Runnable() { 18613 @Override 18614 public void run() { 18615 try { 18616 callback.userStopped(userId); 18617 } catch (RemoteException e) { 18618 } 18619 } 18620 }); 18621 } 18622 return ActivityManager.USER_OP_SUCCESS; 18623 } 18624 18625 if (callback != null) { 18626 uss.mStopCallbacks.add(callback); 18627 } 18628 18629 if (uss.mState != UserStartedState.STATE_STOPPING 18630 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18631 uss.mState = UserStartedState.STATE_STOPPING; 18632 updateStartedUserArrayLocked(); 18633 18634 long ident = Binder.clearCallingIdentity(); 18635 try { 18636 // We are going to broadcast ACTION_USER_STOPPING and then 18637 // once that is done send a final ACTION_SHUTDOWN and then 18638 // stop the user. 18639 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18640 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18641 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18642 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18643 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18644 // This is the result receiver for the final shutdown broadcast. 18645 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18646 @Override 18647 public void performReceive(Intent intent, int resultCode, String data, 18648 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18649 finishUserStop(uss); 18650 } 18651 }; 18652 // This is the result receiver for the initial stopping broadcast. 18653 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18654 @Override 18655 public void performReceive(Intent intent, int resultCode, String data, 18656 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18657 // On to the next. 18658 synchronized (ActivityManagerService.this) { 18659 if (uss.mState != UserStartedState.STATE_STOPPING) { 18660 // Whoops, we are being started back up. Abort, abort! 18661 return; 18662 } 18663 uss.mState = UserStartedState.STATE_SHUTDOWN; 18664 } 18665 mBatteryStatsService.noteEvent( 18666 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18667 Integer.toString(userId), userId); 18668 mSystemServiceManager.stopUser(userId); 18669 broadcastIntentLocked(null, null, shutdownIntent, 18670 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18671 true, false, MY_PID, Process.SYSTEM_UID, userId); 18672 } 18673 }; 18674 // Kick things off. 18675 broadcastIntentLocked(null, null, stoppingIntent, 18676 null, stoppingReceiver, 0, null, null, 18677 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18678 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18679 } finally { 18680 Binder.restoreCallingIdentity(ident); 18681 } 18682 } 18683 18684 return ActivityManager.USER_OP_SUCCESS; 18685 } 18686 18687 void finishUserStop(UserStartedState uss) { 18688 final int userId = uss.mHandle.getIdentifier(); 18689 boolean stopped; 18690 ArrayList<IStopUserCallback> callbacks; 18691 synchronized (this) { 18692 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18693 if (mStartedUsers.get(userId) != uss) { 18694 stopped = false; 18695 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18696 stopped = false; 18697 } else { 18698 stopped = true; 18699 // User can no longer run. 18700 mStartedUsers.remove(userId); 18701 mUserLru.remove(Integer.valueOf(userId)); 18702 updateStartedUserArrayLocked(); 18703 18704 // Clean up all state and processes associated with the user. 18705 // Kill all the processes for the user. 18706 forceStopUserLocked(userId, "finish user"); 18707 } 18708 18709 // Explicitly remove the old information in mRecentTasks. 18710 removeRecentTasksForUserLocked(userId); 18711 } 18712 18713 for (int i=0; i<callbacks.size(); i++) { 18714 try { 18715 if (stopped) callbacks.get(i).userStopped(userId); 18716 else callbacks.get(i).userStopAborted(userId); 18717 } catch (RemoteException e) { 18718 } 18719 } 18720 18721 if (stopped) { 18722 mSystemServiceManager.cleanupUser(userId); 18723 synchronized (this) { 18724 mStackSupervisor.removeUserLocked(userId); 18725 } 18726 } 18727 } 18728 18729 @Override 18730 public UserInfo getCurrentUser() { 18731 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18732 != PackageManager.PERMISSION_GRANTED) && ( 18733 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18734 != PackageManager.PERMISSION_GRANTED)) { 18735 String msg = "Permission Denial: getCurrentUser() from pid=" 18736 + Binder.getCallingPid() 18737 + ", uid=" + Binder.getCallingUid() 18738 + " requires " + INTERACT_ACROSS_USERS; 18739 Slog.w(TAG, msg); 18740 throw new SecurityException(msg); 18741 } 18742 synchronized (this) { 18743 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18744 return getUserManagerLocked().getUserInfo(userId); 18745 } 18746 } 18747 18748 int getCurrentUserIdLocked() { 18749 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18750 } 18751 18752 @Override 18753 public boolean isUserRunning(int userId, boolean orStopped) { 18754 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18755 != PackageManager.PERMISSION_GRANTED) { 18756 String msg = "Permission Denial: isUserRunning() from pid=" 18757 + Binder.getCallingPid() 18758 + ", uid=" + Binder.getCallingUid() 18759 + " requires " + INTERACT_ACROSS_USERS; 18760 Slog.w(TAG, msg); 18761 throw new SecurityException(msg); 18762 } 18763 synchronized (this) { 18764 return isUserRunningLocked(userId, orStopped); 18765 } 18766 } 18767 18768 boolean isUserRunningLocked(int userId, boolean orStopped) { 18769 UserStartedState state = mStartedUsers.get(userId); 18770 if (state == null) { 18771 return false; 18772 } 18773 if (orStopped) { 18774 return true; 18775 } 18776 return state.mState != UserStartedState.STATE_STOPPING 18777 && state.mState != UserStartedState.STATE_SHUTDOWN; 18778 } 18779 18780 @Override 18781 public int[] getRunningUserIds() { 18782 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18783 != PackageManager.PERMISSION_GRANTED) { 18784 String msg = "Permission Denial: isUserRunning() from pid=" 18785 + Binder.getCallingPid() 18786 + ", uid=" + Binder.getCallingUid() 18787 + " requires " + INTERACT_ACROSS_USERS; 18788 Slog.w(TAG, msg); 18789 throw new SecurityException(msg); 18790 } 18791 synchronized (this) { 18792 return mStartedUserArray; 18793 } 18794 } 18795 18796 private void updateStartedUserArrayLocked() { 18797 int num = 0; 18798 for (int i=0; i<mStartedUsers.size(); i++) { 18799 UserStartedState uss = mStartedUsers.valueAt(i); 18800 // This list does not include stopping users. 18801 if (uss.mState != UserStartedState.STATE_STOPPING 18802 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18803 num++; 18804 } 18805 } 18806 mStartedUserArray = new int[num]; 18807 num = 0; 18808 for (int i=0; i<mStartedUsers.size(); i++) { 18809 UserStartedState uss = mStartedUsers.valueAt(i); 18810 if (uss.mState != UserStartedState.STATE_STOPPING 18811 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18812 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18813 num++; 18814 } 18815 } 18816 } 18817 18818 @Override 18819 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18820 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18821 != PackageManager.PERMISSION_GRANTED) { 18822 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18823 + Binder.getCallingPid() 18824 + ", uid=" + Binder.getCallingUid() 18825 + " requires " + INTERACT_ACROSS_USERS_FULL; 18826 Slog.w(TAG, msg); 18827 throw new SecurityException(msg); 18828 } 18829 18830 mUserSwitchObservers.register(observer); 18831 } 18832 18833 @Override 18834 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18835 mUserSwitchObservers.unregister(observer); 18836 } 18837 18838 private boolean userExists(int userId) { 18839 if (userId == 0) { 18840 return true; 18841 } 18842 UserManagerService ums = getUserManagerLocked(); 18843 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18844 } 18845 18846 int[] getUsersLocked() { 18847 UserManagerService ums = getUserManagerLocked(); 18848 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18849 } 18850 18851 UserManagerService getUserManagerLocked() { 18852 if (mUserManager == null) { 18853 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18854 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18855 } 18856 return mUserManager; 18857 } 18858 18859 private int applyUserId(int uid, int userId) { 18860 return UserHandle.getUid(userId, uid); 18861 } 18862 18863 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18864 if (info == null) return null; 18865 ApplicationInfo newInfo = new ApplicationInfo(info); 18866 newInfo.uid = applyUserId(info.uid, userId); 18867 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18868 + info.packageName; 18869 return newInfo; 18870 } 18871 18872 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18873 if (aInfo == null 18874 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18875 return aInfo; 18876 } 18877 18878 ActivityInfo info = new ActivityInfo(aInfo); 18879 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18880 return info; 18881 } 18882 18883 private final class LocalService extends ActivityManagerInternal { 18884 @Override 18885 public void goingToSleep() { 18886 ActivityManagerService.this.goingToSleep(); 18887 } 18888 18889 @Override 18890 public void wakingUp() { 18891 ActivityManagerService.this.wakingUp(); 18892 } 18893 18894 @Override 18895 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18896 String processName, String abiOverride, int uid, Runnable crashHandler) { 18897 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18898 processName, abiOverride, uid, crashHandler); 18899 } 18900 } 18901 18902 /** 18903 * An implementation of IAppTask, that allows an app to manage its own tasks via 18904 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18905 * only the process that calls getAppTasks() can call the AppTask methods. 18906 */ 18907 class AppTaskImpl extends IAppTask.Stub { 18908 private int mTaskId; 18909 private int mCallingUid; 18910 18911 public AppTaskImpl(int taskId, int callingUid) { 18912 mTaskId = taskId; 18913 mCallingUid = callingUid; 18914 } 18915 18916 private void checkCaller() { 18917 if (mCallingUid != Binder.getCallingUid()) { 18918 throw new SecurityException("Caller " + mCallingUid 18919 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18920 } 18921 } 18922 18923 @Override 18924 public void finishAndRemoveTask() { 18925 checkCaller(); 18926 18927 synchronized (ActivityManagerService.this) { 18928 long origId = Binder.clearCallingIdentity(); 18929 try { 18930 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18931 if (tr == null) { 18932 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18933 } 18934 // Only kill the process if we are not a new document 18935 int flags = tr.getBaseIntent().getFlags(); 18936 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18937 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18938 removeTaskByIdLocked(mTaskId, 18939 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18940 } finally { 18941 Binder.restoreCallingIdentity(origId); 18942 } 18943 } 18944 } 18945 18946 @Override 18947 public ActivityManager.RecentTaskInfo getTaskInfo() { 18948 checkCaller(); 18949 18950 synchronized (ActivityManagerService.this) { 18951 long origId = Binder.clearCallingIdentity(); 18952 try { 18953 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18954 if (tr == null) { 18955 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18956 } 18957 return createRecentTaskInfoFromTaskRecord(tr); 18958 } finally { 18959 Binder.restoreCallingIdentity(origId); 18960 } 18961 } 18962 } 18963 18964 @Override 18965 public void moveToFront() { 18966 checkCaller(); 18967 18968 final TaskRecord tr; 18969 synchronized (ActivityManagerService.this) { 18970 tr = recentTaskForIdLocked(mTaskId); 18971 if (tr == null) { 18972 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18973 } 18974 if (tr.getRootActivity() != null) { 18975 moveTaskToFrontLocked(tr.taskId, 0, null); 18976 } 18977 } 18978 18979 startActivityFromRecentsInner(tr.taskId, null); 18980 } 18981 18982 @Override 18983 public int startActivity(IBinder whoThread, String callingPackage, 18984 Intent intent, String resolvedType, Bundle options) { 18985 checkCaller(); 18986 18987 int callingUser = UserHandle.getCallingUserId(); 18988 TaskRecord tr; 18989 IApplicationThread appThread; 18990 synchronized (ActivityManagerService.this) { 18991 tr = recentTaskForIdLocked(mTaskId); 18992 if (tr == null) { 18993 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18994 } 18995 appThread = ApplicationThreadNative.asInterface(whoThread); 18996 if (appThread == null) { 18997 throw new IllegalArgumentException("Bad app thread " + appThread); 18998 } 18999 } 19000 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19001 resolvedType, null, null, null, null, 0, 0, null, null, 19002 null, options, callingUser, null, tr); 19003 } 19004 19005 @Override 19006 public void setExcludeFromRecents(boolean exclude) { 19007 checkCaller(); 19008 19009 synchronized (ActivityManagerService.this) { 19010 long origId = Binder.clearCallingIdentity(); 19011 try { 19012 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19013 if (tr == null) { 19014 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19015 } 19016 Intent intent = tr.getBaseIntent(); 19017 if (exclude) { 19018 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19019 } else { 19020 intent.setFlags(intent.getFlags() 19021 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19022 } 19023 } finally { 19024 Binder.restoreCallingIdentity(origId); 19025 } 19026 } 19027 } 19028 } 19029} 19030