ActivityManagerService.java revision 70af00abf73160235d4efe114fcf4753007a8ff3
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a Recents UI */ 1202 boolean mHasRecents; 1203 1204 /** The dimensions of the thumbnails in the Recents UI. */ 1205 int mThumbnailWidth; 1206 int mThumbnailHeight; 1207 1208 final ServiceThread mHandlerThread; 1209 final MainHandler mHandler; 1210 1211 final class MainHandler extends Handler { 1212 public MainHandler(Looper looper) { 1213 super(looper, null, true); 1214 } 1215 1216 @Override 1217 public void handleMessage(Message msg) { 1218 switch (msg.what) { 1219 case SHOW_ERROR_MSG: { 1220 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1221 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1222 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1223 synchronized (ActivityManagerService.this) { 1224 ProcessRecord proc = (ProcessRecord)data.get("app"); 1225 AppErrorResult res = (AppErrorResult) data.get("result"); 1226 if (proc != null && proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has crash dialog: " + proc); 1228 if (res != null) { 1229 res.set(0); 1230 } 1231 return; 1232 } 1233 boolean isBackground = (UserHandle.getAppId(proc.uid) 1234 >= Process.FIRST_APPLICATION_UID 1235 && proc.pid != MY_PID); 1236 for (int userId : mCurrentProfileIds) { 1237 isBackground &= (proc.userId != userId); 1238 } 1239 if (isBackground && !showBackground) { 1240 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1241 if (res != null) { 1242 res.set(0); 1243 } 1244 return; 1245 } 1246 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1247 Dialog d = new AppErrorDialog(mContext, 1248 ActivityManagerService.this, res, proc); 1249 d.show(); 1250 proc.crashDialog = d; 1251 } else { 1252 // The device is asleep, so just pretend that the user 1253 // saw a crash dialog and hit "force quit". 1254 if (res != null) { 1255 res.set(0); 1256 } 1257 } 1258 } 1259 1260 ensureBootCompleted(); 1261 } break; 1262 case SHOW_NOT_RESPONDING_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1265 ProcessRecord proc = (ProcessRecord)data.get("app"); 1266 if (proc != null && proc.anrDialog != null) { 1267 Slog.e(TAG, "App already has anr dialog: " + proc); 1268 return; 1269 } 1270 1271 Intent intent = new Intent("android.intent.action.ANR"); 1272 if (!mProcessesReady) { 1273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1274 | Intent.FLAG_RECEIVER_FOREGROUND); 1275 } 1276 broadcastIntentLocked(null, null, intent, 1277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1278 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1279 1280 if (mShowDialogs) { 1281 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1282 mContext, proc, (ActivityRecord)data.get("activity"), 1283 msg.arg1 != 0); 1284 d.show(); 1285 proc.anrDialog = d; 1286 } else { 1287 // Just kill the app if there is no dialog to be shown. 1288 killAppAtUsersRequest(proc, null); 1289 } 1290 } 1291 1292 ensureBootCompleted(); 1293 } break; 1294 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1295 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1296 synchronized (ActivityManagerService.this) { 1297 ProcessRecord proc = (ProcessRecord) data.get("app"); 1298 if (proc == null) { 1299 Slog.e(TAG, "App not found when showing strict mode dialog."); 1300 break; 1301 } 1302 if (proc.crashDialog != null) { 1303 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1304 return; 1305 } 1306 AppErrorResult res = (AppErrorResult) data.get("result"); 1307 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1308 Dialog d = new StrictModeViolationDialog(mContext, 1309 ActivityManagerService.this, res, proc); 1310 d.show(); 1311 proc.crashDialog = d; 1312 } else { 1313 // The device is asleep, so just pretend that the user 1314 // saw a crash dialog and hit "force quit". 1315 res.set(0); 1316 } 1317 } 1318 ensureBootCompleted(); 1319 } break; 1320 case SHOW_FACTORY_ERROR_MSG: { 1321 Dialog d = new FactoryErrorDialog( 1322 mContext, msg.getData().getCharSequence("msg")); 1323 d.show(); 1324 ensureBootCompleted(); 1325 } break; 1326 case UPDATE_CONFIGURATION_MSG: { 1327 final ContentResolver resolver = mContext.getContentResolver(); 1328 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1329 } break; 1330 case GC_BACKGROUND_PROCESSES_MSG: { 1331 synchronized (ActivityManagerService.this) { 1332 performAppGcsIfAppropriateLocked(); 1333 } 1334 } break; 1335 case WAIT_FOR_DEBUGGER_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 ProcessRecord app = (ProcessRecord)msg.obj; 1338 if (msg.arg1 != 0) { 1339 if (!app.waitedForDebugger) { 1340 Dialog d = new AppWaitingForDebuggerDialog( 1341 ActivityManagerService.this, 1342 mContext, app); 1343 app.waitDialog = d; 1344 app.waitedForDebugger = true; 1345 d.show(); 1346 } 1347 } else { 1348 if (app.waitDialog != null) { 1349 app.waitDialog.dismiss(); 1350 app.waitDialog = null; 1351 } 1352 } 1353 } 1354 } break; 1355 case SERVICE_TIMEOUT_MSG: { 1356 if (mDidDexOpt) { 1357 mDidDexOpt = false; 1358 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1359 nmsg.obj = msg.obj; 1360 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1361 return; 1362 } 1363 mServices.serviceTimeout((ProcessRecord)msg.obj); 1364 } break; 1365 case UPDATE_TIME_ZONE: { 1366 synchronized (ActivityManagerService.this) { 1367 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1368 ProcessRecord r = mLruProcesses.get(i); 1369 if (r.thread != null) { 1370 try { 1371 r.thread.updateTimeZone(); 1372 } catch (RemoteException ex) { 1373 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1374 } 1375 } 1376 } 1377 } 1378 } break; 1379 case CLEAR_DNS_CACHE_MSG: { 1380 synchronized (ActivityManagerService.this) { 1381 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1382 ProcessRecord r = mLruProcesses.get(i); 1383 if (r.thread != null) { 1384 try { 1385 r.thread.clearDnsCache(); 1386 } catch (RemoteException ex) { 1387 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1388 } 1389 } 1390 } 1391 } 1392 } break; 1393 case UPDATE_HTTP_PROXY_MSG: { 1394 ProxyInfo proxy = (ProxyInfo)msg.obj; 1395 String host = ""; 1396 String port = ""; 1397 String exclList = ""; 1398 Uri pacFileUrl = Uri.EMPTY; 1399 if (proxy != null) { 1400 host = proxy.getHost(); 1401 port = Integer.toString(proxy.getPort()); 1402 exclList = proxy.getExclusionListAsString(); 1403 pacFileUrl = proxy.getPacFileUrl(); 1404 } 1405 synchronized (ActivityManagerService.this) { 1406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1407 ProcessRecord r = mLruProcesses.get(i); 1408 if (r.thread != null) { 1409 try { 1410 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1411 } catch (RemoteException ex) { 1412 Slog.w(TAG, "Failed to update http proxy for: " + 1413 r.info.processName); 1414 } 1415 } 1416 } 1417 } 1418 } break; 1419 case SHOW_UID_ERROR_MSG: { 1420 String title = "System UIDs Inconsistent"; 1421 String text = "UIDs on the system are inconsistent, you need to wipe your" 1422 + " data partition or your device will be unstable."; 1423 Log.e(TAG, title + ": " + text); 1424 if (mShowDialogs) { 1425 // XXX This is a temporary dialog, no need to localize. 1426 AlertDialog d = new BaseErrorDialog(mContext); 1427 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1428 d.setCancelable(false); 1429 d.setTitle(title); 1430 d.setMessage(text); 1431 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1432 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1433 mUidAlert = d; 1434 d.show(); 1435 } 1436 } break; 1437 case IM_FEELING_LUCKY_MSG: { 1438 if (mUidAlert != null) { 1439 mUidAlert.dismiss(); 1440 mUidAlert = null; 1441 } 1442 } break; 1443 case PROC_START_TIMEOUT_MSG: { 1444 if (mDidDexOpt) { 1445 mDidDexOpt = false; 1446 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1447 nmsg.obj = msg.obj; 1448 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1449 return; 1450 } 1451 ProcessRecord app = (ProcessRecord)msg.obj; 1452 synchronized (ActivityManagerService.this) { 1453 processStartTimedOutLocked(app); 1454 } 1455 } break; 1456 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1457 synchronized (ActivityManagerService.this) { 1458 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1459 } 1460 } break; 1461 case KILL_APPLICATION_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 int appid = msg.arg1; 1464 boolean restart = (msg.arg2 == 1); 1465 Bundle bundle = (Bundle)msg.obj; 1466 String pkg = bundle.getString("pkg"); 1467 String reason = bundle.getString("reason"); 1468 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1469 false, UserHandle.USER_ALL, reason); 1470 } 1471 } break; 1472 case FINALIZE_PENDING_INTENT_MSG: { 1473 ((PendingIntentRecord)msg.obj).completeFinalize(); 1474 } break; 1475 case POST_HEAVY_NOTIFICATION_MSG: { 1476 INotificationManager inm = NotificationManager.getService(); 1477 if (inm == null) { 1478 return; 1479 } 1480 1481 ActivityRecord root = (ActivityRecord)msg.obj; 1482 ProcessRecord process = root.app; 1483 if (process == null) { 1484 return; 1485 } 1486 1487 try { 1488 Context context = mContext.createPackageContext(process.info.packageName, 0); 1489 String text = mContext.getString(R.string.heavy_weight_notification, 1490 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1491 Notification notification = new Notification(); 1492 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1493 notification.when = 0; 1494 notification.flags = Notification.FLAG_ONGOING_EVENT; 1495 notification.tickerText = text; 1496 notification.defaults = 0; // please be quiet 1497 notification.sound = null; 1498 notification.vibrate = null; 1499 notification.color = mContext.getResources().getColor( 1500 com.android.internal.R.color.system_notification_accent_color); 1501 notification.setLatestEventInfo(context, text, 1502 mContext.getText(R.string.heavy_weight_notification_detail), 1503 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1504 PendingIntent.FLAG_CANCEL_CURRENT, null, 1505 new UserHandle(root.userId))); 1506 1507 try { 1508 int[] outId = new int[1]; 1509 inm.enqueueNotificationWithTag("android", "android", null, 1510 R.string.heavy_weight_notification, 1511 notification, outId, root.userId); 1512 } catch (RuntimeException e) { 1513 Slog.w(ActivityManagerService.TAG, 1514 "Error showing notification for heavy-weight app", e); 1515 } catch (RemoteException e) { 1516 } 1517 } catch (NameNotFoundException e) { 1518 Slog.w(TAG, "Unable to create context for heavy notification", e); 1519 } 1520 } break; 1521 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 try { 1527 inm.cancelNotificationWithTag("android", null, 1528 R.string.heavy_weight_notification, msg.arg1); 1529 } catch (RuntimeException e) { 1530 Slog.w(ActivityManagerService.TAG, 1531 "Error canceling notification for service", e); 1532 } catch (RemoteException e) { 1533 } 1534 } break; 1535 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 checkExcessivePowerUsageLocked(true); 1538 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1540 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1541 } 1542 } break; 1543 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 ActivityRecord ar = (ActivityRecord)msg.obj; 1546 if (mCompatModeDialog != null) { 1547 if (mCompatModeDialog.mAppInfo.packageName.equals( 1548 ar.info.applicationInfo.packageName)) { 1549 return; 1550 } 1551 mCompatModeDialog.dismiss(); 1552 mCompatModeDialog = null; 1553 } 1554 if (ar != null && false) { 1555 if (mCompatModePackages.getPackageAskCompatModeLocked( 1556 ar.packageName)) { 1557 int mode = mCompatModePackages.computeCompatModeLocked( 1558 ar.info.applicationInfo); 1559 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1560 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1561 mCompatModeDialog = new CompatModeDialog( 1562 ActivityManagerService.this, mContext, 1563 ar.info.applicationInfo); 1564 mCompatModeDialog.show(); 1565 } 1566 } 1567 } 1568 } 1569 break; 1570 } 1571 case DISPATCH_PROCESSES_CHANGED: { 1572 dispatchProcessesChanged(); 1573 break; 1574 } 1575 case DISPATCH_PROCESS_DIED: { 1576 final int pid = msg.arg1; 1577 final int uid = msg.arg2; 1578 dispatchProcessDied(pid, uid); 1579 break; 1580 } 1581 case REPORT_MEM_USAGE_MSG: { 1582 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1583 Thread thread = new Thread() { 1584 @Override public void run() { 1585 final SparseArray<ProcessMemInfo> infoMap 1586 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 infoMap.put(mi.pid, mi); 1590 } 1591 updateCpuStatsNow(); 1592 synchronized (mProcessCpuThread) { 1593 final int N = mProcessCpuTracker.countStats(); 1594 for (int i=0; i<N; i++) { 1595 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1596 if (st.vsize > 0) { 1597 long pss = Debug.getPss(st.pid, null); 1598 if (pss > 0) { 1599 if (infoMap.indexOfKey(st.pid) < 0) { 1600 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1601 ProcessList.NATIVE_ADJ, -1, "native", null); 1602 mi.pss = pss; 1603 memInfos.add(mi); 1604 } 1605 } 1606 } 1607 } 1608 } 1609 1610 long totalPss = 0; 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 if (mi.pss == 0) { 1614 mi.pss = Debug.getPss(mi.pid, null); 1615 } 1616 totalPss += mi.pss; 1617 } 1618 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1619 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1620 if (lhs.oomAdj != rhs.oomAdj) { 1621 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1622 } 1623 if (lhs.pss != rhs.pss) { 1624 return lhs.pss < rhs.pss ? 1 : -1; 1625 } 1626 return 0; 1627 } 1628 }); 1629 1630 StringBuilder tag = new StringBuilder(128); 1631 StringBuilder stack = new StringBuilder(128); 1632 tag.append("Low on memory -- "); 1633 appendMemBucket(tag, totalPss, "total", false); 1634 appendMemBucket(stack, totalPss, "total", true); 1635 1636 StringBuilder logBuilder = new StringBuilder(1024); 1637 logBuilder.append("Low on memory:\n"); 1638 1639 boolean firstLine = true; 1640 int lastOomAdj = Integer.MIN_VALUE; 1641 for (int i=0, N=memInfos.size(); i<N; i++) { 1642 ProcessMemInfo mi = memInfos.get(i); 1643 1644 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1645 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1646 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1647 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1648 if (lastOomAdj != mi.oomAdj) { 1649 lastOomAdj = mi.oomAdj; 1650 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1651 tag.append(" / "); 1652 } 1653 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1654 if (firstLine) { 1655 stack.append(":"); 1656 firstLine = false; 1657 } 1658 stack.append("\n\t at "); 1659 } else { 1660 stack.append("$"); 1661 } 1662 } else { 1663 tag.append(" "); 1664 stack.append("$"); 1665 } 1666 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1667 appendMemBucket(tag, mi.pss, mi.name, false); 1668 } 1669 appendMemBucket(stack, mi.pss, mi.name, true); 1670 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1671 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1672 stack.append("("); 1673 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1674 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1675 stack.append(DUMP_MEM_OOM_LABEL[k]); 1676 stack.append(":"); 1677 stack.append(DUMP_MEM_OOM_ADJ[k]); 1678 } 1679 } 1680 stack.append(")"); 1681 } 1682 } 1683 1684 logBuilder.append(" "); 1685 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1686 logBuilder.append(' '); 1687 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1688 logBuilder.append(' '); 1689 ProcessList.appendRamKb(logBuilder, mi.pss); 1690 logBuilder.append(" kB: "); 1691 logBuilder.append(mi.name); 1692 logBuilder.append(" ("); 1693 logBuilder.append(mi.pid); 1694 logBuilder.append(") "); 1695 logBuilder.append(mi.adjType); 1696 logBuilder.append('\n'); 1697 if (mi.adjReason != null) { 1698 logBuilder.append(" "); 1699 logBuilder.append(mi.adjReason); 1700 logBuilder.append('\n'); 1701 } 1702 } 1703 1704 logBuilder.append(" "); 1705 ProcessList.appendRamKb(logBuilder, totalPss); 1706 logBuilder.append(" kB: TOTAL\n"); 1707 1708 long[] infos = new long[Debug.MEMINFO_COUNT]; 1709 Debug.getMemInfo(infos); 1710 logBuilder.append(" MemInfo: "); 1711 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1712 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1713 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1714 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1715 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1716 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1717 logBuilder.append(" ZRAM: "); 1718 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1719 logBuilder.append(" kB RAM, "); 1720 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1721 logBuilder.append(" kB swap total, "); 1722 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1723 logBuilder.append(" kB swap free\n"); 1724 } 1725 Slog.i(TAG, logBuilder.toString()); 1726 1727 StringBuilder dropBuilder = new StringBuilder(1024); 1728 /* 1729 StringWriter oomSw = new StringWriter(); 1730 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1731 StringWriter catSw = new StringWriter(); 1732 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1733 String[] emptyArgs = new String[] { }; 1734 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1735 oomPw.flush(); 1736 String oomString = oomSw.toString(); 1737 */ 1738 dropBuilder.append(stack); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append('\n'); 1741 dropBuilder.append(logBuilder); 1742 dropBuilder.append('\n'); 1743 /* 1744 dropBuilder.append(oomString); 1745 dropBuilder.append('\n'); 1746 */ 1747 StringWriter catSw = new StringWriter(); 1748 synchronized (ActivityManagerService.this) { 1749 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1750 String[] emptyArgs = new String[] { }; 1751 catPw.println(); 1752 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1753 catPw.println(); 1754 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1755 false, false, null); 1756 catPw.println(); 1757 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1758 catPw.flush(); 1759 } 1760 dropBuilder.append(catSw.toString()); 1761 addErrorToDropBox("lowmem", null, "system_server", null, 1762 null, tag.toString(), dropBuilder.toString(), null, null); 1763 //Slog.i(TAG, "Sent to dropbox:"); 1764 //Slog.i(TAG, dropBuilder.toString()); 1765 synchronized (ActivityManagerService.this) { 1766 long now = SystemClock.uptimeMillis(); 1767 if (mLastMemUsageReportTime < now) { 1768 mLastMemUsageReportTime = now; 1769 } 1770 } 1771 } 1772 }; 1773 thread.start(); 1774 break; 1775 } 1776 case START_USER_SWITCH_MSG: { 1777 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1778 break; 1779 } 1780 case REPORT_USER_SWITCH_MSG: { 1781 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1782 break; 1783 } 1784 case CONTINUE_USER_SWITCH_MSG: { 1785 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1786 break; 1787 } 1788 case USER_SWITCH_TIMEOUT_MSG: { 1789 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1790 break; 1791 } 1792 case IMMERSIVE_MODE_LOCK_MSG: { 1793 final boolean nextState = (msg.arg1 != 0); 1794 if (mUpdateLock.isHeld() != nextState) { 1795 if (DEBUG_IMMERSIVE) { 1796 final ActivityRecord r = (ActivityRecord) msg.obj; 1797 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1798 } 1799 if (nextState) { 1800 mUpdateLock.acquire(); 1801 } else { 1802 mUpdateLock.release(); 1803 } 1804 } 1805 break; 1806 } 1807 case PERSIST_URI_GRANTS_MSG: { 1808 writeGrantedUriPermissions(); 1809 break; 1810 } 1811 case REQUEST_ALL_PSS_MSG: { 1812 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1813 break; 1814 } 1815 case START_PROFILES_MSG: { 1816 synchronized (ActivityManagerService.this) { 1817 startProfilesLocked(); 1818 } 1819 break; 1820 } 1821 case UPDATE_TIME: { 1822 synchronized (ActivityManagerService.this) { 1823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1824 ProcessRecord r = mLruProcesses.get(i); 1825 if (r.thread != null) { 1826 try { 1827 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1828 } catch (RemoteException ex) { 1829 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1830 } 1831 } 1832 } 1833 } 1834 break; 1835 } 1836 case SYSTEM_USER_START_MSG: { 1837 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1838 Integer.toString(msg.arg1), msg.arg1); 1839 mSystemServiceManager.startUser(msg.arg1); 1840 break; 1841 } 1842 case SYSTEM_USER_CURRENT_MSG: { 1843 mBatteryStatsService.noteEvent( 1844 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1845 Integer.toString(msg.arg2), msg.arg2); 1846 mBatteryStatsService.noteEvent( 1847 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1848 Integer.toString(msg.arg1), msg.arg1); 1849 mSystemServiceManager.switchUser(msg.arg1); 1850 mLockToAppRequest.clearPrompt(); 1851 break; 1852 } 1853 case ENTER_ANIMATION_COMPLETE_MSG: { 1854 synchronized (ActivityManagerService.this) { 1855 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1856 if (r != null && r.app != null && r.app.thread != null) { 1857 try { 1858 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1859 } catch (RemoteException e) { 1860 } 1861 } 1862 } 1863 break; 1864 } 1865 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1866 enableScreenAfterBoot(); 1867 break; 1868 } 1869 } 1870 } 1871 }; 1872 1873 static final int COLLECT_PSS_BG_MSG = 1; 1874 1875 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1876 @Override 1877 public void handleMessage(Message msg) { 1878 switch (msg.what) { 1879 case COLLECT_PSS_BG_MSG: { 1880 long start = SystemClock.uptimeMillis(); 1881 MemInfoReader memInfo = null; 1882 synchronized (ActivityManagerService.this) { 1883 if (mFullPssPending) { 1884 mFullPssPending = false; 1885 memInfo = new MemInfoReader(); 1886 } 1887 } 1888 if (memInfo != null) { 1889 updateCpuStatsNow(); 1890 long nativeTotalPss = 0; 1891 synchronized (mProcessCpuThread) { 1892 final int N = mProcessCpuTracker.countStats(); 1893 for (int j=0; j<N; j++) { 1894 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1895 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1896 // This is definitely an application process; skip it. 1897 continue; 1898 } 1899 synchronized (mPidsSelfLocked) { 1900 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1901 // This is one of our own processes; skip it. 1902 continue; 1903 } 1904 } 1905 nativeTotalPss += Debug.getPss(st.pid, null); 1906 } 1907 } 1908 memInfo.readMemInfo(); 1909 synchronized (this) { 1910 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1911 + (SystemClock.uptimeMillis()-start) + "ms"); 1912 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1913 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1914 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1915 +memInfo.getSlabSizeKb(), 1916 nativeTotalPss); 1917 } 1918 } 1919 1920 int i=0, num=0; 1921 long[] tmp = new long[1]; 1922 do { 1923 ProcessRecord proc; 1924 int procState; 1925 int pid; 1926 synchronized (ActivityManagerService.this) { 1927 if (i >= mPendingPssProcesses.size()) { 1928 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1929 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1930 mPendingPssProcesses.clear(); 1931 return; 1932 } 1933 proc = mPendingPssProcesses.get(i); 1934 procState = proc.pssProcState; 1935 if (proc.thread != null && procState == proc.setProcState) { 1936 pid = proc.pid; 1937 } else { 1938 proc = null; 1939 pid = 0; 1940 } 1941 i++; 1942 } 1943 if (proc != null) { 1944 long pss = Debug.getPss(pid, tmp); 1945 synchronized (ActivityManagerService.this) { 1946 if (proc.thread != null && proc.setProcState == procState 1947 && proc.pid == pid) { 1948 num++; 1949 proc.lastPssTime = SystemClock.uptimeMillis(); 1950 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1951 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1952 + ": " + pss + " lastPss=" + proc.lastPss 1953 + " state=" + ProcessList.makeProcStateString(procState)); 1954 if (proc.initialIdlePss == 0) { 1955 proc.initialIdlePss = pss; 1956 } 1957 proc.lastPss = pss; 1958 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1959 proc.lastCachedPss = pss; 1960 } 1961 } 1962 } 1963 } 1964 } while (true); 1965 } 1966 } 1967 } 1968 }; 1969 1970 /** 1971 * Monitor for package changes and update our internal state. 1972 */ 1973 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1974 @Override 1975 public void onPackageRemoved(String packageName, int uid) { 1976 // Remove all tasks with activities in the specified package from the list of recent tasks 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1979 TaskRecord tr = mRecentTasks.get(i); 1980 ComponentName cn = tr.intent.getComponent(); 1981 if (cn != null && cn.getPackageName().equals(packageName)) { 1982 // If the package name matches, remove the task and kill the process 1983 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1984 } 1985 } 1986 } 1987 } 1988 1989 @Override 1990 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1991 onPackageModified(packageName); 1992 return true; 1993 } 1994 1995 @Override 1996 public void onPackageModified(String packageName) { 1997 final PackageManager pm = mContext.getPackageManager(); 1998 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1999 new ArrayList<Pair<Intent, Integer>>(); 2000 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2001 // Copy the list of recent tasks so that we don't hold onto the lock on 2002 // ActivityManagerService for long periods while checking if components exist. 2003 synchronized (ActivityManagerService.this) { 2004 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2005 TaskRecord tr = mRecentTasks.get(i); 2006 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2007 } 2008 } 2009 // Check the recent tasks and filter out all tasks with components that no longer exist. 2010 Intent tmpI = new Intent(); 2011 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2012 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2013 ComponentName cn = p.first.getComponent(); 2014 if (cn != null && cn.getPackageName().equals(packageName)) { 2015 try { 2016 // Add the task to the list to remove if the component no longer exists 2017 tmpI.setComponent(cn); 2018 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2019 tasksToRemove.add(p.second); 2020 } 2021 } catch (Exception e) {} 2022 } 2023 } 2024 // Prune all the tasks with removed components from the list of recent tasks 2025 synchronized (ActivityManagerService.this) { 2026 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2027 // Remove the task but don't kill the process (since other components in that 2028 // package may still be running and in the background) 2029 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2030 } 2031 } 2032 } 2033 2034 @Override 2035 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2036 // Force stop the specified packages 2037 if (packages != null) { 2038 for (String pkg : packages) { 2039 synchronized (ActivityManagerService.this) { 2040 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2041 "finished booting")) { 2042 return true; 2043 } 2044 } 2045 } 2046 } 2047 return false; 2048 } 2049 }; 2050 2051 public void setSystemProcess() { 2052 try { 2053 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2054 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2055 ServiceManager.addService("meminfo", new MemBinder(this)); 2056 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2057 ServiceManager.addService("dbinfo", new DbBinder(this)); 2058 if (MONITOR_CPU_USAGE) { 2059 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2060 } 2061 ServiceManager.addService("permission", new PermissionController(this)); 2062 2063 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2064 "android", STOCK_PM_FLAGS); 2065 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2066 2067 synchronized (this) { 2068 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2069 app.persistent = true; 2070 app.pid = MY_PID; 2071 app.maxAdj = ProcessList.SYSTEM_ADJ; 2072 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2073 mProcessNames.put(app.processName, app.uid, app); 2074 synchronized (mPidsSelfLocked) { 2075 mPidsSelfLocked.put(app.pid, app); 2076 } 2077 updateLruProcessLocked(app, false, null); 2078 updateOomAdjLocked(); 2079 } 2080 } catch (PackageManager.NameNotFoundException e) { 2081 throw new RuntimeException( 2082 "Unable to find android system package", e); 2083 } 2084 } 2085 2086 public void setWindowManager(WindowManagerService wm) { 2087 mWindowManager = wm; 2088 mStackSupervisor.setWindowManager(wm); 2089 } 2090 2091 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2092 mUsageStatsService = usageStatsManager; 2093 } 2094 2095 public void startObservingNativeCrashes() { 2096 final NativeCrashListener ncl = new NativeCrashListener(this); 2097 ncl.start(); 2098 } 2099 2100 public IAppOpsService getAppOpsService() { 2101 return mAppOpsService; 2102 } 2103 2104 static class MemBinder extends Binder { 2105 ActivityManagerService mActivityManagerService; 2106 MemBinder(ActivityManagerService activityManagerService) { 2107 mActivityManagerService = activityManagerService; 2108 } 2109 2110 @Override 2111 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2112 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2113 != PackageManager.PERMISSION_GRANTED) { 2114 pw.println("Permission Denial: can't dump meminfo from from pid=" 2115 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2116 + " without permission " + android.Manifest.permission.DUMP); 2117 return; 2118 } 2119 2120 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2121 } 2122 } 2123 2124 static class GraphicsBinder extends Binder { 2125 ActivityManagerService mActivityManagerService; 2126 GraphicsBinder(ActivityManagerService activityManagerService) { 2127 mActivityManagerService = activityManagerService; 2128 } 2129 2130 @Override 2131 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2132 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2133 != PackageManager.PERMISSION_GRANTED) { 2134 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2135 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2136 + " without permission " + android.Manifest.permission.DUMP); 2137 return; 2138 } 2139 2140 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2141 } 2142 } 2143 2144 static class DbBinder extends Binder { 2145 ActivityManagerService mActivityManagerService; 2146 DbBinder(ActivityManagerService activityManagerService) { 2147 mActivityManagerService = activityManagerService; 2148 } 2149 2150 @Override 2151 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2152 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2153 != PackageManager.PERMISSION_GRANTED) { 2154 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2155 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2156 + " without permission " + android.Manifest.permission.DUMP); 2157 return; 2158 } 2159 2160 mActivityManagerService.dumpDbInfo(fd, pw, args); 2161 } 2162 } 2163 2164 static class CpuBinder extends Binder { 2165 ActivityManagerService mActivityManagerService; 2166 CpuBinder(ActivityManagerService activityManagerService) { 2167 mActivityManagerService = activityManagerService; 2168 } 2169 2170 @Override 2171 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2172 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2173 != PackageManager.PERMISSION_GRANTED) { 2174 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2175 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2176 + " without permission " + android.Manifest.permission.DUMP); 2177 return; 2178 } 2179 2180 synchronized (mActivityManagerService.mProcessCpuThread) { 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2182 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2183 SystemClock.uptimeMillis())); 2184 } 2185 } 2186 } 2187 2188 public static final class Lifecycle extends SystemService { 2189 private final ActivityManagerService mService; 2190 2191 public Lifecycle(Context context) { 2192 super(context); 2193 mService = new ActivityManagerService(context); 2194 } 2195 2196 @Override 2197 public void onStart() { 2198 mService.start(); 2199 } 2200 2201 public ActivityManagerService getService() { 2202 return mService; 2203 } 2204 } 2205 2206 // Note: This method is invoked on the main thread but may need to attach various 2207 // handlers to other threads. So take care to be explicit about the looper. 2208 public ActivityManagerService(Context systemContext) { 2209 mContext = systemContext; 2210 mFactoryTest = FactoryTest.getMode(); 2211 mSystemThread = ActivityThread.currentActivityThread(); 2212 2213 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2214 2215 mHandlerThread = new ServiceThread(TAG, 2216 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2217 mHandlerThread.start(); 2218 mHandler = new MainHandler(mHandlerThread.getLooper()); 2219 2220 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2221 "foreground", BROADCAST_FG_TIMEOUT, false); 2222 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2223 "background", BROADCAST_BG_TIMEOUT, true); 2224 mBroadcastQueues[0] = mFgBroadcastQueue; 2225 mBroadcastQueues[1] = mBgBroadcastQueue; 2226 2227 mServices = new ActiveServices(this); 2228 mProviderMap = new ProviderMap(this); 2229 2230 // TODO: Move creation of battery stats service outside of activity manager service. 2231 File dataDir = Environment.getDataDirectory(); 2232 File systemDir = new File(dataDir, "system"); 2233 systemDir.mkdirs(); 2234 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2235 mBatteryStatsService.getActiveStatistics().readLocked(); 2236 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2237 mOnBattery = DEBUG_POWER ? true 2238 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2239 mBatteryStatsService.getActiveStatistics().setCallback(this); 2240 2241 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2242 2243 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2244 2245 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2246 2247 // User 0 is the first and only user that runs at boot. 2248 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2249 mUserLru.add(Integer.valueOf(0)); 2250 updateStartedUserArrayLocked(); 2251 2252 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2253 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2254 2255 mConfiguration.setToDefaults(); 2256 mConfiguration.setLocale(Locale.getDefault()); 2257 2258 mConfigurationSeq = mConfiguration.seq = 1; 2259 mProcessCpuTracker.init(); 2260 2261 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2262 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2263 mStackSupervisor = new ActivityStackSupervisor(this); 2264 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2265 2266 mProcessCpuThread = new Thread("CpuTracker") { 2267 @Override 2268 public void run() { 2269 while (true) { 2270 try { 2271 try { 2272 synchronized(this) { 2273 final long now = SystemClock.uptimeMillis(); 2274 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2275 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2276 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2277 // + ", write delay=" + nextWriteDelay); 2278 if (nextWriteDelay < nextCpuDelay) { 2279 nextCpuDelay = nextWriteDelay; 2280 } 2281 if (nextCpuDelay > 0) { 2282 mProcessCpuMutexFree.set(true); 2283 this.wait(nextCpuDelay); 2284 } 2285 } 2286 } catch (InterruptedException e) { 2287 } 2288 updateCpuStatsNow(); 2289 } catch (Exception e) { 2290 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2291 } 2292 } 2293 } 2294 }; 2295 2296 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2297 2298 Watchdog.getInstance().addMonitor(this); 2299 Watchdog.getInstance().addThread(mHandler); 2300 } 2301 2302 public void setSystemServiceManager(SystemServiceManager mgr) { 2303 mSystemServiceManager = mgr; 2304 } 2305 2306 private void start() { 2307 Process.removeAllProcessGroups(); 2308 mProcessCpuThread.start(); 2309 2310 mBatteryStatsService.publish(mContext); 2311 mAppOpsService.publish(mContext); 2312 Slog.d("AppOps", "AppOpsService published"); 2313 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2314 } 2315 2316 public void initPowerManagement() { 2317 mStackSupervisor.initPowerManagement(); 2318 mBatteryStatsService.initPowerManagement(); 2319 } 2320 2321 @Override 2322 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2323 throws RemoteException { 2324 if (code == SYSPROPS_TRANSACTION) { 2325 // We need to tell all apps about the system property change. 2326 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2327 synchronized(this) { 2328 final int NP = mProcessNames.getMap().size(); 2329 for (int ip=0; ip<NP; ip++) { 2330 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2331 final int NA = apps.size(); 2332 for (int ia=0; ia<NA; ia++) { 2333 ProcessRecord app = apps.valueAt(ia); 2334 if (app.thread != null) { 2335 procs.add(app.thread.asBinder()); 2336 } 2337 } 2338 } 2339 } 2340 2341 int N = procs.size(); 2342 for (int i=0; i<N; i++) { 2343 Parcel data2 = Parcel.obtain(); 2344 try { 2345 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2346 } catch (RemoteException e) { 2347 } 2348 data2.recycle(); 2349 } 2350 } 2351 try { 2352 return super.onTransact(code, data, reply, flags); 2353 } catch (RuntimeException e) { 2354 // The activity manager only throws security exceptions, so let's 2355 // log all others. 2356 if (!(e instanceof SecurityException)) { 2357 Slog.wtf(TAG, "Activity Manager Crash", e); 2358 } 2359 throw e; 2360 } 2361 } 2362 2363 void updateCpuStats() { 2364 final long now = SystemClock.uptimeMillis(); 2365 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2366 return; 2367 } 2368 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2369 synchronized (mProcessCpuThread) { 2370 mProcessCpuThread.notify(); 2371 } 2372 } 2373 } 2374 2375 void updateCpuStatsNow() { 2376 synchronized (mProcessCpuThread) { 2377 mProcessCpuMutexFree.set(false); 2378 final long now = SystemClock.uptimeMillis(); 2379 boolean haveNewCpuStats = false; 2380 2381 if (MONITOR_CPU_USAGE && 2382 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2383 mLastCpuTime.set(now); 2384 haveNewCpuStats = true; 2385 mProcessCpuTracker.update(); 2386 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2387 //Slog.i(TAG, "Total CPU usage: " 2388 // + mProcessCpu.getTotalCpuPercent() + "%"); 2389 2390 // Slog the cpu usage if the property is set. 2391 if ("true".equals(SystemProperties.get("events.cpu"))) { 2392 int user = mProcessCpuTracker.getLastUserTime(); 2393 int system = mProcessCpuTracker.getLastSystemTime(); 2394 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2395 int irq = mProcessCpuTracker.getLastIrqTime(); 2396 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2397 int idle = mProcessCpuTracker.getLastIdleTime(); 2398 2399 int total = user + system + iowait + irq + softIrq + idle; 2400 if (total == 0) total = 1; 2401 2402 EventLog.writeEvent(EventLogTags.CPU, 2403 ((user+system+iowait+irq+softIrq) * 100) / total, 2404 (user * 100) / total, 2405 (system * 100) / total, 2406 (iowait * 100) / total, 2407 (irq * 100) / total, 2408 (softIrq * 100) / total); 2409 } 2410 } 2411 2412 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2413 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2414 synchronized(bstats) { 2415 synchronized(mPidsSelfLocked) { 2416 if (haveNewCpuStats) { 2417 if (mOnBattery) { 2418 int perc = bstats.startAddingCpuLocked(); 2419 int totalUTime = 0; 2420 int totalSTime = 0; 2421 final int N = mProcessCpuTracker.countStats(); 2422 for (int i=0; i<N; i++) { 2423 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2424 if (!st.working) { 2425 continue; 2426 } 2427 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2428 int otherUTime = (st.rel_utime*perc)/100; 2429 int otherSTime = (st.rel_stime*perc)/100; 2430 totalUTime += otherUTime; 2431 totalSTime += otherSTime; 2432 if (pr != null) { 2433 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2434 if (ps == null || !ps.isActive()) { 2435 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2436 pr.info.uid, pr.processName); 2437 } 2438 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2439 st.rel_stime-otherSTime); 2440 ps.addSpeedStepTimes(cpuSpeedTimes); 2441 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2442 } else { 2443 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2444 if (ps == null || !ps.isActive()) { 2445 st.batteryStats = ps = bstats.getProcessStatsLocked( 2446 bstats.mapUid(st.uid), st.name); 2447 } 2448 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2449 st.rel_stime-otherSTime); 2450 ps.addSpeedStepTimes(cpuSpeedTimes); 2451 } 2452 } 2453 bstats.finishAddingCpuLocked(perc, totalUTime, 2454 totalSTime, cpuSpeedTimes); 2455 } 2456 } 2457 } 2458 2459 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2460 mLastWriteTime = now; 2461 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2462 } 2463 } 2464 } 2465 } 2466 2467 @Override 2468 public void batteryNeedsCpuUpdate() { 2469 updateCpuStatsNow(); 2470 } 2471 2472 @Override 2473 public void batteryPowerChanged(boolean onBattery) { 2474 // When plugging in, update the CPU stats first before changing 2475 // the plug state. 2476 updateCpuStatsNow(); 2477 synchronized (this) { 2478 synchronized(mPidsSelfLocked) { 2479 mOnBattery = DEBUG_POWER ? true : onBattery; 2480 } 2481 } 2482 } 2483 2484 /** 2485 * Initialize the application bind args. These are passed to each 2486 * process when the bindApplication() IPC is sent to the process. They're 2487 * lazily setup to make sure the services are running when they're asked for. 2488 */ 2489 private HashMap<String, IBinder> getCommonServicesLocked() { 2490 if (mAppBindArgs == null) { 2491 mAppBindArgs = new HashMap<String, IBinder>(); 2492 2493 // Setup the application init args 2494 mAppBindArgs.put("package", ServiceManager.getService("package")); 2495 mAppBindArgs.put("window", ServiceManager.getService("window")); 2496 mAppBindArgs.put(Context.ALARM_SERVICE, 2497 ServiceManager.getService(Context.ALARM_SERVICE)); 2498 } 2499 return mAppBindArgs; 2500 } 2501 2502 final void setFocusedActivityLocked(ActivityRecord r) { 2503 if (mFocusedActivity != r) { 2504 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2505 mFocusedActivity = r; 2506 if (r.task != null && r.task.voiceInteractor != null) { 2507 startRunningVoiceLocked(); 2508 } else { 2509 finishRunningVoiceLocked(); 2510 } 2511 mStackSupervisor.setFocusedStack(r); 2512 if (r != null) { 2513 mWindowManager.setFocusedApp(r.appToken, true); 2514 } 2515 applyUpdateLockStateLocked(r); 2516 } 2517 } 2518 2519 final void clearFocusedActivity(ActivityRecord r) { 2520 if (mFocusedActivity == r) { 2521 mFocusedActivity = null; 2522 } 2523 } 2524 2525 @Override 2526 public void setFocusedStack(int stackId) { 2527 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2528 synchronized (ActivityManagerService.this) { 2529 ActivityStack stack = mStackSupervisor.getStack(stackId); 2530 if (stack != null) { 2531 ActivityRecord r = stack.topRunningActivityLocked(null); 2532 if (r != null) { 2533 setFocusedActivityLocked(r); 2534 } 2535 } 2536 } 2537 } 2538 2539 @Override 2540 public void notifyActivityDrawn(IBinder token) { 2541 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2542 synchronized (this) { 2543 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2544 if (r != null) { 2545 r.task.stack.notifyActivityDrawnLocked(r); 2546 } 2547 } 2548 } 2549 2550 final void applyUpdateLockStateLocked(ActivityRecord r) { 2551 // Modifications to the UpdateLock state are done on our handler, outside 2552 // the activity manager's locks. The new state is determined based on the 2553 // state *now* of the relevant activity record. The object is passed to 2554 // the handler solely for logging detail, not to be consulted/modified. 2555 final boolean nextState = r != null && r.immersive; 2556 mHandler.sendMessage( 2557 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2558 } 2559 2560 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2561 Message msg = Message.obtain(); 2562 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2563 msg.obj = r.task.askedCompatMode ? null : r; 2564 mHandler.sendMessage(msg); 2565 } 2566 2567 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2568 String what, Object obj, ProcessRecord srcApp) { 2569 app.lastActivityTime = now; 2570 2571 if (app.activities.size() > 0) { 2572 // Don't want to touch dependent processes that are hosting activities. 2573 return index; 2574 } 2575 2576 int lrui = mLruProcesses.lastIndexOf(app); 2577 if (lrui < 0) { 2578 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2579 + what + " " + obj + " from " + srcApp); 2580 return index; 2581 } 2582 2583 if (lrui >= index) { 2584 // Don't want to cause this to move dependent processes *back* in the 2585 // list as if they were less frequently used. 2586 return index; 2587 } 2588 2589 if (lrui >= mLruProcessActivityStart) { 2590 // Don't want to touch dependent processes that are hosting activities. 2591 return index; 2592 } 2593 2594 mLruProcesses.remove(lrui); 2595 if (index > 0) { 2596 index--; 2597 } 2598 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2599 + " in LRU list: " + app); 2600 mLruProcesses.add(index, app); 2601 return index; 2602 } 2603 2604 final void removeLruProcessLocked(ProcessRecord app) { 2605 int lrui = mLruProcesses.lastIndexOf(app); 2606 if (lrui >= 0) { 2607 if (lrui <= mLruProcessActivityStart) { 2608 mLruProcessActivityStart--; 2609 } 2610 if (lrui <= mLruProcessServiceStart) { 2611 mLruProcessServiceStart--; 2612 } 2613 mLruProcesses.remove(lrui); 2614 } 2615 } 2616 2617 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2618 ProcessRecord client) { 2619 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2620 || app.treatLikeActivity; 2621 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2622 if (!activityChange && hasActivity) { 2623 // The process has activities, so we are only allowing activity-based adjustments 2624 // to move it. It should be kept in the front of the list with other 2625 // processes that have activities, and we don't want those to change their 2626 // order except due to activity operations. 2627 return; 2628 } 2629 2630 mLruSeq++; 2631 final long now = SystemClock.uptimeMillis(); 2632 app.lastActivityTime = now; 2633 2634 // First a quick reject: if the app is already at the position we will 2635 // put it, then there is nothing to do. 2636 if (hasActivity) { 2637 final int N = mLruProcesses.size(); 2638 if (N > 0 && mLruProcesses.get(N-1) == app) { 2639 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2640 return; 2641 } 2642 } else { 2643 if (mLruProcessServiceStart > 0 2644 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2646 return; 2647 } 2648 } 2649 2650 int lrui = mLruProcesses.lastIndexOf(app); 2651 2652 if (app.persistent && lrui >= 0) { 2653 // We don't care about the position of persistent processes, as long as 2654 // they are in the list. 2655 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2656 return; 2657 } 2658 2659 /* In progress: compute new position first, so we can avoid doing work 2660 if the process is not actually going to move. Not yet working. 2661 int addIndex; 2662 int nextIndex; 2663 boolean inActivity = false, inService = false; 2664 if (hasActivity) { 2665 // Process has activities, put it at the very tipsy-top. 2666 addIndex = mLruProcesses.size(); 2667 nextIndex = mLruProcessServiceStart; 2668 inActivity = true; 2669 } else if (hasService) { 2670 // Process has services, put it at the top of the service list. 2671 addIndex = mLruProcessActivityStart; 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 inService = true; 2675 } else { 2676 // Process not otherwise of interest, it goes to the top of the non-service area. 2677 addIndex = mLruProcessServiceStart; 2678 if (client != null) { 2679 int clientIndex = mLruProcesses.lastIndexOf(client); 2680 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2681 + app); 2682 if (clientIndex >= 0 && addIndex > clientIndex) { 2683 addIndex = clientIndex; 2684 } 2685 } 2686 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2687 } 2688 2689 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2690 + mLruProcessActivityStart + "): " + app); 2691 */ 2692 2693 if (lrui >= 0) { 2694 if (lrui < mLruProcessActivityStart) { 2695 mLruProcessActivityStart--; 2696 } 2697 if (lrui < mLruProcessServiceStart) { 2698 mLruProcessServiceStart--; 2699 } 2700 /* 2701 if (addIndex > lrui) { 2702 addIndex--; 2703 } 2704 if (nextIndex > lrui) { 2705 nextIndex--; 2706 } 2707 */ 2708 mLruProcesses.remove(lrui); 2709 } 2710 2711 /* 2712 mLruProcesses.add(addIndex, app); 2713 if (inActivity) { 2714 mLruProcessActivityStart++; 2715 } 2716 if (inService) { 2717 mLruProcessActivityStart++; 2718 } 2719 */ 2720 2721 int nextIndex; 2722 if (hasActivity) { 2723 final int N = mLruProcesses.size(); 2724 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2725 // Process doesn't have activities, but has clients with 2726 // activities... move it up, but one below the top (the top 2727 // should always have a real activity). 2728 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2729 mLruProcesses.add(N-1, app); 2730 // To keep it from spamming the LRU list (by making a bunch of clients), 2731 // we will push down any other entries owned by the app. 2732 final int uid = app.info.uid; 2733 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2734 ProcessRecord subProc = mLruProcesses.get(i); 2735 if (subProc.info.uid == uid) { 2736 // We want to push this one down the list. If the process after 2737 // it is for the same uid, however, don't do so, because we don't 2738 // want them internally to be re-ordered. 2739 if (mLruProcesses.get(i-1).info.uid != uid) { 2740 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2741 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2742 ProcessRecord tmp = mLruProcesses.get(i); 2743 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2744 mLruProcesses.set(i-1, tmp); 2745 i--; 2746 } 2747 } else { 2748 // A gap, we can stop here. 2749 break; 2750 } 2751 } 2752 } else { 2753 // Process has activities, put it at the very tipsy-top. 2754 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2755 mLruProcesses.add(app); 2756 } 2757 nextIndex = mLruProcessServiceStart; 2758 } else if (hasService) { 2759 // Process has services, put it at the top of the service list. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2761 mLruProcesses.add(mLruProcessActivityStart, app); 2762 nextIndex = mLruProcessServiceStart; 2763 mLruProcessActivityStart++; 2764 } else { 2765 // Process not otherwise of interest, it goes to the top of the non-service area. 2766 int index = mLruProcessServiceStart; 2767 if (client != null) { 2768 // If there is a client, don't allow the process to be moved up higher 2769 // in the list than that client. 2770 int clientIndex = mLruProcesses.lastIndexOf(client); 2771 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2772 + " when updating " + app); 2773 if (clientIndex <= lrui) { 2774 // Don't allow the client index restriction to push it down farther in the 2775 // list than it already is. 2776 clientIndex = lrui; 2777 } 2778 if (clientIndex >= 0 && index > clientIndex) { 2779 index = clientIndex; 2780 } 2781 } 2782 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2783 mLruProcesses.add(index, app); 2784 nextIndex = index-1; 2785 mLruProcessActivityStart++; 2786 mLruProcessServiceStart++; 2787 } 2788 2789 // If the app is currently using a content provider or service, 2790 // bump those processes as well. 2791 for (int j=app.connections.size()-1; j>=0; j--) { 2792 ConnectionRecord cr = app.connections.valueAt(j); 2793 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2794 && cr.binding.service.app != null 2795 && cr.binding.service.app.lruSeq != mLruSeq 2796 && !cr.binding.service.app.persistent) { 2797 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2798 "service connection", cr, app); 2799 } 2800 } 2801 for (int j=app.conProviders.size()-1; j>=0; j--) { 2802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2804 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2805 "provider reference", cpr, app); 2806 } 2807 } 2808 } 2809 2810 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2811 if (uid == Process.SYSTEM_UID) { 2812 // The system gets to run in any process. If there are multiple 2813 // processes with the same uid, just pick the first (this 2814 // should never happen). 2815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2816 if (procs == null) return null; 2817 final int N = procs.size(); 2818 for (int i = 0; i < N; i++) { 2819 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2820 } 2821 } 2822 ProcessRecord proc = mProcessNames.get(processName, uid); 2823 if (false && proc != null && !keepIfLarge 2824 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2825 && proc.lastCachedPss >= 4000) { 2826 // Turn this condition on to cause killing to happen regularly, for testing. 2827 if (proc.baseProcessTracker != null) { 2828 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2829 } 2830 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2831 } else if (proc != null && !keepIfLarge 2832 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2833 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2834 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2835 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2836 if (proc.baseProcessTracker != null) { 2837 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2838 } 2839 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2840 } 2841 } 2842 return proc; 2843 } 2844 2845 void ensurePackageDexOpt(String packageName) { 2846 IPackageManager pm = AppGlobals.getPackageManager(); 2847 try { 2848 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2849 mDidDexOpt = true; 2850 } 2851 } catch (RemoteException e) { 2852 } 2853 } 2854 2855 boolean isNextTransitionForward() { 2856 int transit = mWindowManager.getPendingAppTransition(); 2857 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2858 || transit == AppTransition.TRANSIT_TASK_OPEN 2859 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2860 } 2861 2862 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2863 String processName, String abiOverride, int uid, Runnable crashHandler) { 2864 synchronized(this) { 2865 ApplicationInfo info = new ApplicationInfo(); 2866 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2867 // For isolated processes, the former contains the parent's uid and the latter the 2868 // actual uid of the isolated process. 2869 // In the special case introduced by this method (which is, starting an isolated 2870 // process directly from the SystemServer without an actual parent app process) the 2871 // closest thing to a parent's uid is SYSTEM_UID. 2872 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2873 // the |isolated| logic in the ProcessRecord constructor. 2874 info.uid = Process.SYSTEM_UID; 2875 info.processName = processName; 2876 info.className = entryPoint; 2877 info.packageName = "android"; 2878 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2879 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2880 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2881 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2882 crashHandler); 2883 return proc != null ? proc.pid : 0; 2884 } 2885 } 2886 2887 final ProcessRecord startProcessLocked(String processName, 2888 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2889 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2890 boolean isolated, boolean keepIfLarge) { 2891 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2892 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2893 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2894 null /* crashHandler */); 2895 } 2896 2897 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2898 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2899 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2900 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2901 ProcessRecord app; 2902 if (!isolated) { 2903 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2904 } else { 2905 // If this is an isolated process, it can't re-use an existing process. 2906 app = null; 2907 } 2908 // We don't have to do anything more if: 2909 // (1) There is an existing application record; and 2910 // (2) The caller doesn't think it is dead, OR there is no thread 2911 // object attached to it so we know it couldn't have crashed; and 2912 // (3) There is a pid assigned to it, so it is either starting or 2913 // already running. 2914 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2915 + " app=" + app + " knownToBeDead=" + knownToBeDead 2916 + " thread=" + (app != null ? app.thread : null) 2917 + " pid=" + (app != null ? app.pid : -1)); 2918 if (app != null && app.pid > 0) { 2919 if (!knownToBeDead || app.thread == null) { 2920 // We already have the app running, or are waiting for it to 2921 // come up (we have a pid but not yet its thread), so keep it. 2922 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2923 // If this is a new package in the process, add the package to the list 2924 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2925 return app; 2926 } 2927 2928 // An application record is attached to a previous process, 2929 // clean it up now. 2930 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2931 Process.killProcessGroup(app.info.uid, app.pid); 2932 handleAppDiedLocked(app, true, true); 2933 } 2934 2935 String hostingNameStr = hostingName != null 2936 ? hostingName.flattenToShortString() : null; 2937 2938 if (!isolated) { 2939 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2940 // If we are in the background, then check to see if this process 2941 // is bad. If so, we will just silently fail. 2942 if (mBadProcesses.get(info.processName, info.uid) != null) { 2943 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2944 + "/" + info.processName); 2945 return null; 2946 } 2947 } else { 2948 // When the user is explicitly starting a process, then clear its 2949 // crash count so that we won't make it bad until they see at 2950 // least one crash dialog again, and make the process good again 2951 // if it had been bad. 2952 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2953 + "/" + info.processName); 2954 mProcessCrashTimes.remove(info.processName, info.uid); 2955 if (mBadProcesses.get(info.processName, info.uid) != null) { 2956 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2957 UserHandle.getUserId(info.uid), info.uid, 2958 info.processName); 2959 mBadProcesses.remove(info.processName, info.uid); 2960 if (app != null) { 2961 app.bad = false; 2962 } 2963 } 2964 } 2965 } 2966 2967 if (app == null) { 2968 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2969 app.crashHandler = crashHandler; 2970 if (app == null) { 2971 Slog.w(TAG, "Failed making new process record for " 2972 + processName + "/" + info.uid + " isolated=" + isolated); 2973 return null; 2974 } 2975 mProcessNames.put(processName, app.uid, app); 2976 if (isolated) { 2977 mIsolatedProcesses.put(app.uid, app); 2978 } 2979 } else { 2980 // If this is a new package in the process, add the package to the list 2981 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2982 } 2983 2984 // If the system is not ready yet, then hold off on starting this 2985 // process until it is. 2986 if (!mProcessesReady 2987 && !isAllowedWhileBooting(info) 2988 && !allowWhileBooting) { 2989 if (!mProcessesOnHold.contains(app)) { 2990 mProcessesOnHold.add(app); 2991 } 2992 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2993 return app; 2994 } 2995 2996 startProcessLocked( 2997 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2998 return (app.pid != 0) ? app : null; 2999 } 3000 3001 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3002 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3003 } 3004 3005 private final void startProcessLocked(ProcessRecord app, 3006 String hostingType, String hostingNameStr) { 3007 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3008 null /* entryPoint */, null /* entryPointArgs */); 3009 } 3010 3011 private final void startProcessLocked(ProcessRecord app, String hostingType, 3012 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3013 if (app.pid > 0 && app.pid != MY_PID) { 3014 synchronized (mPidsSelfLocked) { 3015 mPidsSelfLocked.remove(app.pid); 3016 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3017 } 3018 app.setPid(0); 3019 } 3020 3021 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3022 "startProcessLocked removing on hold: " + app); 3023 mProcessesOnHold.remove(app); 3024 3025 updateCpuStats(); 3026 3027 try { 3028 int uid = app.uid; 3029 3030 int[] gids = null; 3031 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3032 if (!app.isolated) { 3033 int[] permGids = null; 3034 try { 3035 final PackageManager pm = mContext.getPackageManager(); 3036 permGids = pm.getPackageGids(app.info.packageName); 3037 3038 if (Environment.isExternalStorageEmulated()) { 3039 if (pm.checkPermission( 3040 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3041 app.info.packageName) == PERMISSION_GRANTED) { 3042 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3043 } else { 3044 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3045 } 3046 } 3047 } catch (PackageManager.NameNotFoundException e) { 3048 Slog.w(TAG, "Unable to retrieve gids", e); 3049 } 3050 3051 /* 3052 * Add shared application and profile GIDs so applications can share some 3053 * resources like shared libraries and access user-wide resources 3054 */ 3055 if (permGids == null) { 3056 gids = new int[2]; 3057 } else { 3058 gids = new int[permGids.length + 2]; 3059 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3060 } 3061 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3062 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3063 } 3064 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3065 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3066 && mTopComponent != null 3067 && app.processName.equals(mTopComponent.getPackageName())) { 3068 uid = 0; 3069 } 3070 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3071 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3072 uid = 0; 3073 } 3074 } 3075 int debugFlags = 0; 3076 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3077 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3078 // Also turn on CheckJNI for debuggable apps. It's quite 3079 // awkward to turn on otherwise. 3080 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3081 } 3082 // Run the app in safe mode if its manifest requests so or the 3083 // system is booted in safe mode. 3084 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3085 mSafeMode == true) { 3086 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3087 } 3088 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3089 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3090 } 3091 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3092 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3093 } 3094 if ("1".equals(SystemProperties.get("debug.assert"))) { 3095 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3096 } 3097 3098 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3099 if (requiredAbi == null) { 3100 requiredAbi = Build.SUPPORTED_ABIS[0]; 3101 } 3102 3103 // Start the process. It will either succeed and return a result containing 3104 // the PID of the new process, or else throw a RuntimeException. 3105 boolean isActivityProcess = (entryPoint == null); 3106 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3107 Process.ProcessStartResult startResult = Process.start(entryPoint, 3108 app.processName, uid, uid, gids, debugFlags, mountExternal, 3109 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3110 3111 if (app.isolated) { 3112 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3113 } 3114 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3115 3116 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3117 UserHandle.getUserId(uid), startResult.pid, uid, 3118 app.processName, hostingType, 3119 hostingNameStr != null ? hostingNameStr : ""); 3120 3121 if (app.persistent) { 3122 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3123 } 3124 3125 StringBuilder buf = mStringBuilder; 3126 buf.setLength(0); 3127 buf.append("Start proc "); 3128 buf.append(app.processName); 3129 if (!isActivityProcess) { 3130 buf.append(" ["); 3131 buf.append(entryPoint); 3132 buf.append("]"); 3133 } 3134 buf.append(" for "); 3135 buf.append(hostingType); 3136 if (hostingNameStr != null) { 3137 buf.append(" "); 3138 buf.append(hostingNameStr); 3139 } 3140 buf.append(": pid="); 3141 buf.append(startResult.pid); 3142 buf.append(" uid="); 3143 buf.append(uid); 3144 buf.append(" gids={"); 3145 if (gids != null) { 3146 for (int gi=0; gi<gids.length; gi++) { 3147 if (gi != 0) buf.append(", "); 3148 buf.append(gids[gi]); 3149 3150 } 3151 } 3152 buf.append("}"); 3153 if (requiredAbi != null) { 3154 buf.append(" abi="); 3155 buf.append(requiredAbi); 3156 } 3157 Slog.i(TAG, buf.toString()); 3158 app.setPid(startResult.pid); 3159 app.usingWrapper = startResult.usingWrapper; 3160 app.removed = false; 3161 app.killedByAm = false; 3162 synchronized (mPidsSelfLocked) { 3163 this.mPidsSelfLocked.put(startResult.pid, app); 3164 if (isActivityProcess) { 3165 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3166 msg.obj = app; 3167 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3168 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3169 } 3170 } 3171 } catch (RuntimeException e) { 3172 // XXX do better error recovery. 3173 app.setPid(0); 3174 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3175 if (app.isolated) { 3176 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3177 } 3178 Slog.e(TAG, "Failure starting process " + app.processName, e); 3179 } 3180 } 3181 3182 void updateUsageStats(ActivityRecord component, boolean resumed) { 3183 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3184 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3185 if (resumed) { 3186 if (mUsageStatsService != null) { 3187 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3188 System.currentTimeMillis(), 3189 UsageEvents.Event.MOVE_TO_FOREGROUND); 3190 } 3191 synchronized (stats) { 3192 stats.noteActivityResumedLocked(component.app.uid); 3193 } 3194 } else { 3195 if (mUsageStatsService != null) { 3196 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3197 System.currentTimeMillis(), 3198 UsageEvents.Event.MOVE_TO_BACKGROUND); 3199 } 3200 synchronized (stats) { 3201 stats.noteActivityPausedLocked(component.app.uid); 3202 } 3203 } 3204 } 3205 3206 Intent getHomeIntent() { 3207 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3208 intent.setComponent(mTopComponent); 3209 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3210 intent.addCategory(Intent.CATEGORY_HOME); 3211 } 3212 return intent; 3213 } 3214 3215 boolean startHomeActivityLocked(int userId) { 3216 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3217 && mTopAction == null) { 3218 // We are running in factory test mode, but unable to find 3219 // the factory test app, so just sit around displaying the 3220 // error message and don't try to start anything. 3221 return false; 3222 } 3223 Intent intent = getHomeIntent(); 3224 ActivityInfo aInfo = 3225 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3226 if (aInfo != null) { 3227 intent.setComponent(new ComponentName( 3228 aInfo.applicationInfo.packageName, aInfo.name)); 3229 // Don't do this if the home app is currently being 3230 // instrumented. 3231 aInfo = new ActivityInfo(aInfo); 3232 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3233 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3234 aInfo.applicationInfo.uid, true); 3235 if (app == null || app.instrumentationClass == null) { 3236 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3237 mStackSupervisor.startHomeActivity(intent, aInfo); 3238 } 3239 } 3240 3241 return true; 3242 } 3243 3244 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3245 ActivityInfo ai = null; 3246 ComponentName comp = intent.getComponent(); 3247 try { 3248 if (comp != null) { 3249 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3250 } else { 3251 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3252 intent, 3253 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3254 flags, userId); 3255 3256 if (info != null) { 3257 ai = info.activityInfo; 3258 } 3259 } 3260 } catch (RemoteException e) { 3261 // ignore 3262 } 3263 3264 return ai; 3265 } 3266 3267 /** 3268 * Starts the "new version setup screen" if appropriate. 3269 */ 3270 void startSetupActivityLocked() { 3271 // Only do this once per boot. 3272 if (mCheckedForSetup) { 3273 return; 3274 } 3275 3276 // We will show this screen if the current one is a different 3277 // version than the last one shown, and we are not running in 3278 // low-level factory test mode. 3279 final ContentResolver resolver = mContext.getContentResolver(); 3280 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3281 Settings.Global.getInt(resolver, 3282 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3283 mCheckedForSetup = true; 3284 3285 // See if we should be showing the platform update setup UI. 3286 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3287 List<ResolveInfo> ris = mContext.getPackageManager() 3288 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3289 3290 // We don't allow third party apps to replace this. 3291 ResolveInfo ri = null; 3292 for (int i=0; ris != null && i<ris.size(); i++) { 3293 if ((ris.get(i).activityInfo.applicationInfo.flags 3294 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3295 ri = ris.get(i); 3296 break; 3297 } 3298 } 3299 3300 if (ri != null) { 3301 String vers = ri.activityInfo.metaData != null 3302 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3303 : null; 3304 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3305 vers = ri.activityInfo.applicationInfo.metaData.getString( 3306 Intent.METADATA_SETUP_VERSION); 3307 } 3308 String lastVers = Settings.Secure.getString( 3309 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3310 if (vers != null && !vers.equals(lastVers)) { 3311 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3312 intent.setComponent(new ComponentName( 3313 ri.activityInfo.packageName, ri.activityInfo.name)); 3314 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3315 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3316 null); 3317 } 3318 } 3319 } 3320 } 3321 3322 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3323 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3324 } 3325 3326 void enforceNotIsolatedCaller(String caller) { 3327 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3328 throw new SecurityException("Isolated process not allowed to call " + caller); 3329 } 3330 } 3331 3332 @Override 3333 public int getFrontActivityScreenCompatMode() { 3334 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3335 synchronized (this) { 3336 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3337 } 3338 } 3339 3340 @Override 3341 public void setFrontActivityScreenCompatMode(int mode) { 3342 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3343 "setFrontActivityScreenCompatMode"); 3344 synchronized (this) { 3345 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3346 } 3347 } 3348 3349 @Override 3350 public int getPackageScreenCompatMode(String packageName) { 3351 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3352 synchronized (this) { 3353 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3354 } 3355 } 3356 3357 @Override 3358 public void setPackageScreenCompatMode(String packageName, int mode) { 3359 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3360 "setPackageScreenCompatMode"); 3361 synchronized (this) { 3362 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3363 } 3364 } 3365 3366 @Override 3367 public boolean getPackageAskScreenCompat(String packageName) { 3368 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3369 synchronized (this) { 3370 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3371 } 3372 } 3373 3374 @Override 3375 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3376 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3377 "setPackageAskScreenCompat"); 3378 synchronized (this) { 3379 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3380 } 3381 } 3382 3383 private void dispatchProcessesChanged() { 3384 int N; 3385 synchronized (this) { 3386 N = mPendingProcessChanges.size(); 3387 if (mActiveProcessChanges.length < N) { 3388 mActiveProcessChanges = new ProcessChangeItem[N]; 3389 } 3390 mPendingProcessChanges.toArray(mActiveProcessChanges); 3391 mAvailProcessChanges.addAll(mPendingProcessChanges); 3392 mPendingProcessChanges.clear(); 3393 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3394 } 3395 3396 int i = mProcessObservers.beginBroadcast(); 3397 while (i > 0) { 3398 i--; 3399 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3400 if (observer != null) { 3401 try { 3402 for (int j=0; j<N; j++) { 3403 ProcessChangeItem item = mActiveProcessChanges[j]; 3404 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3405 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3406 + item.pid + " uid=" + item.uid + ": " 3407 + item.foregroundActivities); 3408 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3409 item.foregroundActivities); 3410 } 3411 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3412 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3413 + item.pid + " uid=" + item.uid + ": " + item.processState); 3414 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3415 } 3416 } 3417 } catch (RemoteException e) { 3418 } 3419 } 3420 } 3421 mProcessObservers.finishBroadcast(); 3422 } 3423 3424 private void dispatchProcessDied(int pid, int uid) { 3425 int i = mProcessObservers.beginBroadcast(); 3426 while (i > 0) { 3427 i--; 3428 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3429 if (observer != null) { 3430 try { 3431 observer.onProcessDied(pid, uid); 3432 } catch (RemoteException e) { 3433 } 3434 } 3435 } 3436 mProcessObservers.finishBroadcast(); 3437 } 3438 3439 @Override 3440 public final int startActivity(IApplicationThread caller, String callingPackage, 3441 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3442 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3443 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3444 resultWho, requestCode, startFlags, profilerInfo, options, 3445 UserHandle.getCallingUserId()); 3446 } 3447 3448 @Override 3449 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3450 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3451 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3452 enforceNotIsolatedCaller("startActivity"); 3453 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3454 false, ALLOW_FULL_ONLY, "startActivity", null); 3455 // TODO: Switch to user app stacks here. 3456 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3457 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3458 profilerInfo, null, null, options, userId, null, null); 3459 } 3460 3461 @Override 3462 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3464 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3465 3466 // This is very dangerous -- it allows you to perform a start activity (including 3467 // permission grants) as any app that may launch one of your own activities. So 3468 // we will only allow this to be done from activities that are part of the core framework, 3469 // and then only when they are running as the system. 3470 final ActivityRecord sourceRecord; 3471 final int targetUid; 3472 final String targetPackage; 3473 synchronized (this) { 3474 if (resultTo == null) { 3475 throw new SecurityException("Must be called from an activity"); 3476 } 3477 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3478 if (sourceRecord == null) { 3479 throw new SecurityException("Called with bad activity token: " + resultTo); 3480 } 3481 if (!sourceRecord.info.packageName.equals("android")) { 3482 throw new SecurityException( 3483 "Must be called from an activity that is declared in the android package"); 3484 } 3485 if (sourceRecord.app == null) { 3486 throw new SecurityException("Called without a process attached to activity"); 3487 } 3488 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3489 // This is still okay, as long as this activity is running under the 3490 // uid of the original calling activity. 3491 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3492 throw new SecurityException( 3493 "Calling activity in uid " + sourceRecord.app.uid 3494 + " must be system uid or original calling uid " 3495 + sourceRecord.launchedFromUid); 3496 } 3497 } 3498 targetUid = sourceRecord.launchedFromUid; 3499 targetPackage = sourceRecord.launchedFromPackage; 3500 } 3501 3502 // TODO: Switch to user app stacks here. 3503 try { 3504 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3505 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3506 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3507 return ret; 3508 } catch (SecurityException e) { 3509 // XXX need to figure out how to propagate to original app. 3510 // A SecurityException here is generally actually a fault of the original 3511 // calling activity (such as a fairly granting permissions), so propagate it 3512 // back to them. 3513 /* 3514 StringBuilder msg = new StringBuilder(); 3515 msg.append("While launching"); 3516 msg.append(intent.toString()); 3517 msg.append(": "); 3518 msg.append(e.getMessage()); 3519 */ 3520 throw e; 3521 } 3522 } 3523 3524 @Override 3525 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3527 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3528 enforceNotIsolatedCaller("startActivityAndWait"); 3529 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3530 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3531 WaitResult res = new WaitResult(); 3532 // TODO: Switch to user app stacks here. 3533 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3534 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3535 options, userId, null, null); 3536 return res; 3537 } 3538 3539 @Override 3540 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3541 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3542 int startFlags, Configuration config, Bundle options, int userId) { 3543 enforceNotIsolatedCaller("startActivityWithConfig"); 3544 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3545 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3546 // TODO: Switch to user app stacks here. 3547 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3548 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3549 null, null, config, options, userId, null, null); 3550 return ret; 3551 } 3552 3553 @Override 3554 public int startActivityIntentSender(IApplicationThread caller, 3555 IntentSender intent, Intent fillInIntent, String resolvedType, 3556 IBinder resultTo, String resultWho, int requestCode, 3557 int flagsMask, int flagsValues, Bundle options) { 3558 enforceNotIsolatedCaller("startActivityIntentSender"); 3559 // Refuse possible leaked file descriptors 3560 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3561 throw new IllegalArgumentException("File descriptors passed in Intent"); 3562 } 3563 3564 IIntentSender sender = intent.getTarget(); 3565 if (!(sender instanceof PendingIntentRecord)) { 3566 throw new IllegalArgumentException("Bad PendingIntent object"); 3567 } 3568 3569 PendingIntentRecord pir = (PendingIntentRecord)sender; 3570 3571 synchronized (this) { 3572 // If this is coming from the currently resumed activity, it is 3573 // effectively saying that app switches are allowed at this point. 3574 final ActivityStack stack = getFocusedStack(); 3575 if (stack.mResumedActivity != null && 3576 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3577 mAppSwitchesAllowedTime = 0; 3578 } 3579 } 3580 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3581 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3582 return ret; 3583 } 3584 3585 @Override 3586 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3587 Intent intent, String resolvedType, IVoiceInteractionSession session, 3588 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3589 Bundle options, int userId) { 3590 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3591 != PackageManager.PERMISSION_GRANTED) { 3592 String msg = "Permission Denial: startVoiceActivity() from pid=" 3593 + Binder.getCallingPid() 3594 + ", uid=" + Binder.getCallingUid() 3595 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3596 Slog.w(TAG, msg); 3597 throw new SecurityException(msg); 3598 } 3599 if (session == null || interactor == null) { 3600 throw new NullPointerException("null session or interactor"); 3601 } 3602 userId = handleIncomingUser(callingPid, callingUid, userId, 3603 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3604 // TODO: Switch to user app stacks here. 3605 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3606 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3607 null, options, userId, null, null); 3608 } 3609 3610 @Override 3611 public boolean startNextMatchingActivity(IBinder callingActivity, 3612 Intent intent, Bundle options) { 3613 // Refuse possible leaked file descriptors 3614 if (intent != null && intent.hasFileDescriptors() == true) { 3615 throw new IllegalArgumentException("File descriptors passed in Intent"); 3616 } 3617 3618 synchronized (this) { 3619 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3620 if (r == null) { 3621 ActivityOptions.abort(options); 3622 return false; 3623 } 3624 if (r.app == null || r.app.thread == null) { 3625 // The caller is not running... d'oh! 3626 ActivityOptions.abort(options); 3627 return false; 3628 } 3629 intent = new Intent(intent); 3630 // The caller is not allowed to change the data. 3631 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3632 // And we are resetting to find the next component... 3633 intent.setComponent(null); 3634 3635 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3636 3637 ActivityInfo aInfo = null; 3638 try { 3639 List<ResolveInfo> resolves = 3640 AppGlobals.getPackageManager().queryIntentActivities( 3641 intent, r.resolvedType, 3642 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3643 UserHandle.getCallingUserId()); 3644 3645 // Look for the original activity in the list... 3646 final int N = resolves != null ? resolves.size() : 0; 3647 for (int i=0; i<N; i++) { 3648 ResolveInfo rInfo = resolves.get(i); 3649 if (rInfo.activityInfo.packageName.equals(r.packageName) 3650 && rInfo.activityInfo.name.equals(r.info.name)) { 3651 // We found the current one... the next matching is 3652 // after it. 3653 i++; 3654 if (i<N) { 3655 aInfo = resolves.get(i).activityInfo; 3656 } 3657 if (debug) { 3658 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3659 + "/" + r.info.name); 3660 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3661 + "/" + aInfo.name); 3662 } 3663 break; 3664 } 3665 } 3666 } catch (RemoteException e) { 3667 } 3668 3669 if (aInfo == null) { 3670 // Nobody who is next! 3671 ActivityOptions.abort(options); 3672 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3673 return false; 3674 } 3675 3676 intent.setComponent(new ComponentName( 3677 aInfo.applicationInfo.packageName, aInfo.name)); 3678 intent.setFlags(intent.getFlags()&~( 3679 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3680 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3681 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3682 Intent.FLAG_ACTIVITY_NEW_TASK)); 3683 3684 // Okay now we need to start the new activity, replacing the 3685 // currently running activity. This is a little tricky because 3686 // we want to start the new one as if the current one is finished, 3687 // but not finish the current one first so that there is no flicker. 3688 // And thus... 3689 final boolean wasFinishing = r.finishing; 3690 r.finishing = true; 3691 3692 // Propagate reply information over to the new activity. 3693 final ActivityRecord resultTo = r.resultTo; 3694 final String resultWho = r.resultWho; 3695 final int requestCode = r.requestCode; 3696 r.resultTo = null; 3697 if (resultTo != null) { 3698 resultTo.removeResultsLocked(r, resultWho, requestCode); 3699 } 3700 3701 final long origId = Binder.clearCallingIdentity(); 3702 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3703 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3704 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3705 options, false, null, null, null); 3706 Binder.restoreCallingIdentity(origId); 3707 3708 r.finishing = wasFinishing; 3709 if (res != ActivityManager.START_SUCCESS) { 3710 return false; 3711 } 3712 return true; 3713 } 3714 } 3715 3716 @Override 3717 public final int startActivityFromRecents(int taskId, Bundle options) { 3718 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3719 String msg = "Permission Denial: startActivityFromRecents called without " + 3720 START_TASKS_FROM_RECENTS; 3721 Slog.w(TAG, msg); 3722 throw new SecurityException(msg); 3723 } 3724 return startActivityFromRecentsInner(taskId, options); 3725 } 3726 3727 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3728 final TaskRecord task; 3729 final int callingUid; 3730 final String callingPackage; 3731 final Intent intent; 3732 final int userId; 3733 synchronized (this) { 3734 task = recentTaskForIdLocked(taskId); 3735 if (task == null) { 3736 throw new IllegalArgumentException("Task " + taskId + " not found."); 3737 } 3738 callingUid = task.mCallingUid; 3739 callingPackage = task.mCallingPackage; 3740 intent = task.intent; 3741 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3742 userId = task.userId; 3743 } 3744 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3745 options, userId, null, task); 3746 } 3747 3748 final int startActivityInPackage(int uid, String callingPackage, 3749 Intent intent, String resolvedType, IBinder resultTo, 3750 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3751 IActivityContainer container, TaskRecord inTask) { 3752 3753 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3754 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3755 3756 // TODO: Switch to user app stacks here. 3757 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3758 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3759 null, null, null, options, userId, container, inTask); 3760 return ret; 3761 } 3762 3763 @Override 3764 public final int startActivities(IApplicationThread caller, String callingPackage, 3765 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3766 int userId) { 3767 enforceNotIsolatedCaller("startActivities"); 3768 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3769 false, ALLOW_FULL_ONLY, "startActivity", null); 3770 // TODO: Switch to user app stacks here. 3771 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3772 resolvedTypes, resultTo, options, userId); 3773 return ret; 3774 } 3775 3776 final int startActivitiesInPackage(int uid, String callingPackage, 3777 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3778 Bundle options, int userId) { 3779 3780 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3781 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3782 // TODO: Switch to user app stacks here. 3783 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3784 resultTo, options, userId); 3785 return ret; 3786 } 3787 3788 //explicitly remove thd old information in mRecentTasks when removing existing user. 3789 private void removeRecentTasksForUserLocked(int userId) { 3790 if(userId <= 0) { 3791 Slog.i(TAG, "Can't remove recent task on user " + userId); 3792 return; 3793 } 3794 3795 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3796 TaskRecord tr = mRecentTasks.get(i); 3797 if (tr.userId == userId) { 3798 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3799 + " when finishing user" + userId); 3800 mRecentTasks.remove(i); 3801 tr.removedFromRecents(mTaskPersister); 3802 } 3803 } 3804 3805 // Remove tasks from persistent storage. 3806 mTaskPersister.wakeup(null, true); 3807 } 3808 3809 /** 3810 * Update the recent tasks lists: make sure tasks should still be here (their 3811 * applications / activities still exist), update their availability, fixup ordering 3812 * of affiliations. 3813 */ 3814 void cleanupRecentTasksLocked(int userId) { 3815 if (mRecentTasks == null) { 3816 // Happens when called from the packagemanager broadcast before boot. 3817 return; 3818 } 3819 3820 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3821 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3822 final IPackageManager pm = AppGlobals.getPackageManager(); 3823 final ActivityInfo dummyAct = new ActivityInfo(); 3824 final ApplicationInfo dummyApp = new ApplicationInfo(); 3825 3826 int N = mRecentTasks.size(); 3827 3828 int[] users = userId == UserHandle.USER_ALL 3829 ? getUsersLocked() : new int[] { userId }; 3830 for (int user : users) { 3831 for (int i = 0; i < N; i++) { 3832 TaskRecord task = mRecentTasks.get(i); 3833 if (task.userId != user) { 3834 // Only look at tasks for the user ID of interest. 3835 continue; 3836 } 3837 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3838 // This situation is broken, and we should just get rid of it now. 3839 mRecentTasks.remove(i); 3840 task.removedFromRecents(mTaskPersister); 3841 i--; 3842 N--; 3843 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3844 continue; 3845 } 3846 // Check whether this activity is currently available. 3847 if (task.realActivity != null) { 3848 ActivityInfo ai = availActCache.get(task.realActivity); 3849 if (ai == null) { 3850 try { 3851 ai = pm.getActivityInfo(task.realActivity, 3852 PackageManager.GET_UNINSTALLED_PACKAGES 3853 | PackageManager.GET_DISABLED_COMPONENTS, user); 3854 } catch (RemoteException e) { 3855 // Will never happen. 3856 continue; 3857 } 3858 if (ai == null) { 3859 ai = dummyAct; 3860 } 3861 availActCache.put(task.realActivity, ai); 3862 } 3863 if (ai == dummyAct) { 3864 // This could be either because the activity no longer exists, or the 3865 // app is temporarily gone. For the former we want to remove the recents 3866 // entry; for the latter we want to mark it as unavailable. 3867 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3868 if (app == null) { 3869 try { 3870 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3871 PackageManager.GET_UNINSTALLED_PACKAGES 3872 | PackageManager.GET_DISABLED_COMPONENTS, user); 3873 } catch (RemoteException e) { 3874 // Will never happen. 3875 continue; 3876 } 3877 if (app == null) { 3878 app = dummyApp; 3879 } 3880 availAppCache.put(task.realActivity.getPackageName(), app); 3881 } 3882 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3883 // Doesn't exist any more! Good-bye. 3884 mRecentTasks.remove(i); 3885 task.removedFromRecents(mTaskPersister); 3886 i--; 3887 N--; 3888 Slog.w(TAG, "Removing no longer valid recent: " + task); 3889 continue; 3890 } else { 3891 // Otherwise just not available for now. 3892 if (task.isAvailable) { 3893 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3894 + task); 3895 } 3896 task.isAvailable = false; 3897 } 3898 } else { 3899 if (!ai.enabled || !ai.applicationInfo.enabled 3900 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3901 if (task.isAvailable) { 3902 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3903 + task + " (enabled=" + ai.enabled + "/" 3904 + ai.applicationInfo.enabled + " flags=" 3905 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3906 } 3907 task.isAvailable = false; 3908 } else { 3909 if (!task.isAvailable) { 3910 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3911 + task); 3912 } 3913 task.isAvailable = true; 3914 } 3915 } 3916 } 3917 } 3918 } 3919 3920 // Verify the affiliate chain for each task. 3921 for (int i = 0; i < N; ) { 3922 TaskRecord task = mRecentTasks.remove(i); 3923 if (mTmpRecents.contains(task)) { 3924 continue; 3925 } 3926 int affiliatedTaskId = task.mAffiliatedTaskId; 3927 while (true) { 3928 TaskRecord next = task.mNextAffiliate; 3929 if (next == null) { 3930 break; 3931 } 3932 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3933 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3934 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3935 task.setNextAffiliate(null); 3936 if (next.mPrevAffiliate == task) { 3937 next.setPrevAffiliate(null); 3938 } 3939 break; 3940 } 3941 if (next.mPrevAffiliate != task) { 3942 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3943 next.mPrevAffiliate + " task=" + task); 3944 next.setPrevAffiliate(null); 3945 task.setNextAffiliate(null); 3946 break; 3947 } 3948 if (!mRecentTasks.contains(next)) { 3949 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3950 task.setNextAffiliate(null); 3951 // We know that next.mPrevAffiliate is always task, from above, so clear 3952 // its previous affiliate. 3953 next.setPrevAffiliate(null); 3954 break; 3955 } 3956 task = next; 3957 } 3958 // task is now the end of the list 3959 do { 3960 mRecentTasks.remove(task); 3961 mRecentTasks.add(i++, task); 3962 mTmpRecents.add(task); 3963 task.inRecents = true; 3964 } while ((task = task.mPrevAffiliate) != null); 3965 } 3966 mTmpRecents.clear(); 3967 // mRecentTasks is now in sorted, affiliated order. 3968 } 3969 3970 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3971 int N = mRecentTasks.size(); 3972 TaskRecord top = task; 3973 int topIndex = taskIndex; 3974 while (top.mNextAffiliate != null && topIndex > 0) { 3975 top = top.mNextAffiliate; 3976 topIndex--; 3977 } 3978 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3979 + topIndex + " from intial " + taskIndex); 3980 // Find the end of the chain, doing a sanity check along the way. 3981 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3982 int endIndex = topIndex; 3983 TaskRecord prev = top; 3984 while (endIndex < N) { 3985 TaskRecord cur = mRecentTasks.get(endIndex); 3986 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3987 + endIndex + " " + cur); 3988 if (cur == top) { 3989 // Verify start of the chain. 3990 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3991 Slog.wtf(TAG, "Bad chain @" + endIndex 3992 + ": first task has next affiliate: " + prev); 3993 sane = false; 3994 break; 3995 } 3996 } else { 3997 // Verify middle of the chain's next points back to the one before. 3998 if (cur.mNextAffiliate != prev 3999 || cur.mNextAffiliateTaskId != prev.taskId) { 4000 Slog.wtf(TAG, "Bad chain @" + endIndex 4001 + ": middle task " + cur + " @" + endIndex 4002 + " has bad next affiliate " 4003 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4004 + ", expected " + prev); 4005 sane = false; 4006 break; 4007 } 4008 } 4009 if (cur.mPrevAffiliateTaskId == -1) { 4010 // Chain ends here. 4011 if (cur.mPrevAffiliate != null) { 4012 Slog.wtf(TAG, "Bad chain @" + endIndex 4013 + ": last task " + cur + " has previous affiliate " 4014 + cur.mPrevAffiliate); 4015 sane = false; 4016 } 4017 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4018 break; 4019 } else { 4020 // Verify middle of the chain's prev points to a valid item. 4021 if (cur.mPrevAffiliate == null) { 4022 Slog.wtf(TAG, "Bad chain @" + endIndex 4023 + ": task " + cur + " has previous affiliate " 4024 + cur.mPrevAffiliate + " but should be id " 4025 + cur.mPrevAffiliate); 4026 sane = false; 4027 break; 4028 } 4029 } 4030 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4031 Slog.wtf(TAG, "Bad chain @" + endIndex 4032 + ": task " + cur + " has affiliated id " 4033 + cur.mAffiliatedTaskId + " but should be " 4034 + task.mAffiliatedTaskId); 4035 sane = false; 4036 break; 4037 } 4038 prev = cur; 4039 endIndex++; 4040 if (endIndex >= N) { 4041 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4042 + ": last task " + prev); 4043 sane = false; 4044 break; 4045 } 4046 } 4047 if (sane) { 4048 if (endIndex < taskIndex) { 4049 Slog.wtf(TAG, "Bad chain @" + endIndex 4050 + ": did not extend to task " + task + " @" + taskIndex); 4051 sane = false; 4052 } 4053 } 4054 if (sane) { 4055 // All looks good, we can just move all of the affiliated tasks 4056 // to the top. 4057 for (int i=topIndex; i<=endIndex; i++) { 4058 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4059 + " from " + i + " to " + (i-topIndex)); 4060 TaskRecord cur = mRecentTasks.remove(i); 4061 mRecentTasks.add(i-topIndex, cur); 4062 } 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4064 + " to " + endIndex); 4065 return true; 4066 } 4067 4068 // Whoops, couldn't do it. 4069 return false; 4070 } 4071 4072 final void addRecentTaskLocked(TaskRecord task) { 4073 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4074 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4075 4076 int N = mRecentTasks.size(); 4077 // Quick case: check if the top-most recent task is the same. 4078 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4079 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4080 return; 4081 } 4082 // Another quick case: check if this is part of a set of affiliated 4083 // tasks that are at the top. 4084 if (isAffiliated && N > 0 && task.inRecents 4085 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4086 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4087 + " at top when adding " + task); 4088 return; 4089 } 4090 // Another quick case: never add voice sessions. 4091 if (task.voiceSession != null) { 4092 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4093 return; 4094 } 4095 4096 boolean needAffiliationFix = false; 4097 4098 // Slightly less quick case: the task is already in recents, so all we need 4099 // to do is move it. 4100 if (task.inRecents) { 4101 int taskIndex = mRecentTasks.indexOf(task); 4102 if (taskIndex >= 0) { 4103 if (!isAffiliated) { 4104 // Simple case: this is not an affiliated task, so we just move it to the front. 4105 mRecentTasks.remove(taskIndex); 4106 mRecentTasks.add(0, task); 4107 notifyTaskPersisterLocked(task, false); 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4109 + " from " + taskIndex); 4110 return; 4111 } else { 4112 // More complicated: need to keep all affiliated tasks together. 4113 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4114 // All went well. 4115 return; 4116 } 4117 4118 // Uh oh... something bad in the affiliation chain, try to rebuild 4119 // everything and then go through our general path of adding a new task. 4120 needAffiliationFix = true; 4121 } 4122 } else { 4123 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4124 needAffiliationFix = true; 4125 } 4126 } 4127 4128 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4129 trimRecentsForTask(task, true); 4130 4131 N = mRecentTasks.size(); 4132 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4133 final TaskRecord tr = mRecentTasks.remove(N - 1); 4134 tr.removedFromRecents(mTaskPersister); 4135 N--; 4136 } 4137 task.inRecents = true; 4138 if (!isAffiliated || needAffiliationFix) { 4139 // If this is a simple non-affiliated task, or we had some failure trying to 4140 // handle it as part of an affilated task, then just place it at the top. 4141 mRecentTasks.add(0, task); 4142 } else if (isAffiliated) { 4143 // If this is a new affiliated task, then move all of the affiliated tasks 4144 // to the front and insert this new one. 4145 TaskRecord other = task.mNextAffiliate; 4146 if (other == null) { 4147 other = task.mPrevAffiliate; 4148 } 4149 if (other != null) { 4150 int otherIndex = mRecentTasks.indexOf(other); 4151 if (otherIndex >= 0) { 4152 // Insert new task at appropriate location. 4153 int taskIndex; 4154 if (other == task.mNextAffiliate) { 4155 // We found the index of our next affiliation, which is who is 4156 // before us in the list, so add after that point. 4157 taskIndex = otherIndex+1; 4158 } else { 4159 // We found the index of our previous affiliation, which is who is 4160 // after us in the list, so add at their position. 4161 taskIndex = otherIndex; 4162 } 4163 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4164 + taskIndex + ": " + task); 4165 mRecentTasks.add(taskIndex, task); 4166 4167 // Now move everything to the front. 4168 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4169 // All went well. 4170 return; 4171 } 4172 4173 // Uh oh... something bad in the affiliation chain, try to rebuild 4174 // everything and then go through our general path of adding a new task. 4175 needAffiliationFix = true; 4176 } else { 4177 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4178 + other); 4179 needAffiliationFix = true; 4180 } 4181 } else { 4182 if (DEBUG_RECENTS) Slog.d(TAG, 4183 "addRecent: adding affiliated task without next/prev:" + task); 4184 needAffiliationFix = true; 4185 } 4186 } 4187 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4188 4189 if (needAffiliationFix) { 4190 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4191 cleanupRecentTasksLocked(task.userId); 4192 } 4193 } 4194 4195 /** 4196 * If needed, remove oldest existing entries in recents that are for the same kind 4197 * of task as the given one. 4198 */ 4199 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4200 int N = mRecentTasks.size(); 4201 final Intent intent = task.intent; 4202 final boolean document = intent != null && intent.isDocument(); 4203 4204 int maxRecents = task.maxRecents - 1; 4205 for (int i=0; i<N; i++) { 4206 final TaskRecord tr = mRecentTasks.get(i); 4207 if (task != tr) { 4208 if (task.userId != tr.userId) { 4209 continue; 4210 } 4211 if (i > MAX_RECENT_BITMAPS) { 4212 tr.freeLastThumbnail(); 4213 } 4214 final Intent trIntent = tr.intent; 4215 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4216 (intent == null || !intent.filterEquals(trIntent))) { 4217 continue; 4218 } 4219 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4220 if (document && trIsDocument) { 4221 // These are the same document activity (not necessarily the same doc). 4222 if (maxRecents > 0) { 4223 --maxRecents; 4224 continue; 4225 } 4226 // Hit the maximum number of documents for this task. Fall through 4227 // and remove this document from recents. 4228 } else if (document || trIsDocument) { 4229 // Only one of these is a document. Not the droid we're looking for. 4230 continue; 4231 } 4232 } 4233 4234 if (!doTrim) { 4235 // If the caller is not actually asking for a trim, just tell them we reached 4236 // a point where the trim would happen. 4237 return i; 4238 } 4239 4240 // Either task and tr are the same or, their affinities match or their intents match 4241 // and neither of them is a document, or they are documents using the same activity 4242 // and their maxRecents has been reached. 4243 tr.disposeThumbnail(); 4244 mRecentTasks.remove(i); 4245 if (task != tr) { 4246 tr.removedFromRecents(mTaskPersister); 4247 } 4248 i--; 4249 N--; 4250 if (task.intent == null) { 4251 // If the new recent task we are adding is not fully 4252 // specified, then replace it with the existing recent task. 4253 task = tr; 4254 } 4255 notifyTaskPersisterLocked(tr, false); 4256 } 4257 4258 return -1; 4259 } 4260 4261 @Override 4262 public void reportActivityFullyDrawn(IBinder token) { 4263 synchronized (this) { 4264 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4265 if (r == null) { 4266 return; 4267 } 4268 r.reportFullyDrawnLocked(); 4269 } 4270 } 4271 4272 @Override 4273 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4274 synchronized (this) { 4275 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4276 if (r == null) { 4277 return; 4278 } 4279 final long origId = Binder.clearCallingIdentity(); 4280 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4281 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4282 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4283 if (config != null) { 4284 r.frozenBeforeDestroy = true; 4285 if (!updateConfigurationLocked(config, r, false, false)) { 4286 mStackSupervisor.resumeTopActivitiesLocked(); 4287 } 4288 } 4289 Binder.restoreCallingIdentity(origId); 4290 } 4291 } 4292 4293 @Override 4294 public int getRequestedOrientation(IBinder token) { 4295 synchronized (this) { 4296 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4297 if (r == null) { 4298 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4299 } 4300 return mWindowManager.getAppOrientation(r.appToken); 4301 } 4302 } 4303 4304 /** 4305 * This is the internal entry point for handling Activity.finish(). 4306 * 4307 * @param token The Binder token referencing the Activity we want to finish. 4308 * @param resultCode Result code, if any, from this Activity. 4309 * @param resultData Result data (Intent), if any, from this Activity. 4310 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4311 * the root Activity in the task. 4312 * 4313 * @return Returns true if the activity successfully finished, or false if it is still running. 4314 */ 4315 @Override 4316 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4317 boolean finishTask) { 4318 // Refuse possible leaked file descriptors 4319 if (resultData != null && resultData.hasFileDescriptors() == true) { 4320 throw new IllegalArgumentException("File descriptors passed in Intent"); 4321 } 4322 4323 synchronized(this) { 4324 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4325 if (r == null) { 4326 return true; 4327 } 4328 // Keep track of the root activity of the task before we finish it 4329 TaskRecord tr = r.task; 4330 ActivityRecord rootR = tr.getRootActivity(); 4331 // Do not allow task to finish in Lock Task mode. 4332 if (tr == mStackSupervisor.mLockTaskModeTask) { 4333 if (rootR == r) { 4334 mStackSupervisor.showLockTaskToast(); 4335 return false; 4336 } 4337 } 4338 if (mController != null) { 4339 // Find the first activity that is not finishing. 4340 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4341 if (next != null) { 4342 // ask watcher if this is allowed 4343 boolean resumeOK = true; 4344 try { 4345 resumeOK = mController.activityResuming(next.packageName); 4346 } catch (RemoteException e) { 4347 mController = null; 4348 Watchdog.getInstance().setActivityController(null); 4349 } 4350 4351 if (!resumeOK) { 4352 return false; 4353 } 4354 } 4355 } 4356 final long origId = Binder.clearCallingIdentity(); 4357 try { 4358 boolean res; 4359 if (finishTask && r == rootR) { 4360 // If requested, remove the task that is associated to this activity only if it 4361 // was the root activity in the task. The result code and data is ignored because 4362 // we don't support returning them across task boundaries. 4363 res = removeTaskByIdLocked(tr.taskId, 0); 4364 } else { 4365 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4366 resultData, "app-request", true); 4367 } 4368 return res; 4369 } finally { 4370 Binder.restoreCallingIdentity(origId); 4371 } 4372 } 4373 } 4374 4375 @Override 4376 public final void finishHeavyWeightApp() { 4377 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4378 != PackageManager.PERMISSION_GRANTED) { 4379 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4380 + Binder.getCallingPid() 4381 + ", uid=" + Binder.getCallingUid() 4382 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4383 Slog.w(TAG, msg); 4384 throw new SecurityException(msg); 4385 } 4386 4387 synchronized(this) { 4388 if (mHeavyWeightProcess == null) { 4389 return; 4390 } 4391 4392 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4393 mHeavyWeightProcess.activities); 4394 for (int i=0; i<activities.size(); i++) { 4395 ActivityRecord r = activities.get(i); 4396 if (!r.finishing) { 4397 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4398 null, "finish-heavy", true); 4399 } 4400 } 4401 4402 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4403 mHeavyWeightProcess.userId, 0)); 4404 mHeavyWeightProcess = null; 4405 } 4406 } 4407 4408 @Override 4409 public void crashApplication(int uid, int initialPid, String packageName, 4410 String message) { 4411 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4412 != PackageManager.PERMISSION_GRANTED) { 4413 String msg = "Permission Denial: crashApplication() from pid=" 4414 + Binder.getCallingPid() 4415 + ", uid=" + Binder.getCallingUid() 4416 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4417 Slog.w(TAG, msg); 4418 throw new SecurityException(msg); 4419 } 4420 4421 synchronized(this) { 4422 ProcessRecord proc = null; 4423 4424 // Figure out which process to kill. We don't trust that initialPid 4425 // still has any relation to current pids, so must scan through the 4426 // list. 4427 synchronized (mPidsSelfLocked) { 4428 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4429 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4430 if (p.uid != uid) { 4431 continue; 4432 } 4433 if (p.pid == initialPid) { 4434 proc = p; 4435 break; 4436 } 4437 if (p.pkgList.containsKey(packageName)) { 4438 proc = p; 4439 } 4440 } 4441 } 4442 4443 if (proc == null) { 4444 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4445 + " initialPid=" + initialPid 4446 + " packageName=" + packageName); 4447 return; 4448 } 4449 4450 if (proc.thread != null) { 4451 if (proc.pid == Process.myPid()) { 4452 Log.w(TAG, "crashApplication: trying to crash self!"); 4453 return; 4454 } 4455 long ident = Binder.clearCallingIdentity(); 4456 try { 4457 proc.thread.scheduleCrash(message); 4458 } catch (RemoteException e) { 4459 } 4460 Binder.restoreCallingIdentity(ident); 4461 } 4462 } 4463 } 4464 4465 @Override 4466 public final void finishSubActivity(IBinder token, String resultWho, 4467 int requestCode) { 4468 synchronized(this) { 4469 final long origId = Binder.clearCallingIdentity(); 4470 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4471 if (r != null) { 4472 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4473 } 4474 Binder.restoreCallingIdentity(origId); 4475 } 4476 } 4477 4478 @Override 4479 public boolean finishActivityAffinity(IBinder token) { 4480 synchronized(this) { 4481 final long origId = Binder.clearCallingIdentity(); 4482 try { 4483 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4484 4485 ActivityRecord rootR = r.task.getRootActivity(); 4486 // Do not allow task to finish in Lock Task mode. 4487 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4488 if (rootR == r) { 4489 mStackSupervisor.showLockTaskToast(); 4490 return false; 4491 } 4492 } 4493 boolean res = false; 4494 if (r != null) { 4495 res = r.task.stack.finishActivityAffinityLocked(r); 4496 } 4497 return res; 4498 } finally { 4499 Binder.restoreCallingIdentity(origId); 4500 } 4501 } 4502 } 4503 4504 @Override 4505 public void finishVoiceTask(IVoiceInteractionSession session) { 4506 synchronized(this) { 4507 final long origId = Binder.clearCallingIdentity(); 4508 try { 4509 mStackSupervisor.finishVoiceTask(session); 4510 } finally { 4511 Binder.restoreCallingIdentity(origId); 4512 } 4513 } 4514 4515 } 4516 4517 @Override 4518 public boolean releaseActivityInstance(IBinder token) { 4519 synchronized(this) { 4520 final long origId = Binder.clearCallingIdentity(); 4521 try { 4522 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4523 if (r.task == null || r.task.stack == null) { 4524 return false; 4525 } 4526 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4527 } finally { 4528 Binder.restoreCallingIdentity(origId); 4529 } 4530 } 4531 } 4532 4533 @Override 4534 public void releaseSomeActivities(IApplicationThread appInt) { 4535 synchronized(this) { 4536 final long origId = Binder.clearCallingIdentity(); 4537 try { 4538 ProcessRecord app = getRecordForAppLocked(appInt); 4539 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4540 } finally { 4541 Binder.restoreCallingIdentity(origId); 4542 } 4543 } 4544 } 4545 4546 @Override 4547 public boolean willActivityBeVisible(IBinder token) { 4548 synchronized(this) { 4549 ActivityStack stack = ActivityRecord.getStackLocked(token); 4550 if (stack != null) { 4551 return stack.willActivityBeVisibleLocked(token); 4552 } 4553 return false; 4554 } 4555 } 4556 4557 @Override 4558 public void overridePendingTransition(IBinder token, String packageName, 4559 int enterAnim, int exitAnim) { 4560 synchronized(this) { 4561 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4562 if (self == null) { 4563 return; 4564 } 4565 4566 final long origId = Binder.clearCallingIdentity(); 4567 4568 if (self.state == ActivityState.RESUMED 4569 || self.state == ActivityState.PAUSING) { 4570 mWindowManager.overridePendingAppTransition(packageName, 4571 enterAnim, exitAnim, null); 4572 } 4573 4574 Binder.restoreCallingIdentity(origId); 4575 } 4576 } 4577 4578 /** 4579 * Main function for removing an existing process from the activity manager 4580 * as a result of that process going away. Clears out all connections 4581 * to the process. 4582 */ 4583 private final void handleAppDiedLocked(ProcessRecord app, 4584 boolean restarting, boolean allowRestart) { 4585 int pid = app.pid; 4586 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4587 if (!restarting) { 4588 removeLruProcessLocked(app); 4589 if (pid > 0) { 4590 ProcessList.remove(pid); 4591 } 4592 } 4593 4594 if (mProfileProc == app) { 4595 clearProfilerLocked(); 4596 } 4597 4598 // Remove this application's activities from active lists. 4599 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4600 4601 app.activities.clear(); 4602 4603 if (app.instrumentationClass != null) { 4604 Slog.w(TAG, "Crash of app " + app.processName 4605 + " running instrumentation " + app.instrumentationClass); 4606 Bundle info = new Bundle(); 4607 info.putString("shortMsg", "Process crashed."); 4608 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4609 } 4610 4611 if (!restarting) { 4612 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4613 // If there was nothing to resume, and we are not already 4614 // restarting this process, but there is a visible activity that 4615 // is hosted by the process... then make sure all visible 4616 // activities are running, taking care of restarting this 4617 // process. 4618 if (hasVisibleActivities) { 4619 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4620 } 4621 } 4622 } 4623 } 4624 4625 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4626 IBinder threadBinder = thread.asBinder(); 4627 // Find the application record. 4628 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4629 ProcessRecord rec = mLruProcesses.get(i); 4630 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4631 return i; 4632 } 4633 } 4634 return -1; 4635 } 4636 4637 final ProcessRecord getRecordForAppLocked( 4638 IApplicationThread thread) { 4639 if (thread == null) { 4640 return null; 4641 } 4642 4643 int appIndex = getLRURecordIndexForAppLocked(thread); 4644 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4645 } 4646 4647 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4648 // If there are no longer any background processes running, 4649 // and the app that died was not running instrumentation, 4650 // then tell everyone we are now low on memory. 4651 boolean haveBg = false; 4652 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4653 ProcessRecord rec = mLruProcesses.get(i); 4654 if (rec.thread != null 4655 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4656 haveBg = true; 4657 break; 4658 } 4659 } 4660 4661 if (!haveBg) { 4662 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4663 if (doReport) { 4664 long now = SystemClock.uptimeMillis(); 4665 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4666 doReport = false; 4667 } else { 4668 mLastMemUsageReportTime = now; 4669 } 4670 } 4671 final ArrayList<ProcessMemInfo> memInfos 4672 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4673 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4674 long now = SystemClock.uptimeMillis(); 4675 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4676 ProcessRecord rec = mLruProcesses.get(i); 4677 if (rec == dyingProc || rec.thread == null) { 4678 continue; 4679 } 4680 if (doReport) { 4681 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4682 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4683 } 4684 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4685 // The low memory report is overriding any current 4686 // state for a GC request. Make sure to do 4687 // heavy/important/visible/foreground processes first. 4688 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4689 rec.lastRequestedGc = 0; 4690 } else { 4691 rec.lastRequestedGc = rec.lastLowMemory; 4692 } 4693 rec.reportLowMemory = true; 4694 rec.lastLowMemory = now; 4695 mProcessesToGc.remove(rec); 4696 addProcessToGcListLocked(rec); 4697 } 4698 } 4699 if (doReport) { 4700 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4701 mHandler.sendMessage(msg); 4702 } 4703 scheduleAppGcsLocked(); 4704 } 4705 } 4706 4707 final void appDiedLocked(ProcessRecord app) { 4708 appDiedLocked(app, app.pid, app.thread); 4709 } 4710 4711 final void appDiedLocked(ProcessRecord app, int pid, 4712 IApplicationThread thread) { 4713 4714 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4715 synchronized (stats) { 4716 stats.noteProcessDiedLocked(app.info.uid, pid); 4717 } 4718 4719 Process.killProcessGroup(app.info.uid, pid); 4720 4721 // Clean up already done if the process has been re-started. 4722 if (app.pid == pid && app.thread != null && 4723 app.thread.asBinder() == thread.asBinder()) { 4724 boolean doLowMem = app.instrumentationClass == null; 4725 boolean doOomAdj = doLowMem; 4726 if (!app.killedByAm) { 4727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4728 + ") has died."); 4729 mAllowLowerMemLevel = true; 4730 } else { 4731 // Note that we always want to do oom adj to update our state with the 4732 // new number of procs. 4733 mAllowLowerMemLevel = false; 4734 doLowMem = false; 4735 } 4736 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4737 if (DEBUG_CLEANUP) Slog.v( 4738 TAG, "Dying app: " + app + ", pid: " + pid 4739 + ", thread: " + thread.asBinder()); 4740 handleAppDiedLocked(app, false, true); 4741 4742 if (doOomAdj) { 4743 updateOomAdjLocked(); 4744 } 4745 if (doLowMem) { 4746 doLowMemReportIfNeededLocked(app); 4747 } 4748 } else if (app.pid != pid) { 4749 // A new process has already been started. 4750 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4751 + ") has died and restarted (pid " + app.pid + ")."); 4752 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4753 } else if (DEBUG_PROCESSES) { 4754 Slog.d(TAG, "Received spurious death notification for thread " 4755 + thread.asBinder()); 4756 } 4757 } 4758 4759 /** 4760 * If a stack trace dump file is configured, dump process stack traces. 4761 * @param clearTraces causes the dump file to be erased prior to the new 4762 * traces being written, if true; when false, the new traces will be 4763 * appended to any existing file content. 4764 * @param firstPids of dalvik VM processes to dump stack traces for first 4765 * @param lastPids of dalvik VM processes to dump stack traces for last 4766 * @param nativeProcs optional list of native process names to dump stack crawls 4767 * @return file containing stack traces, or null if no dump file is configured 4768 */ 4769 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4770 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4771 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4772 if (tracesPath == null || tracesPath.length() == 0) { 4773 return null; 4774 } 4775 4776 File tracesFile = new File(tracesPath); 4777 try { 4778 File tracesDir = tracesFile.getParentFile(); 4779 if (!tracesDir.exists()) { 4780 tracesFile.mkdirs(); 4781 if (!SELinux.restorecon(tracesDir)) { 4782 return null; 4783 } 4784 } 4785 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4786 4787 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4788 tracesFile.createNewFile(); 4789 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4790 } catch (IOException e) { 4791 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4792 return null; 4793 } 4794 4795 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4796 return tracesFile; 4797 } 4798 4799 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4801 // Use a FileObserver to detect when traces finish writing. 4802 // The order of traces is considered important to maintain for legibility. 4803 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4804 @Override 4805 public synchronized void onEvent(int event, String path) { notify(); } 4806 }; 4807 4808 try { 4809 observer.startWatching(); 4810 4811 // First collect all of the stacks of the most important pids. 4812 if (firstPids != null) { 4813 try { 4814 int num = firstPids.size(); 4815 for (int i = 0; i < num; i++) { 4816 synchronized (observer) { 4817 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4818 observer.wait(200); // Wait for write-close, give up after 200msec 4819 } 4820 } 4821 } catch (InterruptedException e) { 4822 Log.wtf(TAG, e); 4823 } 4824 } 4825 4826 // Next collect the stacks of the native pids 4827 if (nativeProcs != null) { 4828 int[] pids = Process.getPidsForCommands(nativeProcs); 4829 if (pids != null) { 4830 for (int pid : pids) { 4831 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4832 } 4833 } 4834 } 4835 4836 // Lastly, measure CPU usage. 4837 if (processCpuTracker != null) { 4838 processCpuTracker.init(); 4839 System.gc(); 4840 processCpuTracker.update(); 4841 try { 4842 synchronized (processCpuTracker) { 4843 processCpuTracker.wait(500); // measure over 1/2 second. 4844 } 4845 } catch (InterruptedException e) { 4846 } 4847 processCpuTracker.update(); 4848 4849 // We'll take the stack crawls of just the top apps using CPU. 4850 final int N = processCpuTracker.countWorkingStats(); 4851 int numProcs = 0; 4852 for (int i=0; i<N && numProcs<5; i++) { 4853 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4854 if (lastPids.indexOfKey(stats.pid) >= 0) { 4855 numProcs++; 4856 try { 4857 synchronized (observer) { 4858 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4859 observer.wait(200); // Wait for write-close, give up after 200msec 4860 } 4861 } catch (InterruptedException e) { 4862 Log.wtf(TAG, e); 4863 } 4864 4865 } 4866 } 4867 } 4868 } finally { 4869 observer.stopWatching(); 4870 } 4871 } 4872 4873 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4874 if (true || IS_USER_BUILD) { 4875 return; 4876 } 4877 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4878 if (tracesPath == null || tracesPath.length() == 0) { 4879 return; 4880 } 4881 4882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4883 StrictMode.allowThreadDiskWrites(); 4884 try { 4885 final File tracesFile = new File(tracesPath); 4886 final File tracesDir = tracesFile.getParentFile(); 4887 final File tracesTmp = new File(tracesDir, "__tmp__"); 4888 try { 4889 if (!tracesDir.exists()) { 4890 tracesFile.mkdirs(); 4891 if (!SELinux.restorecon(tracesDir.getPath())) { 4892 return; 4893 } 4894 } 4895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4896 4897 if (tracesFile.exists()) { 4898 tracesTmp.delete(); 4899 tracesFile.renameTo(tracesTmp); 4900 } 4901 StringBuilder sb = new StringBuilder(); 4902 Time tobj = new Time(); 4903 tobj.set(System.currentTimeMillis()); 4904 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4905 sb.append(": "); 4906 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4907 sb.append(" since "); 4908 sb.append(msg); 4909 FileOutputStream fos = new FileOutputStream(tracesFile); 4910 fos.write(sb.toString().getBytes()); 4911 if (app == null) { 4912 fos.write("\n*** No application process!".getBytes()); 4913 } 4914 fos.close(); 4915 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4916 } catch (IOException e) { 4917 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4918 return; 4919 } 4920 4921 if (app != null) { 4922 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4923 firstPids.add(app.pid); 4924 dumpStackTraces(tracesPath, firstPids, null, null, null); 4925 } 4926 4927 File lastTracesFile = null; 4928 File curTracesFile = null; 4929 for (int i=9; i>=0; i--) { 4930 String name = String.format(Locale.US, "slow%02d.txt", i); 4931 curTracesFile = new File(tracesDir, name); 4932 if (curTracesFile.exists()) { 4933 if (lastTracesFile != null) { 4934 curTracesFile.renameTo(lastTracesFile); 4935 } else { 4936 curTracesFile.delete(); 4937 } 4938 } 4939 lastTracesFile = curTracesFile; 4940 } 4941 tracesFile.renameTo(curTracesFile); 4942 if (tracesTmp.exists()) { 4943 tracesTmp.renameTo(tracesFile); 4944 } 4945 } finally { 4946 StrictMode.setThreadPolicy(oldPolicy); 4947 } 4948 } 4949 4950 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4951 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4952 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4953 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4954 4955 if (mController != null) { 4956 try { 4957 // 0 == continue, -1 = kill process immediately 4958 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4959 if (res < 0 && app.pid != MY_PID) { 4960 app.kill("anr", true); 4961 } 4962 } catch (RemoteException e) { 4963 mController = null; 4964 Watchdog.getInstance().setActivityController(null); 4965 } 4966 } 4967 4968 long anrTime = SystemClock.uptimeMillis(); 4969 if (MONITOR_CPU_USAGE) { 4970 updateCpuStatsNow(); 4971 } 4972 4973 synchronized (this) { 4974 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4975 if (mShuttingDown) { 4976 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4977 return; 4978 } else if (app.notResponding) { 4979 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4980 return; 4981 } else if (app.crashing) { 4982 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4983 return; 4984 } 4985 4986 // In case we come through here for the same app before completing 4987 // this one, mark as anring now so we will bail out. 4988 app.notResponding = true; 4989 4990 // Log the ANR to the event log. 4991 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4992 app.processName, app.info.flags, annotation); 4993 4994 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4995 firstPids.add(app.pid); 4996 4997 int parentPid = app.pid; 4998 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4999 if (parentPid != app.pid) firstPids.add(parentPid); 5000 5001 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5002 5003 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5004 ProcessRecord r = mLruProcesses.get(i); 5005 if (r != null && r.thread != null) { 5006 int pid = r.pid; 5007 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5008 if (r.persistent) { 5009 firstPids.add(pid); 5010 } else { 5011 lastPids.put(pid, Boolean.TRUE); 5012 } 5013 } 5014 } 5015 } 5016 } 5017 5018 // Log the ANR to the main log. 5019 StringBuilder info = new StringBuilder(); 5020 info.setLength(0); 5021 info.append("ANR in ").append(app.processName); 5022 if (activity != null && activity.shortComponentName != null) { 5023 info.append(" (").append(activity.shortComponentName).append(")"); 5024 } 5025 info.append("\n"); 5026 info.append("PID: ").append(app.pid).append("\n"); 5027 if (annotation != null) { 5028 info.append("Reason: ").append(annotation).append("\n"); 5029 } 5030 if (parent != null && parent != activity) { 5031 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5032 } 5033 5034 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5035 5036 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5037 NATIVE_STACKS_OF_INTEREST); 5038 5039 String cpuInfo = null; 5040 if (MONITOR_CPU_USAGE) { 5041 updateCpuStatsNow(); 5042 synchronized (mProcessCpuThread) { 5043 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5044 } 5045 info.append(processCpuTracker.printCurrentLoad()); 5046 info.append(cpuInfo); 5047 } 5048 5049 info.append(processCpuTracker.printCurrentState(anrTime)); 5050 5051 Slog.e(TAG, info.toString()); 5052 if (tracesFile == null) { 5053 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5054 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5055 } 5056 5057 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5058 cpuInfo, tracesFile, null); 5059 5060 if (mController != null) { 5061 try { 5062 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5063 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5064 if (res != 0) { 5065 if (res < 0 && app.pid != MY_PID) { 5066 app.kill("anr", true); 5067 } else { 5068 synchronized (this) { 5069 mServices.scheduleServiceTimeoutLocked(app); 5070 } 5071 } 5072 return; 5073 } 5074 } catch (RemoteException e) { 5075 mController = null; 5076 Watchdog.getInstance().setActivityController(null); 5077 } 5078 } 5079 5080 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5081 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5082 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5083 5084 synchronized (this) { 5085 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5086 app.kill("bg anr", true); 5087 return; 5088 } 5089 5090 // Set the app's notResponding state, and look up the errorReportReceiver 5091 makeAppNotRespondingLocked(app, 5092 activity != null ? activity.shortComponentName : null, 5093 annotation != null ? "ANR " + annotation : "ANR", 5094 info.toString()); 5095 5096 // Bring up the infamous App Not Responding dialog 5097 Message msg = Message.obtain(); 5098 HashMap<String, Object> map = new HashMap<String, Object>(); 5099 msg.what = SHOW_NOT_RESPONDING_MSG; 5100 msg.obj = map; 5101 msg.arg1 = aboveSystem ? 1 : 0; 5102 map.put("app", app); 5103 if (activity != null) { 5104 map.put("activity", activity); 5105 } 5106 5107 mHandler.sendMessage(msg); 5108 } 5109 } 5110 5111 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5112 if (!mLaunchWarningShown) { 5113 mLaunchWarningShown = true; 5114 mHandler.post(new Runnable() { 5115 @Override 5116 public void run() { 5117 synchronized (ActivityManagerService.this) { 5118 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5119 d.show(); 5120 mHandler.postDelayed(new Runnable() { 5121 @Override 5122 public void run() { 5123 synchronized (ActivityManagerService.this) { 5124 d.dismiss(); 5125 mLaunchWarningShown = false; 5126 } 5127 } 5128 }, 4000); 5129 } 5130 } 5131 }); 5132 } 5133 } 5134 5135 @Override 5136 public boolean clearApplicationUserData(final String packageName, 5137 final IPackageDataObserver observer, int userId) { 5138 enforceNotIsolatedCaller("clearApplicationUserData"); 5139 int uid = Binder.getCallingUid(); 5140 int pid = Binder.getCallingPid(); 5141 userId = handleIncomingUser(pid, uid, 5142 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5143 long callingId = Binder.clearCallingIdentity(); 5144 try { 5145 IPackageManager pm = AppGlobals.getPackageManager(); 5146 int pkgUid = -1; 5147 synchronized(this) { 5148 try { 5149 pkgUid = pm.getPackageUid(packageName, userId); 5150 } catch (RemoteException e) { 5151 } 5152 if (pkgUid == -1) { 5153 Slog.w(TAG, "Invalid packageName: " + packageName); 5154 if (observer != null) { 5155 try { 5156 observer.onRemoveCompleted(packageName, false); 5157 } catch (RemoteException e) { 5158 Slog.i(TAG, "Observer no longer exists."); 5159 } 5160 } 5161 return false; 5162 } 5163 if (uid == pkgUid || checkComponentPermission( 5164 android.Manifest.permission.CLEAR_APP_USER_DATA, 5165 pid, uid, -1, true) 5166 == PackageManager.PERMISSION_GRANTED) { 5167 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5168 } else { 5169 throw new SecurityException("PID " + pid + " does not have permission " 5170 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5171 + " of package " + packageName); 5172 } 5173 5174 // Remove all tasks match the cleared application package and user 5175 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5176 final TaskRecord tr = mRecentTasks.get(i); 5177 final String taskPackageName = 5178 tr.getBaseIntent().getComponent().getPackageName(); 5179 if (tr.userId != userId) continue; 5180 if (!taskPackageName.equals(packageName)) continue; 5181 removeTaskByIdLocked(tr.taskId, 0); 5182 } 5183 } 5184 5185 try { 5186 // Clear application user data 5187 pm.clearApplicationUserData(packageName, observer, userId); 5188 5189 synchronized(this) { 5190 // Remove all permissions granted from/to this package 5191 removeUriPermissionsForPackageLocked(packageName, userId, true); 5192 } 5193 5194 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5195 Uri.fromParts("package", packageName, null)); 5196 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5197 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5198 null, null, 0, null, null, null, false, false, userId); 5199 } catch (RemoteException e) { 5200 } 5201 } finally { 5202 Binder.restoreCallingIdentity(callingId); 5203 } 5204 return true; 5205 } 5206 5207 @Override 5208 public void killBackgroundProcesses(final String packageName, int userId) { 5209 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5210 != PackageManager.PERMISSION_GRANTED && 5211 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5212 != PackageManager.PERMISSION_GRANTED) { 5213 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5214 + Binder.getCallingPid() 5215 + ", uid=" + Binder.getCallingUid() 5216 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5217 Slog.w(TAG, msg); 5218 throw new SecurityException(msg); 5219 } 5220 5221 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5222 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5223 long callingId = Binder.clearCallingIdentity(); 5224 try { 5225 IPackageManager pm = AppGlobals.getPackageManager(); 5226 synchronized(this) { 5227 int appId = -1; 5228 try { 5229 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5230 } catch (RemoteException e) { 5231 } 5232 if (appId == -1) { 5233 Slog.w(TAG, "Invalid packageName: " + packageName); 5234 return; 5235 } 5236 killPackageProcessesLocked(packageName, appId, userId, 5237 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5238 } 5239 } finally { 5240 Binder.restoreCallingIdentity(callingId); 5241 } 5242 } 5243 5244 @Override 5245 public void killAllBackgroundProcesses() { 5246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5247 != PackageManager.PERMISSION_GRANTED) { 5248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5249 + Binder.getCallingPid() 5250 + ", uid=" + Binder.getCallingUid() 5251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5252 Slog.w(TAG, msg); 5253 throw new SecurityException(msg); 5254 } 5255 5256 long callingId = Binder.clearCallingIdentity(); 5257 try { 5258 synchronized(this) { 5259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5260 final int NP = mProcessNames.getMap().size(); 5261 for (int ip=0; ip<NP; ip++) { 5262 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5263 final int NA = apps.size(); 5264 for (int ia=0; ia<NA; ia++) { 5265 ProcessRecord app = apps.valueAt(ia); 5266 if (app.persistent) { 5267 // we don't kill persistent processes 5268 continue; 5269 } 5270 if (app.removed) { 5271 procs.add(app); 5272 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5273 app.removed = true; 5274 procs.add(app); 5275 } 5276 } 5277 } 5278 5279 int N = procs.size(); 5280 for (int i=0; i<N; i++) { 5281 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5282 } 5283 mAllowLowerMemLevel = true; 5284 updateOomAdjLocked(); 5285 doLowMemReportIfNeededLocked(null); 5286 } 5287 } finally { 5288 Binder.restoreCallingIdentity(callingId); 5289 } 5290 } 5291 5292 @Override 5293 public void forceStopPackage(final String packageName, int userId) { 5294 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5295 != PackageManager.PERMISSION_GRANTED) { 5296 String msg = "Permission Denial: forceStopPackage() from pid=" 5297 + Binder.getCallingPid() 5298 + ", uid=" + Binder.getCallingUid() 5299 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5300 Slog.w(TAG, msg); 5301 throw new SecurityException(msg); 5302 } 5303 final int callingPid = Binder.getCallingPid(); 5304 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5305 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5306 long callingId = Binder.clearCallingIdentity(); 5307 try { 5308 IPackageManager pm = AppGlobals.getPackageManager(); 5309 synchronized(this) { 5310 int[] users = userId == UserHandle.USER_ALL 5311 ? getUsersLocked() : new int[] { userId }; 5312 for (int user : users) { 5313 int pkgUid = -1; 5314 try { 5315 pkgUid = pm.getPackageUid(packageName, user); 5316 } catch (RemoteException e) { 5317 } 5318 if (pkgUid == -1) { 5319 Slog.w(TAG, "Invalid packageName: " + packageName); 5320 continue; 5321 } 5322 try { 5323 pm.setPackageStoppedState(packageName, true, user); 5324 } catch (RemoteException e) { 5325 } catch (IllegalArgumentException e) { 5326 Slog.w(TAG, "Failed trying to unstop package " 5327 + packageName + ": " + e); 5328 } 5329 if (isUserRunningLocked(user, false)) { 5330 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5331 } 5332 } 5333 } 5334 } finally { 5335 Binder.restoreCallingIdentity(callingId); 5336 } 5337 } 5338 5339 @Override 5340 public void addPackageDependency(String packageName) { 5341 synchronized (this) { 5342 int callingPid = Binder.getCallingPid(); 5343 if (callingPid == Process.myPid()) { 5344 // Yeah, um, no. 5345 Slog.w(TAG, "Can't addPackageDependency on system process"); 5346 return; 5347 } 5348 ProcessRecord proc; 5349 synchronized (mPidsSelfLocked) { 5350 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5351 } 5352 if (proc != null) { 5353 if (proc.pkgDeps == null) { 5354 proc.pkgDeps = new ArraySet<String>(1); 5355 } 5356 proc.pkgDeps.add(packageName); 5357 } 5358 } 5359 } 5360 5361 /* 5362 * The pkg name and app id have to be specified. 5363 */ 5364 @Override 5365 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5366 if (pkg == null) { 5367 return; 5368 } 5369 // Make sure the uid is valid. 5370 if (appid < 0) { 5371 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5372 return; 5373 } 5374 int callerUid = Binder.getCallingUid(); 5375 // Only the system server can kill an application 5376 if (callerUid == Process.SYSTEM_UID) { 5377 // Post an aysnc message to kill the application 5378 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5379 msg.arg1 = appid; 5380 msg.arg2 = 0; 5381 Bundle bundle = new Bundle(); 5382 bundle.putString("pkg", pkg); 5383 bundle.putString("reason", reason); 5384 msg.obj = bundle; 5385 mHandler.sendMessage(msg); 5386 } else { 5387 throw new SecurityException(callerUid + " cannot kill pkg: " + 5388 pkg); 5389 } 5390 } 5391 5392 @Override 5393 public void closeSystemDialogs(String reason) { 5394 enforceNotIsolatedCaller("closeSystemDialogs"); 5395 5396 final int pid = Binder.getCallingPid(); 5397 final int uid = Binder.getCallingUid(); 5398 final long origId = Binder.clearCallingIdentity(); 5399 try { 5400 synchronized (this) { 5401 // Only allow this from foreground processes, so that background 5402 // applications can't abuse it to prevent system UI from being shown. 5403 if (uid >= Process.FIRST_APPLICATION_UID) { 5404 ProcessRecord proc; 5405 synchronized (mPidsSelfLocked) { 5406 proc = mPidsSelfLocked.get(pid); 5407 } 5408 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5409 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5410 + " from background process " + proc); 5411 return; 5412 } 5413 } 5414 closeSystemDialogsLocked(reason); 5415 } 5416 } finally { 5417 Binder.restoreCallingIdentity(origId); 5418 } 5419 } 5420 5421 void closeSystemDialogsLocked(String reason) { 5422 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5423 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5424 | Intent.FLAG_RECEIVER_FOREGROUND); 5425 if (reason != null) { 5426 intent.putExtra("reason", reason); 5427 } 5428 mWindowManager.closeSystemDialogs(reason); 5429 5430 mStackSupervisor.closeSystemDialogsLocked(); 5431 5432 broadcastIntentLocked(null, null, intent, null, 5433 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5434 Process.SYSTEM_UID, UserHandle.USER_ALL); 5435 } 5436 5437 @Override 5438 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5439 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5440 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5441 for (int i=pids.length-1; i>=0; i--) { 5442 ProcessRecord proc; 5443 int oomAdj; 5444 synchronized (this) { 5445 synchronized (mPidsSelfLocked) { 5446 proc = mPidsSelfLocked.get(pids[i]); 5447 oomAdj = proc != null ? proc.setAdj : 0; 5448 } 5449 } 5450 infos[i] = new Debug.MemoryInfo(); 5451 Debug.getMemoryInfo(pids[i], infos[i]); 5452 if (proc != null) { 5453 synchronized (this) { 5454 if (proc.thread != null && proc.setAdj == oomAdj) { 5455 // Record this for posterity if the process has been stable. 5456 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5457 infos[i].getTotalUss(), false, proc.pkgList); 5458 } 5459 } 5460 } 5461 } 5462 return infos; 5463 } 5464 5465 @Override 5466 public long[] getProcessPss(int[] pids) { 5467 enforceNotIsolatedCaller("getProcessPss"); 5468 long[] pss = new long[pids.length]; 5469 for (int i=pids.length-1; i>=0; i--) { 5470 ProcessRecord proc; 5471 int oomAdj; 5472 synchronized (this) { 5473 synchronized (mPidsSelfLocked) { 5474 proc = mPidsSelfLocked.get(pids[i]); 5475 oomAdj = proc != null ? proc.setAdj : 0; 5476 } 5477 } 5478 long[] tmpUss = new long[1]; 5479 pss[i] = Debug.getPss(pids[i], tmpUss); 5480 if (proc != null) { 5481 synchronized (this) { 5482 if (proc.thread != null && proc.setAdj == oomAdj) { 5483 // Record this for posterity if the process has been stable. 5484 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5485 } 5486 } 5487 } 5488 } 5489 return pss; 5490 } 5491 5492 @Override 5493 public void killApplicationProcess(String processName, int uid) { 5494 if (processName == null) { 5495 return; 5496 } 5497 5498 int callerUid = Binder.getCallingUid(); 5499 // Only the system server can kill an application 5500 if (callerUid == Process.SYSTEM_UID) { 5501 synchronized (this) { 5502 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5503 if (app != null && app.thread != null) { 5504 try { 5505 app.thread.scheduleSuicide(); 5506 } catch (RemoteException e) { 5507 // If the other end already died, then our work here is done. 5508 } 5509 } else { 5510 Slog.w(TAG, "Process/uid not found attempting kill of " 5511 + processName + " / " + uid); 5512 } 5513 } 5514 } else { 5515 throw new SecurityException(callerUid + " cannot kill app process: " + 5516 processName); 5517 } 5518 } 5519 5520 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5521 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5522 false, true, false, false, UserHandle.getUserId(uid), reason); 5523 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5524 Uri.fromParts("package", packageName, null)); 5525 if (!mProcessesReady) { 5526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5527 | Intent.FLAG_RECEIVER_FOREGROUND); 5528 } 5529 intent.putExtra(Intent.EXTRA_UID, uid); 5530 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5531 broadcastIntentLocked(null, null, intent, 5532 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5533 false, false, 5534 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5535 } 5536 5537 private void forceStopUserLocked(int userId, String reason) { 5538 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5539 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5540 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5541 | Intent.FLAG_RECEIVER_FOREGROUND); 5542 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5543 broadcastIntentLocked(null, null, intent, 5544 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5545 false, false, 5546 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5547 } 5548 5549 private final boolean killPackageProcessesLocked(String packageName, int appId, 5550 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5551 boolean doit, boolean evenPersistent, String reason) { 5552 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5553 5554 // Remove all processes this package may have touched: all with the 5555 // same UID (except for the system or root user), and all whose name 5556 // matches the package name. 5557 final int NP = mProcessNames.getMap().size(); 5558 for (int ip=0; ip<NP; ip++) { 5559 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5560 final int NA = apps.size(); 5561 for (int ia=0; ia<NA; ia++) { 5562 ProcessRecord app = apps.valueAt(ia); 5563 if (app.persistent && !evenPersistent) { 5564 // we don't kill persistent processes 5565 continue; 5566 } 5567 if (app.removed) { 5568 if (doit) { 5569 procs.add(app); 5570 } 5571 continue; 5572 } 5573 5574 // Skip process if it doesn't meet our oom adj requirement. 5575 if (app.setAdj < minOomAdj) { 5576 continue; 5577 } 5578 5579 // If no package is specified, we call all processes under the 5580 // give user id. 5581 if (packageName == null) { 5582 if (app.userId != userId) { 5583 continue; 5584 } 5585 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5586 continue; 5587 } 5588 // Package has been specified, we want to hit all processes 5589 // that match it. We need to qualify this by the processes 5590 // that are running under the specified app and user ID. 5591 } else { 5592 final boolean isDep = app.pkgDeps != null 5593 && app.pkgDeps.contains(packageName); 5594 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5595 continue; 5596 } 5597 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5598 continue; 5599 } 5600 if (!app.pkgList.containsKey(packageName) && !isDep) { 5601 continue; 5602 } 5603 } 5604 5605 // Process has passed all conditions, kill it! 5606 if (!doit) { 5607 return true; 5608 } 5609 app.removed = true; 5610 procs.add(app); 5611 } 5612 } 5613 5614 int N = procs.size(); 5615 for (int i=0; i<N; i++) { 5616 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5617 } 5618 updateOomAdjLocked(); 5619 return N > 0; 5620 } 5621 5622 private final boolean forceStopPackageLocked(String name, int appId, 5623 boolean callerWillRestart, boolean purgeCache, boolean doit, 5624 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5625 int i; 5626 int N; 5627 5628 if (userId == UserHandle.USER_ALL && name == null) { 5629 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5630 } 5631 5632 if (appId < 0 && name != null) { 5633 try { 5634 appId = UserHandle.getAppId( 5635 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5636 } catch (RemoteException e) { 5637 } 5638 } 5639 5640 if (doit) { 5641 if (name != null) { 5642 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5643 + " user=" + userId + ": " + reason); 5644 } else { 5645 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5646 } 5647 5648 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5649 for (int ip=pmap.size()-1; ip>=0; ip--) { 5650 SparseArray<Long> ba = pmap.valueAt(ip); 5651 for (i=ba.size()-1; i>=0; i--) { 5652 boolean remove = false; 5653 final int entUid = ba.keyAt(i); 5654 if (name != null) { 5655 if (userId == UserHandle.USER_ALL) { 5656 if (UserHandle.getAppId(entUid) == appId) { 5657 remove = true; 5658 } 5659 } else { 5660 if (entUid == UserHandle.getUid(userId, appId)) { 5661 remove = true; 5662 } 5663 } 5664 } else if (UserHandle.getUserId(entUid) == userId) { 5665 remove = true; 5666 } 5667 if (remove) { 5668 ba.removeAt(i); 5669 } 5670 } 5671 if (ba.size() == 0) { 5672 pmap.removeAt(ip); 5673 } 5674 } 5675 } 5676 5677 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5678 -100, callerWillRestart, true, doit, evenPersistent, 5679 name == null ? ("stop user " + userId) : ("stop " + name)); 5680 5681 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5682 if (!doit) { 5683 return true; 5684 } 5685 didSomething = true; 5686 } 5687 5688 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5689 if (!doit) { 5690 return true; 5691 } 5692 didSomething = true; 5693 } 5694 5695 if (name == null) { 5696 // Remove all sticky broadcasts from this user. 5697 mStickyBroadcasts.remove(userId); 5698 } 5699 5700 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5701 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5702 userId, providers)) { 5703 if (!doit) { 5704 return true; 5705 } 5706 didSomething = true; 5707 } 5708 N = providers.size(); 5709 for (i=0; i<N; i++) { 5710 removeDyingProviderLocked(null, providers.get(i), true); 5711 } 5712 5713 // Remove transient permissions granted from/to this package/user 5714 removeUriPermissionsForPackageLocked(name, userId, false); 5715 5716 if (name == null || uninstalling) { 5717 // Remove pending intents. For now we only do this when force 5718 // stopping users, because we have some problems when doing this 5719 // for packages -- app widgets are not currently cleaned up for 5720 // such packages, so they can be left with bad pending intents. 5721 if (mIntentSenderRecords.size() > 0) { 5722 Iterator<WeakReference<PendingIntentRecord>> it 5723 = mIntentSenderRecords.values().iterator(); 5724 while (it.hasNext()) { 5725 WeakReference<PendingIntentRecord> wpir = it.next(); 5726 if (wpir == null) { 5727 it.remove(); 5728 continue; 5729 } 5730 PendingIntentRecord pir = wpir.get(); 5731 if (pir == null) { 5732 it.remove(); 5733 continue; 5734 } 5735 if (name == null) { 5736 // Stopping user, remove all objects for the user. 5737 if (pir.key.userId != userId) { 5738 // Not the same user, skip it. 5739 continue; 5740 } 5741 } else { 5742 if (UserHandle.getAppId(pir.uid) != appId) { 5743 // Different app id, skip it. 5744 continue; 5745 } 5746 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5747 // Different user, skip it. 5748 continue; 5749 } 5750 if (!pir.key.packageName.equals(name)) { 5751 // Different package, skip it. 5752 continue; 5753 } 5754 } 5755 if (!doit) { 5756 return true; 5757 } 5758 didSomething = true; 5759 it.remove(); 5760 pir.canceled = true; 5761 if (pir.key.activity != null) { 5762 pir.key.activity.pendingResults.remove(pir.ref); 5763 } 5764 } 5765 } 5766 } 5767 5768 if (doit) { 5769 if (purgeCache && name != null) { 5770 AttributeCache ac = AttributeCache.instance(); 5771 if (ac != null) { 5772 ac.removePackage(name); 5773 } 5774 } 5775 if (mBooted) { 5776 mStackSupervisor.resumeTopActivitiesLocked(); 5777 mStackSupervisor.scheduleIdleLocked(); 5778 } 5779 } 5780 5781 return didSomething; 5782 } 5783 5784 private final boolean removeProcessLocked(ProcessRecord app, 5785 boolean callerWillRestart, boolean allowRestart, String reason) { 5786 final String name = app.processName; 5787 final int uid = app.uid; 5788 if (DEBUG_PROCESSES) Slog.d( 5789 TAG, "Force removing proc " + app.toShortString() + " (" + name 5790 + "/" + uid + ")"); 5791 5792 mProcessNames.remove(name, uid); 5793 mIsolatedProcesses.remove(app.uid); 5794 if (mHeavyWeightProcess == app) { 5795 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5796 mHeavyWeightProcess.userId, 0)); 5797 mHeavyWeightProcess = null; 5798 } 5799 boolean needRestart = false; 5800 if (app.pid > 0 && app.pid != MY_PID) { 5801 int pid = app.pid; 5802 synchronized (mPidsSelfLocked) { 5803 mPidsSelfLocked.remove(pid); 5804 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5805 } 5806 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5807 if (app.isolated) { 5808 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5809 } 5810 app.kill(reason, true); 5811 handleAppDiedLocked(app, true, allowRestart); 5812 removeLruProcessLocked(app); 5813 5814 if (app.persistent && !app.isolated) { 5815 if (!callerWillRestart) { 5816 addAppLocked(app.info, false, null /* ABI override */); 5817 } else { 5818 needRestart = true; 5819 } 5820 } 5821 } else { 5822 mRemovedProcesses.add(app); 5823 } 5824 5825 return needRestart; 5826 } 5827 5828 private final void processStartTimedOutLocked(ProcessRecord app) { 5829 final int pid = app.pid; 5830 boolean gone = false; 5831 synchronized (mPidsSelfLocked) { 5832 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5833 if (knownApp != null && knownApp.thread == null) { 5834 mPidsSelfLocked.remove(pid); 5835 gone = true; 5836 } 5837 } 5838 5839 if (gone) { 5840 Slog.w(TAG, "Process " + app + " failed to attach"); 5841 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5842 pid, app.uid, app.processName); 5843 mProcessNames.remove(app.processName, app.uid); 5844 mIsolatedProcesses.remove(app.uid); 5845 if (mHeavyWeightProcess == app) { 5846 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5847 mHeavyWeightProcess.userId, 0)); 5848 mHeavyWeightProcess = null; 5849 } 5850 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5851 if (app.isolated) { 5852 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5853 } 5854 // Take care of any launching providers waiting for this process. 5855 checkAppInLaunchingProvidersLocked(app, true); 5856 // Take care of any services that are waiting for the process. 5857 mServices.processStartTimedOutLocked(app); 5858 app.kill("start timeout", true); 5859 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5860 Slog.w(TAG, "Unattached app died before backup, skipping"); 5861 try { 5862 IBackupManager bm = IBackupManager.Stub.asInterface( 5863 ServiceManager.getService(Context.BACKUP_SERVICE)); 5864 bm.agentDisconnected(app.info.packageName); 5865 } catch (RemoteException e) { 5866 // Can't happen; the backup manager is local 5867 } 5868 } 5869 if (isPendingBroadcastProcessLocked(pid)) { 5870 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5871 skipPendingBroadcastLocked(pid); 5872 } 5873 } else { 5874 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5875 } 5876 } 5877 5878 private final boolean attachApplicationLocked(IApplicationThread thread, 5879 int pid) { 5880 5881 // Find the application record that is being attached... either via 5882 // the pid if we are running in multiple processes, or just pull the 5883 // next app record if we are emulating process with anonymous threads. 5884 ProcessRecord app; 5885 if (pid != MY_PID && pid >= 0) { 5886 synchronized (mPidsSelfLocked) { 5887 app = mPidsSelfLocked.get(pid); 5888 } 5889 } else { 5890 app = null; 5891 } 5892 5893 if (app == null) { 5894 Slog.w(TAG, "No pending application record for pid " + pid 5895 + " (IApplicationThread " + thread + "); dropping process"); 5896 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5897 if (pid > 0 && pid != MY_PID) { 5898 Process.killProcessQuiet(pid); 5899 //TODO: Process.killProcessGroup(app.info.uid, pid); 5900 } else { 5901 try { 5902 thread.scheduleExit(); 5903 } catch (Exception e) { 5904 // Ignore exceptions. 5905 } 5906 } 5907 return false; 5908 } 5909 5910 // If this application record is still attached to a previous 5911 // process, clean it up now. 5912 if (app.thread != null) { 5913 handleAppDiedLocked(app, true, true); 5914 } 5915 5916 // Tell the process all about itself. 5917 5918 if (localLOGV) Slog.v( 5919 TAG, "Binding process pid " + pid + " to record " + app); 5920 5921 final String processName = app.processName; 5922 try { 5923 AppDeathRecipient adr = new AppDeathRecipient( 5924 app, pid, thread); 5925 thread.asBinder().linkToDeath(adr, 0); 5926 app.deathRecipient = adr; 5927 } catch (RemoteException e) { 5928 app.resetPackageList(mProcessStats); 5929 startProcessLocked(app, "link fail", processName); 5930 return false; 5931 } 5932 5933 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5934 5935 app.makeActive(thread, mProcessStats); 5936 app.curAdj = app.setAdj = -100; 5937 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5938 app.forcingToForeground = null; 5939 updateProcessForegroundLocked(app, false, false); 5940 app.hasShownUi = false; 5941 app.debugging = false; 5942 app.cached = false; 5943 5944 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5945 5946 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5947 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5948 5949 if (!normalMode) { 5950 Slog.i(TAG, "Launching preboot mode app: " + app); 5951 } 5952 5953 if (localLOGV) Slog.v( 5954 TAG, "New app record " + app 5955 + " thread=" + thread.asBinder() + " pid=" + pid); 5956 try { 5957 int testMode = IApplicationThread.DEBUG_OFF; 5958 if (mDebugApp != null && mDebugApp.equals(processName)) { 5959 testMode = mWaitForDebugger 5960 ? IApplicationThread.DEBUG_WAIT 5961 : IApplicationThread.DEBUG_ON; 5962 app.debugging = true; 5963 if (mDebugTransient) { 5964 mDebugApp = mOrigDebugApp; 5965 mWaitForDebugger = mOrigWaitForDebugger; 5966 } 5967 } 5968 String profileFile = app.instrumentationProfileFile; 5969 ParcelFileDescriptor profileFd = null; 5970 int samplingInterval = 0; 5971 boolean profileAutoStop = false; 5972 if (mProfileApp != null && mProfileApp.equals(processName)) { 5973 mProfileProc = app; 5974 profileFile = mProfileFile; 5975 profileFd = mProfileFd; 5976 samplingInterval = mSamplingInterval; 5977 profileAutoStop = mAutoStopProfiler; 5978 } 5979 boolean enableOpenGlTrace = false; 5980 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5981 enableOpenGlTrace = true; 5982 mOpenGlTraceApp = null; 5983 } 5984 5985 // If the app is being launched for restore or full backup, set it up specially 5986 boolean isRestrictedBackupMode = false; 5987 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5988 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5989 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5990 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5991 } 5992 5993 ensurePackageDexOpt(app.instrumentationInfo != null 5994 ? app.instrumentationInfo.packageName 5995 : app.info.packageName); 5996 if (app.instrumentationClass != null) { 5997 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5998 } 5999 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6000 + processName + " with config " + mConfiguration); 6001 ApplicationInfo appInfo = app.instrumentationInfo != null 6002 ? app.instrumentationInfo : app.info; 6003 app.compat = compatibilityInfoForPackageLocked(appInfo); 6004 if (profileFd != null) { 6005 profileFd = profileFd.dup(); 6006 } 6007 ProfilerInfo profilerInfo = profileFile == null ? null 6008 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6009 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6010 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6011 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6012 isRestrictedBackupMode || !normalMode, app.persistent, 6013 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6014 mCoreSettingsObserver.getCoreSettingsLocked()); 6015 updateLruProcessLocked(app, false, null); 6016 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6017 } catch (Exception e) { 6018 // todo: Yikes! What should we do? For now we will try to 6019 // start another process, but that could easily get us in 6020 // an infinite loop of restarting processes... 6021 Slog.w(TAG, "Exception thrown during bind!", e); 6022 6023 app.resetPackageList(mProcessStats); 6024 app.unlinkDeathRecipient(); 6025 startProcessLocked(app, "bind fail", processName); 6026 return false; 6027 } 6028 6029 // Remove this record from the list of starting applications. 6030 mPersistentStartingProcesses.remove(app); 6031 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6032 "Attach application locked removing on hold: " + app); 6033 mProcessesOnHold.remove(app); 6034 6035 boolean badApp = false; 6036 boolean didSomething = false; 6037 6038 // See if the top visible activity is waiting to run in this process... 6039 if (normalMode) { 6040 try { 6041 if (mStackSupervisor.attachApplicationLocked(app)) { 6042 didSomething = true; 6043 } 6044 } catch (Exception e) { 6045 badApp = true; 6046 } 6047 } 6048 6049 // Find any services that should be running in this process... 6050 if (!badApp) { 6051 try { 6052 didSomething |= mServices.attachApplicationLocked(app, processName); 6053 } catch (Exception e) { 6054 badApp = true; 6055 } 6056 } 6057 6058 // Check if a next-broadcast receiver is in this process... 6059 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6060 try { 6061 didSomething |= sendPendingBroadcastsLocked(app); 6062 } catch (Exception e) { 6063 // If the app died trying to launch the receiver we declare it 'bad' 6064 badApp = true; 6065 } 6066 } 6067 6068 // Check whether the next backup agent is in this process... 6069 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6070 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6071 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6072 try { 6073 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6074 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6075 mBackupTarget.backupMode); 6076 } catch (Exception e) { 6077 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6078 e.printStackTrace(); 6079 } 6080 } 6081 6082 if (badApp) { 6083 // todo: Also need to kill application to deal with all 6084 // kinds of exceptions. 6085 handleAppDiedLocked(app, false, true); 6086 return false; 6087 } 6088 6089 if (!didSomething) { 6090 updateOomAdjLocked(); 6091 } 6092 6093 return true; 6094 } 6095 6096 @Override 6097 public final void attachApplication(IApplicationThread thread) { 6098 synchronized (this) { 6099 int callingPid = Binder.getCallingPid(); 6100 final long origId = Binder.clearCallingIdentity(); 6101 attachApplicationLocked(thread, callingPid); 6102 Binder.restoreCallingIdentity(origId); 6103 } 6104 } 6105 6106 @Override 6107 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6108 final long origId = Binder.clearCallingIdentity(); 6109 synchronized (this) { 6110 ActivityStack stack = ActivityRecord.getStackLocked(token); 6111 if (stack != null) { 6112 ActivityRecord r = 6113 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6114 if (stopProfiling) { 6115 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6116 try { 6117 mProfileFd.close(); 6118 } catch (IOException e) { 6119 } 6120 clearProfilerLocked(); 6121 } 6122 } 6123 } 6124 } 6125 Binder.restoreCallingIdentity(origId); 6126 } 6127 6128 void postEnableScreenAfterBootLocked() { 6129 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6130 } 6131 6132 void enableScreenAfterBoot() { 6133 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6134 SystemClock.uptimeMillis()); 6135 mWindowManager.enableScreenAfterBoot(); 6136 6137 synchronized (this) { 6138 updateEventDispatchingLocked(); 6139 } 6140 } 6141 6142 @Override 6143 public void showBootMessage(final CharSequence msg, final boolean always) { 6144 enforceNotIsolatedCaller("showBootMessage"); 6145 mWindowManager.showBootMessage(msg, always); 6146 } 6147 6148 @Override 6149 public void keyguardWaitingForActivityDrawn() { 6150 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6151 final long token = Binder.clearCallingIdentity(); 6152 try { 6153 synchronized (this) { 6154 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6155 mWindowManager.keyguardWaitingForActivityDrawn(); 6156 } 6157 } finally { 6158 Binder.restoreCallingIdentity(token); 6159 } 6160 } 6161 6162 final void finishBooting() { 6163 // Register receivers to handle package update events 6164 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6165 6166 // Let system services know. 6167 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6168 6169 synchronized (this) { 6170 // Ensure that any processes we had put on hold are now started 6171 // up. 6172 final int NP = mProcessesOnHold.size(); 6173 if (NP > 0) { 6174 ArrayList<ProcessRecord> procs = 6175 new ArrayList<ProcessRecord>(mProcessesOnHold); 6176 for (int ip=0; ip<NP; ip++) { 6177 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6178 + procs.get(ip)); 6179 startProcessLocked(procs.get(ip), "on-hold", null); 6180 } 6181 } 6182 6183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6184 // Start looking for apps that are abusing wake locks. 6185 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6186 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6187 // Tell anyone interested that we are done booting! 6188 SystemProperties.set("sys.boot_completed", "1"); 6189 SystemProperties.set("dev.bootcomplete", "1"); 6190 for (int i=0; i<mStartedUsers.size(); i++) { 6191 UserStartedState uss = mStartedUsers.valueAt(i); 6192 if (uss.mState == UserStartedState.STATE_BOOTING) { 6193 uss.mState = UserStartedState.STATE_RUNNING; 6194 final int userId = mStartedUsers.keyAt(i); 6195 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6196 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6197 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6198 broadcastIntentLocked(null, null, intent, null, 6199 new IIntentReceiver.Stub() { 6200 @Override 6201 public void performReceive(Intent intent, int resultCode, 6202 String data, Bundle extras, boolean ordered, 6203 boolean sticky, int sendingUser) { 6204 synchronized (ActivityManagerService.this) { 6205 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6206 true, false); 6207 } 6208 } 6209 }, 6210 0, null, null, 6211 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6212 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6213 userId); 6214 } 6215 } 6216 scheduleStartProfilesLocked(); 6217 } 6218 } 6219 } 6220 6221 final void ensureBootCompleted() { 6222 boolean booting; 6223 boolean enableScreen; 6224 synchronized (this) { 6225 booting = mBooting; 6226 mBooting = false; 6227 enableScreen = !mBooted; 6228 mBooted = true; 6229 } 6230 6231 if (booting) { 6232 finishBooting(); 6233 } 6234 6235 if (enableScreen) { 6236 enableScreenAfterBoot(); 6237 } 6238 } 6239 6240 @Override 6241 public final void activityResumed(IBinder token) { 6242 final long origId = Binder.clearCallingIdentity(); 6243 synchronized(this) { 6244 ActivityStack stack = ActivityRecord.getStackLocked(token); 6245 if (stack != null) { 6246 ActivityRecord.activityResumedLocked(token); 6247 } 6248 } 6249 Binder.restoreCallingIdentity(origId); 6250 } 6251 6252 @Override 6253 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6254 final long origId = Binder.clearCallingIdentity(); 6255 synchronized(this) { 6256 ActivityStack stack = ActivityRecord.getStackLocked(token); 6257 if (stack != null) { 6258 stack.activityPausedLocked(token, false, persistentState); 6259 } 6260 } 6261 Binder.restoreCallingIdentity(origId); 6262 } 6263 6264 @Override 6265 public final void activityStopped(IBinder token, Bundle icicle, 6266 PersistableBundle persistentState, CharSequence description) { 6267 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6268 6269 // Refuse possible leaked file descriptors 6270 if (icicle != null && icicle.hasFileDescriptors()) { 6271 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6272 } 6273 6274 final long origId = Binder.clearCallingIdentity(); 6275 6276 synchronized (this) { 6277 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6278 if (r != null) { 6279 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6280 } 6281 } 6282 6283 trimApplications(); 6284 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 @Override 6289 public final void activityDestroyed(IBinder token) { 6290 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6291 synchronized (this) { 6292 ActivityStack stack = ActivityRecord.getStackLocked(token); 6293 if (stack != null) { 6294 stack.activityDestroyedLocked(token); 6295 } 6296 } 6297 } 6298 6299 @Override 6300 public final void backgroundResourcesReleased(IBinder token) { 6301 final long origId = Binder.clearCallingIdentity(); 6302 try { 6303 synchronized (this) { 6304 ActivityStack stack = ActivityRecord.getStackLocked(token); 6305 if (stack != null) { 6306 stack.backgroundResourcesReleased(token); 6307 } 6308 } 6309 } finally { 6310 Binder.restoreCallingIdentity(origId); 6311 } 6312 } 6313 6314 @Override 6315 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6316 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6317 } 6318 6319 @Override 6320 public final void notifyEnterAnimationComplete(IBinder token) { 6321 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6322 } 6323 6324 @Override 6325 public String getCallingPackage(IBinder token) { 6326 synchronized (this) { 6327 ActivityRecord r = getCallingRecordLocked(token); 6328 return r != null ? r.info.packageName : null; 6329 } 6330 } 6331 6332 @Override 6333 public ComponentName getCallingActivity(IBinder token) { 6334 synchronized (this) { 6335 ActivityRecord r = getCallingRecordLocked(token); 6336 return r != null ? r.intent.getComponent() : null; 6337 } 6338 } 6339 6340 private ActivityRecord getCallingRecordLocked(IBinder token) { 6341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6342 if (r == null) { 6343 return null; 6344 } 6345 return r.resultTo; 6346 } 6347 6348 @Override 6349 public ComponentName getActivityClassForToken(IBinder token) { 6350 synchronized(this) { 6351 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6352 if (r == null) { 6353 return null; 6354 } 6355 return r.intent.getComponent(); 6356 } 6357 } 6358 6359 @Override 6360 public String getPackageForToken(IBinder token) { 6361 synchronized(this) { 6362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6363 if (r == null) { 6364 return null; 6365 } 6366 return r.packageName; 6367 } 6368 } 6369 6370 @Override 6371 public IIntentSender getIntentSender(int type, 6372 String packageName, IBinder token, String resultWho, 6373 int requestCode, Intent[] intents, String[] resolvedTypes, 6374 int flags, Bundle options, int userId) { 6375 enforceNotIsolatedCaller("getIntentSender"); 6376 // Refuse possible leaked file descriptors 6377 if (intents != null) { 6378 if (intents.length < 1) { 6379 throw new IllegalArgumentException("Intents array length must be >= 1"); 6380 } 6381 for (int i=0; i<intents.length; i++) { 6382 Intent intent = intents[i]; 6383 if (intent != null) { 6384 if (intent.hasFileDescriptors()) { 6385 throw new IllegalArgumentException("File descriptors passed in Intent"); 6386 } 6387 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6388 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6389 throw new IllegalArgumentException( 6390 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6391 } 6392 intents[i] = new Intent(intent); 6393 } 6394 } 6395 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6396 throw new IllegalArgumentException( 6397 "Intent array length does not match resolvedTypes length"); 6398 } 6399 } 6400 if (options != null) { 6401 if (options.hasFileDescriptors()) { 6402 throw new IllegalArgumentException("File descriptors passed in options"); 6403 } 6404 } 6405 6406 synchronized(this) { 6407 int callingUid = Binder.getCallingUid(); 6408 int origUserId = userId; 6409 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6410 type == ActivityManager.INTENT_SENDER_BROADCAST, 6411 ALLOW_NON_FULL, "getIntentSender", null); 6412 if (origUserId == UserHandle.USER_CURRENT) { 6413 // We don't want to evaluate this until the pending intent is 6414 // actually executed. However, we do want to always do the 6415 // security checking for it above. 6416 userId = UserHandle.USER_CURRENT; 6417 } 6418 try { 6419 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6420 int uid = AppGlobals.getPackageManager() 6421 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6422 if (!UserHandle.isSameApp(callingUid, uid)) { 6423 String msg = "Permission Denial: getIntentSender() from pid=" 6424 + Binder.getCallingPid() 6425 + ", uid=" + Binder.getCallingUid() 6426 + ", (need uid=" + uid + ")" 6427 + " is not allowed to send as package " + packageName; 6428 Slog.w(TAG, msg); 6429 throw new SecurityException(msg); 6430 } 6431 } 6432 6433 return getIntentSenderLocked(type, packageName, callingUid, userId, 6434 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6435 6436 } catch (RemoteException e) { 6437 throw new SecurityException(e); 6438 } 6439 } 6440 } 6441 6442 IIntentSender getIntentSenderLocked(int type, String packageName, 6443 int callingUid, int userId, IBinder token, String resultWho, 6444 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6445 Bundle options) { 6446 if (DEBUG_MU) 6447 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6448 ActivityRecord activity = null; 6449 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6450 activity = ActivityRecord.isInStackLocked(token); 6451 if (activity == null) { 6452 return null; 6453 } 6454 if (activity.finishing) { 6455 return null; 6456 } 6457 } 6458 6459 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6460 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6461 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6462 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6463 |PendingIntent.FLAG_UPDATE_CURRENT); 6464 6465 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6466 type, packageName, activity, resultWho, 6467 requestCode, intents, resolvedTypes, flags, options, userId); 6468 WeakReference<PendingIntentRecord> ref; 6469 ref = mIntentSenderRecords.get(key); 6470 PendingIntentRecord rec = ref != null ? ref.get() : null; 6471 if (rec != null) { 6472 if (!cancelCurrent) { 6473 if (updateCurrent) { 6474 if (rec.key.requestIntent != null) { 6475 rec.key.requestIntent.replaceExtras(intents != null ? 6476 intents[intents.length - 1] : null); 6477 } 6478 if (intents != null) { 6479 intents[intents.length-1] = rec.key.requestIntent; 6480 rec.key.allIntents = intents; 6481 rec.key.allResolvedTypes = resolvedTypes; 6482 } else { 6483 rec.key.allIntents = null; 6484 rec.key.allResolvedTypes = null; 6485 } 6486 } 6487 return rec; 6488 } 6489 rec.canceled = true; 6490 mIntentSenderRecords.remove(key); 6491 } 6492 if (noCreate) { 6493 return rec; 6494 } 6495 rec = new PendingIntentRecord(this, key, callingUid); 6496 mIntentSenderRecords.put(key, rec.ref); 6497 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6498 if (activity.pendingResults == null) { 6499 activity.pendingResults 6500 = new HashSet<WeakReference<PendingIntentRecord>>(); 6501 } 6502 activity.pendingResults.add(rec.ref); 6503 } 6504 return rec; 6505 } 6506 6507 @Override 6508 public void cancelIntentSender(IIntentSender sender) { 6509 if (!(sender instanceof PendingIntentRecord)) { 6510 return; 6511 } 6512 synchronized(this) { 6513 PendingIntentRecord rec = (PendingIntentRecord)sender; 6514 try { 6515 int uid = AppGlobals.getPackageManager() 6516 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6517 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6518 String msg = "Permission Denial: cancelIntentSender() from pid=" 6519 + Binder.getCallingPid() 6520 + ", uid=" + Binder.getCallingUid() 6521 + " is not allowed to cancel packges " 6522 + rec.key.packageName; 6523 Slog.w(TAG, msg); 6524 throw new SecurityException(msg); 6525 } 6526 } catch (RemoteException e) { 6527 throw new SecurityException(e); 6528 } 6529 cancelIntentSenderLocked(rec, true); 6530 } 6531 } 6532 6533 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6534 rec.canceled = true; 6535 mIntentSenderRecords.remove(rec.key); 6536 if (cleanActivity && rec.key.activity != null) { 6537 rec.key.activity.pendingResults.remove(rec.ref); 6538 } 6539 } 6540 6541 @Override 6542 public String getPackageForIntentSender(IIntentSender pendingResult) { 6543 if (!(pendingResult instanceof PendingIntentRecord)) { 6544 return null; 6545 } 6546 try { 6547 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6548 return res.key.packageName; 6549 } catch (ClassCastException e) { 6550 } 6551 return null; 6552 } 6553 6554 @Override 6555 public int getUidForIntentSender(IIntentSender sender) { 6556 if (sender instanceof PendingIntentRecord) { 6557 try { 6558 PendingIntentRecord res = (PendingIntentRecord)sender; 6559 return res.uid; 6560 } catch (ClassCastException e) { 6561 } 6562 } 6563 return -1; 6564 } 6565 6566 @Override 6567 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6568 if (!(pendingResult instanceof PendingIntentRecord)) { 6569 return false; 6570 } 6571 try { 6572 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6573 if (res.key.allIntents == null) { 6574 return false; 6575 } 6576 for (int i=0; i<res.key.allIntents.length; i++) { 6577 Intent intent = res.key.allIntents[i]; 6578 if (intent.getPackage() != null && intent.getComponent() != null) { 6579 return false; 6580 } 6581 } 6582 return true; 6583 } catch (ClassCastException e) { 6584 } 6585 return false; 6586 } 6587 6588 @Override 6589 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6590 if (!(pendingResult instanceof PendingIntentRecord)) { 6591 return false; 6592 } 6593 try { 6594 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6595 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6596 return true; 6597 } 6598 return false; 6599 } catch (ClassCastException e) { 6600 } 6601 return false; 6602 } 6603 6604 @Override 6605 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6606 if (!(pendingResult instanceof PendingIntentRecord)) { 6607 return null; 6608 } 6609 try { 6610 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6611 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6612 } catch (ClassCastException e) { 6613 } 6614 return null; 6615 } 6616 6617 @Override 6618 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6619 if (!(pendingResult instanceof PendingIntentRecord)) { 6620 return null; 6621 } 6622 try { 6623 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6624 Intent intent = res.key.requestIntent; 6625 if (intent != null) { 6626 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6627 || res.lastTagPrefix.equals(prefix))) { 6628 return res.lastTag; 6629 } 6630 res.lastTagPrefix = prefix; 6631 StringBuilder sb = new StringBuilder(128); 6632 if (prefix != null) { 6633 sb.append(prefix); 6634 } 6635 if (intent.getAction() != null) { 6636 sb.append(intent.getAction()); 6637 } else if (intent.getComponent() != null) { 6638 intent.getComponent().appendShortString(sb); 6639 } else { 6640 sb.append("?"); 6641 } 6642 return res.lastTag = sb.toString(); 6643 } 6644 } catch (ClassCastException e) { 6645 } 6646 return null; 6647 } 6648 6649 @Override 6650 public void setProcessLimit(int max) { 6651 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6652 "setProcessLimit()"); 6653 synchronized (this) { 6654 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6655 mProcessLimitOverride = max; 6656 } 6657 trimApplications(); 6658 } 6659 6660 @Override 6661 public int getProcessLimit() { 6662 synchronized (this) { 6663 return mProcessLimitOverride; 6664 } 6665 } 6666 6667 void foregroundTokenDied(ForegroundToken token) { 6668 synchronized (ActivityManagerService.this) { 6669 synchronized (mPidsSelfLocked) { 6670 ForegroundToken cur 6671 = mForegroundProcesses.get(token.pid); 6672 if (cur != token) { 6673 return; 6674 } 6675 mForegroundProcesses.remove(token.pid); 6676 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6677 if (pr == null) { 6678 return; 6679 } 6680 pr.forcingToForeground = null; 6681 updateProcessForegroundLocked(pr, false, false); 6682 } 6683 updateOomAdjLocked(); 6684 } 6685 } 6686 6687 @Override 6688 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6689 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6690 "setProcessForeground()"); 6691 synchronized(this) { 6692 boolean changed = false; 6693 6694 synchronized (mPidsSelfLocked) { 6695 ProcessRecord pr = mPidsSelfLocked.get(pid); 6696 if (pr == null && isForeground) { 6697 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6698 return; 6699 } 6700 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6701 if (oldToken != null) { 6702 oldToken.token.unlinkToDeath(oldToken, 0); 6703 mForegroundProcesses.remove(pid); 6704 if (pr != null) { 6705 pr.forcingToForeground = null; 6706 } 6707 changed = true; 6708 } 6709 if (isForeground && token != null) { 6710 ForegroundToken newToken = new ForegroundToken() { 6711 @Override 6712 public void binderDied() { 6713 foregroundTokenDied(this); 6714 } 6715 }; 6716 newToken.pid = pid; 6717 newToken.token = token; 6718 try { 6719 token.linkToDeath(newToken, 0); 6720 mForegroundProcesses.put(pid, newToken); 6721 pr.forcingToForeground = token; 6722 changed = true; 6723 } catch (RemoteException e) { 6724 // If the process died while doing this, we will later 6725 // do the cleanup with the process death link. 6726 } 6727 } 6728 } 6729 6730 if (changed) { 6731 updateOomAdjLocked(); 6732 } 6733 } 6734 } 6735 6736 // ========================================================= 6737 // PERMISSIONS 6738 // ========================================================= 6739 6740 static class PermissionController extends IPermissionController.Stub { 6741 ActivityManagerService mActivityManagerService; 6742 PermissionController(ActivityManagerService activityManagerService) { 6743 mActivityManagerService = activityManagerService; 6744 } 6745 6746 @Override 6747 public boolean checkPermission(String permission, int pid, int uid) { 6748 return mActivityManagerService.checkPermission(permission, pid, 6749 uid) == PackageManager.PERMISSION_GRANTED; 6750 } 6751 } 6752 6753 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6754 @Override 6755 public int checkComponentPermission(String permission, int pid, int uid, 6756 int owningUid, boolean exported) { 6757 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6758 owningUid, exported); 6759 } 6760 6761 @Override 6762 public Object getAMSLock() { 6763 return ActivityManagerService.this; 6764 } 6765 } 6766 6767 /** 6768 * This can be called with or without the global lock held. 6769 */ 6770 int checkComponentPermission(String permission, int pid, int uid, 6771 int owningUid, boolean exported) { 6772 // We might be performing an operation on behalf of an indirect binder 6773 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6774 // client identity accordingly before proceeding. 6775 Identity tlsIdentity = sCallerIdentity.get(); 6776 if (tlsIdentity != null) { 6777 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6778 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6779 uid = tlsIdentity.uid; 6780 pid = tlsIdentity.pid; 6781 } 6782 6783 if (pid == MY_PID) { 6784 return PackageManager.PERMISSION_GRANTED; 6785 } 6786 6787 return ActivityManager.checkComponentPermission(permission, uid, 6788 owningUid, exported); 6789 } 6790 6791 /** 6792 * As the only public entry point for permissions checking, this method 6793 * can enforce the semantic that requesting a check on a null global 6794 * permission is automatically denied. (Internally a null permission 6795 * string is used when calling {@link #checkComponentPermission} in cases 6796 * when only uid-based security is needed.) 6797 * 6798 * This can be called with or without the global lock held. 6799 */ 6800 @Override 6801 public int checkPermission(String permission, int pid, int uid) { 6802 if (permission == null) { 6803 return PackageManager.PERMISSION_DENIED; 6804 } 6805 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6806 } 6807 6808 /** 6809 * Binder IPC calls go through the public entry point. 6810 * This can be called with or without the global lock held. 6811 */ 6812 int checkCallingPermission(String permission) { 6813 return checkPermission(permission, 6814 Binder.getCallingPid(), 6815 UserHandle.getAppId(Binder.getCallingUid())); 6816 } 6817 6818 /** 6819 * This can be called with or without the global lock held. 6820 */ 6821 void enforceCallingPermission(String permission, String func) { 6822 if (checkCallingPermission(permission) 6823 == PackageManager.PERMISSION_GRANTED) { 6824 return; 6825 } 6826 6827 String msg = "Permission Denial: " + func + " from pid=" 6828 + Binder.getCallingPid() 6829 + ", uid=" + Binder.getCallingUid() 6830 + " requires " + permission; 6831 Slog.w(TAG, msg); 6832 throw new SecurityException(msg); 6833 } 6834 6835 /** 6836 * Determine if UID is holding permissions required to access {@link Uri} in 6837 * the given {@link ProviderInfo}. Final permission checking is always done 6838 * in {@link ContentProvider}. 6839 */ 6840 private final boolean checkHoldingPermissionsLocked( 6841 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6842 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6843 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6844 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6845 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6846 != PERMISSION_GRANTED) { 6847 return false; 6848 } 6849 } 6850 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6851 } 6852 6853 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6854 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6855 if (pi.applicationInfo.uid == uid) { 6856 return true; 6857 } else if (!pi.exported) { 6858 return false; 6859 } 6860 6861 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6862 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6863 try { 6864 // check if target holds top-level <provider> permissions 6865 if (!readMet && pi.readPermission != null && considerUidPermissions 6866 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6867 readMet = true; 6868 } 6869 if (!writeMet && pi.writePermission != null && considerUidPermissions 6870 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6871 writeMet = true; 6872 } 6873 6874 // track if unprotected read/write is allowed; any denied 6875 // <path-permission> below removes this ability 6876 boolean allowDefaultRead = pi.readPermission == null; 6877 boolean allowDefaultWrite = pi.writePermission == null; 6878 6879 // check if target holds any <path-permission> that match uri 6880 final PathPermission[] pps = pi.pathPermissions; 6881 if (pps != null) { 6882 final String path = grantUri.uri.getPath(); 6883 int i = pps.length; 6884 while (i > 0 && (!readMet || !writeMet)) { 6885 i--; 6886 PathPermission pp = pps[i]; 6887 if (pp.match(path)) { 6888 if (!readMet) { 6889 final String pprperm = pp.getReadPermission(); 6890 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6891 + pprperm + " for " + pp.getPath() 6892 + ": match=" + pp.match(path) 6893 + " check=" + pm.checkUidPermission(pprperm, uid)); 6894 if (pprperm != null) { 6895 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6896 == PERMISSION_GRANTED) { 6897 readMet = true; 6898 } else { 6899 allowDefaultRead = false; 6900 } 6901 } 6902 } 6903 if (!writeMet) { 6904 final String ppwperm = pp.getWritePermission(); 6905 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6906 + ppwperm + " for " + pp.getPath() 6907 + ": match=" + pp.match(path) 6908 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6909 if (ppwperm != null) { 6910 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6911 == PERMISSION_GRANTED) { 6912 writeMet = true; 6913 } else { 6914 allowDefaultWrite = false; 6915 } 6916 } 6917 } 6918 } 6919 } 6920 } 6921 6922 // grant unprotected <provider> read/write, if not blocked by 6923 // <path-permission> above 6924 if (allowDefaultRead) readMet = true; 6925 if (allowDefaultWrite) writeMet = true; 6926 6927 } catch (RemoteException e) { 6928 return false; 6929 } 6930 6931 return readMet && writeMet; 6932 } 6933 6934 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6935 ProviderInfo pi = null; 6936 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6937 if (cpr != null) { 6938 pi = cpr.info; 6939 } else { 6940 try { 6941 pi = AppGlobals.getPackageManager().resolveContentProvider( 6942 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6943 } catch (RemoteException ex) { 6944 } 6945 } 6946 return pi; 6947 } 6948 6949 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6950 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6951 if (targetUris != null) { 6952 return targetUris.get(grantUri); 6953 } 6954 return null; 6955 } 6956 6957 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6958 String targetPkg, int targetUid, GrantUri grantUri) { 6959 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6960 if (targetUris == null) { 6961 targetUris = Maps.newArrayMap(); 6962 mGrantedUriPermissions.put(targetUid, targetUris); 6963 } 6964 6965 UriPermission perm = targetUris.get(grantUri); 6966 if (perm == null) { 6967 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6968 targetUris.put(grantUri, perm); 6969 } 6970 6971 return perm; 6972 } 6973 6974 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6975 final int modeFlags) { 6976 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6977 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6978 : UriPermission.STRENGTH_OWNED; 6979 6980 // Root gets to do everything. 6981 if (uid == 0) { 6982 return true; 6983 } 6984 6985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6986 if (perms == null) return false; 6987 6988 // First look for exact match 6989 final UriPermission exactPerm = perms.get(grantUri); 6990 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6991 return true; 6992 } 6993 6994 // No exact match, look for prefixes 6995 final int N = perms.size(); 6996 for (int i = 0; i < N; i++) { 6997 final UriPermission perm = perms.valueAt(i); 6998 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6999 && perm.getStrength(modeFlags) >= minStrength) { 7000 return true; 7001 } 7002 } 7003 7004 return false; 7005 } 7006 7007 /** 7008 * @param uri This uri must NOT contain an embedded userId. 7009 * @param userId The userId in which the uri is to be resolved. 7010 */ 7011 @Override 7012 public int checkUriPermission(Uri uri, int pid, int uid, 7013 final int modeFlags, int userId) { 7014 enforceNotIsolatedCaller("checkUriPermission"); 7015 7016 // Another redirected-binder-call permissions check as in 7017 // {@link checkComponentPermission}. 7018 Identity tlsIdentity = sCallerIdentity.get(); 7019 if (tlsIdentity != null) { 7020 uid = tlsIdentity.uid; 7021 pid = tlsIdentity.pid; 7022 } 7023 7024 // Our own process gets to do everything. 7025 if (pid == MY_PID) { 7026 return PackageManager.PERMISSION_GRANTED; 7027 } 7028 synchronized (this) { 7029 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7030 ? PackageManager.PERMISSION_GRANTED 7031 : PackageManager.PERMISSION_DENIED; 7032 } 7033 } 7034 7035 /** 7036 * Check if the targetPkg can be granted permission to access uri by 7037 * the callingUid using the given modeFlags. Throws a security exception 7038 * if callingUid is not allowed to do this. Returns the uid of the target 7039 * if the URI permission grant should be performed; returns -1 if it is not 7040 * needed (for example targetPkg already has permission to access the URI). 7041 * If you already know the uid of the target, you can supply it in 7042 * lastTargetUid else set that to -1. 7043 */ 7044 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7045 final int modeFlags, int lastTargetUid) { 7046 if (!Intent.isAccessUriMode(modeFlags)) { 7047 return -1; 7048 } 7049 7050 if (targetPkg != null) { 7051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7052 "Checking grant " + targetPkg + " permission to " + grantUri); 7053 } 7054 7055 final IPackageManager pm = AppGlobals.getPackageManager(); 7056 7057 // If this is not a content: uri, we can't do anything with it. 7058 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7059 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7060 "Can't grant URI permission for non-content URI: " + grantUri); 7061 return -1; 7062 } 7063 7064 final String authority = grantUri.uri.getAuthority(); 7065 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7066 if (pi == null) { 7067 Slog.w(TAG, "No content provider found for permission check: " + 7068 grantUri.uri.toSafeString()); 7069 return -1; 7070 } 7071 7072 int targetUid = lastTargetUid; 7073 if (targetUid < 0 && targetPkg != null) { 7074 try { 7075 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7076 if (targetUid < 0) { 7077 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7078 "Can't grant URI permission no uid for: " + targetPkg); 7079 return -1; 7080 } 7081 } catch (RemoteException ex) { 7082 return -1; 7083 } 7084 } 7085 7086 if (targetUid >= 0) { 7087 // First... does the target actually need this permission? 7088 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7089 // No need to grant the target this permission. 7090 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7091 "Target " + targetPkg + " already has full permission to " + grantUri); 7092 return -1; 7093 } 7094 } else { 7095 // First... there is no target package, so can anyone access it? 7096 boolean allowed = pi.exported; 7097 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7098 if (pi.readPermission != null) { 7099 allowed = false; 7100 } 7101 } 7102 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7103 if (pi.writePermission != null) { 7104 allowed = false; 7105 } 7106 } 7107 if (allowed) { 7108 return -1; 7109 } 7110 } 7111 7112 /* There is a special cross user grant if: 7113 * - The target is on another user. 7114 * - Apps on the current user can access the uri without any uid permissions. 7115 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7116 * grant uri permissions. 7117 */ 7118 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7119 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7120 modeFlags, false /*without considering the uid permissions*/); 7121 7122 // Second... is the provider allowing granting of URI permissions? 7123 if (!specialCrossUserGrant) { 7124 if (!pi.grantUriPermissions) { 7125 throw new SecurityException("Provider " + pi.packageName 7126 + "/" + pi.name 7127 + " does not allow granting of Uri permissions (uri " 7128 + grantUri + ")"); 7129 } 7130 if (pi.uriPermissionPatterns != null) { 7131 final int N = pi.uriPermissionPatterns.length; 7132 boolean allowed = false; 7133 for (int i=0; i<N; i++) { 7134 if (pi.uriPermissionPatterns[i] != null 7135 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7136 allowed = true; 7137 break; 7138 } 7139 } 7140 if (!allowed) { 7141 throw new SecurityException("Provider " + pi.packageName 7142 + "/" + pi.name 7143 + " does not allow granting of permission to path of Uri " 7144 + grantUri); 7145 } 7146 } 7147 } 7148 7149 // Third... does the caller itself have permission to access 7150 // this uri? 7151 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7152 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7153 // Require they hold a strong enough Uri permission 7154 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7155 throw new SecurityException("Uid " + callingUid 7156 + " does not have permission to uri " + grantUri); 7157 } 7158 } 7159 } 7160 return targetUid; 7161 } 7162 7163 /** 7164 * @param uri This uri must NOT contain an embedded userId. 7165 * @param userId The userId in which the uri is to be resolved. 7166 */ 7167 @Override 7168 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7169 final int modeFlags, int userId) { 7170 enforceNotIsolatedCaller("checkGrantUriPermission"); 7171 synchronized(this) { 7172 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7173 new GrantUri(userId, uri, false), modeFlags, -1); 7174 } 7175 } 7176 7177 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7178 final int modeFlags, UriPermissionOwner owner) { 7179 if (!Intent.isAccessUriMode(modeFlags)) { 7180 return; 7181 } 7182 7183 // So here we are: the caller has the assumed permission 7184 // to the uri, and the target doesn't. Let's now give this to 7185 // the target. 7186 7187 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7188 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7189 7190 final String authority = grantUri.uri.getAuthority(); 7191 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7192 if (pi == null) { 7193 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7194 return; 7195 } 7196 7197 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7198 grantUri.prefix = true; 7199 } 7200 final UriPermission perm = findOrCreateUriPermissionLocked( 7201 pi.packageName, targetPkg, targetUid, grantUri); 7202 perm.grantModes(modeFlags, owner); 7203 } 7204 7205 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7206 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7207 if (targetPkg == null) { 7208 throw new NullPointerException("targetPkg"); 7209 } 7210 int targetUid; 7211 final IPackageManager pm = AppGlobals.getPackageManager(); 7212 try { 7213 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7214 } catch (RemoteException ex) { 7215 return; 7216 } 7217 7218 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7219 targetUid); 7220 if (targetUid < 0) { 7221 return; 7222 } 7223 7224 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7225 owner); 7226 } 7227 7228 static class NeededUriGrants extends ArrayList<GrantUri> { 7229 final String targetPkg; 7230 final int targetUid; 7231 final int flags; 7232 7233 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7234 this.targetPkg = targetPkg; 7235 this.targetUid = targetUid; 7236 this.flags = flags; 7237 } 7238 } 7239 7240 /** 7241 * Like checkGrantUriPermissionLocked, but takes an Intent. 7242 */ 7243 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7244 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7246 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7247 + " clip=" + (intent != null ? intent.getClipData() : null) 7248 + " from " + intent + "; flags=0x" 7249 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7250 7251 if (targetPkg == null) { 7252 throw new NullPointerException("targetPkg"); 7253 } 7254 7255 if (intent == null) { 7256 return null; 7257 } 7258 Uri data = intent.getData(); 7259 ClipData clip = intent.getClipData(); 7260 if (data == null && clip == null) { 7261 return null; 7262 } 7263 // Default userId for uris in the intent (if they don't specify it themselves) 7264 int contentUserHint = intent.getContentUserHint(); 7265 if (contentUserHint == UserHandle.USER_CURRENT) { 7266 contentUserHint = UserHandle.getUserId(callingUid); 7267 } 7268 final IPackageManager pm = AppGlobals.getPackageManager(); 7269 int targetUid; 7270 if (needed != null) { 7271 targetUid = needed.targetUid; 7272 } else { 7273 try { 7274 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7275 } catch (RemoteException ex) { 7276 return null; 7277 } 7278 if (targetUid < 0) { 7279 if (DEBUG_URI_PERMISSION) { 7280 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7281 + " on user " + targetUserId); 7282 } 7283 return null; 7284 } 7285 } 7286 if (data != null) { 7287 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7288 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7289 targetUid); 7290 if (targetUid > 0) { 7291 if (needed == null) { 7292 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7293 } 7294 needed.add(grantUri); 7295 } 7296 } 7297 if (clip != null) { 7298 for (int i=0; i<clip.getItemCount(); i++) { 7299 Uri uri = clip.getItemAt(i).getUri(); 7300 if (uri != null) { 7301 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7302 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7303 targetUid); 7304 if (targetUid > 0) { 7305 if (needed == null) { 7306 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7307 } 7308 needed.add(grantUri); 7309 } 7310 } else { 7311 Intent clipIntent = clip.getItemAt(i).getIntent(); 7312 if (clipIntent != null) { 7313 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7314 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7315 if (newNeeded != null) { 7316 needed = newNeeded; 7317 } 7318 } 7319 } 7320 } 7321 } 7322 7323 return needed; 7324 } 7325 7326 /** 7327 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7328 */ 7329 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7330 UriPermissionOwner owner) { 7331 if (needed != null) { 7332 for (int i=0; i<needed.size(); i++) { 7333 GrantUri grantUri = needed.get(i); 7334 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7335 grantUri, needed.flags, owner); 7336 } 7337 } 7338 } 7339 7340 void grantUriPermissionFromIntentLocked(int callingUid, 7341 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7342 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7343 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7344 if (needed == null) { 7345 return; 7346 } 7347 7348 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7349 } 7350 7351 /** 7352 * @param uri This uri must NOT contain an embedded userId. 7353 * @param userId The userId in which the uri is to be resolved. 7354 */ 7355 @Override 7356 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7357 final int modeFlags, int userId) { 7358 enforceNotIsolatedCaller("grantUriPermission"); 7359 GrantUri grantUri = new GrantUri(userId, uri, false); 7360 synchronized(this) { 7361 final ProcessRecord r = getRecordForAppLocked(caller); 7362 if (r == null) { 7363 throw new SecurityException("Unable to find app for caller " 7364 + caller 7365 + " when granting permission to uri " + grantUri); 7366 } 7367 if (targetPkg == null) { 7368 throw new IllegalArgumentException("null target"); 7369 } 7370 if (grantUri == null) { 7371 throw new IllegalArgumentException("null uri"); 7372 } 7373 7374 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7376 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7377 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7378 7379 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7380 UserHandle.getUserId(r.uid)); 7381 } 7382 } 7383 7384 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7385 if (perm.modeFlags == 0) { 7386 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7387 perm.targetUid); 7388 if (perms != null) { 7389 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7390 "Removing " + perm.targetUid + " permission to " + perm.uri); 7391 7392 perms.remove(perm.uri); 7393 if (perms.isEmpty()) { 7394 mGrantedUriPermissions.remove(perm.targetUid); 7395 } 7396 } 7397 } 7398 } 7399 7400 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7401 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7402 7403 final IPackageManager pm = AppGlobals.getPackageManager(); 7404 final String authority = grantUri.uri.getAuthority(); 7405 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7406 if (pi == null) { 7407 Slog.w(TAG, "No content provider found for permission revoke: " 7408 + grantUri.toSafeString()); 7409 return; 7410 } 7411 7412 // Does the caller have this permission on the URI? 7413 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7414 // Right now, if you are not the original owner of the permission, 7415 // you are not allowed to revoke it. 7416 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7417 throw new SecurityException("Uid " + callingUid 7418 + " does not have permission to uri " + grantUri); 7419 //} 7420 } 7421 7422 boolean persistChanged = false; 7423 7424 // Go through all of the permissions and remove any that match. 7425 int N = mGrantedUriPermissions.size(); 7426 for (int i = 0; i < N; i++) { 7427 final int targetUid = mGrantedUriPermissions.keyAt(i); 7428 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7429 7430 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7431 final UriPermission perm = it.next(); 7432 if (perm.uri.sourceUserId == grantUri.sourceUserId 7433 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7434 if (DEBUG_URI_PERMISSION) 7435 Slog.v(TAG, 7436 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7437 persistChanged |= perm.revokeModes( 7438 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7439 if (perm.modeFlags == 0) { 7440 it.remove(); 7441 } 7442 } 7443 } 7444 7445 if (perms.isEmpty()) { 7446 mGrantedUriPermissions.remove(targetUid); 7447 N--; 7448 i--; 7449 } 7450 } 7451 7452 if (persistChanged) { 7453 schedulePersistUriGrants(); 7454 } 7455 } 7456 7457 /** 7458 * @param uri This uri must NOT contain an embedded userId. 7459 * @param userId The userId in which the uri is to be resolved. 7460 */ 7461 @Override 7462 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7463 int userId) { 7464 enforceNotIsolatedCaller("revokeUriPermission"); 7465 synchronized(this) { 7466 final ProcessRecord r = getRecordForAppLocked(caller); 7467 if (r == null) { 7468 throw new SecurityException("Unable to find app for caller " 7469 + caller 7470 + " when revoking permission to uri " + uri); 7471 } 7472 if (uri == null) { 7473 Slog.w(TAG, "revokeUriPermission: null uri"); 7474 return; 7475 } 7476 7477 if (!Intent.isAccessUriMode(modeFlags)) { 7478 return; 7479 } 7480 7481 final IPackageManager pm = AppGlobals.getPackageManager(); 7482 final String authority = uri.getAuthority(); 7483 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7484 if (pi == null) { 7485 Slog.w(TAG, "No content provider found for permission revoke: " 7486 + uri.toSafeString()); 7487 return; 7488 } 7489 7490 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7491 } 7492 } 7493 7494 /** 7495 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7496 * given package. 7497 * 7498 * @param packageName Package name to match, or {@code null} to apply to all 7499 * packages. 7500 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7501 * to all users. 7502 * @param persistable If persistable grants should be removed. 7503 */ 7504 private void removeUriPermissionsForPackageLocked( 7505 String packageName, int userHandle, boolean persistable) { 7506 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7507 throw new IllegalArgumentException("Must narrow by either package or user"); 7508 } 7509 7510 boolean persistChanged = false; 7511 7512 int N = mGrantedUriPermissions.size(); 7513 for (int i = 0; i < N; i++) { 7514 final int targetUid = mGrantedUriPermissions.keyAt(i); 7515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7516 7517 // Only inspect grants matching user 7518 if (userHandle == UserHandle.USER_ALL 7519 || userHandle == UserHandle.getUserId(targetUid)) { 7520 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7521 final UriPermission perm = it.next(); 7522 7523 // Only inspect grants matching package 7524 if (packageName == null || perm.sourcePkg.equals(packageName) 7525 || perm.targetPkg.equals(packageName)) { 7526 persistChanged |= perm.revokeModes( 7527 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7528 7529 // Only remove when no modes remain; any persisted grants 7530 // will keep this alive. 7531 if (perm.modeFlags == 0) { 7532 it.remove(); 7533 } 7534 } 7535 } 7536 7537 if (perms.isEmpty()) { 7538 mGrantedUriPermissions.remove(targetUid); 7539 N--; 7540 i--; 7541 } 7542 } 7543 } 7544 7545 if (persistChanged) { 7546 schedulePersistUriGrants(); 7547 } 7548 } 7549 7550 @Override 7551 public IBinder newUriPermissionOwner(String name) { 7552 enforceNotIsolatedCaller("newUriPermissionOwner"); 7553 synchronized(this) { 7554 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7555 return owner.getExternalTokenLocked(); 7556 } 7557 } 7558 7559 /** 7560 * @param uri This uri must NOT contain an embedded userId. 7561 * @param sourceUserId The userId in which the uri is to be resolved. 7562 * @param targetUserId The userId of the app that receives the grant. 7563 */ 7564 @Override 7565 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7566 final int modeFlags, int sourceUserId, int targetUserId) { 7567 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7568 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7569 synchronized(this) { 7570 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7571 if (owner == null) { 7572 throw new IllegalArgumentException("Unknown owner: " + token); 7573 } 7574 if (fromUid != Binder.getCallingUid()) { 7575 if (Binder.getCallingUid() != Process.myUid()) { 7576 // Only system code can grant URI permissions on behalf 7577 // of other users. 7578 throw new SecurityException("nice try"); 7579 } 7580 } 7581 if (targetPkg == null) { 7582 throw new IllegalArgumentException("null target"); 7583 } 7584 if (uri == null) { 7585 throw new IllegalArgumentException("null uri"); 7586 } 7587 7588 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7589 modeFlags, owner, targetUserId); 7590 } 7591 } 7592 7593 /** 7594 * @param uri This uri must NOT contain an embedded userId. 7595 * @param userId The userId in which the uri is to be resolved. 7596 */ 7597 @Override 7598 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 7605 if (uri == null) { 7606 owner.removeUriPermissionsLocked(mode); 7607 } else { 7608 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7609 } 7610 } 7611 } 7612 7613 private void schedulePersistUriGrants() { 7614 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7615 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7616 10 * DateUtils.SECOND_IN_MILLIS); 7617 } 7618 } 7619 7620 private void writeGrantedUriPermissions() { 7621 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7622 7623 // Snapshot permissions so we can persist without lock 7624 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7625 synchronized (this) { 7626 final int size = mGrantedUriPermissions.size(); 7627 for (int i = 0; i < size; i++) { 7628 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7629 for (UriPermission perm : perms.values()) { 7630 if (perm.persistedModeFlags != 0) { 7631 persist.add(perm.snapshot()); 7632 } 7633 } 7634 } 7635 } 7636 7637 FileOutputStream fos = null; 7638 try { 7639 fos = mGrantFile.startWrite(); 7640 7641 XmlSerializer out = new FastXmlSerializer(); 7642 out.setOutput(fos, "utf-8"); 7643 out.startDocument(null, true); 7644 out.startTag(null, TAG_URI_GRANTS); 7645 for (UriPermission.Snapshot perm : persist) { 7646 out.startTag(null, TAG_URI_GRANT); 7647 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7648 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7649 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7650 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7651 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7652 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7653 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7654 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7655 out.endTag(null, TAG_URI_GRANT); 7656 } 7657 out.endTag(null, TAG_URI_GRANTS); 7658 out.endDocument(); 7659 7660 mGrantFile.finishWrite(fos); 7661 } catch (IOException e) { 7662 if (fos != null) { 7663 mGrantFile.failWrite(fos); 7664 } 7665 } 7666 } 7667 7668 private void readGrantedUriPermissionsLocked() { 7669 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7670 7671 final long now = System.currentTimeMillis(); 7672 7673 FileInputStream fis = null; 7674 try { 7675 fis = mGrantFile.openRead(); 7676 final XmlPullParser in = Xml.newPullParser(); 7677 in.setInput(fis, null); 7678 7679 int type; 7680 while ((type = in.next()) != END_DOCUMENT) { 7681 final String tag = in.getName(); 7682 if (type == START_TAG) { 7683 if (TAG_URI_GRANT.equals(tag)) { 7684 final int sourceUserId; 7685 final int targetUserId; 7686 final int userHandle = readIntAttribute(in, 7687 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7688 if (userHandle != UserHandle.USER_NULL) { 7689 // For backwards compatibility. 7690 sourceUserId = userHandle; 7691 targetUserId = userHandle; 7692 } else { 7693 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7694 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7695 } 7696 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7697 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7698 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7699 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7700 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7701 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7702 7703 // Sanity check that provider still belongs to source package 7704 final ProviderInfo pi = getProviderInfoLocked( 7705 uri.getAuthority(), sourceUserId); 7706 if (pi != null && sourcePkg.equals(pi.packageName)) { 7707 int targetUid = -1; 7708 try { 7709 targetUid = AppGlobals.getPackageManager() 7710 .getPackageUid(targetPkg, targetUserId); 7711 } catch (RemoteException e) { 7712 } 7713 if (targetUid != -1) { 7714 final UriPermission perm = findOrCreateUriPermissionLocked( 7715 sourcePkg, targetPkg, targetUid, 7716 new GrantUri(sourceUserId, uri, prefix)); 7717 perm.initPersistedModes(modeFlags, createdTime); 7718 } 7719 } else { 7720 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7721 + " but instead found " + pi); 7722 } 7723 } 7724 } 7725 } 7726 } catch (FileNotFoundException e) { 7727 // Missing grants is okay 7728 } catch (IOException e) { 7729 Log.wtf(TAG, "Failed reading Uri grants", e); 7730 } catch (XmlPullParserException e) { 7731 Log.wtf(TAG, "Failed reading Uri grants", e); 7732 } finally { 7733 IoUtils.closeQuietly(fis); 7734 } 7735 } 7736 7737 /** 7738 * @param uri This uri must NOT contain an embedded userId. 7739 * @param userId The userId in which the uri is to be resolved. 7740 */ 7741 @Override 7742 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7743 enforceNotIsolatedCaller("takePersistableUriPermission"); 7744 7745 Preconditions.checkFlagsArgument(modeFlags, 7746 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7747 7748 synchronized (this) { 7749 final int callingUid = Binder.getCallingUid(); 7750 boolean persistChanged = false; 7751 GrantUri grantUri = new GrantUri(userId, uri, false); 7752 7753 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7754 new GrantUri(userId, uri, false)); 7755 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7756 new GrantUri(userId, uri, true)); 7757 7758 final boolean exactValid = (exactPerm != null) 7759 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7760 final boolean prefixValid = (prefixPerm != null) 7761 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7762 7763 if (!(exactValid || prefixValid)) { 7764 throw new SecurityException("No persistable permission grants found for UID " 7765 + callingUid + " and Uri " + grantUri.toSafeString()); 7766 } 7767 7768 if (exactValid) { 7769 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7770 } 7771 if (prefixValid) { 7772 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7773 } 7774 7775 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7776 7777 if (persistChanged) { 7778 schedulePersistUriGrants(); 7779 } 7780 } 7781 } 7782 7783 /** 7784 * @param uri This uri must NOT contain an embedded userId. 7785 * @param userId The userId in which the uri is to be resolved. 7786 */ 7787 @Override 7788 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7789 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7790 7791 Preconditions.checkFlagsArgument(modeFlags, 7792 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7793 7794 synchronized (this) { 7795 final int callingUid = Binder.getCallingUid(); 7796 boolean persistChanged = false; 7797 7798 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7799 new GrantUri(userId, uri, false)); 7800 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7801 new GrantUri(userId, uri, true)); 7802 if (exactPerm == null && prefixPerm == null) { 7803 throw new SecurityException("No permission grants found for UID " + callingUid 7804 + " and Uri " + uri.toSafeString()); 7805 } 7806 7807 if (exactPerm != null) { 7808 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7809 removeUriPermissionIfNeededLocked(exactPerm); 7810 } 7811 if (prefixPerm != null) { 7812 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7813 removeUriPermissionIfNeededLocked(prefixPerm); 7814 } 7815 7816 if (persistChanged) { 7817 schedulePersistUriGrants(); 7818 } 7819 } 7820 } 7821 7822 /** 7823 * Prune any older {@link UriPermission} for the given UID until outstanding 7824 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7825 * 7826 * @return if any mutations occured that require persisting. 7827 */ 7828 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7829 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7830 if (perms == null) return false; 7831 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7832 7833 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7834 for (UriPermission perm : perms.values()) { 7835 if (perm.persistedModeFlags != 0) { 7836 persisted.add(perm); 7837 } 7838 } 7839 7840 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7841 if (trimCount <= 0) return false; 7842 7843 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7844 for (int i = 0; i < trimCount; i++) { 7845 final UriPermission perm = persisted.get(i); 7846 7847 if (DEBUG_URI_PERMISSION) { 7848 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7849 } 7850 7851 perm.releasePersistableModes(~0); 7852 removeUriPermissionIfNeededLocked(perm); 7853 } 7854 7855 return true; 7856 } 7857 7858 @Override 7859 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7860 String packageName, boolean incoming) { 7861 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7862 Preconditions.checkNotNull(packageName, "packageName"); 7863 7864 final int callingUid = Binder.getCallingUid(); 7865 final IPackageManager pm = AppGlobals.getPackageManager(); 7866 try { 7867 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7868 if (packageUid != callingUid) { 7869 throw new SecurityException( 7870 "Package " + packageName + " does not belong to calling UID " + callingUid); 7871 } 7872 } catch (RemoteException e) { 7873 throw new SecurityException("Failed to verify package name ownership"); 7874 } 7875 7876 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7877 synchronized (this) { 7878 if (incoming) { 7879 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7880 callingUid); 7881 if (perms == null) { 7882 Slog.w(TAG, "No permission grants found for " + packageName); 7883 } else { 7884 for (UriPermission perm : perms.values()) { 7885 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7886 result.add(perm.buildPersistedPublicApiObject()); 7887 } 7888 } 7889 } 7890 } else { 7891 final int size = mGrantedUriPermissions.size(); 7892 for (int i = 0; i < size; i++) { 7893 final ArrayMap<GrantUri, UriPermission> perms = 7894 mGrantedUriPermissions.valueAt(i); 7895 for (UriPermission perm : perms.values()) { 7896 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7897 result.add(perm.buildPersistedPublicApiObject()); 7898 } 7899 } 7900 } 7901 } 7902 } 7903 return new ParceledListSlice<android.content.UriPermission>(result); 7904 } 7905 7906 @Override 7907 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7908 synchronized (this) { 7909 ProcessRecord app = 7910 who != null ? getRecordForAppLocked(who) : null; 7911 if (app == null) return; 7912 7913 Message msg = Message.obtain(); 7914 msg.what = WAIT_FOR_DEBUGGER_MSG; 7915 msg.obj = app; 7916 msg.arg1 = waiting ? 1 : 0; 7917 mHandler.sendMessage(msg); 7918 } 7919 } 7920 7921 @Override 7922 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7923 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7924 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7925 outInfo.availMem = Process.getFreeMemory(); 7926 outInfo.totalMem = Process.getTotalMemory(); 7927 outInfo.threshold = homeAppMem; 7928 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7929 outInfo.hiddenAppThreshold = cachedAppMem; 7930 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7931 ProcessList.SERVICE_ADJ); 7932 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7933 ProcessList.VISIBLE_APP_ADJ); 7934 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7935 ProcessList.FOREGROUND_APP_ADJ); 7936 } 7937 7938 // ========================================================= 7939 // TASK MANAGEMENT 7940 // ========================================================= 7941 7942 @Override 7943 public List<IAppTask> getAppTasks(String callingPackage) { 7944 int callingUid = Binder.getCallingUid(); 7945 long ident = Binder.clearCallingIdentity(); 7946 7947 synchronized(this) { 7948 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7949 try { 7950 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7951 7952 final int N = mRecentTasks.size(); 7953 for (int i = 0; i < N; i++) { 7954 TaskRecord tr = mRecentTasks.get(i); 7955 // Skip tasks that do not match the caller. We don't need to verify 7956 // callingPackage, because we are also limiting to callingUid and know 7957 // that will limit to the correct security sandbox. 7958 if (tr.effectiveUid != callingUid) { 7959 continue; 7960 } 7961 Intent intent = tr.getBaseIntent(); 7962 if (intent == null || 7963 !callingPackage.equals(intent.getComponent().getPackageName())) { 7964 continue; 7965 } 7966 ActivityManager.RecentTaskInfo taskInfo = 7967 createRecentTaskInfoFromTaskRecord(tr); 7968 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7969 list.add(taskImpl); 7970 } 7971 } finally { 7972 Binder.restoreCallingIdentity(ident); 7973 } 7974 return list; 7975 } 7976 } 7977 7978 @Override 7979 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7980 final int callingUid = Binder.getCallingUid(); 7981 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7982 7983 synchronized(this) { 7984 if (localLOGV) Slog.v( 7985 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7986 7987 final boolean allowed = checkCallingPermission( 7988 android.Manifest.permission.GET_TASKS) 7989 == PackageManager.PERMISSION_GRANTED; 7990 if (!allowed) { 7991 Slog.w(TAG, "getTasks: caller " + callingUid 7992 + " does not hold GET_TASKS; limiting output"); 7993 } 7994 7995 // TODO: Improve with MRU list from all ActivityStacks. 7996 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7997 } 7998 7999 return list; 8000 } 8001 8002 TaskRecord getMostRecentTask() { 8003 return mRecentTasks.get(0); 8004 } 8005 8006 /** 8007 * Creates a new RecentTaskInfo from a TaskRecord. 8008 */ 8009 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8010 // Update the task description to reflect any changes in the task stack 8011 tr.updateTaskDescription(); 8012 8013 // Compose the recent task info 8014 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8015 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8016 rti.persistentId = tr.taskId; 8017 rti.baseIntent = new Intent(tr.getBaseIntent()); 8018 rti.origActivity = tr.origActivity; 8019 rti.description = tr.lastDescription; 8020 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8021 rti.userId = tr.userId; 8022 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8023 rti.firstActiveTime = tr.firstActiveTime; 8024 rti.lastActiveTime = tr.lastActiveTime; 8025 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8026 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8027 return rti; 8028 } 8029 8030 @Override 8031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8032 final int callingUid = Binder.getCallingUid(); 8033 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8034 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8035 8036 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8037 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8038 synchronized (this) { 8039 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8040 == PackageManager.PERMISSION_GRANTED; 8041 if (!allowed) { 8042 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8043 + " does not hold GET_TASKS; limiting output"); 8044 } 8045 final boolean detailed = checkCallingPermission( 8046 android.Manifest.permission.GET_DETAILED_TASKS) 8047 == PackageManager.PERMISSION_GRANTED; 8048 8049 final int N = mRecentTasks.size(); 8050 ArrayList<ActivityManager.RecentTaskInfo> res 8051 = new ArrayList<ActivityManager.RecentTaskInfo>( 8052 maxNum < N ? maxNum : N); 8053 8054 final Set<Integer> includedUsers; 8055 if (includeProfiles) { 8056 includedUsers = getProfileIdsLocked(userId); 8057 } else { 8058 includedUsers = new HashSet<Integer>(); 8059 } 8060 includedUsers.add(Integer.valueOf(userId)); 8061 8062 for (int i=0; i<N && maxNum > 0; i++) { 8063 TaskRecord tr = mRecentTasks.get(i); 8064 // Only add calling user or related users recent tasks 8065 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8066 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8067 continue; 8068 } 8069 8070 // Return the entry if desired by the caller. We always return 8071 // the first entry, because callers always expect this to be the 8072 // foreground app. We may filter others if the caller has 8073 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8074 // we should exclude the entry. 8075 8076 if (i == 0 8077 || withExcluded 8078 || (tr.intent == null) 8079 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8080 == 0)) { 8081 if (!allowed) { 8082 // If the caller doesn't have the GET_TASKS permission, then only 8083 // allow them to see a small subset of tasks -- their own and home. 8084 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8085 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8086 continue; 8087 } 8088 } 8089 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8090 if (tr.stack != null && tr.stack.isHomeStack()) { 8091 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8092 continue; 8093 } 8094 } 8095 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8096 // Don't include auto remove tasks that are finished or finishing. 8097 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8098 + tr); 8099 continue; 8100 } 8101 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8102 && !tr.isAvailable) { 8103 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8104 continue; 8105 } 8106 8107 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8108 if (!detailed) { 8109 rti.baseIntent.replaceExtras((Bundle)null); 8110 } 8111 8112 res.add(rti); 8113 maxNum--; 8114 } 8115 } 8116 return res; 8117 } 8118 } 8119 8120 private TaskRecord recentTaskForIdLocked(int id) { 8121 final int N = mRecentTasks.size(); 8122 for (int i=0; i<N; i++) { 8123 TaskRecord tr = mRecentTasks.get(i); 8124 if (tr.taskId == id) { 8125 return tr; 8126 } 8127 } 8128 return null; 8129 } 8130 8131 @Override 8132 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8133 synchronized (this) { 8134 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8135 "getTaskThumbnail()"); 8136 TaskRecord tr = recentTaskForIdLocked(id); 8137 if (tr != null) { 8138 return tr.getTaskThumbnailLocked(); 8139 } 8140 } 8141 return null; 8142 } 8143 8144 @Override 8145 public int addAppTask(IBinder activityToken, Intent intent, 8146 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8147 final int callingUid = Binder.getCallingUid(); 8148 final long callingIdent = Binder.clearCallingIdentity(); 8149 8150 try { 8151 synchronized (this) { 8152 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8153 if (r == null) { 8154 throw new IllegalArgumentException("Activity does not exist; token=" 8155 + activityToken); 8156 } 8157 ComponentName comp = intent.getComponent(); 8158 if (comp == null) { 8159 throw new IllegalArgumentException("Intent " + intent 8160 + " must specify explicit component"); 8161 } 8162 if (thumbnail.getWidth() != mThumbnailWidth 8163 || thumbnail.getHeight() != mThumbnailHeight) { 8164 throw new IllegalArgumentException("Bad thumbnail size: got " 8165 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8166 + mThumbnailWidth + "x" + mThumbnailHeight); 8167 } 8168 if (intent.getSelector() != null) { 8169 intent.setSelector(null); 8170 } 8171 if (intent.getSourceBounds() != null) { 8172 intent.setSourceBounds(null); 8173 } 8174 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8175 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8176 // The caller has added this as an auto-remove task... that makes no 8177 // sense, so turn off auto-remove. 8178 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8179 } 8180 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8181 // Must be a new task. 8182 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8183 } 8184 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8185 mLastAddedTaskActivity = null; 8186 } 8187 ActivityInfo ainfo = mLastAddedTaskActivity; 8188 if (ainfo == null) { 8189 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8190 comp, 0, UserHandle.getUserId(callingUid)); 8191 if (ainfo.applicationInfo.uid != callingUid) { 8192 throw new SecurityException( 8193 "Can't add task for another application: target uid=" 8194 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8195 } 8196 } 8197 8198 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8199 intent, description); 8200 8201 int trimIdx = trimRecentsForTask(task, false); 8202 if (trimIdx >= 0) { 8203 // If this would have caused a trim, then we'll abort because that 8204 // means it would be added at the end of the list but then just removed. 8205 return -1; 8206 } 8207 8208 final int N = mRecentTasks.size(); 8209 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8210 final TaskRecord tr = mRecentTasks.remove(N - 1); 8211 tr.removedFromRecents(mTaskPersister); 8212 } 8213 8214 task.inRecents = true; 8215 mRecentTasks.add(task); 8216 r.task.stack.addTask(task, false, false); 8217 8218 task.setLastThumbnail(thumbnail); 8219 task.freeLastThumbnail(); 8220 8221 return task.taskId; 8222 } 8223 } finally { 8224 Binder.restoreCallingIdentity(callingIdent); 8225 } 8226 } 8227 8228 @Override 8229 public Point getAppTaskThumbnailSize() { 8230 synchronized (this) { 8231 return new Point(mThumbnailWidth, mThumbnailHeight); 8232 } 8233 } 8234 8235 @Override 8236 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8237 synchronized (this) { 8238 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8239 if (r != null) { 8240 r.taskDescription = td; 8241 r.task.updateTaskDescription(); 8242 } 8243 } 8244 } 8245 8246 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8247 mRecentTasks.remove(tr); 8248 tr.removedFromRecents(mTaskPersister); 8249 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8250 Intent baseIntent = new Intent( 8251 tr.intent != null ? tr.intent : tr.affinityIntent); 8252 ComponentName component = baseIntent.getComponent(); 8253 if (component == null) { 8254 Slog.w(TAG, "Now component for base intent of task: " + tr); 8255 return; 8256 } 8257 8258 // Find any running services associated with this app. 8259 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8260 8261 if (killProcesses) { 8262 // Find any running processes associated with this app. 8263 final String pkg = component.getPackageName(); 8264 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8265 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8266 for (int i=0; i<pmap.size(); i++) { 8267 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8268 for (int j=0; j<uids.size(); j++) { 8269 ProcessRecord proc = uids.valueAt(j); 8270 if (proc.userId != tr.userId) { 8271 continue; 8272 } 8273 if (!proc.pkgList.containsKey(pkg)) { 8274 continue; 8275 } 8276 procs.add(proc); 8277 } 8278 } 8279 8280 // Kill the running processes. 8281 for (int i=0; i<procs.size(); i++) { 8282 ProcessRecord pr = procs.get(i); 8283 if (pr == mHomeProcess) { 8284 // Don't kill the home process along with tasks from the same package. 8285 continue; 8286 } 8287 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8288 pr.kill("remove task", true); 8289 } else { 8290 pr.waitingToKill = "remove task"; 8291 } 8292 } 8293 } 8294 } 8295 8296 /** 8297 * Removes the task with the specified task id. 8298 * 8299 * @param taskId Identifier of the task to be removed. 8300 * @param flags Additional operational flags. May be 0 or 8301 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8302 * @return Returns true if the given task was found and removed. 8303 */ 8304 private boolean removeTaskByIdLocked(int taskId, int flags) { 8305 TaskRecord tr = recentTaskForIdLocked(taskId); 8306 if (tr != null) { 8307 tr.removeTaskActivitiesLocked(); 8308 cleanUpRemovedTaskLocked(tr, flags); 8309 if (tr.isPersistable) { 8310 notifyTaskPersisterLocked(null, true); 8311 } 8312 return true; 8313 } 8314 return false; 8315 } 8316 8317 @Override 8318 public boolean removeTask(int taskId, int flags) { 8319 synchronized (this) { 8320 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8321 "removeTask()"); 8322 long ident = Binder.clearCallingIdentity(); 8323 try { 8324 return removeTaskByIdLocked(taskId, flags); 8325 } finally { 8326 Binder.restoreCallingIdentity(ident); 8327 } 8328 } 8329 } 8330 8331 /** 8332 * TODO: Add mController hook 8333 */ 8334 @Override 8335 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8336 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8337 "moveTaskToFront()"); 8338 8339 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8340 synchronized(this) { 8341 moveTaskToFrontLocked(taskId, flags, options); 8342 } 8343 } 8344 8345 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8346 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8347 Binder.getCallingUid(), "Task to front")) { 8348 ActivityOptions.abort(options); 8349 return; 8350 } 8351 final long origId = Binder.clearCallingIdentity(); 8352 try { 8353 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8354 if (task == null) { 8355 return; 8356 } 8357 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8358 mStackSupervisor.showLockTaskToast(); 8359 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8360 return; 8361 } 8362 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8363 if (prev != null && prev.isRecentsActivity()) { 8364 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8365 } 8366 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8367 } finally { 8368 Binder.restoreCallingIdentity(origId); 8369 } 8370 ActivityOptions.abort(options); 8371 } 8372 8373 @Override 8374 public void moveTaskToBack(int taskId) { 8375 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8376 "moveTaskToBack()"); 8377 8378 synchronized(this) { 8379 TaskRecord tr = recentTaskForIdLocked(taskId); 8380 if (tr != null) { 8381 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8382 ActivityStack stack = tr.stack; 8383 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8385 Binder.getCallingUid(), "Task to back")) { 8386 return; 8387 } 8388 } 8389 final long origId = Binder.clearCallingIdentity(); 8390 try { 8391 stack.moveTaskToBackLocked(taskId, null); 8392 } finally { 8393 Binder.restoreCallingIdentity(origId); 8394 } 8395 } 8396 } 8397 } 8398 8399 /** 8400 * Moves an activity, and all of the other activities within the same task, to the bottom 8401 * of the history stack. The activity's order within the task is unchanged. 8402 * 8403 * @param token A reference to the activity we wish to move 8404 * @param nonRoot If false then this only works if the activity is the root 8405 * of a task; if true it will work for any activity in a task. 8406 * @return Returns true if the move completed, false if not. 8407 */ 8408 @Override 8409 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8410 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8411 synchronized(this) { 8412 final long origId = Binder.clearCallingIdentity(); 8413 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8414 if (taskId >= 0) { 8415 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8416 } 8417 Binder.restoreCallingIdentity(origId); 8418 } 8419 return false; 8420 } 8421 8422 @Override 8423 public void moveTaskBackwards(int task) { 8424 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8425 "moveTaskBackwards()"); 8426 8427 synchronized(this) { 8428 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8429 Binder.getCallingUid(), "Task backwards")) { 8430 return; 8431 } 8432 final long origId = Binder.clearCallingIdentity(); 8433 moveTaskBackwardsLocked(task); 8434 Binder.restoreCallingIdentity(origId); 8435 } 8436 } 8437 8438 private final void moveTaskBackwardsLocked(int task) { 8439 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8440 } 8441 8442 @Override 8443 public IBinder getHomeActivityToken() throws RemoteException { 8444 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8445 "getHomeActivityToken()"); 8446 synchronized (this) { 8447 return mStackSupervisor.getHomeActivityToken(); 8448 } 8449 } 8450 8451 @Override 8452 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8453 IActivityContainerCallback callback) throws RemoteException { 8454 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8455 "createActivityContainer()"); 8456 synchronized (this) { 8457 if (parentActivityToken == null) { 8458 throw new IllegalArgumentException("parent token must not be null"); 8459 } 8460 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8461 if (r == null) { 8462 return null; 8463 } 8464 if (callback == null) { 8465 throw new IllegalArgumentException("callback must not be null"); 8466 } 8467 return mStackSupervisor.createActivityContainer(r, callback); 8468 } 8469 } 8470 8471 @Override 8472 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8473 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8474 "deleteActivityContainer()"); 8475 synchronized (this) { 8476 mStackSupervisor.deleteActivityContainer(container); 8477 } 8478 } 8479 8480 @Override 8481 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8482 throws RemoteException { 8483 synchronized (this) { 8484 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8485 if (stack != null) { 8486 return stack.mActivityContainer; 8487 } 8488 return null; 8489 } 8490 } 8491 8492 @Override 8493 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8494 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8495 "moveTaskToStack()"); 8496 if (stackId == HOME_STACK_ID) { 8497 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8498 new RuntimeException("here").fillInStackTrace()); 8499 } 8500 synchronized (this) { 8501 long ident = Binder.clearCallingIdentity(); 8502 try { 8503 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8504 + stackId + " toTop=" + toTop); 8505 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8506 } finally { 8507 Binder.restoreCallingIdentity(ident); 8508 } 8509 } 8510 } 8511 8512 @Override 8513 public void resizeStack(int stackBoxId, Rect bounds) { 8514 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8515 "resizeStackBox()"); 8516 long ident = Binder.clearCallingIdentity(); 8517 try { 8518 mWindowManager.resizeStack(stackBoxId, bounds); 8519 } finally { 8520 Binder.restoreCallingIdentity(ident); 8521 } 8522 } 8523 8524 @Override 8525 public List<StackInfo> getAllStackInfos() { 8526 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8527 "getAllStackInfos()"); 8528 long ident = Binder.clearCallingIdentity(); 8529 try { 8530 synchronized (this) { 8531 return mStackSupervisor.getAllStackInfosLocked(); 8532 } 8533 } finally { 8534 Binder.restoreCallingIdentity(ident); 8535 } 8536 } 8537 8538 @Override 8539 public StackInfo getStackInfo(int stackId) { 8540 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8541 "getStackInfo()"); 8542 long ident = Binder.clearCallingIdentity(); 8543 try { 8544 synchronized (this) { 8545 return mStackSupervisor.getStackInfoLocked(stackId); 8546 } 8547 } finally { 8548 Binder.restoreCallingIdentity(ident); 8549 } 8550 } 8551 8552 @Override 8553 public boolean isInHomeStack(int taskId) { 8554 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8555 "getStackInfo()"); 8556 long ident = Binder.clearCallingIdentity(); 8557 try { 8558 synchronized (this) { 8559 TaskRecord tr = recentTaskForIdLocked(taskId); 8560 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8561 } 8562 } finally { 8563 Binder.restoreCallingIdentity(ident); 8564 } 8565 } 8566 8567 @Override 8568 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8569 synchronized(this) { 8570 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8571 } 8572 } 8573 8574 private boolean isLockTaskAuthorized(String pkg) { 8575 final DevicePolicyManager dpm = (DevicePolicyManager) 8576 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8577 try { 8578 int uid = mContext.getPackageManager().getPackageUid(pkg, 8579 Binder.getCallingUserHandle().getIdentifier()); 8580 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8581 } catch (NameNotFoundException e) { 8582 return false; 8583 } 8584 } 8585 8586 void startLockTaskMode(TaskRecord task) { 8587 final String pkg; 8588 synchronized (this) { 8589 pkg = task.intent.getComponent().getPackageName(); 8590 } 8591 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8592 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8593 final TaskRecord taskRecord = task; 8594 mHandler.post(new Runnable() { 8595 @Override 8596 public void run() { 8597 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8598 } 8599 }); 8600 return; 8601 } 8602 long ident = Binder.clearCallingIdentity(); 8603 try { 8604 synchronized (this) { 8605 // Since we lost lock on task, make sure it is still there. 8606 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8607 if (task != null) { 8608 if (!isSystemInitiated 8609 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8610 throw new IllegalArgumentException("Invalid task, not in foreground"); 8611 } 8612 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8613 } 8614 } 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public void startLockTaskMode(int taskId) { 8622 final TaskRecord task; 8623 long ident = Binder.clearCallingIdentity(); 8624 try { 8625 synchronized (this) { 8626 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8627 } 8628 } finally { 8629 Binder.restoreCallingIdentity(ident); 8630 } 8631 if (task != null) { 8632 startLockTaskMode(task); 8633 } 8634 } 8635 8636 @Override 8637 public void startLockTaskMode(IBinder token) { 8638 final TaskRecord task; 8639 long ident = Binder.clearCallingIdentity(); 8640 try { 8641 synchronized (this) { 8642 final ActivityRecord r = ActivityRecord.forToken(token); 8643 if (r == null) { 8644 return; 8645 } 8646 task = r.task; 8647 } 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 if (task != null) { 8652 startLockTaskMode(task); 8653 } 8654 } 8655 8656 @Override 8657 public void startLockTaskModeOnCurrent() throws RemoteException { 8658 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8659 ActivityRecord r = null; 8660 synchronized (this) { 8661 r = mStackSupervisor.topRunningActivityLocked(); 8662 } 8663 startLockTaskMode(r.task); 8664 } 8665 8666 @Override 8667 public void stopLockTaskMode() { 8668 // Verify that the user matches the package of the intent for the TaskRecord 8669 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8670 // and stopLockTaskMode. 8671 final int callingUid = Binder.getCallingUid(); 8672 if (callingUid != Process.SYSTEM_UID) { 8673 try { 8674 String pkg = 8675 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8676 int uid = mContext.getPackageManager().getPackageUid(pkg, 8677 Binder.getCallingUserHandle().getIdentifier()); 8678 if (uid != callingUid) { 8679 throw new SecurityException("Invalid uid, expected " + uid); 8680 } 8681 } catch (NameNotFoundException e) { 8682 Log.d(TAG, "stopLockTaskMode " + e); 8683 return; 8684 } 8685 } 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 Log.d(TAG, "stopLockTaskMode"); 8689 // Stop lock task 8690 synchronized (this) { 8691 mStackSupervisor.setLockTaskModeLocked(null, false); 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(ident); 8695 } 8696 } 8697 8698 @Override 8699 public void stopLockTaskModeOnCurrent() throws RemoteException { 8700 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 stopLockTaskMode(); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public boolean isInLockTaskMode() { 8711 synchronized (this) { 8712 return mStackSupervisor.isInLockTaskMode(); 8713 } 8714 } 8715 8716 // ========================================================= 8717 // CONTENT PROVIDERS 8718 // ========================================================= 8719 8720 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8721 List<ProviderInfo> providers = null; 8722 try { 8723 providers = AppGlobals.getPackageManager(). 8724 queryContentProviders(app.processName, app.uid, 8725 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8726 } catch (RemoteException ex) { 8727 } 8728 if (DEBUG_MU) 8729 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8730 int userId = app.userId; 8731 if (providers != null) { 8732 int N = providers.size(); 8733 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8734 for (int i=0; i<N; i++) { 8735 ProviderInfo cpi = 8736 (ProviderInfo)providers.get(i); 8737 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8738 cpi.name, cpi.flags); 8739 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8740 // This is a singleton provider, but a user besides the 8741 // default user is asking to initialize a process it runs 8742 // in... well, no, it doesn't actually run in this process, 8743 // it runs in the process of the default user. Get rid of it. 8744 providers.remove(i); 8745 N--; 8746 i--; 8747 continue; 8748 } 8749 8750 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8751 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8752 if (cpr == null) { 8753 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8754 mProviderMap.putProviderByClass(comp, cpr); 8755 } 8756 if (DEBUG_MU) 8757 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8758 app.pubProviders.put(cpi.name, cpr); 8759 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8760 // Don't add this if it is a platform component that is marked 8761 // to run in multiple processes, because this is actually 8762 // part of the framework so doesn't make sense to track as a 8763 // separate apk in the process. 8764 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8765 mProcessStats); 8766 } 8767 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8768 } 8769 } 8770 return providers; 8771 } 8772 8773 /** 8774 * Check if {@link ProcessRecord} has a possible chance at accessing the 8775 * given {@link ProviderInfo}. Final permission checking is always done 8776 * in {@link ContentProvider}. 8777 */ 8778 private final String checkContentProviderPermissionLocked( 8779 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8780 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8781 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8782 boolean checkedGrants = false; 8783 if (checkUser) { 8784 // Looking for cross-user grants before enforcing the typical cross-users permissions 8785 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8786 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8787 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8788 return null; 8789 } 8790 checkedGrants = true; 8791 } 8792 userId = handleIncomingUser(callingPid, callingUid, userId, 8793 false, ALLOW_NON_FULL, 8794 "checkContentProviderPermissionLocked " + cpi.authority, null); 8795 if (userId != tmpTargetUserId) { 8796 // When we actually went to determine the final targer user ID, this ended 8797 // up different than our initial check for the authority. This is because 8798 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8799 // SELF. So we need to re-check the grants again. 8800 checkedGrants = false; 8801 } 8802 } 8803 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8804 cpi.applicationInfo.uid, cpi.exported) 8805 == PackageManager.PERMISSION_GRANTED) { 8806 return null; 8807 } 8808 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8809 cpi.applicationInfo.uid, cpi.exported) 8810 == PackageManager.PERMISSION_GRANTED) { 8811 return null; 8812 } 8813 8814 PathPermission[] pps = cpi.pathPermissions; 8815 if (pps != null) { 8816 int i = pps.length; 8817 while (i > 0) { 8818 i--; 8819 PathPermission pp = pps[i]; 8820 String pprperm = pp.getReadPermission(); 8821 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8822 cpi.applicationInfo.uid, cpi.exported) 8823 == PackageManager.PERMISSION_GRANTED) { 8824 return null; 8825 } 8826 String ppwperm = pp.getWritePermission(); 8827 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8828 cpi.applicationInfo.uid, cpi.exported) 8829 == PackageManager.PERMISSION_GRANTED) { 8830 return null; 8831 } 8832 } 8833 } 8834 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8835 return null; 8836 } 8837 8838 String msg; 8839 if (!cpi.exported) { 8840 msg = "Permission Denial: opening provider " + cpi.name 8841 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8842 + ", uid=" + callingUid + ") that is not exported from uid " 8843 + cpi.applicationInfo.uid; 8844 } else { 8845 msg = "Permission Denial: opening provider " + cpi.name 8846 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8847 + ", uid=" + callingUid + ") requires " 8848 + cpi.readPermission + " or " + cpi.writePermission; 8849 } 8850 Slog.w(TAG, msg); 8851 return msg; 8852 } 8853 8854 /** 8855 * Returns if the ContentProvider has granted a uri to callingUid 8856 */ 8857 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8858 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8859 if (perms != null) { 8860 for (int i=perms.size()-1; i>=0; i--) { 8861 GrantUri grantUri = perms.keyAt(i); 8862 if (grantUri.sourceUserId == userId || !checkUser) { 8863 if (matchesProvider(grantUri.uri, cpi)) { 8864 return true; 8865 } 8866 } 8867 } 8868 } 8869 return false; 8870 } 8871 8872 /** 8873 * Returns true if the uri authority is one of the authorities specified in the provider. 8874 */ 8875 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8876 String uriAuth = uri.getAuthority(); 8877 String cpiAuth = cpi.authority; 8878 if (cpiAuth.indexOf(';') == -1) { 8879 return cpiAuth.equals(uriAuth); 8880 } 8881 String[] cpiAuths = cpiAuth.split(";"); 8882 int length = cpiAuths.length; 8883 for (int i = 0; i < length; i++) { 8884 if (cpiAuths[i].equals(uriAuth)) return true; 8885 } 8886 return false; 8887 } 8888 8889 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8890 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8891 if (r != null) { 8892 for (int i=0; i<r.conProviders.size(); i++) { 8893 ContentProviderConnection conn = r.conProviders.get(i); 8894 if (conn.provider == cpr) { 8895 if (DEBUG_PROVIDER) Slog.v(TAG, 8896 "Adding provider requested by " 8897 + r.processName + " from process " 8898 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8899 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8900 if (stable) { 8901 conn.stableCount++; 8902 conn.numStableIncs++; 8903 } else { 8904 conn.unstableCount++; 8905 conn.numUnstableIncs++; 8906 } 8907 return conn; 8908 } 8909 } 8910 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8911 if (stable) { 8912 conn.stableCount = 1; 8913 conn.numStableIncs = 1; 8914 } else { 8915 conn.unstableCount = 1; 8916 conn.numUnstableIncs = 1; 8917 } 8918 cpr.connections.add(conn); 8919 r.conProviders.add(conn); 8920 return conn; 8921 } 8922 cpr.addExternalProcessHandleLocked(externalProcessToken); 8923 return null; 8924 } 8925 8926 boolean decProviderCountLocked(ContentProviderConnection conn, 8927 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8928 if (conn != null) { 8929 cpr = conn.provider; 8930 if (DEBUG_PROVIDER) Slog.v(TAG, 8931 "Removing provider requested by " 8932 + conn.client.processName + " from process " 8933 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8934 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8935 if (stable) { 8936 conn.stableCount--; 8937 } else { 8938 conn.unstableCount--; 8939 } 8940 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8941 cpr.connections.remove(conn); 8942 conn.client.conProviders.remove(conn); 8943 return true; 8944 } 8945 return false; 8946 } 8947 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8948 return false; 8949 } 8950 8951 private void checkTime(long startTime, String where) { 8952 long now = SystemClock.elapsedRealtime(); 8953 if ((now-startTime) > 1000) { 8954 // If we are taking more than a second, log about it. 8955 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8956 } 8957 } 8958 8959 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8960 String name, IBinder token, boolean stable, int userId) { 8961 ContentProviderRecord cpr; 8962 ContentProviderConnection conn = null; 8963 ProviderInfo cpi = null; 8964 8965 synchronized(this) { 8966 long startTime = SystemClock.elapsedRealtime(); 8967 8968 ProcessRecord r = null; 8969 if (caller != null) { 8970 r = getRecordForAppLocked(caller); 8971 if (r == null) { 8972 throw new SecurityException( 8973 "Unable to find app for caller " + caller 8974 + " (pid=" + Binder.getCallingPid() 8975 + ") when getting content provider " + name); 8976 } 8977 } 8978 8979 boolean checkCrossUser = true; 8980 8981 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 8982 8983 // First check if this content provider has been published... 8984 cpr = mProviderMap.getProviderByName(name, userId); 8985 // If that didn't work, check if it exists for user 0 and then 8986 // verify that it's a singleton provider before using it. 8987 if (cpr == null && userId != UserHandle.USER_OWNER) { 8988 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8989 if (cpr != null) { 8990 cpi = cpr.info; 8991 if (isSingleton(cpi.processName, cpi.applicationInfo, 8992 cpi.name, cpi.flags) 8993 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8994 userId = UserHandle.USER_OWNER; 8995 checkCrossUser = false; 8996 } else { 8997 cpr = null; 8998 cpi = null; 8999 } 9000 } 9001 } 9002 9003 boolean providerRunning = cpr != null; 9004 if (providerRunning) { 9005 cpi = cpr.info; 9006 String msg; 9007 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9008 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9009 != null) { 9010 throw new SecurityException(msg); 9011 } 9012 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9013 9014 if (r != null && cpr.canRunHere(r)) { 9015 // This provider has been published or is in the process 9016 // of being published... but it is also allowed to run 9017 // in the caller's process, so don't make a connection 9018 // and just let the caller instantiate its own instance. 9019 ContentProviderHolder holder = cpr.newHolder(null); 9020 // don't give caller the provider object, it needs 9021 // to make its own. 9022 holder.provider = null; 9023 return holder; 9024 } 9025 9026 final long origId = Binder.clearCallingIdentity(); 9027 9028 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9029 9030 // In this case the provider instance already exists, so we can 9031 // return it right away. 9032 conn = incProviderCountLocked(r, cpr, token, stable); 9033 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9034 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9035 // If this is a perceptible app accessing the provider, 9036 // make sure to count it as being accessed and thus 9037 // back up on the LRU list. This is good because 9038 // content providers are often expensive to start. 9039 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9040 updateLruProcessLocked(cpr.proc, false, null); 9041 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9042 } 9043 } 9044 9045 if (cpr.proc != null) { 9046 if (false) { 9047 if (cpr.name.flattenToShortString().equals( 9048 "com.android.providers.calendar/.CalendarProvider2")) { 9049 Slog.v(TAG, "****************** KILLING " 9050 + cpr.name.flattenToShortString()); 9051 Process.killProcess(cpr.proc.pid); 9052 } 9053 } 9054 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9055 boolean success = updateOomAdjLocked(cpr.proc); 9056 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9057 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9058 // NOTE: there is still a race here where a signal could be 9059 // pending on the process even though we managed to update its 9060 // adj level. Not sure what to do about this, but at least 9061 // the race is now smaller. 9062 if (!success) { 9063 // Uh oh... it looks like the provider's process 9064 // has been killed on us. We need to wait for a new 9065 // process to be started, and make sure its death 9066 // doesn't kill our process. 9067 Slog.i(TAG, 9068 "Existing provider " + cpr.name.flattenToShortString() 9069 + " is crashing; detaching " + r); 9070 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9071 checkTime(startTime, "getContentProviderImpl: before appDied"); 9072 appDiedLocked(cpr.proc); 9073 checkTime(startTime, "getContentProviderImpl: after appDied"); 9074 if (!lastRef) { 9075 // This wasn't the last ref our process had on 9076 // the provider... we have now been killed, bail. 9077 return null; 9078 } 9079 providerRunning = false; 9080 conn = null; 9081 } 9082 } 9083 9084 Binder.restoreCallingIdentity(origId); 9085 } 9086 9087 boolean singleton; 9088 if (!providerRunning) { 9089 try { 9090 cpi = AppGlobals.getPackageManager(). 9091 resolveContentProvider(name, 9092 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9093 } catch (RemoteException ex) { 9094 } 9095 if (cpi == null) { 9096 return null; 9097 } 9098 // If the provider is a singleton AND 9099 // (it's a call within the same user || the provider is a 9100 // privileged app) 9101 // Then allow connecting to the singleton provider 9102 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9103 cpi.name, cpi.flags) 9104 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9105 if (singleton) { 9106 userId = UserHandle.USER_OWNER; 9107 } 9108 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9109 9110 String msg; 9111 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9112 != null) { 9113 throw new SecurityException(msg); 9114 } 9115 9116 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9117 && !cpi.processName.equals("system")) { 9118 // If this content provider does not run in the system 9119 // process, and the system is not yet ready to run other 9120 // processes, then fail fast instead of hanging. 9121 throw new IllegalArgumentException( 9122 "Attempt to launch content provider before system ready"); 9123 } 9124 9125 // Make sure that the user who owns this provider is started. If not, 9126 // we don't want to allow it to run. 9127 if (mStartedUsers.get(userId) == null) { 9128 Slog.w(TAG, "Unable to launch app " 9129 + cpi.applicationInfo.packageName + "/" 9130 + cpi.applicationInfo.uid + " for provider " 9131 + name + ": user " + userId + " is stopped"); 9132 return null; 9133 } 9134 9135 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9136 cpr = mProviderMap.getProviderByClass(comp, userId); 9137 final boolean firstClass = cpr == null; 9138 if (firstClass) { 9139 try { 9140 ApplicationInfo ai = 9141 AppGlobals.getPackageManager(). 9142 getApplicationInfo( 9143 cpi.applicationInfo.packageName, 9144 STOCK_PM_FLAGS, userId); 9145 if (ai == null) { 9146 Slog.w(TAG, "No package info for content provider " 9147 + cpi.name); 9148 return null; 9149 } 9150 ai = getAppInfoForUser(ai, userId); 9151 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9152 } catch (RemoteException ex) { 9153 // pm is in same process, this will never happen. 9154 } 9155 } 9156 9157 if (r != null && cpr.canRunHere(r)) { 9158 // If this is a multiprocess provider, then just return its 9159 // info and allow the caller to instantiate it. Only do 9160 // this if the provider is the same user as the caller's 9161 // process, or can run as root (so can be in any process). 9162 return cpr.newHolder(null); 9163 } 9164 9165 if (DEBUG_PROVIDER) { 9166 RuntimeException e = new RuntimeException("here"); 9167 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9168 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9169 } 9170 9171 // This is single process, and our app is now connecting to it. 9172 // See if we are already in the process of launching this 9173 // provider. 9174 final int N = mLaunchingProviders.size(); 9175 int i; 9176 for (i=0; i<N; i++) { 9177 if (mLaunchingProviders.get(i) == cpr) { 9178 break; 9179 } 9180 } 9181 9182 // If the provider is not already being launched, then get it 9183 // started. 9184 if (i >= N) { 9185 final long origId = Binder.clearCallingIdentity(); 9186 9187 try { 9188 // Content provider is now in use, its package can't be stopped. 9189 try { 9190 AppGlobals.getPackageManager().setPackageStoppedState( 9191 cpr.appInfo.packageName, false, userId); 9192 } catch (RemoteException e) { 9193 } catch (IllegalArgumentException e) { 9194 Slog.w(TAG, "Failed trying to unstop package " 9195 + cpr.appInfo.packageName + ": " + e); 9196 } 9197 9198 // Use existing process if already started 9199 ProcessRecord proc = getProcessRecordLocked( 9200 cpi.processName, cpr.appInfo.uid, false); 9201 if (proc != null && proc.thread != null) { 9202 if (DEBUG_PROVIDER) { 9203 Slog.d(TAG, "Installing in existing process " + proc); 9204 } 9205 proc.pubProviders.put(cpi.name, cpr); 9206 try { 9207 proc.thread.scheduleInstallProvider(cpi); 9208 } catch (RemoteException e) { 9209 } 9210 } else { 9211 proc = startProcessLocked(cpi.processName, 9212 cpr.appInfo, false, 0, "content provider", 9213 new ComponentName(cpi.applicationInfo.packageName, 9214 cpi.name), false, false, false); 9215 if (proc == null) { 9216 Slog.w(TAG, "Unable to launch app " 9217 + cpi.applicationInfo.packageName + "/" 9218 + cpi.applicationInfo.uid + " for provider " 9219 + name + ": process is bad"); 9220 return null; 9221 } 9222 } 9223 cpr.launchingApp = proc; 9224 mLaunchingProviders.add(cpr); 9225 } finally { 9226 Binder.restoreCallingIdentity(origId); 9227 } 9228 } 9229 9230 // Make sure the provider is published (the same provider class 9231 // may be published under multiple names). 9232 if (firstClass) { 9233 mProviderMap.putProviderByClass(comp, cpr); 9234 } 9235 9236 mProviderMap.putProviderByName(name, cpr); 9237 conn = incProviderCountLocked(r, cpr, token, stable); 9238 if (conn != null) { 9239 conn.waiting = true; 9240 } 9241 } 9242 } 9243 9244 // Wait for the provider to be published... 9245 synchronized (cpr) { 9246 while (cpr.provider == null) { 9247 if (cpr.launchingApp == null) { 9248 Slog.w(TAG, "Unable to launch app " 9249 + cpi.applicationInfo.packageName + "/" 9250 + cpi.applicationInfo.uid + " for provider " 9251 + name + ": launching app became null"); 9252 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9253 UserHandle.getUserId(cpi.applicationInfo.uid), 9254 cpi.applicationInfo.packageName, 9255 cpi.applicationInfo.uid, name); 9256 return null; 9257 } 9258 try { 9259 if (DEBUG_MU) { 9260 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9261 + cpr.launchingApp); 9262 } 9263 if (conn != null) { 9264 conn.waiting = true; 9265 } 9266 cpr.wait(); 9267 } catch (InterruptedException ex) { 9268 } finally { 9269 if (conn != null) { 9270 conn.waiting = false; 9271 } 9272 } 9273 } 9274 } 9275 return cpr != null ? cpr.newHolder(conn) : null; 9276 } 9277 9278 @Override 9279 public final ContentProviderHolder getContentProvider( 9280 IApplicationThread caller, String name, int userId, boolean stable) { 9281 enforceNotIsolatedCaller("getContentProvider"); 9282 if (caller == null) { 9283 String msg = "null IApplicationThread when getting content provider " 9284 + name; 9285 Slog.w(TAG, msg); 9286 throw new SecurityException(msg); 9287 } 9288 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9289 // with cross-user grant. 9290 return getContentProviderImpl(caller, name, null, stable, userId); 9291 } 9292 9293 public ContentProviderHolder getContentProviderExternal( 9294 String name, int userId, IBinder token) { 9295 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9296 "Do not have permission in call getContentProviderExternal()"); 9297 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9298 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9299 return getContentProviderExternalUnchecked(name, token, userId); 9300 } 9301 9302 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9303 IBinder token, int userId) { 9304 return getContentProviderImpl(null, name, token, true, userId); 9305 } 9306 9307 /** 9308 * Drop a content provider from a ProcessRecord's bookkeeping 9309 */ 9310 public void removeContentProvider(IBinder connection, boolean stable) { 9311 enforceNotIsolatedCaller("removeContentProvider"); 9312 long ident = Binder.clearCallingIdentity(); 9313 try { 9314 synchronized (this) { 9315 ContentProviderConnection conn; 9316 try { 9317 conn = (ContentProviderConnection)connection; 9318 } catch (ClassCastException e) { 9319 String msg ="removeContentProvider: " + connection 9320 + " not a ContentProviderConnection"; 9321 Slog.w(TAG, msg); 9322 throw new IllegalArgumentException(msg); 9323 } 9324 if (conn == null) { 9325 throw new NullPointerException("connection is null"); 9326 } 9327 if (decProviderCountLocked(conn, null, null, stable)) { 9328 updateOomAdjLocked(); 9329 } 9330 } 9331 } finally { 9332 Binder.restoreCallingIdentity(ident); 9333 } 9334 } 9335 9336 public void removeContentProviderExternal(String name, IBinder token) { 9337 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9338 "Do not have permission in call removeContentProviderExternal()"); 9339 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9340 } 9341 9342 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9343 synchronized (this) { 9344 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9345 if(cpr == null) { 9346 //remove from mProvidersByClass 9347 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9348 return; 9349 } 9350 9351 //update content provider record entry info 9352 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9353 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9354 if (localCpr.hasExternalProcessHandles()) { 9355 if (localCpr.removeExternalProcessHandleLocked(token)) { 9356 updateOomAdjLocked(); 9357 } else { 9358 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9359 + " with no external reference for token: " 9360 + token + "."); 9361 } 9362 } else { 9363 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9364 + " with no external references."); 9365 } 9366 } 9367 } 9368 9369 public final void publishContentProviders(IApplicationThread caller, 9370 List<ContentProviderHolder> providers) { 9371 if (providers == null) { 9372 return; 9373 } 9374 9375 enforceNotIsolatedCaller("publishContentProviders"); 9376 synchronized (this) { 9377 final ProcessRecord r = getRecordForAppLocked(caller); 9378 if (DEBUG_MU) 9379 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9380 if (r == null) { 9381 throw new SecurityException( 9382 "Unable to find app for caller " + caller 9383 + " (pid=" + Binder.getCallingPid() 9384 + ") when publishing content providers"); 9385 } 9386 9387 final long origId = Binder.clearCallingIdentity(); 9388 9389 final int N = providers.size(); 9390 for (int i=0; i<N; i++) { 9391 ContentProviderHolder src = providers.get(i); 9392 if (src == null || src.info == null || src.provider == null) { 9393 continue; 9394 } 9395 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9396 if (DEBUG_MU) 9397 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9398 if (dst != null) { 9399 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9400 mProviderMap.putProviderByClass(comp, dst); 9401 String names[] = dst.info.authority.split(";"); 9402 for (int j = 0; j < names.length; j++) { 9403 mProviderMap.putProviderByName(names[j], dst); 9404 } 9405 9406 int NL = mLaunchingProviders.size(); 9407 int j; 9408 for (j=0; j<NL; j++) { 9409 if (mLaunchingProviders.get(j) == dst) { 9410 mLaunchingProviders.remove(j); 9411 j--; 9412 NL--; 9413 } 9414 } 9415 synchronized (dst) { 9416 dst.provider = src.provider; 9417 dst.proc = r; 9418 dst.notifyAll(); 9419 } 9420 updateOomAdjLocked(r); 9421 } 9422 } 9423 9424 Binder.restoreCallingIdentity(origId); 9425 } 9426 } 9427 9428 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9429 ContentProviderConnection conn; 9430 try { 9431 conn = (ContentProviderConnection)connection; 9432 } catch (ClassCastException e) { 9433 String msg ="refContentProvider: " + connection 9434 + " not a ContentProviderConnection"; 9435 Slog.w(TAG, msg); 9436 throw new IllegalArgumentException(msg); 9437 } 9438 if (conn == null) { 9439 throw new NullPointerException("connection is null"); 9440 } 9441 9442 synchronized (this) { 9443 if (stable > 0) { 9444 conn.numStableIncs += stable; 9445 } 9446 stable = conn.stableCount + stable; 9447 if (stable < 0) { 9448 throw new IllegalStateException("stableCount < 0: " + stable); 9449 } 9450 9451 if (unstable > 0) { 9452 conn.numUnstableIncs += unstable; 9453 } 9454 unstable = conn.unstableCount + unstable; 9455 if (unstable < 0) { 9456 throw new IllegalStateException("unstableCount < 0: " + unstable); 9457 } 9458 9459 if ((stable+unstable) <= 0) { 9460 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9461 + stable + " unstable=" + unstable); 9462 } 9463 conn.stableCount = stable; 9464 conn.unstableCount = unstable; 9465 return !conn.dead; 9466 } 9467 } 9468 9469 public void unstableProviderDied(IBinder connection) { 9470 ContentProviderConnection conn; 9471 try { 9472 conn = (ContentProviderConnection)connection; 9473 } catch (ClassCastException e) { 9474 String msg ="refContentProvider: " + connection 9475 + " not a ContentProviderConnection"; 9476 Slog.w(TAG, msg); 9477 throw new IllegalArgumentException(msg); 9478 } 9479 if (conn == null) { 9480 throw new NullPointerException("connection is null"); 9481 } 9482 9483 // Safely retrieve the content provider associated with the connection. 9484 IContentProvider provider; 9485 synchronized (this) { 9486 provider = conn.provider.provider; 9487 } 9488 9489 if (provider == null) { 9490 // Um, yeah, we're way ahead of you. 9491 return; 9492 } 9493 9494 // Make sure the caller is being honest with us. 9495 if (provider.asBinder().pingBinder()) { 9496 // Er, no, still looks good to us. 9497 synchronized (this) { 9498 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9499 + " says " + conn + " died, but we don't agree"); 9500 return; 9501 } 9502 } 9503 9504 // Well look at that! It's dead! 9505 synchronized (this) { 9506 if (conn.provider.provider != provider) { 9507 // But something changed... good enough. 9508 return; 9509 } 9510 9511 ProcessRecord proc = conn.provider.proc; 9512 if (proc == null || proc.thread == null) { 9513 // Seems like the process is already cleaned up. 9514 return; 9515 } 9516 9517 // As far as we're concerned, this is just like receiving a 9518 // death notification... just a bit prematurely. 9519 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9520 + ") early provider death"); 9521 final long ident = Binder.clearCallingIdentity(); 9522 try { 9523 appDiedLocked(proc); 9524 } finally { 9525 Binder.restoreCallingIdentity(ident); 9526 } 9527 } 9528 } 9529 9530 @Override 9531 public void appNotRespondingViaProvider(IBinder connection) { 9532 enforceCallingPermission( 9533 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9534 9535 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9536 if (conn == null) { 9537 Slog.w(TAG, "ContentProviderConnection is null"); 9538 return; 9539 } 9540 9541 final ProcessRecord host = conn.provider.proc; 9542 if (host == null) { 9543 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9544 return; 9545 } 9546 9547 final long token = Binder.clearCallingIdentity(); 9548 try { 9549 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9550 } finally { 9551 Binder.restoreCallingIdentity(token); 9552 } 9553 } 9554 9555 public final void installSystemProviders() { 9556 List<ProviderInfo> providers; 9557 synchronized (this) { 9558 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9559 providers = generateApplicationProvidersLocked(app); 9560 if (providers != null) { 9561 for (int i=providers.size()-1; i>=0; i--) { 9562 ProviderInfo pi = (ProviderInfo)providers.get(i); 9563 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9564 Slog.w(TAG, "Not installing system proc provider " + pi.name 9565 + ": not system .apk"); 9566 providers.remove(i); 9567 } 9568 } 9569 } 9570 } 9571 if (providers != null) { 9572 mSystemThread.installSystemProviders(providers); 9573 } 9574 9575 mCoreSettingsObserver = new CoreSettingsObserver(this); 9576 9577 //mUsageStatsService.monitorPackages(); 9578 } 9579 9580 /** 9581 * Allows apps to retrieve the MIME type of a URI. 9582 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9583 * users, then it does not need permission to access the ContentProvider. 9584 * Either, it needs cross-user uri grants. 9585 * 9586 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9587 * 9588 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9589 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9590 */ 9591 public String getProviderMimeType(Uri uri, int userId) { 9592 enforceNotIsolatedCaller("getProviderMimeType"); 9593 final String name = uri.getAuthority(); 9594 int callingUid = Binder.getCallingUid(); 9595 int callingPid = Binder.getCallingPid(); 9596 long ident = 0; 9597 boolean clearedIdentity = false; 9598 userId = unsafeConvertIncomingUser(userId); 9599 if (UserHandle.getUserId(callingUid) != userId) { 9600 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9601 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9602 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9603 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9604 clearedIdentity = true; 9605 ident = Binder.clearCallingIdentity(); 9606 } 9607 } 9608 ContentProviderHolder holder = null; 9609 try { 9610 holder = getContentProviderExternalUnchecked(name, null, userId); 9611 if (holder != null) { 9612 return holder.provider.getType(uri); 9613 } 9614 } catch (RemoteException e) { 9615 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9616 return null; 9617 } finally { 9618 // We need to clear the identity to call removeContentProviderExternalUnchecked 9619 if (!clearedIdentity) { 9620 ident = Binder.clearCallingIdentity(); 9621 } 9622 try { 9623 if (holder != null) { 9624 removeContentProviderExternalUnchecked(name, null, userId); 9625 } 9626 } finally { 9627 Binder.restoreCallingIdentity(ident); 9628 } 9629 } 9630 9631 return null; 9632 } 9633 9634 // ========================================================= 9635 // GLOBAL MANAGEMENT 9636 // ========================================================= 9637 9638 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9639 boolean isolated, int isolatedUid) { 9640 String proc = customProcess != null ? customProcess : info.processName; 9641 BatteryStatsImpl.Uid.Proc ps = null; 9642 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9643 int uid = info.uid; 9644 if (isolated) { 9645 if (isolatedUid == 0) { 9646 int userId = UserHandle.getUserId(uid); 9647 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9648 while (true) { 9649 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9650 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9651 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9652 } 9653 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9654 mNextIsolatedProcessUid++; 9655 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9656 // No process for this uid, use it. 9657 break; 9658 } 9659 stepsLeft--; 9660 if (stepsLeft <= 0) { 9661 return null; 9662 } 9663 } 9664 } else { 9665 // Special case for startIsolatedProcess (internal only), where 9666 // the uid of the isolated process is specified by the caller. 9667 uid = isolatedUid; 9668 } 9669 } 9670 return new ProcessRecord(stats, info, proc, uid); 9671 } 9672 9673 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9674 String abiOverride) { 9675 ProcessRecord app; 9676 if (!isolated) { 9677 app = getProcessRecordLocked(info.processName, info.uid, true); 9678 } else { 9679 app = null; 9680 } 9681 9682 if (app == null) { 9683 app = newProcessRecordLocked(info, null, isolated, 0); 9684 mProcessNames.put(info.processName, app.uid, app); 9685 if (isolated) { 9686 mIsolatedProcesses.put(app.uid, app); 9687 } 9688 updateLruProcessLocked(app, false, null); 9689 updateOomAdjLocked(); 9690 } 9691 9692 // This package really, really can not be stopped. 9693 try { 9694 AppGlobals.getPackageManager().setPackageStoppedState( 9695 info.packageName, false, UserHandle.getUserId(app.uid)); 9696 } catch (RemoteException e) { 9697 } catch (IllegalArgumentException e) { 9698 Slog.w(TAG, "Failed trying to unstop package " 9699 + info.packageName + ": " + e); 9700 } 9701 9702 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9703 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9704 app.persistent = true; 9705 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9706 } 9707 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9708 mPersistentStartingProcesses.add(app); 9709 startProcessLocked(app, "added application", app.processName, abiOverride, 9710 null /* entryPoint */, null /* entryPointArgs */); 9711 } 9712 9713 return app; 9714 } 9715 9716 public void unhandledBack() { 9717 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9718 "unhandledBack()"); 9719 9720 synchronized(this) { 9721 final long origId = Binder.clearCallingIdentity(); 9722 try { 9723 getFocusedStack().unhandledBackLocked(); 9724 } finally { 9725 Binder.restoreCallingIdentity(origId); 9726 } 9727 } 9728 } 9729 9730 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9731 enforceNotIsolatedCaller("openContentUri"); 9732 final int userId = UserHandle.getCallingUserId(); 9733 String name = uri.getAuthority(); 9734 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9735 ParcelFileDescriptor pfd = null; 9736 if (cph != null) { 9737 // We record the binder invoker's uid in thread-local storage before 9738 // going to the content provider to open the file. Later, in the code 9739 // that handles all permissions checks, we look for this uid and use 9740 // that rather than the Activity Manager's own uid. The effect is that 9741 // we do the check against the caller's permissions even though it looks 9742 // to the content provider like the Activity Manager itself is making 9743 // the request. 9744 sCallerIdentity.set(new Identity( 9745 Binder.getCallingPid(), Binder.getCallingUid())); 9746 try { 9747 pfd = cph.provider.openFile(null, uri, "r", null); 9748 } catch (FileNotFoundException e) { 9749 // do nothing; pfd will be returned null 9750 } finally { 9751 // Ensure that whatever happens, we clean up the identity state 9752 sCallerIdentity.remove(); 9753 } 9754 9755 // We've got the fd now, so we're done with the provider. 9756 removeContentProviderExternalUnchecked(name, null, userId); 9757 } else { 9758 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9759 } 9760 return pfd; 9761 } 9762 9763 // Actually is sleeping or shutting down or whatever else in the future 9764 // is an inactive state. 9765 public boolean isSleepingOrShuttingDown() { 9766 return mSleeping || mShuttingDown; 9767 } 9768 9769 public boolean isSleeping() { 9770 return mSleeping; 9771 } 9772 9773 void goingToSleep() { 9774 synchronized(this) { 9775 mWentToSleep = true; 9776 updateEventDispatchingLocked(); 9777 goToSleepIfNeededLocked(); 9778 } 9779 } 9780 9781 void finishRunningVoiceLocked() { 9782 if (mRunningVoice) { 9783 mRunningVoice = false; 9784 goToSleepIfNeededLocked(); 9785 } 9786 } 9787 9788 void goToSleepIfNeededLocked() { 9789 if (mWentToSleep && !mRunningVoice) { 9790 if (!mSleeping) { 9791 mSleeping = true; 9792 mStackSupervisor.goingToSleepLocked(); 9793 9794 // Initialize the wake times of all processes. 9795 checkExcessivePowerUsageLocked(false); 9796 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9797 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9798 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9799 } 9800 } 9801 } 9802 9803 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9804 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9805 // Never persist the home stack. 9806 return; 9807 } 9808 mTaskPersister.wakeup(task, flush); 9809 } 9810 9811 @Override 9812 public boolean shutdown(int timeout) { 9813 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9814 != PackageManager.PERMISSION_GRANTED) { 9815 throw new SecurityException("Requires permission " 9816 + android.Manifest.permission.SHUTDOWN); 9817 } 9818 9819 boolean timedout = false; 9820 9821 synchronized(this) { 9822 mShuttingDown = true; 9823 updateEventDispatchingLocked(); 9824 timedout = mStackSupervisor.shutdownLocked(timeout); 9825 } 9826 9827 mAppOpsService.shutdown(); 9828 if (mUsageStatsService != null) { 9829 mUsageStatsService.prepareShutdown(); 9830 } 9831 mBatteryStatsService.shutdown(); 9832 synchronized (this) { 9833 mProcessStats.shutdownLocked(); 9834 } 9835 notifyTaskPersisterLocked(null, true); 9836 9837 return timedout; 9838 } 9839 9840 public final void activitySlept(IBinder token) { 9841 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9842 9843 final long origId = Binder.clearCallingIdentity(); 9844 9845 synchronized (this) { 9846 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9847 if (r != null) { 9848 mStackSupervisor.activitySleptLocked(r); 9849 } 9850 } 9851 9852 Binder.restoreCallingIdentity(origId); 9853 } 9854 9855 void logLockScreen(String msg) { 9856 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9857 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9858 mWentToSleep + " mSleeping=" + mSleeping); 9859 } 9860 9861 private void comeOutOfSleepIfNeededLocked() { 9862 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9863 if (mSleeping) { 9864 mSleeping = false; 9865 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9866 } 9867 } 9868 } 9869 9870 void wakingUp() { 9871 synchronized(this) { 9872 mWentToSleep = false; 9873 updateEventDispatchingLocked(); 9874 comeOutOfSleepIfNeededLocked(); 9875 } 9876 } 9877 9878 void startRunningVoiceLocked() { 9879 if (!mRunningVoice) { 9880 mRunningVoice = true; 9881 comeOutOfSleepIfNeededLocked(); 9882 } 9883 } 9884 9885 private void updateEventDispatchingLocked() { 9886 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9887 } 9888 9889 public void setLockScreenShown(boolean shown) { 9890 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9891 != PackageManager.PERMISSION_GRANTED) { 9892 throw new SecurityException("Requires permission " 9893 + android.Manifest.permission.DEVICE_POWER); 9894 } 9895 9896 synchronized(this) { 9897 long ident = Binder.clearCallingIdentity(); 9898 try { 9899 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9900 mLockScreenShown = shown; 9901 comeOutOfSleepIfNeededLocked(); 9902 } finally { 9903 Binder.restoreCallingIdentity(ident); 9904 } 9905 } 9906 } 9907 9908 @Override 9909 public void stopAppSwitches() { 9910 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9911 != PackageManager.PERMISSION_GRANTED) { 9912 throw new SecurityException("Requires permission " 9913 + android.Manifest.permission.STOP_APP_SWITCHES); 9914 } 9915 9916 synchronized(this) { 9917 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9918 + APP_SWITCH_DELAY_TIME; 9919 mDidAppSwitch = false; 9920 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9921 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9922 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9923 } 9924 } 9925 9926 public void resumeAppSwitches() { 9927 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9928 != PackageManager.PERMISSION_GRANTED) { 9929 throw new SecurityException("Requires permission " 9930 + android.Manifest.permission.STOP_APP_SWITCHES); 9931 } 9932 9933 synchronized(this) { 9934 // Note that we don't execute any pending app switches... we will 9935 // let those wait until either the timeout, or the next start 9936 // activity request. 9937 mAppSwitchesAllowedTime = 0; 9938 } 9939 } 9940 9941 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9942 String name) { 9943 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9944 return true; 9945 } 9946 9947 final int perm = checkComponentPermission( 9948 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9949 callingUid, -1, true); 9950 if (perm == PackageManager.PERMISSION_GRANTED) { 9951 return true; 9952 } 9953 9954 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9955 return false; 9956 } 9957 9958 public void setDebugApp(String packageName, boolean waitForDebugger, 9959 boolean persistent) { 9960 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9961 "setDebugApp()"); 9962 9963 long ident = Binder.clearCallingIdentity(); 9964 try { 9965 // Note that this is not really thread safe if there are multiple 9966 // callers into it at the same time, but that's not a situation we 9967 // care about. 9968 if (persistent) { 9969 final ContentResolver resolver = mContext.getContentResolver(); 9970 Settings.Global.putString( 9971 resolver, Settings.Global.DEBUG_APP, 9972 packageName); 9973 Settings.Global.putInt( 9974 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9975 waitForDebugger ? 1 : 0); 9976 } 9977 9978 synchronized (this) { 9979 if (!persistent) { 9980 mOrigDebugApp = mDebugApp; 9981 mOrigWaitForDebugger = mWaitForDebugger; 9982 } 9983 mDebugApp = packageName; 9984 mWaitForDebugger = waitForDebugger; 9985 mDebugTransient = !persistent; 9986 if (packageName != null) { 9987 forceStopPackageLocked(packageName, -1, false, false, true, true, 9988 false, UserHandle.USER_ALL, "set debug app"); 9989 } 9990 } 9991 } finally { 9992 Binder.restoreCallingIdentity(ident); 9993 } 9994 } 9995 9996 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9997 synchronized (this) { 9998 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9999 if (!isDebuggable) { 10000 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10001 throw new SecurityException("Process not debuggable: " + app.packageName); 10002 } 10003 } 10004 10005 mOpenGlTraceApp = processName; 10006 } 10007 } 10008 10009 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10010 synchronized (this) { 10011 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10012 if (!isDebuggable) { 10013 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10014 throw new SecurityException("Process not debuggable: " + app.packageName); 10015 } 10016 } 10017 mProfileApp = processName; 10018 mProfileFile = profilerInfo.profileFile; 10019 if (mProfileFd != null) { 10020 try { 10021 mProfileFd.close(); 10022 } catch (IOException e) { 10023 } 10024 mProfileFd = null; 10025 } 10026 mProfileFd = profilerInfo.profileFd; 10027 mSamplingInterval = profilerInfo.samplingInterval; 10028 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10029 mProfileType = 0; 10030 } 10031 } 10032 10033 @Override 10034 public void setAlwaysFinish(boolean enabled) { 10035 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10036 "setAlwaysFinish()"); 10037 10038 Settings.Global.putInt( 10039 mContext.getContentResolver(), 10040 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10041 10042 synchronized (this) { 10043 mAlwaysFinishActivities = enabled; 10044 } 10045 } 10046 10047 @Override 10048 public void setActivityController(IActivityController controller) { 10049 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10050 "setActivityController()"); 10051 synchronized (this) { 10052 mController = controller; 10053 Watchdog.getInstance().setActivityController(controller); 10054 } 10055 } 10056 10057 @Override 10058 public void setUserIsMonkey(boolean userIsMonkey) { 10059 synchronized (this) { 10060 synchronized (mPidsSelfLocked) { 10061 final int callingPid = Binder.getCallingPid(); 10062 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10063 if (precessRecord == null) { 10064 throw new SecurityException("Unknown process: " + callingPid); 10065 } 10066 if (precessRecord.instrumentationUiAutomationConnection == null) { 10067 throw new SecurityException("Only an instrumentation process " 10068 + "with a UiAutomation can call setUserIsMonkey"); 10069 } 10070 } 10071 mUserIsMonkey = userIsMonkey; 10072 } 10073 } 10074 10075 @Override 10076 public boolean isUserAMonkey() { 10077 synchronized (this) { 10078 // If there is a controller also implies the user is a monkey. 10079 return (mUserIsMonkey || mController != null); 10080 } 10081 } 10082 10083 public void requestBugReport() { 10084 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10085 SystemProperties.set("ctl.start", "bugreport"); 10086 } 10087 10088 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10089 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10090 } 10091 10092 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10093 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10094 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10095 } 10096 return KEY_DISPATCHING_TIMEOUT; 10097 } 10098 10099 @Override 10100 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10101 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10102 != PackageManager.PERMISSION_GRANTED) { 10103 throw new SecurityException("Requires permission " 10104 + android.Manifest.permission.FILTER_EVENTS); 10105 } 10106 ProcessRecord proc; 10107 long timeout; 10108 synchronized (this) { 10109 synchronized (mPidsSelfLocked) { 10110 proc = mPidsSelfLocked.get(pid); 10111 } 10112 timeout = getInputDispatchingTimeoutLocked(proc); 10113 } 10114 10115 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10116 return -1; 10117 } 10118 10119 return timeout; 10120 } 10121 10122 /** 10123 * Handle input dispatching timeouts. 10124 * Returns whether input dispatching should be aborted or not. 10125 */ 10126 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10127 final ActivityRecord activity, final ActivityRecord parent, 10128 final boolean aboveSystem, String reason) { 10129 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10130 != PackageManager.PERMISSION_GRANTED) { 10131 throw new SecurityException("Requires permission " 10132 + android.Manifest.permission.FILTER_EVENTS); 10133 } 10134 10135 final String annotation; 10136 if (reason == null) { 10137 annotation = "Input dispatching timed out"; 10138 } else { 10139 annotation = "Input dispatching timed out (" + reason + ")"; 10140 } 10141 10142 if (proc != null) { 10143 synchronized (this) { 10144 if (proc.debugging) { 10145 return false; 10146 } 10147 10148 if (mDidDexOpt) { 10149 // Give more time since we were dexopting. 10150 mDidDexOpt = false; 10151 return false; 10152 } 10153 10154 if (proc.instrumentationClass != null) { 10155 Bundle info = new Bundle(); 10156 info.putString("shortMsg", "keyDispatchingTimedOut"); 10157 info.putString("longMsg", annotation); 10158 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10159 return true; 10160 } 10161 } 10162 mHandler.post(new Runnable() { 10163 @Override 10164 public void run() { 10165 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10166 } 10167 }); 10168 } 10169 10170 return true; 10171 } 10172 10173 public Bundle getAssistContextExtras(int requestType) { 10174 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10175 "getAssistContextExtras()"); 10176 PendingAssistExtras pae; 10177 Bundle extras = new Bundle(); 10178 synchronized (this) { 10179 ActivityRecord activity = getFocusedStack().mResumedActivity; 10180 if (activity == null) { 10181 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10182 return null; 10183 } 10184 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10185 if (activity.app == null || activity.app.thread == null) { 10186 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10187 return extras; 10188 } 10189 if (activity.app.pid == Binder.getCallingPid()) { 10190 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10191 return extras; 10192 } 10193 pae = new PendingAssistExtras(activity); 10194 try { 10195 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10196 requestType); 10197 mPendingAssistExtras.add(pae); 10198 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10199 } catch (RemoteException e) { 10200 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10201 return extras; 10202 } 10203 } 10204 synchronized (pae) { 10205 while (!pae.haveResult) { 10206 try { 10207 pae.wait(); 10208 } catch (InterruptedException e) { 10209 } 10210 } 10211 if (pae.result != null) { 10212 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10213 } 10214 } 10215 synchronized (this) { 10216 mPendingAssistExtras.remove(pae); 10217 mHandler.removeCallbacks(pae); 10218 } 10219 return extras; 10220 } 10221 10222 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10223 PendingAssistExtras pae = (PendingAssistExtras)token; 10224 synchronized (pae) { 10225 pae.result = extras; 10226 pae.haveResult = true; 10227 pae.notifyAll(); 10228 } 10229 } 10230 10231 public void registerProcessObserver(IProcessObserver observer) { 10232 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10233 "registerProcessObserver()"); 10234 synchronized (this) { 10235 mProcessObservers.register(observer); 10236 } 10237 } 10238 10239 @Override 10240 public void unregisterProcessObserver(IProcessObserver observer) { 10241 synchronized (this) { 10242 mProcessObservers.unregister(observer); 10243 } 10244 } 10245 10246 @Override 10247 public boolean convertFromTranslucent(IBinder token) { 10248 final long origId = Binder.clearCallingIdentity(); 10249 try { 10250 synchronized (this) { 10251 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10252 if (r == null) { 10253 return false; 10254 } 10255 if (r.changeWindowTranslucency(true)) { 10256 mWindowManager.setAppFullscreen(token, true); 10257 r.task.stack.releaseBackgroundResources(); 10258 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10259 return true; 10260 } 10261 return false; 10262 } 10263 } finally { 10264 Binder.restoreCallingIdentity(origId); 10265 } 10266 } 10267 10268 @Override 10269 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10270 final long origId = Binder.clearCallingIdentity(); 10271 try { 10272 synchronized (this) { 10273 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10274 if (r == null) { 10275 return false; 10276 } 10277 int index = r.task.mActivities.lastIndexOf(r); 10278 if (index > 0) { 10279 ActivityRecord under = r.task.mActivities.get(index - 1); 10280 under.returningOptions = options; 10281 } 10282 if (r.changeWindowTranslucency(false)) { 10283 r.task.stack.convertToTranslucent(r); 10284 mWindowManager.setAppFullscreen(token, false); 10285 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10286 return true; 10287 } else { 10288 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10289 return false; 10290 } 10291 } 10292 } finally { 10293 Binder.restoreCallingIdentity(origId); 10294 } 10295 } 10296 10297 @Override 10298 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10299 final long origId = Binder.clearCallingIdentity(); 10300 try { 10301 synchronized (this) { 10302 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10303 if (r != null) { 10304 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10305 } 10306 } 10307 return false; 10308 } finally { 10309 Binder.restoreCallingIdentity(origId); 10310 } 10311 } 10312 10313 @Override 10314 public boolean isBackgroundVisibleBehind(IBinder token) { 10315 final long origId = Binder.clearCallingIdentity(); 10316 try { 10317 synchronized (this) { 10318 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10319 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10320 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10321 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10322 return visible; 10323 } 10324 } finally { 10325 Binder.restoreCallingIdentity(origId); 10326 } 10327 } 10328 10329 @Override 10330 public ActivityOptions getActivityOptions(IBinder token) { 10331 final long origId = Binder.clearCallingIdentity(); 10332 try { 10333 synchronized (this) { 10334 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10335 if (r != null) { 10336 final ActivityOptions activityOptions = r.pendingOptions; 10337 r.pendingOptions = null; 10338 return activityOptions; 10339 } 10340 return null; 10341 } 10342 } finally { 10343 Binder.restoreCallingIdentity(origId); 10344 } 10345 } 10346 10347 @Override 10348 public void setImmersive(IBinder token, boolean immersive) { 10349 synchronized(this) { 10350 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10351 if (r == null) { 10352 throw new IllegalArgumentException(); 10353 } 10354 r.immersive = immersive; 10355 10356 // update associated state if we're frontmost 10357 if (r == mFocusedActivity) { 10358 if (DEBUG_IMMERSIVE) { 10359 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10360 } 10361 applyUpdateLockStateLocked(r); 10362 } 10363 } 10364 } 10365 10366 @Override 10367 public boolean isImmersive(IBinder token) { 10368 synchronized (this) { 10369 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10370 if (r == null) { 10371 throw new IllegalArgumentException(); 10372 } 10373 return r.immersive; 10374 } 10375 } 10376 10377 public boolean isTopActivityImmersive() { 10378 enforceNotIsolatedCaller("startActivity"); 10379 synchronized (this) { 10380 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10381 return (r != null) ? r.immersive : false; 10382 } 10383 } 10384 10385 @Override 10386 public boolean isTopOfTask(IBinder token) { 10387 synchronized (this) { 10388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10389 if (r == null) { 10390 throw new IllegalArgumentException(); 10391 } 10392 return r.task.getTopActivity() == r; 10393 } 10394 } 10395 10396 public final void enterSafeMode() { 10397 synchronized(this) { 10398 // It only makes sense to do this before the system is ready 10399 // and started launching other packages. 10400 if (!mSystemReady) { 10401 try { 10402 AppGlobals.getPackageManager().enterSafeMode(); 10403 } catch (RemoteException e) { 10404 } 10405 } 10406 10407 mSafeMode = true; 10408 } 10409 } 10410 10411 public final void showSafeModeOverlay() { 10412 View v = LayoutInflater.from(mContext).inflate( 10413 com.android.internal.R.layout.safe_mode, null); 10414 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10415 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10416 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10417 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10418 lp.gravity = Gravity.BOTTOM | Gravity.START; 10419 lp.format = v.getBackground().getOpacity(); 10420 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10421 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10422 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10423 ((WindowManager)mContext.getSystemService( 10424 Context.WINDOW_SERVICE)).addView(v, lp); 10425 } 10426 10427 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10428 if (!(sender instanceof PendingIntentRecord)) { 10429 return; 10430 } 10431 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10432 synchronized (stats) { 10433 if (mBatteryStatsService.isOnBattery()) { 10434 mBatteryStatsService.enforceCallingPermission(); 10435 PendingIntentRecord rec = (PendingIntentRecord)sender; 10436 int MY_UID = Binder.getCallingUid(); 10437 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10438 BatteryStatsImpl.Uid.Pkg pkg = 10439 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10440 sourcePkg != null ? sourcePkg : rec.key.packageName); 10441 pkg.incWakeupsLocked(); 10442 } 10443 } 10444 } 10445 10446 public boolean killPids(int[] pids, String pReason, boolean secure) { 10447 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10448 throw new SecurityException("killPids only available to the system"); 10449 } 10450 String reason = (pReason == null) ? "Unknown" : pReason; 10451 // XXX Note: don't acquire main activity lock here, because the window 10452 // manager calls in with its locks held. 10453 10454 boolean killed = false; 10455 synchronized (mPidsSelfLocked) { 10456 int[] types = new int[pids.length]; 10457 int worstType = 0; 10458 for (int i=0; i<pids.length; i++) { 10459 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10460 if (proc != null) { 10461 int type = proc.setAdj; 10462 types[i] = type; 10463 if (type > worstType) { 10464 worstType = type; 10465 } 10466 } 10467 } 10468 10469 // If the worst oom_adj is somewhere in the cached proc LRU range, 10470 // then constrain it so we will kill all cached procs. 10471 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10472 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10473 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10474 } 10475 10476 // If this is not a secure call, don't let it kill processes that 10477 // are important. 10478 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10479 worstType = ProcessList.SERVICE_ADJ; 10480 } 10481 10482 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10483 for (int i=0; i<pids.length; i++) { 10484 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10485 if (proc == null) { 10486 continue; 10487 } 10488 int adj = proc.setAdj; 10489 if (adj >= worstType && !proc.killedByAm) { 10490 proc.kill(reason, true); 10491 killed = true; 10492 } 10493 } 10494 } 10495 return killed; 10496 } 10497 10498 @Override 10499 public void killUid(int uid, String reason) { 10500 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10501 throw new SecurityException("killUid only available to the system"); 10502 } 10503 synchronized (this) { 10504 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10505 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10506 reason != null ? reason : "kill uid"); 10507 } 10508 } 10509 10510 @Override 10511 public boolean killProcessesBelowForeground(String reason) { 10512 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10513 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10514 } 10515 10516 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10517 } 10518 10519 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10520 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10521 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10522 } 10523 10524 boolean killed = false; 10525 synchronized (mPidsSelfLocked) { 10526 final int size = mPidsSelfLocked.size(); 10527 for (int i = 0; i < size; i++) { 10528 final int pid = mPidsSelfLocked.keyAt(i); 10529 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10530 if (proc == null) continue; 10531 10532 final int adj = proc.setAdj; 10533 if (adj > belowAdj && !proc.killedByAm) { 10534 proc.kill(reason, true); 10535 killed = true; 10536 } 10537 } 10538 } 10539 return killed; 10540 } 10541 10542 @Override 10543 public void hang(final IBinder who, boolean allowRestart) { 10544 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10545 != PackageManager.PERMISSION_GRANTED) { 10546 throw new SecurityException("Requires permission " 10547 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10548 } 10549 10550 final IBinder.DeathRecipient death = new DeathRecipient() { 10551 @Override 10552 public void binderDied() { 10553 synchronized (this) { 10554 notifyAll(); 10555 } 10556 } 10557 }; 10558 10559 try { 10560 who.linkToDeath(death, 0); 10561 } catch (RemoteException e) { 10562 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10563 return; 10564 } 10565 10566 synchronized (this) { 10567 Watchdog.getInstance().setAllowRestart(allowRestart); 10568 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10569 synchronized (death) { 10570 while (who.isBinderAlive()) { 10571 try { 10572 death.wait(); 10573 } catch (InterruptedException e) { 10574 } 10575 } 10576 } 10577 Watchdog.getInstance().setAllowRestart(true); 10578 } 10579 } 10580 10581 @Override 10582 public void restart() { 10583 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10584 != PackageManager.PERMISSION_GRANTED) { 10585 throw new SecurityException("Requires permission " 10586 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10587 } 10588 10589 Log.i(TAG, "Sending shutdown broadcast..."); 10590 10591 BroadcastReceiver br = new BroadcastReceiver() { 10592 @Override public void onReceive(Context context, Intent intent) { 10593 // Now the broadcast is done, finish up the low-level shutdown. 10594 Log.i(TAG, "Shutting down activity manager..."); 10595 shutdown(10000); 10596 Log.i(TAG, "Shutdown complete, restarting!"); 10597 Process.killProcess(Process.myPid()); 10598 System.exit(10); 10599 } 10600 }; 10601 10602 // First send the high-level shut down broadcast. 10603 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10604 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10605 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10606 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10607 mContext.sendOrderedBroadcastAsUser(intent, 10608 UserHandle.ALL, null, br, mHandler, 0, null, null); 10609 */ 10610 br.onReceive(mContext, intent); 10611 } 10612 10613 private long getLowRamTimeSinceIdle(long now) { 10614 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10615 } 10616 10617 @Override 10618 public void performIdleMaintenance() { 10619 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10620 != PackageManager.PERMISSION_GRANTED) { 10621 throw new SecurityException("Requires permission " 10622 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10623 } 10624 10625 synchronized (this) { 10626 final long now = SystemClock.uptimeMillis(); 10627 final long timeSinceLastIdle = now - mLastIdleTime; 10628 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10629 mLastIdleTime = now; 10630 mLowRamTimeSinceLastIdle = 0; 10631 if (mLowRamStartTime != 0) { 10632 mLowRamStartTime = now; 10633 } 10634 10635 StringBuilder sb = new StringBuilder(128); 10636 sb.append("Idle maintenance over "); 10637 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10638 sb.append(" low RAM for "); 10639 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10640 Slog.i(TAG, sb.toString()); 10641 10642 // If at least 1/3 of our time since the last idle period has been spent 10643 // with RAM low, then we want to kill processes. 10644 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10645 10646 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10647 ProcessRecord proc = mLruProcesses.get(i); 10648 if (proc.notCachedSinceIdle) { 10649 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10650 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10651 if (doKilling && proc.initialIdlePss != 0 10652 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10653 proc.kill("idle maint (pss " + proc.lastPss 10654 + " from " + proc.initialIdlePss + ")", true); 10655 } 10656 } 10657 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10658 proc.notCachedSinceIdle = true; 10659 proc.initialIdlePss = 0; 10660 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10661 isSleeping(), now); 10662 } 10663 } 10664 10665 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10666 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10667 } 10668 } 10669 10670 private void retrieveSettings() { 10671 final ContentResolver resolver = mContext.getContentResolver(); 10672 String debugApp = Settings.Global.getString( 10673 resolver, Settings.Global.DEBUG_APP); 10674 boolean waitForDebugger = Settings.Global.getInt( 10675 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10676 boolean alwaysFinishActivities = Settings.Global.getInt( 10677 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10678 boolean forceRtl = Settings.Global.getInt( 10679 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10680 // Transfer any global setting for forcing RTL layout, into a System Property 10681 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10682 10683 Configuration configuration = new Configuration(); 10684 Settings.System.getConfiguration(resolver, configuration); 10685 if (forceRtl) { 10686 // This will take care of setting the correct layout direction flags 10687 configuration.setLayoutDirection(configuration.locale); 10688 } 10689 10690 synchronized (this) { 10691 mDebugApp = mOrigDebugApp = debugApp; 10692 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10693 mAlwaysFinishActivities = alwaysFinishActivities; 10694 // This happens before any activities are started, so we can 10695 // change mConfiguration in-place. 10696 updateConfigurationLocked(configuration, null, false, true); 10697 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10698 } 10699 } 10700 10701 /** Loads resources after the current configuration has been set. */ 10702 private void loadResourcesOnSystemReady() { 10703 final Resources res = mContext.getResources(); 10704 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10705 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10706 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10707 } 10708 10709 public boolean testIsSystemReady() { 10710 // no need to synchronize(this) just to read & return the value 10711 return mSystemReady; 10712 } 10713 10714 private static File getCalledPreBootReceiversFile() { 10715 File dataDir = Environment.getDataDirectory(); 10716 File systemDir = new File(dataDir, "system"); 10717 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10718 return fname; 10719 } 10720 10721 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10722 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10723 File file = getCalledPreBootReceiversFile(); 10724 FileInputStream fis = null; 10725 try { 10726 fis = new FileInputStream(file); 10727 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10728 int fvers = dis.readInt(); 10729 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10730 String vers = dis.readUTF(); 10731 String codename = dis.readUTF(); 10732 String build = dis.readUTF(); 10733 if (android.os.Build.VERSION.RELEASE.equals(vers) 10734 && android.os.Build.VERSION.CODENAME.equals(codename) 10735 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10736 int num = dis.readInt(); 10737 while (num > 0) { 10738 num--; 10739 String pkg = dis.readUTF(); 10740 String cls = dis.readUTF(); 10741 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10742 } 10743 } 10744 } 10745 } catch (FileNotFoundException e) { 10746 } catch (IOException e) { 10747 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10748 } finally { 10749 if (fis != null) { 10750 try { 10751 fis.close(); 10752 } catch (IOException e) { 10753 } 10754 } 10755 } 10756 return lastDoneReceivers; 10757 } 10758 10759 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10760 File file = getCalledPreBootReceiversFile(); 10761 FileOutputStream fos = null; 10762 DataOutputStream dos = null; 10763 try { 10764 fos = new FileOutputStream(file); 10765 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10766 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10767 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10768 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10769 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10770 dos.writeInt(list.size()); 10771 for (int i=0; i<list.size(); i++) { 10772 dos.writeUTF(list.get(i).getPackageName()); 10773 dos.writeUTF(list.get(i).getClassName()); 10774 } 10775 } catch (IOException e) { 10776 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10777 file.delete(); 10778 } finally { 10779 FileUtils.sync(fos); 10780 if (dos != null) { 10781 try { 10782 dos.close(); 10783 } catch (IOException e) { 10784 // TODO Auto-generated catch block 10785 e.printStackTrace(); 10786 } 10787 } 10788 } 10789 } 10790 10791 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10792 ArrayList<ComponentName> doneReceivers, int userId) { 10793 boolean waitingUpdate = false; 10794 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10795 List<ResolveInfo> ris = null; 10796 try { 10797 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10798 intent, null, 0, userId); 10799 } catch (RemoteException e) { 10800 } 10801 if (ris != null) { 10802 for (int i=ris.size()-1; i>=0; i--) { 10803 if ((ris.get(i).activityInfo.applicationInfo.flags 10804 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10805 ris.remove(i); 10806 } 10807 } 10808 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10809 10810 // For User 0, load the version number. When delivering to a new user, deliver 10811 // to all receivers. 10812 if (userId == UserHandle.USER_OWNER) { 10813 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10814 for (int i=0; i<ris.size(); i++) { 10815 ActivityInfo ai = ris.get(i).activityInfo; 10816 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10817 if (lastDoneReceivers.contains(comp)) { 10818 // We already did the pre boot receiver for this app with the current 10819 // platform version, so don't do it again... 10820 ris.remove(i); 10821 i--; 10822 // ...however, do keep it as one that has been done, so we don't 10823 // forget about it when rewriting the file of last done receivers. 10824 doneReceivers.add(comp); 10825 } 10826 } 10827 } 10828 10829 // If primary user, send broadcast to all available users, else just to userId 10830 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10831 : new int[] { userId }; 10832 for (int i = 0; i < ris.size(); i++) { 10833 ActivityInfo ai = ris.get(i).activityInfo; 10834 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10835 doneReceivers.add(comp); 10836 intent.setComponent(comp); 10837 for (int j=0; j<users.length; j++) { 10838 IIntentReceiver finisher = null; 10839 // On last receiver and user, set up a completion callback 10840 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10841 finisher = new IIntentReceiver.Stub() { 10842 public void performReceive(Intent intent, int resultCode, 10843 String data, Bundle extras, boolean ordered, 10844 boolean sticky, int sendingUser) { 10845 // The raw IIntentReceiver interface is called 10846 // with the AM lock held, so redispatch to 10847 // execute our code without the lock. 10848 mHandler.post(onFinishCallback); 10849 } 10850 }; 10851 } 10852 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10853 + " for user " + users[j]); 10854 broadcastIntentLocked(null, null, intent, null, finisher, 10855 0, null, null, null, AppOpsManager.OP_NONE, 10856 true, false, MY_PID, Process.SYSTEM_UID, 10857 users[j]); 10858 if (finisher != null) { 10859 waitingUpdate = true; 10860 } 10861 } 10862 } 10863 } 10864 10865 return waitingUpdate; 10866 } 10867 10868 public void systemReady(final Runnable goingCallback) { 10869 synchronized(this) { 10870 if (mSystemReady) { 10871 // If we're done calling all the receivers, run the next "boot phase" passed in 10872 // by the SystemServer 10873 if (goingCallback != null) { 10874 goingCallback.run(); 10875 } 10876 return; 10877 } 10878 10879 // Make sure we have the current profile info, since it is needed for 10880 // security checks. 10881 updateCurrentProfileIdsLocked(); 10882 10883 if (mRecentTasks == null) { 10884 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10885 if (!mRecentTasks.isEmpty()) { 10886 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10887 } 10888 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10889 mTaskPersister.startPersisting(); 10890 } 10891 10892 // Check to see if there are any update receivers to run. 10893 if (!mDidUpdate) { 10894 if (mWaitingUpdate) { 10895 return; 10896 } 10897 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10898 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10899 public void run() { 10900 synchronized (ActivityManagerService.this) { 10901 mDidUpdate = true; 10902 } 10903 writeLastDonePreBootReceivers(doneReceivers); 10904 showBootMessage(mContext.getText( 10905 R.string.android_upgrading_complete), 10906 false); 10907 systemReady(goingCallback); 10908 } 10909 }, doneReceivers, UserHandle.USER_OWNER); 10910 10911 if (mWaitingUpdate) { 10912 return; 10913 } 10914 mDidUpdate = true; 10915 } 10916 10917 mAppOpsService.systemReady(); 10918 mSystemReady = true; 10919 } 10920 10921 ArrayList<ProcessRecord> procsToKill = null; 10922 synchronized(mPidsSelfLocked) { 10923 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10924 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10925 if (!isAllowedWhileBooting(proc.info)){ 10926 if (procsToKill == null) { 10927 procsToKill = new ArrayList<ProcessRecord>(); 10928 } 10929 procsToKill.add(proc); 10930 } 10931 } 10932 } 10933 10934 synchronized(this) { 10935 if (procsToKill != null) { 10936 for (int i=procsToKill.size()-1; i>=0; i--) { 10937 ProcessRecord proc = procsToKill.get(i); 10938 Slog.i(TAG, "Removing system update proc: " + proc); 10939 removeProcessLocked(proc, true, false, "system update done"); 10940 } 10941 } 10942 10943 // Now that we have cleaned up any update processes, we 10944 // are ready to start launching real processes and know that 10945 // we won't trample on them any more. 10946 mProcessesReady = true; 10947 } 10948 10949 Slog.i(TAG, "System now ready"); 10950 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10951 SystemClock.uptimeMillis()); 10952 10953 synchronized(this) { 10954 // Make sure we have no pre-ready processes sitting around. 10955 10956 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10957 ResolveInfo ri = mContext.getPackageManager() 10958 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10959 STOCK_PM_FLAGS); 10960 CharSequence errorMsg = null; 10961 if (ri != null) { 10962 ActivityInfo ai = ri.activityInfo; 10963 ApplicationInfo app = ai.applicationInfo; 10964 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10965 mTopAction = Intent.ACTION_FACTORY_TEST; 10966 mTopData = null; 10967 mTopComponent = new ComponentName(app.packageName, 10968 ai.name); 10969 } else { 10970 errorMsg = mContext.getResources().getText( 10971 com.android.internal.R.string.factorytest_not_system); 10972 } 10973 } else { 10974 errorMsg = mContext.getResources().getText( 10975 com.android.internal.R.string.factorytest_no_action); 10976 } 10977 if (errorMsg != null) { 10978 mTopAction = null; 10979 mTopData = null; 10980 mTopComponent = null; 10981 Message msg = Message.obtain(); 10982 msg.what = SHOW_FACTORY_ERROR_MSG; 10983 msg.getData().putCharSequence("msg", errorMsg); 10984 mHandler.sendMessage(msg); 10985 } 10986 } 10987 } 10988 10989 retrieveSettings(); 10990 loadResourcesOnSystemReady(); 10991 10992 synchronized (this) { 10993 readGrantedUriPermissionsLocked(); 10994 } 10995 10996 if (goingCallback != null) goingCallback.run(); 10997 10998 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10999 Integer.toString(mCurrentUserId), mCurrentUserId); 11000 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11001 Integer.toString(mCurrentUserId), mCurrentUserId); 11002 mSystemServiceManager.startUser(mCurrentUserId); 11003 11004 synchronized (this) { 11005 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11006 try { 11007 List apps = AppGlobals.getPackageManager(). 11008 getPersistentApplications(STOCK_PM_FLAGS); 11009 if (apps != null) { 11010 int N = apps.size(); 11011 int i; 11012 for (i=0; i<N; i++) { 11013 ApplicationInfo info 11014 = (ApplicationInfo)apps.get(i); 11015 if (info != null && 11016 !info.packageName.equals("android")) { 11017 addAppLocked(info, false, null /* ABI override */); 11018 } 11019 } 11020 } 11021 } catch (RemoteException ex) { 11022 // pm is in same process, this will never happen. 11023 } 11024 } 11025 11026 // Start up initial activity. 11027 mBooting = true; 11028 11029 try { 11030 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11031 Message msg = Message.obtain(); 11032 msg.what = SHOW_UID_ERROR_MSG; 11033 mHandler.sendMessage(msg); 11034 } 11035 } catch (RemoteException e) { 11036 } 11037 11038 long ident = Binder.clearCallingIdentity(); 11039 try { 11040 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11041 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11042 | Intent.FLAG_RECEIVER_FOREGROUND); 11043 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11044 broadcastIntentLocked(null, null, intent, 11045 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11046 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11047 intent = new Intent(Intent.ACTION_USER_STARTING); 11048 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11049 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11050 broadcastIntentLocked(null, null, intent, 11051 null, new IIntentReceiver.Stub() { 11052 @Override 11053 public void performReceive(Intent intent, int resultCode, String data, 11054 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11055 throws RemoteException { 11056 } 11057 }, 0, null, null, 11058 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11059 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11060 } catch (Throwable t) { 11061 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11062 } finally { 11063 Binder.restoreCallingIdentity(ident); 11064 } 11065 mStackSupervisor.resumeTopActivitiesLocked(); 11066 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11067 } 11068 } 11069 11070 private boolean makeAppCrashingLocked(ProcessRecord app, 11071 String shortMsg, String longMsg, String stackTrace) { 11072 app.crashing = true; 11073 app.crashingReport = generateProcessError(app, 11074 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11075 startAppProblemLocked(app); 11076 app.stopFreezingAllLocked(); 11077 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11078 } 11079 11080 private void makeAppNotRespondingLocked(ProcessRecord app, 11081 String activity, String shortMsg, String longMsg) { 11082 app.notResponding = true; 11083 app.notRespondingReport = generateProcessError(app, 11084 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11085 activity, shortMsg, longMsg, null); 11086 startAppProblemLocked(app); 11087 app.stopFreezingAllLocked(); 11088 } 11089 11090 /** 11091 * Generate a process error record, suitable for attachment to a ProcessRecord. 11092 * 11093 * @param app The ProcessRecord in which the error occurred. 11094 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11095 * ActivityManager.AppErrorStateInfo 11096 * @param activity The activity associated with the crash, if known. 11097 * @param shortMsg Short message describing the crash. 11098 * @param longMsg Long message describing the crash. 11099 * @param stackTrace Full crash stack trace, may be null. 11100 * 11101 * @return Returns a fully-formed AppErrorStateInfo record. 11102 */ 11103 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11104 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11105 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11106 11107 report.condition = condition; 11108 report.processName = app.processName; 11109 report.pid = app.pid; 11110 report.uid = app.info.uid; 11111 report.tag = activity; 11112 report.shortMsg = shortMsg; 11113 report.longMsg = longMsg; 11114 report.stackTrace = stackTrace; 11115 11116 return report; 11117 } 11118 11119 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11120 synchronized (this) { 11121 app.crashing = false; 11122 app.crashingReport = null; 11123 app.notResponding = false; 11124 app.notRespondingReport = null; 11125 if (app.anrDialog == fromDialog) { 11126 app.anrDialog = null; 11127 } 11128 if (app.waitDialog == fromDialog) { 11129 app.waitDialog = null; 11130 } 11131 if (app.pid > 0 && app.pid != MY_PID) { 11132 handleAppCrashLocked(app, null, null, null); 11133 app.kill("user request after error", true); 11134 } 11135 } 11136 } 11137 11138 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11139 String stackTrace) { 11140 long now = SystemClock.uptimeMillis(); 11141 11142 Long crashTime; 11143 if (!app.isolated) { 11144 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11145 } else { 11146 crashTime = null; 11147 } 11148 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11149 // This process loses! 11150 Slog.w(TAG, "Process " + app.info.processName 11151 + " has crashed too many times: killing!"); 11152 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11153 app.userId, app.info.processName, app.uid); 11154 mStackSupervisor.handleAppCrashLocked(app); 11155 if (!app.persistent) { 11156 // We don't want to start this process again until the user 11157 // explicitly does so... but for persistent process, we really 11158 // need to keep it running. If a persistent process is actually 11159 // repeatedly crashing, then badness for everyone. 11160 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11161 app.info.processName); 11162 if (!app.isolated) { 11163 // XXX We don't have a way to mark isolated processes 11164 // as bad, since they don't have a peristent identity. 11165 mBadProcesses.put(app.info.processName, app.uid, 11166 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11167 mProcessCrashTimes.remove(app.info.processName, app.uid); 11168 } 11169 app.bad = true; 11170 app.removed = true; 11171 // Don't let services in this process be restarted and potentially 11172 // annoy the user repeatedly. Unless it is persistent, since those 11173 // processes run critical code. 11174 removeProcessLocked(app, false, false, "crash"); 11175 mStackSupervisor.resumeTopActivitiesLocked(); 11176 return false; 11177 } 11178 mStackSupervisor.resumeTopActivitiesLocked(); 11179 } else { 11180 mStackSupervisor.finishTopRunningActivityLocked(app); 11181 } 11182 11183 // Bump up the crash count of any services currently running in the proc. 11184 for (int i=app.services.size()-1; i>=0; i--) { 11185 // Any services running in the application need to be placed 11186 // back in the pending list. 11187 ServiceRecord sr = app.services.valueAt(i); 11188 sr.crashCount++; 11189 } 11190 11191 // If the crashing process is what we consider to be the "home process" and it has been 11192 // replaced by a third-party app, clear the package preferred activities from packages 11193 // with a home activity running in the process to prevent a repeatedly crashing app 11194 // from blocking the user to manually clear the list. 11195 final ArrayList<ActivityRecord> activities = app.activities; 11196 if (app == mHomeProcess && activities.size() > 0 11197 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11198 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11199 final ActivityRecord r = activities.get(activityNdx); 11200 if (r.isHomeActivity()) { 11201 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11202 try { 11203 ActivityThread.getPackageManager() 11204 .clearPackagePreferredActivities(r.packageName); 11205 } catch (RemoteException c) { 11206 // pm is in same process, this will never happen. 11207 } 11208 } 11209 } 11210 } 11211 11212 if (!app.isolated) { 11213 // XXX Can't keep track of crash times for isolated processes, 11214 // because they don't have a perisistent identity. 11215 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11216 } 11217 11218 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11219 return true; 11220 } 11221 11222 void startAppProblemLocked(ProcessRecord app) { 11223 // If this app is not running under the current user, then we 11224 // can't give it a report button because that would require 11225 // launching the report UI under a different user. 11226 app.errorReportReceiver = null; 11227 11228 for (int userId : mCurrentProfileIds) { 11229 if (app.userId == userId) { 11230 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11231 mContext, app.info.packageName, app.info.flags); 11232 } 11233 } 11234 skipCurrentReceiverLocked(app); 11235 } 11236 11237 void skipCurrentReceiverLocked(ProcessRecord app) { 11238 for (BroadcastQueue queue : mBroadcastQueues) { 11239 queue.skipCurrentReceiverLocked(app); 11240 } 11241 } 11242 11243 /** 11244 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11245 * The application process will exit immediately after this call returns. 11246 * @param app object of the crashing app, null for the system server 11247 * @param crashInfo describing the exception 11248 */ 11249 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11250 ProcessRecord r = findAppProcess(app, "Crash"); 11251 final String processName = app == null ? "system_server" 11252 : (r == null ? "unknown" : r.processName); 11253 11254 handleApplicationCrashInner("crash", r, processName, crashInfo); 11255 } 11256 11257 /* Native crash reporting uses this inner version because it needs to be somewhat 11258 * decoupled from the AM-managed cleanup lifecycle 11259 */ 11260 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11261 ApplicationErrorReport.CrashInfo crashInfo) { 11262 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11263 UserHandle.getUserId(Binder.getCallingUid()), processName, 11264 r == null ? -1 : r.info.flags, 11265 crashInfo.exceptionClassName, 11266 crashInfo.exceptionMessage, 11267 crashInfo.throwFileName, 11268 crashInfo.throwLineNumber); 11269 11270 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11271 11272 crashApplication(r, crashInfo); 11273 } 11274 11275 public void handleApplicationStrictModeViolation( 11276 IBinder app, 11277 int violationMask, 11278 StrictMode.ViolationInfo info) { 11279 ProcessRecord r = findAppProcess(app, "StrictMode"); 11280 if (r == null) { 11281 return; 11282 } 11283 11284 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11285 Integer stackFingerprint = info.hashCode(); 11286 boolean logIt = true; 11287 synchronized (mAlreadyLoggedViolatedStacks) { 11288 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11289 logIt = false; 11290 // TODO: sub-sample into EventLog for these, with 11291 // the info.durationMillis? Then we'd get 11292 // the relative pain numbers, without logging all 11293 // the stack traces repeatedly. We'd want to do 11294 // likewise in the client code, which also does 11295 // dup suppression, before the Binder call. 11296 } else { 11297 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11298 mAlreadyLoggedViolatedStacks.clear(); 11299 } 11300 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11301 } 11302 } 11303 if (logIt) { 11304 logStrictModeViolationToDropBox(r, info); 11305 } 11306 } 11307 11308 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11309 AppErrorResult result = new AppErrorResult(); 11310 synchronized (this) { 11311 final long origId = Binder.clearCallingIdentity(); 11312 11313 Message msg = Message.obtain(); 11314 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11315 HashMap<String, Object> data = new HashMap<String, Object>(); 11316 data.put("result", result); 11317 data.put("app", r); 11318 data.put("violationMask", violationMask); 11319 data.put("info", info); 11320 msg.obj = data; 11321 mHandler.sendMessage(msg); 11322 11323 Binder.restoreCallingIdentity(origId); 11324 } 11325 int res = result.get(); 11326 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11327 } 11328 } 11329 11330 // Depending on the policy in effect, there could be a bunch of 11331 // these in quick succession so we try to batch these together to 11332 // minimize disk writes, number of dropbox entries, and maximize 11333 // compression, by having more fewer, larger records. 11334 private void logStrictModeViolationToDropBox( 11335 ProcessRecord process, 11336 StrictMode.ViolationInfo info) { 11337 if (info == null) { 11338 return; 11339 } 11340 final boolean isSystemApp = process == null || 11341 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11342 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11343 final String processName = process == null ? "unknown" : process.processName; 11344 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11345 final DropBoxManager dbox = (DropBoxManager) 11346 mContext.getSystemService(Context.DROPBOX_SERVICE); 11347 11348 // Exit early if the dropbox isn't configured to accept this report type. 11349 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11350 11351 boolean bufferWasEmpty; 11352 boolean needsFlush; 11353 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11354 synchronized (sb) { 11355 bufferWasEmpty = sb.length() == 0; 11356 appendDropBoxProcessHeaders(process, processName, sb); 11357 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11358 sb.append("System-App: ").append(isSystemApp).append("\n"); 11359 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11360 if (info.violationNumThisLoop != 0) { 11361 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11362 } 11363 if (info.numAnimationsRunning != 0) { 11364 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11365 } 11366 if (info.broadcastIntentAction != null) { 11367 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11368 } 11369 if (info.durationMillis != -1) { 11370 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11371 } 11372 if (info.numInstances != -1) { 11373 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11374 } 11375 if (info.tags != null) { 11376 for (String tag : info.tags) { 11377 sb.append("Span-Tag: ").append(tag).append("\n"); 11378 } 11379 } 11380 sb.append("\n"); 11381 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11382 sb.append(info.crashInfo.stackTrace); 11383 } 11384 sb.append("\n"); 11385 11386 // Only buffer up to ~64k. Various logging bits truncate 11387 // things at 128k. 11388 needsFlush = (sb.length() > 64 * 1024); 11389 } 11390 11391 // Flush immediately if the buffer's grown too large, or this 11392 // is a non-system app. Non-system apps are isolated with a 11393 // different tag & policy and not batched. 11394 // 11395 // Batching is useful during internal testing with 11396 // StrictMode settings turned up high. Without batching, 11397 // thousands of separate files could be created on boot. 11398 if (!isSystemApp || needsFlush) { 11399 new Thread("Error dump: " + dropboxTag) { 11400 @Override 11401 public void run() { 11402 String report; 11403 synchronized (sb) { 11404 report = sb.toString(); 11405 sb.delete(0, sb.length()); 11406 sb.trimToSize(); 11407 } 11408 if (report.length() != 0) { 11409 dbox.addText(dropboxTag, report); 11410 } 11411 } 11412 }.start(); 11413 return; 11414 } 11415 11416 // System app batching: 11417 if (!bufferWasEmpty) { 11418 // An existing dropbox-writing thread is outstanding, so 11419 // we don't need to start it up. The existing thread will 11420 // catch the buffer appends we just did. 11421 return; 11422 } 11423 11424 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11425 // (After this point, we shouldn't access AMS internal data structures.) 11426 new Thread("Error dump: " + dropboxTag) { 11427 @Override 11428 public void run() { 11429 // 5 second sleep to let stacks arrive and be batched together 11430 try { 11431 Thread.sleep(5000); // 5 seconds 11432 } catch (InterruptedException e) {} 11433 11434 String errorReport; 11435 synchronized (mStrictModeBuffer) { 11436 errorReport = mStrictModeBuffer.toString(); 11437 if (errorReport.length() == 0) { 11438 return; 11439 } 11440 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11441 mStrictModeBuffer.trimToSize(); 11442 } 11443 dbox.addText(dropboxTag, errorReport); 11444 } 11445 }.start(); 11446 } 11447 11448 /** 11449 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11450 * @param app object of the crashing app, null for the system server 11451 * @param tag reported by the caller 11452 * @param system whether this wtf is coming from the system 11453 * @param crashInfo describing the context of the error 11454 * @return true if the process should exit immediately (WTF is fatal) 11455 */ 11456 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11457 final ApplicationErrorReport.CrashInfo crashInfo) { 11458 final ProcessRecord r = findAppProcess(app, "WTF"); 11459 final String processName = app == null ? "system_server" 11460 : (r == null ? "unknown" : r.processName); 11461 11462 EventLog.writeEvent(EventLogTags.AM_WTF, 11463 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11464 processName, 11465 r == null ? -1 : r.info.flags, 11466 tag, crashInfo.exceptionMessage); 11467 11468 if (system) { 11469 // If this is coming from the system, we could very well have low-level 11470 // system locks held, so we want to do this all asynchronously. And we 11471 // never want this to become fatal, so there is that too. 11472 mHandler.post(new Runnable() { 11473 @Override public void run() { 11474 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11475 crashInfo); 11476 } 11477 }); 11478 return false; 11479 } 11480 11481 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11482 11483 if (r != null && r.pid != Process.myPid() && 11484 Settings.Global.getInt(mContext.getContentResolver(), 11485 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11486 crashApplication(r, crashInfo); 11487 return true; 11488 } else { 11489 return false; 11490 } 11491 } 11492 11493 /** 11494 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11495 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11496 */ 11497 private ProcessRecord findAppProcess(IBinder app, String reason) { 11498 if (app == null) { 11499 return null; 11500 } 11501 11502 synchronized (this) { 11503 final int NP = mProcessNames.getMap().size(); 11504 for (int ip=0; ip<NP; ip++) { 11505 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11506 final int NA = apps.size(); 11507 for (int ia=0; ia<NA; ia++) { 11508 ProcessRecord p = apps.valueAt(ia); 11509 if (p.thread != null && p.thread.asBinder() == app) { 11510 return p; 11511 } 11512 } 11513 } 11514 11515 Slog.w(TAG, "Can't find mystery application for " + reason 11516 + " from pid=" + Binder.getCallingPid() 11517 + " uid=" + Binder.getCallingUid() + ": " + app); 11518 return null; 11519 } 11520 } 11521 11522 /** 11523 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11524 * to append various headers to the dropbox log text. 11525 */ 11526 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11527 StringBuilder sb) { 11528 // Watchdog thread ends up invoking this function (with 11529 // a null ProcessRecord) to add the stack file to dropbox. 11530 // Do not acquire a lock on this (am) in such cases, as it 11531 // could cause a potential deadlock, if and when watchdog 11532 // is invoked due to unavailability of lock on am and it 11533 // would prevent watchdog from killing system_server. 11534 if (process == null) { 11535 sb.append("Process: ").append(processName).append("\n"); 11536 return; 11537 } 11538 // Note: ProcessRecord 'process' is guarded by the service 11539 // instance. (notably process.pkgList, which could otherwise change 11540 // concurrently during execution of this method) 11541 synchronized (this) { 11542 sb.append("Process: ").append(processName).append("\n"); 11543 int flags = process.info.flags; 11544 IPackageManager pm = AppGlobals.getPackageManager(); 11545 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11546 for (int ip=0; ip<process.pkgList.size(); ip++) { 11547 String pkg = process.pkgList.keyAt(ip); 11548 sb.append("Package: ").append(pkg); 11549 try { 11550 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11551 if (pi != null) { 11552 sb.append(" v").append(pi.versionCode); 11553 if (pi.versionName != null) { 11554 sb.append(" (").append(pi.versionName).append(")"); 11555 } 11556 } 11557 } catch (RemoteException e) { 11558 Slog.e(TAG, "Error getting package info: " + pkg, e); 11559 } 11560 sb.append("\n"); 11561 } 11562 } 11563 } 11564 11565 private static String processClass(ProcessRecord process) { 11566 if (process == null || process.pid == MY_PID) { 11567 return "system_server"; 11568 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11569 return "system_app"; 11570 } else { 11571 return "data_app"; 11572 } 11573 } 11574 11575 /** 11576 * Write a description of an error (crash, WTF, ANR) to the drop box. 11577 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11578 * @param process which caused the error, null means the system server 11579 * @param activity which triggered the error, null if unknown 11580 * @param parent activity related to the error, null if unknown 11581 * @param subject line related to the error, null if absent 11582 * @param report in long form describing the error, null if absent 11583 * @param logFile to include in the report, null if none 11584 * @param crashInfo giving an application stack trace, null if absent 11585 */ 11586 public void addErrorToDropBox(String eventType, 11587 ProcessRecord process, String processName, ActivityRecord activity, 11588 ActivityRecord parent, String subject, 11589 final String report, final File logFile, 11590 final ApplicationErrorReport.CrashInfo crashInfo) { 11591 // NOTE -- this must never acquire the ActivityManagerService lock, 11592 // otherwise the watchdog may be prevented from resetting the system. 11593 11594 final String dropboxTag = processClass(process) + "_" + eventType; 11595 final DropBoxManager dbox = (DropBoxManager) 11596 mContext.getSystemService(Context.DROPBOX_SERVICE); 11597 11598 // Exit early if the dropbox isn't configured to accept this report type. 11599 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11600 11601 final StringBuilder sb = new StringBuilder(1024); 11602 appendDropBoxProcessHeaders(process, processName, sb); 11603 if (activity != null) { 11604 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11605 } 11606 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11607 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11608 } 11609 if (parent != null && parent != activity) { 11610 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11611 } 11612 if (subject != null) { 11613 sb.append("Subject: ").append(subject).append("\n"); 11614 } 11615 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11616 if (Debug.isDebuggerConnected()) { 11617 sb.append("Debugger: Connected\n"); 11618 } 11619 sb.append("\n"); 11620 11621 // Do the rest in a worker thread to avoid blocking the caller on I/O 11622 // (After this point, we shouldn't access AMS internal data structures.) 11623 Thread worker = new Thread("Error dump: " + dropboxTag) { 11624 @Override 11625 public void run() { 11626 if (report != null) { 11627 sb.append(report); 11628 } 11629 if (logFile != null) { 11630 try { 11631 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11632 "\n\n[[TRUNCATED]]")); 11633 } catch (IOException e) { 11634 Slog.e(TAG, "Error reading " + logFile, e); 11635 } 11636 } 11637 if (crashInfo != null && crashInfo.stackTrace != null) { 11638 sb.append(crashInfo.stackTrace); 11639 } 11640 11641 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11642 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11643 if (lines > 0) { 11644 sb.append("\n"); 11645 11646 // Merge several logcat streams, and take the last N lines 11647 InputStreamReader input = null; 11648 try { 11649 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11650 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11651 "-b", "crash", 11652 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11653 11654 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11655 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11656 input = new InputStreamReader(logcat.getInputStream()); 11657 11658 int num; 11659 char[] buf = new char[8192]; 11660 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11661 } catch (IOException e) { 11662 Slog.e(TAG, "Error running logcat", e); 11663 } finally { 11664 if (input != null) try { input.close(); } catch (IOException e) {} 11665 } 11666 } 11667 11668 dbox.addText(dropboxTag, sb.toString()); 11669 } 11670 }; 11671 11672 if (process == null) { 11673 // If process is null, we are being called from some internal code 11674 // and may be about to die -- run this synchronously. 11675 worker.run(); 11676 } else { 11677 worker.start(); 11678 } 11679 } 11680 11681 /** 11682 * Bring up the "unexpected error" dialog box for a crashing app. 11683 * Deal with edge cases (intercepts from instrumented applications, 11684 * ActivityController, error intent receivers, that sort of thing). 11685 * @param r the application crashing 11686 * @param crashInfo describing the failure 11687 */ 11688 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11689 long timeMillis = System.currentTimeMillis(); 11690 String shortMsg = crashInfo.exceptionClassName; 11691 String longMsg = crashInfo.exceptionMessage; 11692 String stackTrace = crashInfo.stackTrace; 11693 if (shortMsg != null && longMsg != null) { 11694 longMsg = shortMsg + ": " + longMsg; 11695 } else if (shortMsg != null) { 11696 longMsg = shortMsg; 11697 } 11698 11699 AppErrorResult result = new AppErrorResult(); 11700 synchronized (this) { 11701 if (mController != null) { 11702 try { 11703 String name = r != null ? r.processName : null; 11704 int pid = r != null ? r.pid : Binder.getCallingPid(); 11705 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11706 if (!mController.appCrashed(name, pid, 11707 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11708 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11709 && "Native crash".equals(crashInfo.exceptionClassName)) { 11710 Slog.w(TAG, "Skip killing native crashed app " + name 11711 + "(" + pid + ") during testing"); 11712 } else { 11713 Slog.w(TAG, "Force-killing crashed app " + name 11714 + " at watcher's request"); 11715 if (r != null) { 11716 r.kill("crash", true); 11717 } else { 11718 // Huh. 11719 Process.killProcess(pid); 11720 Process.killProcessGroup(uid, pid); 11721 } 11722 } 11723 return; 11724 } 11725 } catch (RemoteException e) { 11726 mController = null; 11727 Watchdog.getInstance().setActivityController(null); 11728 } 11729 } 11730 11731 final long origId = Binder.clearCallingIdentity(); 11732 11733 // If this process is running instrumentation, finish it. 11734 if (r != null && r.instrumentationClass != null) { 11735 Slog.w(TAG, "Error in app " + r.processName 11736 + " running instrumentation " + r.instrumentationClass + ":"); 11737 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11738 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11739 Bundle info = new Bundle(); 11740 info.putString("shortMsg", shortMsg); 11741 info.putString("longMsg", longMsg); 11742 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11743 Binder.restoreCallingIdentity(origId); 11744 return; 11745 } 11746 11747 // If we can't identify the process or it's already exceeded its crash quota, 11748 // quit right away without showing a crash dialog. 11749 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11750 Binder.restoreCallingIdentity(origId); 11751 return; 11752 } 11753 11754 Message msg = Message.obtain(); 11755 msg.what = SHOW_ERROR_MSG; 11756 HashMap data = new HashMap(); 11757 data.put("result", result); 11758 data.put("app", r); 11759 msg.obj = data; 11760 mHandler.sendMessage(msg); 11761 11762 Binder.restoreCallingIdentity(origId); 11763 } 11764 11765 int res = result.get(); 11766 11767 Intent appErrorIntent = null; 11768 synchronized (this) { 11769 if (r != null && !r.isolated) { 11770 // XXX Can't keep track of crash time for isolated processes, 11771 // since they don't have a persistent identity. 11772 mProcessCrashTimes.put(r.info.processName, r.uid, 11773 SystemClock.uptimeMillis()); 11774 } 11775 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11776 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11777 } 11778 } 11779 11780 if (appErrorIntent != null) { 11781 try { 11782 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11783 } catch (ActivityNotFoundException e) { 11784 Slog.w(TAG, "bug report receiver dissappeared", e); 11785 } 11786 } 11787 } 11788 11789 Intent createAppErrorIntentLocked(ProcessRecord r, 11790 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11791 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11792 if (report == null) { 11793 return null; 11794 } 11795 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11796 result.setComponent(r.errorReportReceiver); 11797 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11798 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11799 return result; 11800 } 11801 11802 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11803 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11804 if (r.errorReportReceiver == null) { 11805 return null; 11806 } 11807 11808 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11809 return null; 11810 } 11811 11812 ApplicationErrorReport report = new ApplicationErrorReport(); 11813 report.packageName = r.info.packageName; 11814 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11815 report.processName = r.processName; 11816 report.time = timeMillis; 11817 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11818 11819 if (r.crashing || r.forceCrashReport) { 11820 report.type = ApplicationErrorReport.TYPE_CRASH; 11821 report.crashInfo = crashInfo; 11822 } else if (r.notResponding) { 11823 report.type = ApplicationErrorReport.TYPE_ANR; 11824 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11825 11826 report.anrInfo.activity = r.notRespondingReport.tag; 11827 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11828 report.anrInfo.info = r.notRespondingReport.longMsg; 11829 } 11830 11831 return report; 11832 } 11833 11834 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11835 enforceNotIsolatedCaller("getProcessesInErrorState"); 11836 // assume our apps are happy - lazy create the list 11837 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11838 11839 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11840 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11841 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11842 11843 synchronized (this) { 11844 11845 // iterate across all processes 11846 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11847 ProcessRecord app = mLruProcesses.get(i); 11848 if (!allUsers && app.userId != userId) { 11849 continue; 11850 } 11851 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11852 // This one's in trouble, so we'll generate a report for it 11853 // crashes are higher priority (in case there's a crash *and* an anr) 11854 ActivityManager.ProcessErrorStateInfo report = null; 11855 if (app.crashing) { 11856 report = app.crashingReport; 11857 } else if (app.notResponding) { 11858 report = app.notRespondingReport; 11859 } 11860 11861 if (report != null) { 11862 if (errList == null) { 11863 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11864 } 11865 errList.add(report); 11866 } else { 11867 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11868 " crashing = " + app.crashing + 11869 " notResponding = " + app.notResponding); 11870 } 11871 } 11872 } 11873 } 11874 11875 return errList; 11876 } 11877 11878 static int procStateToImportance(int procState, int memAdj, 11879 ActivityManager.RunningAppProcessInfo currApp) { 11880 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11881 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11882 currApp.lru = memAdj; 11883 } else { 11884 currApp.lru = 0; 11885 } 11886 return imp; 11887 } 11888 11889 private void fillInProcMemInfo(ProcessRecord app, 11890 ActivityManager.RunningAppProcessInfo outInfo) { 11891 outInfo.pid = app.pid; 11892 outInfo.uid = app.info.uid; 11893 if (mHeavyWeightProcess == app) { 11894 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11895 } 11896 if (app.persistent) { 11897 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11898 } 11899 if (app.activities.size() > 0) { 11900 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11901 } 11902 outInfo.lastTrimLevel = app.trimMemoryLevel; 11903 int adj = app.curAdj; 11904 int procState = app.curProcState; 11905 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11906 outInfo.importanceReasonCode = app.adjTypeCode; 11907 outInfo.processState = app.curProcState; 11908 } 11909 11910 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11911 enforceNotIsolatedCaller("getRunningAppProcesses"); 11912 // Lazy instantiation of list 11913 List<ActivityManager.RunningAppProcessInfo> runList = null; 11914 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11915 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11916 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11917 synchronized (this) { 11918 // Iterate across all processes 11919 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11920 ProcessRecord app = mLruProcesses.get(i); 11921 if (!allUsers && app.userId != userId) { 11922 continue; 11923 } 11924 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11925 // Generate process state info for running application 11926 ActivityManager.RunningAppProcessInfo currApp = 11927 new ActivityManager.RunningAppProcessInfo(app.processName, 11928 app.pid, app.getPackageList()); 11929 fillInProcMemInfo(app, currApp); 11930 if (app.adjSource instanceof ProcessRecord) { 11931 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11932 currApp.importanceReasonImportance = 11933 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11934 app.adjSourceProcState); 11935 } else if (app.adjSource instanceof ActivityRecord) { 11936 ActivityRecord r = (ActivityRecord)app.adjSource; 11937 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11938 } 11939 if (app.adjTarget instanceof ComponentName) { 11940 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11941 } 11942 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11943 // + " lru=" + currApp.lru); 11944 if (runList == null) { 11945 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11946 } 11947 runList.add(currApp); 11948 } 11949 } 11950 } 11951 return runList; 11952 } 11953 11954 public List<ApplicationInfo> getRunningExternalApplications() { 11955 enforceNotIsolatedCaller("getRunningExternalApplications"); 11956 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11957 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11958 if (runningApps != null && runningApps.size() > 0) { 11959 Set<String> extList = new HashSet<String>(); 11960 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11961 if (app.pkgList != null) { 11962 for (String pkg : app.pkgList) { 11963 extList.add(pkg); 11964 } 11965 } 11966 } 11967 IPackageManager pm = AppGlobals.getPackageManager(); 11968 for (String pkg : extList) { 11969 try { 11970 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11971 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11972 retList.add(info); 11973 } 11974 } catch (RemoteException e) { 11975 } 11976 } 11977 } 11978 return retList; 11979 } 11980 11981 @Override 11982 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11983 enforceNotIsolatedCaller("getMyMemoryState"); 11984 synchronized (this) { 11985 ProcessRecord proc; 11986 synchronized (mPidsSelfLocked) { 11987 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11988 } 11989 fillInProcMemInfo(proc, outInfo); 11990 } 11991 } 11992 11993 @Override 11994 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11995 if (checkCallingPermission(android.Manifest.permission.DUMP) 11996 != PackageManager.PERMISSION_GRANTED) { 11997 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11998 + Binder.getCallingPid() 11999 + ", uid=" + Binder.getCallingUid() 12000 + " without permission " 12001 + android.Manifest.permission.DUMP); 12002 return; 12003 } 12004 12005 boolean dumpAll = false; 12006 boolean dumpClient = false; 12007 String dumpPackage = null; 12008 12009 int opti = 0; 12010 while (opti < args.length) { 12011 String opt = args[opti]; 12012 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12013 break; 12014 } 12015 opti++; 12016 if ("-a".equals(opt)) { 12017 dumpAll = true; 12018 } else if ("-c".equals(opt)) { 12019 dumpClient = true; 12020 } else if ("-h".equals(opt)) { 12021 pw.println("Activity manager dump options:"); 12022 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12023 pw.println(" cmd may be one of:"); 12024 pw.println(" a[ctivities]: activity stack state"); 12025 pw.println(" r[recents]: recent activities state"); 12026 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12027 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12028 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12029 pw.println(" o[om]: out of memory management"); 12030 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12031 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12032 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12033 pw.println(" service [COMP_SPEC]: service client-side state"); 12034 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12035 pw.println(" all: dump all activities"); 12036 pw.println(" top: dump the top activity"); 12037 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12038 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12039 pw.println(" a partial substring in a component name, a"); 12040 pw.println(" hex object identifier."); 12041 pw.println(" -a: include all available server state."); 12042 pw.println(" -c: include client state."); 12043 return; 12044 } else { 12045 pw.println("Unknown argument: " + opt + "; use -h for help"); 12046 } 12047 } 12048 12049 long origId = Binder.clearCallingIdentity(); 12050 boolean more = false; 12051 // Is the caller requesting to dump a particular piece of data? 12052 if (opti < args.length) { 12053 String cmd = args[opti]; 12054 opti++; 12055 if ("activities".equals(cmd) || "a".equals(cmd)) { 12056 synchronized (this) { 12057 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12058 } 12059 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12060 synchronized (this) { 12061 dumpRecentsLocked(fd, pw, args, opti, true, null); 12062 } 12063 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12064 String[] newArgs; 12065 String name; 12066 if (opti >= args.length) { 12067 name = null; 12068 newArgs = EMPTY_STRING_ARRAY; 12069 } else { 12070 name = args[opti]; 12071 opti++; 12072 newArgs = new String[args.length - opti]; 12073 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12074 args.length - opti); 12075 } 12076 synchronized (this) { 12077 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12078 } 12079 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12080 String[] newArgs; 12081 String name; 12082 if (opti >= args.length) { 12083 name = null; 12084 newArgs = EMPTY_STRING_ARRAY; 12085 } else { 12086 name = args[opti]; 12087 opti++; 12088 newArgs = new String[args.length - opti]; 12089 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12090 args.length - opti); 12091 } 12092 synchronized (this) { 12093 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12094 } 12095 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12096 String[] newArgs; 12097 String name; 12098 if (opti >= args.length) { 12099 name = null; 12100 newArgs = EMPTY_STRING_ARRAY; 12101 } else { 12102 name = args[opti]; 12103 opti++; 12104 newArgs = new String[args.length - opti]; 12105 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12106 args.length - opti); 12107 } 12108 synchronized (this) { 12109 dumpProcessesLocked(fd, pw, args, opti, true, name); 12110 } 12111 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12112 synchronized (this) { 12113 dumpOomLocked(fd, pw, args, opti, true); 12114 } 12115 } else if ("provider".equals(cmd)) { 12116 String[] newArgs; 12117 String name; 12118 if (opti >= args.length) { 12119 name = null; 12120 newArgs = EMPTY_STRING_ARRAY; 12121 } else { 12122 name = args[opti]; 12123 opti++; 12124 newArgs = new String[args.length - opti]; 12125 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12126 } 12127 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12128 pw.println("No providers match: " + name); 12129 pw.println("Use -h for help."); 12130 } 12131 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12132 synchronized (this) { 12133 dumpProvidersLocked(fd, pw, args, opti, true, null); 12134 } 12135 } else if ("service".equals(cmd)) { 12136 String[] newArgs; 12137 String name; 12138 if (opti >= args.length) { 12139 name = null; 12140 newArgs = EMPTY_STRING_ARRAY; 12141 } else { 12142 name = args[opti]; 12143 opti++; 12144 newArgs = new String[args.length - opti]; 12145 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12146 args.length - opti); 12147 } 12148 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12149 pw.println("No services match: " + name); 12150 pw.println("Use -h for help."); 12151 } 12152 } else if ("package".equals(cmd)) { 12153 String[] newArgs; 12154 if (opti >= args.length) { 12155 pw.println("package: no package name specified"); 12156 pw.println("Use -h for help."); 12157 } else { 12158 dumpPackage = args[opti]; 12159 opti++; 12160 newArgs = new String[args.length - opti]; 12161 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12162 args.length - opti); 12163 args = newArgs; 12164 opti = 0; 12165 more = true; 12166 } 12167 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12168 synchronized (this) { 12169 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12170 } 12171 } else { 12172 // Dumping a single activity? 12173 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12174 pw.println("Bad activity command, or no activities match: " + cmd); 12175 pw.println("Use -h for help."); 12176 } 12177 } 12178 if (!more) { 12179 Binder.restoreCallingIdentity(origId); 12180 return; 12181 } 12182 } 12183 12184 // No piece of data specified, dump everything. 12185 synchronized (this) { 12186 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12187 pw.println(); 12188 if (dumpAll) { 12189 pw.println("-------------------------------------------------------------------------------"); 12190 } 12191 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12192 pw.println(); 12193 if (dumpAll) { 12194 pw.println("-------------------------------------------------------------------------------"); 12195 } 12196 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12197 pw.println(); 12198 if (dumpAll) { 12199 pw.println("-------------------------------------------------------------------------------"); 12200 } 12201 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12202 pw.println(); 12203 if (dumpAll) { 12204 pw.println("-------------------------------------------------------------------------------"); 12205 } 12206 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12207 pw.println(); 12208 if (dumpAll) { 12209 pw.println("-------------------------------------------------------------------------------"); 12210 } 12211 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12212 pw.println(); 12213 if (dumpAll) { 12214 pw.println("-------------------------------------------------------------------------------"); 12215 } 12216 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12217 } 12218 Binder.restoreCallingIdentity(origId); 12219 } 12220 12221 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12222 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12223 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12224 12225 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12226 dumpPackage); 12227 boolean needSep = printedAnything; 12228 12229 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12230 dumpPackage, needSep, " mFocusedActivity: "); 12231 if (printed) { 12232 printedAnything = true; 12233 needSep = false; 12234 } 12235 12236 if (dumpPackage == null) { 12237 if (needSep) { 12238 pw.println(); 12239 } 12240 needSep = true; 12241 printedAnything = true; 12242 mStackSupervisor.dump(pw, " "); 12243 } 12244 12245 if (!printedAnything) { 12246 pw.println(" (nothing)"); 12247 } 12248 } 12249 12250 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12251 int opti, boolean dumpAll, String dumpPackage) { 12252 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12253 12254 boolean printedAnything = false; 12255 12256 if (mRecentTasks.size() > 0) { 12257 boolean printedHeader = false; 12258 12259 final int N = mRecentTasks.size(); 12260 for (int i=0; i<N; i++) { 12261 TaskRecord tr = mRecentTasks.get(i); 12262 if (dumpPackage != null) { 12263 if (tr.realActivity == null || 12264 !dumpPackage.equals(tr.realActivity)) { 12265 continue; 12266 } 12267 } 12268 if (!printedHeader) { 12269 pw.println(" Recent tasks:"); 12270 printedHeader = true; 12271 printedAnything = true; 12272 } 12273 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12274 pw.println(tr); 12275 if (dumpAll) { 12276 mRecentTasks.get(i).dump(pw, " "); 12277 } 12278 } 12279 } 12280 12281 if (!printedAnything) { 12282 pw.println(" (nothing)"); 12283 } 12284 } 12285 12286 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12287 int opti, boolean dumpAll, String dumpPackage) { 12288 boolean needSep = false; 12289 boolean printedAnything = false; 12290 int numPers = 0; 12291 12292 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12293 12294 if (dumpAll) { 12295 final int NP = mProcessNames.getMap().size(); 12296 for (int ip=0; ip<NP; ip++) { 12297 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12298 final int NA = procs.size(); 12299 for (int ia=0; ia<NA; ia++) { 12300 ProcessRecord r = procs.valueAt(ia); 12301 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12302 continue; 12303 } 12304 if (!needSep) { 12305 pw.println(" All known processes:"); 12306 needSep = true; 12307 printedAnything = true; 12308 } 12309 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12310 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12311 pw.print(" "); pw.println(r); 12312 r.dump(pw, " "); 12313 if (r.persistent) { 12314 numPers++; 12315 } 12316 } 12317 } 12318 } 12319 12320 if (mIsolatedProcesses.size() > 0) { 12321 boolean printed = false; 12322 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12323 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12324 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12325 continue; 12326 } 12327 if (!printed) { 12328 if (needSep) { 12329 pw.println(); 12330 } 12331 pw.println(" Isolated process list (sorted by uid):"); 12332 printedAnything = true; 12333 printed = true; 12334 needSep = true; 12335 } 12336 pw.println(String.format("%sIsolated #%2d: %s", 12337 " ", i, r.toString())); 12338 } 12339 } 12340 12341 if (mLruProcesses.size() > 0) { 12342 if (needSep) { 12343 pw.println(); 12344 } 12345 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12346 pw.print(" total, non-act at "); 12347 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12348 pw.print(", non-svc at "); 12349 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12350 pw.println("):"); 12351 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12352 needSep = true; 12353 printedAnything = true; 12354 } 12355 12356 if (dumpAll || dumpPackage != null) { 12357 synchronized (mPidsSelfLocked) { 12358 boolean printed = false; 12359 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12360 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12361 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12362 continue; 12363 } 12364 if (!printed) { 12365 if (needSep) pw.println(); 12366 needSep = true; 12367 pw.println(" PID mappings:"); 12368 printed = true; 12369 printedAnything = true; 12370 } 12371 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12372 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12373 } 12374 } 12375 } 12376 12377 if (mForegroundProcesses.size() > 0) { 12378 synchronized (mPidsSelfLocked) { 12379 boolean printed = false; 12380 for (int i=0; i<mForegroundProcesses.size(); i++) { 12381 ProcessRecord r = mPidsSelfLocked.get( 12382 mForegroundProcesses.valueAt(i).pid); 12383 if (dumpPackage != null && (r == null 12384 || !r.pkgList.containsKey(dumpPackage))) { 12385 continue; 12386 } 12387 if (!printed) { 12388 if (needSep) pw.println(); 12389 needSep = true; 12390 pw.println(" Foreground Processes:"); 12391 printed = true; 12392 printedAnything = true; 12393 } 12394 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12395 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12396 } 12397 } 12398 } 12399 12400 if (mPersistentStartingProcesses.size() > 0) { 12401 if (needSep) pw.println(); 12402 needSep = true; 12403 printedAnything = true; 12404 pw.println(" Persisent processes that are starting:"); 12405 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12406 "Starting Norm", "Restarting PERS", dumpPackage); 12407 } 12408 12409 if (mRemovedProcesses.size() > 0) { 12410 if (needSep) pw.println(); 12411 needSep = true; 12412 printedAnything = true; 12413 pw.println(" Processes that are being removed:"); 12414 dumpProcessList(pw, this, mRemovedProcesses, " ", 12415 "Removed Norm", "Removed PERS", dumpPackage); 12416 } 12417 12418 if (mProcessesOnHold.size() > 0) { 12419 if (needSep) pw.println(); 12420 needSep = true; 12421 printedAnything = true; 12422 pw.println(" Processes that are on old until the system is ready:"); 12423 dumpProcessList(pw, this, mProcessesOnHold, " ", 12424 "OnHold Norm", "OnHold PERS", dumpPackage); 12425 } 12426 12427 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12428 12429 if (mProcessCrashTimes.getMap().size() > 0) { 12430 boolean printed = false; 12431 long now = SystemClock.uptimeMillis(); 12432 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12433 final int NP = pmap.size(); 12434 for (int ip=0; ip<NP; ip++) { 12435 String pname = pmap.keyAt(ip); 12436 SparseArray<Long> uids = pmap.valueAt(ip); 12437 final int N = uids.size(); 12438 for (int i=0; i<N; i++) { 12439 int puid = uids.keyAt(i); 12440 ProcessRecord r = mProcessNames.get(pname, puid); 12441 if (dumpPackage != null && (r == null 12442 || !r.pkgList.containsKey(dumpPackage))) { 12443 continue; 12444 } 12445 if (!printed) { 12446 if (needSep) pw.println(); 12447 needSep = true; 12448 pw.println(" Time since processes crashed:"); 12449 printed = true; 12450 printedAnything = true; 12451 } 12452 pw.print(" Process "); pw.print(pname); 12453 pw.print(" uid "); pw.print(puid); 12454 pw.print(": last crashed "); 12455 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12456 pw.println(" ago"); 12457 } 12458 } 12459 } 12460 12461 if (mBadProcesses.getMap().size() > 0) { 12462 boolean printed = false; 12463 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12464 final int NP = pmap.size(); 12465 for (int ip=0; ip<NP; ip++) { 12466 String pname = pmap.keyAt(ip); 12467 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12468 final int N = uids.size(); 12469 for (int i=0; i<N; i++) { 12470 int puid = uids.keyAt(i); 12471 ProcessRecord r = mProcessNames.get(pname, puid); 12472 if (dumpPackage != null && (r == null 12473 || !r.pkgList.containsKey(dumpPackage))) { 12474 continue; 12475 } 12476 if (!printed) { 12477 if (needSep) pw.println(); 12478 needSep = true; 12479 pw.println(" Bad processes:"); 12480 printedAnything = true; 12481 } 12482 BadProcessInfo info = uids.valueAt(i); 12483 pw.print(" Bad process "); pw.print(pname); 12484 pw.print(" uid "); pw.print(puid); 12485 pw.print(": crashed at time "); pw.println(info.time); 12486 if (info.shortMsg != null) { 12487 pw.print(" Short msg: "); pw.println(info.shortMsg); 12488 } 12489 if (info.longMsg != null) { 12490 pw.print(" Long msg: "); pw.println(info.longMsg); 12491 } 12492 if (info.stack != null) { 12493 pw.println(" Stack:"); 12494 int lastPos = 0; 12495 for (int pos=0; pos<info.stack.length(); pos++) { 12496 if (info.stack.charAt(pos) == '\n') { 12497 pw.print(" "); 12498 pw.write(info.stack, lastPos, pos-lastPos); 12499 pw.println(); 12500 lastPos = pos+1; 12501 } 12502 } 12503 if (lastPos < info.stack.length()) { 12504 pw.print(" "); 12505 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12506 pw.println(); 12507 } 12508 } 12509 } 12510 } 12511 } 12512 12513 if (dumpPackage == null) { 12514 pw.println(); 12515 needSep = false; 12516 pw.println(" mStartedUsers:"); 12517 for (int i=0; i<mStartedUsers.size(); i++) { 12518 UserStartedState uss = mStartedUsers.valueAt(i); 12519 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12520 pw.print(": "); uss.dump("", pw); 12521 } 12522 pw.print(" mStartedUserArray: ["); 12523 for (int i=0; i<mStartedUserArray.length; i++) { 12524 if (i > 0) pw.print(", "); 12525 pw.print(mStartedUserArray[i]); 12526 } 12527 pw.println("]"); 12528 pw.print(" mUserLru: ["); 12529 for (int i=0; i<mUserLru.size(); i++) { 12530 if (i > 0) pw.print(", "); 12531 pw.print(mUserLru.get(i)); 12532 } 12533 pw.println("]"); 12534 if (dumpAll) { 12535 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12536 } 12537 synchronized (mUserProfileGroupIdsSelfLocked) { 12538 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12539 pw.println(" mUserProfileGroupIds:"); 12540 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12541 pw.print(" User #"); 12542 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12543 pw.print(" -> profile #"); 12544 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12545 } 12546 } 12547 } 12548 } 12549 if (mHomeProcess != null && (dumpPackage == null 12550 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12551 if (needSep) { 12552 pw.println(); 12553 needSep = false; 12554 } 12555 pw.println(" mHomeProcess: " + mHomeProcess); 12556 } 12557 if (mPreviousProcess != null && (dumpPackage == null 12558 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12559 if (needSep) { 12560 pw.println(); 12561 needSep = false; 12562 } 12563 pw.println(" mPreviousProcess: " + mPreviousProcess); 12564 } 12565 if (dumpAll) { 12566 StringBuilder sb = new StringBuilder(128); 12567 sb.append(" mPreviousProcessVisibleTime: "); 12568 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12569 pw.println(sb); 12570 } 12571 if (mHeavyWeightProcess != null && (dumpPackage == null 12572 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12573 if (needSep) { 12574 pw.println(); 12575 needSep = false; 12576 } 12577 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12578 } 12579 if (dumpPackage == null) { 12580 pw.println(" mConfiguration: " + mConfiguration); 12581 } 12582 if (dumpAll) { 12583 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12584 if (mCompatModePackages.getPackages().size() > 0) { 12585 boolean printed = false; 12586 for (Map.Entry<String, Integer> entry 12587 : mCompatModePackages.getPackages().entrySet()) { 12588 String pkg = entry.getKey(); 12589 int mode = entry.getValue(); 12590 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12591 continue; 12592 } 12593 if (!printed) { 12594 pw.println(" mScreenCompatPackages:"); 12595 printed = true; 12596 } 12597 pw.print(" "); pw.print(pkg); pw.print(": "); 12598 pw.print(mode); pw.println(); 12599 } 12600 } 12601 } 12602 if (dumpPackage == null) { 12603 if (mSleeping || mWentToSleep || mLockScreenShown) { 12604 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12605 + " mLockScreenShown " + mLockScreenShown); 12606 } 12607 if (mShuttingDown || mRunningVoice) { 12608 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12609 } 12610 } 12611 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12612 || mOrigWaitForDebugger) { 12613 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12614 || dumpPackage.equals(mOrigDebugApp)) { 12615 if (needSep) { 12616 pw.println(); 12617 needSep = false; 12618 } 12619 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12620 + " mDebugTransient=" + mDebugTransient 12621 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12622 } 12623 } 12624 if (mOpenGlTraceApp != null) { 12625 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12626 if (needSep) { 12627 pw.println(); 12628 needSep = false; 12629 } 12630 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12631 } 12632 } 12633 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12634 || mProfileFd != null) { 12635 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12636 if (needSep) { 12637 pw.println(); 12638 needSep = false; 12639 } 12640 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12641 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12642 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12643 + mAutoStopProfiler); 12644 pw.println(" mProfileType=" + mProfileType); 12645 } 12646 } 12647 if (dumpPackage == null) { 12648 if (mAlwaysFinishActivities || mController != null) { 12649 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12650 + " mController=" + mController); 12651 } 12652 if (dumpAll) { 12653 pw.println(" Total persistent processes: " + numPers); 12654 pw.println(" mProcessesReady=" + mProcessesReady 12655 + " mSystemReady=" + mSystemReady); 12656 pw.println(" mBooting=" + mBooting 12657 + " mBooted=" + mBooted 12658 + " mFactoryTest=" + mFactoryTest); 12659 pw.print(" mLastPowerCheckRealtime="); 12660 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12661 pw.println(""); 12662 pw.print(" mLastPowerCheckUptime="); 12663 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12664 pw.println(""); 12665 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12666 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12667 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12668 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12669 + " (" + mLruProcesses.size() + " total)" 12670 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12671 + " mNumServiceProcs=" + mNumServiceProcs 12672 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12673 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12674 + " mLastMemoryLevel" + mLastMemoryLevel 12675 + " mLastNumProcesses" + mLastNumProcesses); 12676 long now = SystemClock.uptimeMillis(); 12677 pw.print(" mLastIdleTime="); 12678 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12679 pw.print(" mLowRamSinceLastIdle="); 12680 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12681 pw.println(); 12682 } 12683 } 12684 12685 if (!printedAnything) { 12686 pw.println(" (nothing)"); 12687 } 12688 } 12689 12690 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12691 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12692 if (mProcessesToGc.size() > 0) { 12693 boolean printed = false; 12694 long now = SystemClock.uptimeMillis(); 12695 for (int i=0; i<mProcessesToGc.size(); i++) { 12696 ProcessRecord proc = mProcessesToGc.get(i); 12697 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12698 continue; 12699 } 12700 if (!printed) { 12701 if (needSep) pw.println(); 12702 needSep = true; 12703 pw.println(" Processes that are waiting to GC:"); 12704 printed = true; 12705 } 12706 pw.print(" Process "); pw.println(proc); 12707 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12708 pw.print(", last gced="); 12709 pw.print(now-proc.lastRequestedGc); 12710 pw.print(" ms ago, last lowMem="); 12711 pw.print(now-proc.lastLowMemory); 12712 pw.println(" ms ago"); 12713 12714 } 12715 } 12716 return needSep; 12717 } 12718 12719 void printOomLevel(PrintWriter pw, String name, int adj) { 12720 pw.print(" "); 12721 if (adj >= 0) { 12722 pw.print(' '); 12723 if (adj < 10) pw.print(' '); 12724 } else { 12725 if (adj > -10) pw.print(' '); 12726 } 12727 pw.print(adj); 12728 pw.print(": "); 12729 pw.print(name); 12730 pw.print(" ("); 12731 pw.print(mProcessList.getMemLevel(adj)/1024); 12732 pw.println(" kB)"); 12733 } 12734 12735 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12736 int opti, boolean dumpAll) { 12737 boolean needSep = false; 12738 12739 if (mLruProcesses.size() > 0) { 12740 if (needSep) pw.println(); 12741 needSep = true; 12742 pw.println(" OOM levels:"); 12743 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12744 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12745 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12746 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12747 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12748 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12749 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12750 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12751 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12752 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12753 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12754 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12755 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12756 12757 if (needSep) pw.println(); 12758 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12759 pw.print(" total, non-act at "); 12760 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12761 pw.print(", non-svc at "); 12762 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12763 pw.println("):"); 12764 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12765 needSep = true; 12766 } 12767 12768 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12769 12770 pw.println(); 12771 pw.println(" mHomeProcess: " + mHomeProcess); 12772 pw.println(" mPreviousProcess: " + mPreviousProcess); 12773 if (mHeavyWeightProcess != null) { 12774 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12775 } 12776 12777 return true; 12778 } 12779 12780 /** 12781 * There are three ways to call this: 12782 * - no provider specified: dump all the providers 12783 * - a flattened component name that matched an existing provider was specified as the 12784 * first arg: dump that one provider 12785 * - the first arg isn't the flattened component name of an existing provider: 12786 * dump all providers whose component contains the first arg as a substring 12787 */ 12788 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12789 int opti, boolean dumpAll) { 12790 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12791 } 12792 12793 static class ItemMatcher { 12794 ArrayList<ComponentName> components; 12795 ArrayList<String> strings; 12796 ArrayList<Integer> objects; 12797 boolean all; 12798 12799 ItemMatcher() { 12800 all = true; 12801 } 12802 12803 void build(String name) { 12804 ComponentName componentName = ComponentName.unflattenFromString(name); 12805 if (componentName != null) { 12806 if (components == null) { 12807 components = new ArrayList<ComponentName>(); 12808 } 12809 components.add(componentName); 12810 all = false; 12811 } else { 12812 int objectId = 0; 12813 // Not a '/' separated full component name; maybe an object ID? 12814 try { 12815 objectId = Integer.parseInt(name, 16); 12816 if (objects == null) { 12817 objects = new ArrayList<Integer>(); 12818 } 12819 objects.add(objectId); 12820 all = false; 12821 } catch (RuntimeException e) { 12822 // Not an integer; just do string match. 12823 if (strings == null) { 12824 strings = new ArrayList<String>(); 12825 } 12826 strings.add(name); 12827 all = false; 12828 } 12829 } 12830 } 12831 12832 int build(String[] args, int opti) { 12833 for (; opti<args.length; opti++) { 12834 String name = args[opti]; 12835 if ("--".equals(name)) { 12836 return opti+1; 12837 } 12838 build(name); 12839 } 12840 return opti; 12841 } 12842 12843 boolean match(Object object, ComponentName comp) { 12844 if (all) { 12845 return true; 12846 } 12847 if (components != null) { 12848 for (int i=0; i<components.size(); i++) { 12849 if (components.get(i).equals(comp)) { 12850 return true; 12851 } 12852 } 12853 } 12854 if (objects != null) { 12855 for (int i=0; i<objects.size(); i++) { 12856 if (System.identityHashCode(object) == objects.get(i)) { 12857 return true; 12858 } 12859 } 12860 } 12861 if (strings != null) { 12862 String flat = comp.flattenToString(); 12863 for (int i=0; i<strings.size(); i++) { 12864 if (flat.contains(strings.get(i))) { 12865 return true; 12866 } 12867 } 12868 } 12869 return false; 12870 } 12871 } 12872 12873 /** 12874 * There are three things that cmd can be: 12875 * - a flattened component name that matches an existing activity 12876 * - the cmd arg isn't the flattened component name of an existing activity: 12877 * dump all activity whose component contains the cmd as a substring 12878 * - A hex number of the ActivityRecord object instance. 12879 */ 12880 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12881 int opti, boolean dumpAll) { 12882 ArrayList<ActivityRecord> activities; 12883 12884 synchronized (this) { 12885 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12886 } 12887 12888 if (activities.size() <= 0) { 12889 return false; 12890 } 12891 12892 String[] newArgs = new String[args.length - opti]; 12893 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12894 12895 TaskRecord lastTask = null; 12896 boolean needSep = false; 12897 for (int i=activities.size()-1; i>=0; i--) { 12898 ActivityRecord r = activities.get(i); 12899 if (needSep) { 12900 pw.println(); 12901 } 12902 needSep = true; 12903 synchronized (this) { 12904 if (lastTask != r.task) { 12905 lastTask = r.task; 12906 pw.print("TASK "); pw.print(lastTask.affinity); 12907 pw.print(" id="); pw.println(lastTask.taskId); 12908 if (dumpAll) { 12909 lastTask.dump(pw, " "); 12910 } 12911 } 12912 } 12913 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12914 } 12915 return true; 12916 } 12917 12918 /** 12919 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12920 * there is a thread associated with the activity. 12921 */ 12922 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12923 final ActivityRecord r, String[] args, boolean dumpAll) { 12924 String innerPrefix = prefix + " "; 12925 synchronized (this) { 12926 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12927 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12928 pw.print(" pid="); 12929 if (r.app != null) pw.println(r.app.pid); 12930 else pw.println("(not running)"); 12931 if (dumpAll) { 12932 r.dump(pw, innerPrefix); 12933 } 12934 } 12935 if (r.app != null && r.app.thread != null) { 12936 // flush anything that is already in the PrintWriter since the thread is going 12937 // to write to the file descriptor directly 12938 pw.flush(); 12939 try { 12940 TransferPipe tp = new TransferPipe(); 12941 try { 12942 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12943 r.appToken, innerPrefix, args); 12944 tp.go(fd); 12945 } finally { 12946 tp.kill(); 12947 } 12948 } catch (IOException e) { 12949 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12950 } catch (RemoteException e) { 12951 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12952 } 12953 } 12954 } 12955 12956 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12957 int opti, boolean dumpAll, String dumpPackage) { 12958 boolean needSep = false; 12959 boolean onlyHistory = false; 12960 boolean printedAnything = false; 12961 12962 if ("history".equals(dumpPackage)) { 12963 if (opti < args.length && "-s".equals(args[opti])) { 12964 dumpAll = false; 12965 } 12966 onlyHistory = true; 12967 dumpPackage = null; 12968 } 12969 12970 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12971 if (!onlyHistory && dumpAll) { 12972 if (mRegisteredReceivers.size() > 0) { 12973 boolean printed = false; 12974 Iterator it = mRegisteredReceivers.values().iterator(); 12975 while (it.hasNext()) { 12976 ReceiverList r = (ReceiverList)it.next(); 12977 if (dumpPackage != null && (r.app == null || 12978 !dumpPackage.equals(r.app.info.packageName))) { 12979 continue; 12980 } 12981 if (!printed) { 12982 pw.println(" Registered Receivers:"); 12983 needSep = true; 12984 printed = true; 12985 printedAnything = true; 12986 } 12987 pw.print(" * "); pw.println(r); 12988 r.dump(pw, " "); 12989 } 12990 } 12991 12992 if (mReceiverResolver.dump(pw, needSep ? 12993 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12994 " ", dumpPackage, false)) { 12995 needSep = true; 12996 printedAnything = true; 12997 } 12998 } 12999 13000 for (BroadcastQueue q : mBroadcastQueues) { 13001 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13002 printedAnything |= needSep; 13003 } 13004 13005 needSep = true; 13006 13007 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13008 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13009 if (needSep) { 13010 pw.println(); 13011 } 13012 needSep = true; 13013 printedAnything = true; 13014 pw.print(" Sticky broadcasts for user "); 13015 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13016 StringBuilder sb = new StringBuilder(128); 13017 for (Map.Entry<String, ArrayList<Intent>> ent 13018 : mStickyBroadcasts.valueAt(user).entrySet()) { 13019 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13020 if (dumpAll) { 13021 pw.println(":"); 13022 ArrayList<Intent> intents = ent.getValue(); 13023 final int N = intents.size(); 13024 for (int i=0; i<N; i++) { 13025 sb.setLength(0); 13026 sb.append(" Intent: "); 13027 intents.get(i).toShortString(sb, false, true, false, false); 13028 pw.println(sb.toString()); 13029 Bundle bundle = intents.get(i).getExtras(); 13030 if (bundle != null) { 13031 pw.print(" "); 13032 pw.println(bundle.toString()); 13033 } 13034 } 13035 } else { 13036 pw.println(""); 13037 } 13038 } 13039 } 13040 } 13041 13042 if (!onlyHistory && dumpAll) { 13043 pw.println(); 13044 for (BroadcastQueue queue : mBroadcastQueues) { 13045 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13046 + queue.mBroadcastsScheduled); 13047 } 13048 pw.println(" mHandler:"); 13049 mHandler.dump(new PrintWriterPrinter(pw), " "); 13050 needSep = true; 13051 printedAnything = true; 13052 } 13053 13054 if (!printedAnything) { 13055 pw.println(" (nothing)"); 13056 } 13057 } 13058 13059 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13060 int opti, boolean dumpAll, String dumpPackage) { 13061 boolean needSep; 13062 boolean printedAnything = false; 13063 13064 ItemMatcher matcher = new ItemMatcher(); 13065 matcher.build(args, opti); 13066 13067 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13068 13069 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13070 printedAnything |= needSep; 13071 13072 if (mLaunchingProviders.size() > 0) { 13073 boolean printed = false; 13074 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13075 ContentProviderRecord r = mLaunchingProviders.get(i); 13076 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13077 continue; 13078 } 13079 if (!printed) { 13080 if (needSep) pw.println(); 13081 needSep = true; 13082 pw.println(" Launching content providers:"); 13083 printed = true; 13084 printedAnything = true; 13085 } 13086 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13087 pw.println(r); 13088 } 13089 } 13090 13091 if (mGrantedUriPermissions.size() > 0) { 13092 boolean printed = false; 13093 int dumpUid = -2; 13094 if (dumpPackage != null) { 13095 try { 13096 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13097 } catch (NameNotFoundException e) { 13098 dumpUid = -1; 13099 } 13100 } 13101 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13102 int uid = mGrantedUriPermissions.keyAt(i); 13103 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13104 continue; 13105 } 13106 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13107 if (!printed) { 13108 if (needSep) pw.println(); 13109 needSep = true; 13110 pw.println(" Granted Uri Permissions:"); 13111 printed = true; 13112 printedAnything = true; 13113 } 13114 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13115 for (UriPermission perm : perms.values()) { 13116 pw.print(" "); pw.println(perm); 13117 if (dumpAll) { 13118 perm.dump(pw, " "); 13119 } 13120 } 13121 } 13122 } 13123 13124 if (!printedAnything) { 13125 pw.println(" (nothing)"); 13126 } 13127 } 13128 13129 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13130 int opti, boolean dumpAll, String dumpPackage) { 13131 boolean printed = false; 13132 13133 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13134 13135 if (mIntentSenderRecords.size() > 0) { 13136 Iterator<WeakReference<PendingIntentRecord>> it 13137 = mIntentSenderRecords.values().iterator(); 13138 while (it.hasNext()) { 13139 WeakReference<PendingIntentRecord> ref = it.next(); 13140 PendingIntentRecord rec = ref != null ? ref.get(): null; 13141 if (dumpPackage != null && (rec == null 13142 || !dumpPackage.equals(rec.key.packageName))) { 13143 continue; 13144 } 13145 printed = true; 13146 if (rec != null) { 13147 pw.print(" * "); pw.println(rec); 13148 if (dumpAll) { 13149 rec.dump(pw, " "); 13150 } 13151 } else { 13152 pw.print(" * "); pw.println(ref); 13153 } 13154 } 13155 } 13156 13157 if (!printed) { 13158 pw.println(" (nothing)"); 13159 } 13160 } 13161 13162 private static final int dumpProcessList(PrintWriter pw, 13163 ActivityManagerService service, List list, 13164 String prefix, String normalLabel, String persistentLabel, 13165 String dumpPackage) { 13166 int numPers = 0; 13167 final int N = list.size()-1; 13168 for (int i=N; i>=0; i--) { 13169 ProcessRecord r = (ProcessRecord)list.get(i); 13170 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13171 continue; 13172 } 13173 pw.println(String.format("%s%s #%2d: %s", 13174 prefix, (r.persistent ? persistentLabel : normalLabel), 13175 i, r.toString())); 13176 if (r.persistent) { 13177 numPers++; 13178 } 13179 } 13180 return numPers; 13181 } 13182 13183 private static final boolean dumpProcessOomList(PrintWriter pw, 13184 ActivityManagerService service, List<ProcessRecord> origList, 13185 String prefix, String normalLabel, String persistentLabel, 13186 boolean inclDetails, String dumpPackage) { 13187 13188 ArrayList<Pair<ProcessRecord, Integer>> list 13189 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13190 for (int i=0; i<origList.size(); i++) { 13191 ProcessRecord r = origList.get(i); 13192 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13193 continue; 13194 } 13195 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13196 } 13197 13198 if (list.size() <= 0) { 13199 return false; 13200 } 13201 13202 Comparator<Pair<ProcessRecord, Integer>> comparator 13203 = new Comparator<Pair<ProcessRecord, Integer>>() { 13204 @Override 13205 public int compare(Pair<ProcessRecord, Integer> object1, 13206 Pair<ProcessRecord, Integer> object2) { 13207 if (object1.first.setAdj != object2.first.setAdj) { 13208 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13209 } 13210 if (object1.second.intValue() != object2.second.intValue()) { 13211 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13212 } 13213 return 0; 13214 } 13215 }; 13216 13217 Collections.sort(list, comparator); 13218 13219 final long curRealtime = SystemClock.elapsedRealtime(); 13220 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13221 final long curUptime = SystemClock.uptimeMillis(); 13222 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13223 13224 for (int i=list.size()-1; i>=0; i--) { 13225 ProcessRecord r = list.get(i).first; 13226 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13227 char schedGroup; 13228 switch (r.setSchedGroup) { 13229 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13230 schedGroup = 'B'; 13231 break; 13232 case Process.THREAD_GROUP_DEFAULT: 13233 schedGroup = 'F'; 13234 break; 13235 default: 13236 schedGroup = '?'; 13237 break; 13238 } 13239 char foreground; 13240 if (r.foregroundActivities) { 13241 foreground = 'A'; 13242 } else if (r.foregroundServices) { 13243 foreground = 'S'; 13244 } else { 13245 foreground = ' '; 13246 } 13247 String procState = ProcessList.makeProcStateString(r.curProcState); 13248 pw.print(prefix); 13249 pw.print(r.persistent ? persistentLabel : normalLabel); 13250 pw.print(" #"); 13251 int num = (origList.size()-1)-list.get(i).second; 13252 if (num < 10) pw.print(' '); 13253 pw.print(num); 13254 pw.print(": "); 13255 pw.print(oomAdj); 13256 pw.print(' '); 13257 pw.print(schedGroup); 13258 pw.print('/'); 13259 pw.print(foreground); 13260 pw.print('/'); 13261 pw.print(procState); 13262 pw.print(" trm:"); 13263 if (r.trimMemoryLevel < 10) pw.print(' '); 13264 pw.print(r.trimMemoryLevel); 13265 pw.print(' '); 13266 pw.print(r.toShortString()); 13267 pw.print(" ("); 13268 pw.print(r.adjType); 13269 pw.println(')'); 13270 if (r.adjSource != null || r.adjTarget != null) { 13271 pw.print(prefix); 13272 pw.print(" "); 13273 if (r.adjTarget instanceof ComponentName) { 13274 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13275 } else if (r.adjTarget != null) { 13276 pw.print(r.adjTarget.toString()); 13277 } else { 13278 pw.print("{null}"); 13279 } 13280 pw.print("<="); 13281 if (r.adjSource instanceof ProcessRecord) { 13282 pw.print("Proc{"); 13283 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13284 pw.println("}"); 13285 } else if (r.adjSource != null) { 13286 pw.println(r.adjSource.toString()); 13287 } else { 13288 pw.println("{null}"); 13289 } 13290 } 13291 if (inclDetails) { 13292 pw.print(prefix); 13293 pw.print(" "); 13294 pw.print("oom: max="); pw.print(r.maxAdj); 13295 pw.print(" curRaw="); pw.print(r.curRawAdj); 13296 pw.print(" setRaw="); pw.print(r.setRawAdj); 13297 pw.print(" cur="); pw.print(r.curAdj); 13298 pw.print(" set="); pw.println(r.setAdj); 13299 pw.print(prefix); 13300 pw.print(" "); 13301 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13302 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13303 pw.print(" lastPss="); pw.print(r.lastPss); 13304 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13305 pw.print(prefix); 13306 pw.print(" "); 13307 pw.print("cached="); pw.print(r.cached); 13308 pw.print(" empty="); pw.print(r.empty); 13309 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13310 13311 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13312 if (r.lastWakeTime != 0) { 13313 long wtime; 13314 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13315 synchronized (stats) { 13316 wtime = stats.getProcessWakeTime(r.info.uid, 13317 r.pid, curRealtime); 13318 } 13319 long timeUsed = wtime - r.lastWakeTime; 13320 pw.print(prefix); 13321 pw.print(" "); 13322 pw.print("keep awake over "); 13323 TimeUtils.formatDuration(realtimeSince, pw); 13324 pw.print(" used "); 13325 TimeUtils.formatDuration(timeUsed, pw); 13326 pw.print(" ("); 13327 pw.print((timeUsed*100)/realtimeSince); 13328 pw.println("%)"); 13329 } 13330 if (r.lastCpuTime != 0) { 13331 long timeUsed = r.curCpuTime - r.lastCpuTime; 13332 pw.print(prefix); 13333 pw.print(" "); 13334 pw.print("run cpu over "); 13335 TimeUtils.formatDuration(uptimeSince, pw); 13336 pw.print(" used "); 13337 TimeUtils.formatDuration(timeUsed, pw); 13338 pw.print(" ("); 13339 pw.print((timeUsed*100)/uptimeSince); 13340 pw.println("%)"); 13341 } 13342 } 13343 } 13344 } 13345 return true; 13346 } 13347 13348 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13349 ArrayList<ProcessRecord> procs; 13350 synchronized (this) { 13351 if (args != null && args.length > start 13352 && args[start].charAt(0) != '-') { 13353 procs = new ArrayList<ProcessRecord>(); 13354 int pid = -1; 13355 try { 13356 pid = Integer.parseInt(args[start]); 13357 } catch (NumberFormatException e) { 13358 } 13359 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13360 ProcessRecord proc = mLruProcesses.get(i); 13361 if (proc.pid == pid) { 13362 procs.add(proc); 13363 } else if (proc.processName.equals(args[start])) { 13364 procs.add(proc); 13365 } 13366 } 13367 if (procs.size() <= 0) { 13368 return null; 13369 } 13370 } else { 13371 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13372 } 13373 } 13374 return procs; 13375 } 13376 13377 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13378 PrintWriter pw, String[] args) { 13379 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13380 if (procs == null) { 13381 pw.println("No process found for: " + args[0]); 13382 return; 13383 } 13384 13385 long uptime = SystemClock.uptimeMillis(); 13386 long realtime = SystemClock.elapsedRealtime(); 13387 pw.println("Applications Graphics Acceleration Info:"); 13388 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13389 13390 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13391 ProcessRecord r = procs.get(i); 13392 if (r.thread != null) { 13393 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13394 pw.flush(); 13395 try { 13396 TransferPipe tp = new TransferPipe(); 13397 try { 13398 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13399 tp.go(fd); 13400 } finally { 13401 tp.kill(); 13402 } 13403 } catch (IOException e) { 13404 pw.println("Failure while dumping the app: " + r); 13405 pw.flush(); 13406 } catch (RemoteException e) { 13407 pw.println("Got a RemoteException while dumping the app " + r); 13408 pw.flush(); 13409 } 13410 } 13411 } 13412 } 13413 13414 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13415 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13416 if (procs == null) { 13417 pw.println("No process found for: " + args[0]); 13418 return; 13419 } 13420 13421 pw.println("Applications Database Info:"); 13422 13423 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13424 ProcessRecord r = procs.get(i); 13425 if (r.thread != null) { 13426 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13427 pw.flush(); 13428 try { 13429 TransferPipe tp = new TransferPipe(); 13430 try { 13431 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13432 tp.go(fd); 13433 } finally { 13434 tp.kill(); 13435 } 13436 } catch (IOException e) { 13437 pw.println("Failure while dumping the app: " + r); 13438 pw.flush(); 13439 } catch (RemoteException e) { 13440 pw.println("Got a RemoteException while dumping the app " + r); 13441 pw.flush(); 13442 } 13443 } 13444 } 13445 } 13446 13447 final static class MemItem { 13448 final boolean isProc; 13449 final String label; 13450 final String shortLabel; 13451 final long pss; 13452 final int id; 13453 final boolean hasActivities; 13454 ArrayList<MemItem> subitems; 13455 13456 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13457 boolean _hasActivities) { 13458 isProc = true; 13459 label = _label; 13460 shortLabel = _shortLabel; 13461 pss = _pss; 13462 id = _id; 13463 hasActivities = _hasActivities; 13464 } 13465 13466 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13467 isProc = false; 13468 label = _label; 13469 shortLabel = _shortLabel; 13470 pss = _pss; 13471 id = _id; 13472 hasActivities = false; 13473 } 13474 } 13475 13476 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13477 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13478 if (sort && !isCompact) { 13479 Collections.sort(items, new Comparator<MemItem>() { 13480 @Override 13481 public int compare(MemItem lhs, MemItem rhs) { 13482 if (lhs.pss < rhs.pss) { 13483 return 1; 13484 } else if (lhs.pss > rhs.pss) { 13485 return -1; 13486 } 13487 return 0; 13488 } 13489 }); 13490 } 13491 13492 for (int i=0; i<items.size(); i++) { 13493 MemItem mi = items.get(i); 13494 if (!isCompact) { 13495 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13496 } else if (mi.isProc) { 13497 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13498 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13499 pw.println(mi.hasActivities ? ",a" : ",e"); 13500 } else { 13501 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13502 pw.println(mi.pss); 13503 } 13504 if (mi.subitems != null) { 13505 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13506 true, isCompact); 13507 } 13508 } 13509 } 13510 13511 // These are in KB. 13512 static final long[] DUMP_MEM_BUCKETS = new long[] { 13513 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13514 120*1024, 160*1024, 200*1024, 13515 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13516 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13517 }; 13518 13519 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13520 boolean stackLike) { 13521 int start = label.lastIndexOf('.'); 13522 if (start >= 0) start++; 13523 else start = 0; 13524 int end = label.length(); 13525 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13526 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13527 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13528 out.append(bucket); 13529 out.append(stackLike ? "MB." : "MB "); 13530 out.append(label, start, end); 13531 return; 13532 } 13533 } 13534 out.append(memKB/1024); 13535 out.append(stackLike ? "MB." : "MB "); 13536 out.append(label, start, end); 13537 } 13538 13539 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13540 ProcessList.NATIVE_ADJ, 13541 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13542 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13543 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13544 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13545 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13546 }; 13547 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13548 "Native", 13549 "System", "Persistent", "Foreground", 13550 "Visible", "Perceptible", 13551 "Heavy Weight", "Backup", 13552 "A Services", "Home", 13553 "Previous", "B Services", "Cached" 13554 }; 13555 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13556 "native", 13557 "sys", "pers", "fore", 13558 "vis", "percept", 13559 "heavy", "backup", 13560 "servicea", "home", 13561 "prev", "serviceb", "cached" 13562 }; 13563 13564 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13565 long realtime, boolean isCheckinRequest, boolean isCompact) { 13566 if (isCheckinRequest || isCompact) { 13567 // short checkin version 13568 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13569 } else { 13570 pw.println("Applications Memory Usage (kB):"); 13571 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13572 } 13573 } 13574 13575 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13576 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13577 boolean dumpDetails = false; 13578 boolean dumpFullDetails = false; 13579 boolean dumpDalvik = false; 13580 boolean oomOnly = false; 13581 boolean isCompact = false; 13582 boolean localOnly = false; 13583 13584 int opti = 0; 13585 while (opti < args.length) { 13586 String opt = args[opti]; 13587 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13588 break; 13589 } 13590 opti++; 13591 if ("-a".equals(opt)) { 13592 dumpDetails = true; 13593 dumpFullDetails = true; 13594 dumpDalvik = true; 13595 } else if ("-d".equals(opt)) { 13596 dumpDalvik = true; 13597 } else if ("-c".equals(opt)) { 13598 isCompact = true; 13599 } else if ("--oom".equals(opt)) { 13600 oomOnly = true; 13601 } else if ("--local".equals(opt)) { 13602 localOnly = true; 13603 } else if ("-h".equals(opt)) { 13604 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13605 pw.println(" -a: include all available information for each process."); 13606 pw.println(" -d: include dalvik details when dumping process details."); 13607 pw.println(" -c: dump in a compact machine-parseable representation."); 13608 pw.println(" --oom: only show processes organized by oom adj."); 13609 pw.println(" --local: only collect details locally, don't call process."); 13610 pw.println("If [process] is specified it can be the name or "); 13611 pw.println("pid of a specific process to dump."); 13612 return; 13613 } else { 13614 pw.println("Unknown argument: " + opt + "; use -h for help"); 13615 } 13616 } 13617 13618 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13619 long uptime = SystemClock.uptimeMillis(); 13620 long realtime = SystemClock.elapsedRealtime(); 13621 final long[] tmpLong = new long[1]; 13622 13623 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13624 if (procs == null) { 13625 // No Java processes. Maybe they want to print a native process. 13626 if (args != null && args.length > opti 13627 && args[opti].charAt(0) != '-') { 13628 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13629 = new ArrayList<ProcessCpuTracker.Stats>(); 13630 updateCpuStatsNow(); 13631 int findPid = -1; 13632 try { 13633 findPid = Integer.parseInt(args[opti]); 13634 } catch (NumberFormatException e) { 13635 } 13636 synchronized (mProcessCpuThread) { 13637 final int N = mProcessCpuTracker.countStats(); 13638 for (int i=0; i<N; i++) { 13639 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13640 if (st.pid == findPid || (st.baseName != null 13641 && st.baseName.equals(args[opti]))) { 13642 nativeProcs.add(st); 13643 } 13644 } 13645 } 13646 if (nativeProcs.size() > 0) { 13647 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13648 isCompact); 13649 Debug.MemoryInfo mi = null; 13650 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13651 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13652 final int pid = r.pid; 13653 if (!isCheckinRequest && dumpDetails) { 13654 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13655 } 13656 if (mi == null) { 13657 mi = new Debug.MemoryInfo(); 13658 } 13659 if (dumpDetails || (!brief && !oomOnly)) { 13660 Debug.getMemoryInfo(pid, mi); 13661 } else { 13662 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13663 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13664 } 13665 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13666 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13667 if (isCheckinRequest) { 13668 pw.println(); 13669 } 13670 } 13671 return; 13672 } 13673 } 13674 pw.println("No process found for: " + args[opti]); 13675 return; 13676 } 13677 13678 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13679 dumpDetails = true; 13680 } 13681 13682 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13683 13684 String[] innerArgs = new String[args.length-opti]; 13685 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13686 13687 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13688 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13689 long nativePss=0, dalvikPss=0, otherPss=0; 13690 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13691 13692 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13693 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13694 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13695 13696 long totalPss = 0; 13697 long cachedPss = 0; 13698 13699 Debug.MemoryInfo mi = null; 13700 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13701 final ProcessRecord r = procs.get(i); 13702 final IApplicationThread thread; 13703 final int pid; 13704 final int oomAdj; 13705 final boolean hasActivities; 13706 synchronized (this) { 13707 thread = r.thread; 13708 pid = r.pid; 13709 oomAdj = r.getSetAdjWithServices(); 13710 hasActivities = r.activities.size() > 0; 13711 } 13712 if (thread != null) { 13713 if (!isCheckinRequest && dumpDetails) { 13714 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13715 } 13716 if (mi == null) { 13717 mi = new Debug.MemoryInfo(); 13718 } 13719 if (dumpDetails || (!brief && !oomOnly)) { 13720 Debug.getMemoryInfo(pid, mi); 13721 } else { 13722 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13723 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13724 } 13725 if (dumpDetails) { 13726 if (localOnly) { 13727 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13728 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13729 if (isCheckinRequest) { 13730 pw.println(); 13731 } 13732 } else { 13733 try { 13734 pw.flush(); 13735 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13736 dumpDalvik, innerArgs); 13737 } catch (RemoteException e) { 13738 if (!isCheckinRequest) { 13739 pw.println("Got RemoteException!"); 13740 pw.flush(); 13741 } 13742 } 13743 } 13744 } 13745 13746 final long myTotalPss = mi.getTotalPss(); 13747 final long myTotalUss = mi.getTotalUss(); 13748 13749 synchronized (this) { 13750 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13751 // Record this for posterity if the process has been stable. 13752 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13753 } 13754 } 13755 13756 if (!isCheckinRequest && mi != null) { 13757 totalPss += myTotalPss; 13758 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13759 (hasActivities ? " / activities)" : ")"), 13760 r.processName, myTotalPss, pid, hasActivities); 13761 procMems.add(pssItem); 13762 procMemsMap.put(pid, pssItem); 13763 13764 nativePss += mi.nativePss; 13765 dalvikPss += mi.dalvikPss; 13766 otherPss += mi.otherPss; 13767 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13768 long mem = mi.getOtherPss(j); 13769 miscPss[j] += mem; 13770 otherPss -= mem; 13771 } 13772 13773 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13774 cachedPss += myTotalPss; 13775 } 13776 13777 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13778 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13779 || oomIndex == (oomPss.length-1)) { 13780 oomPss[oomIndex] += myTotalPss; 13781 if (oomProcs[oomIndex] == null) { 13782 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13783 } 13784 oomProcs[oomIndex].add(pssItem); 13785 break; 13786 } 13787 } 13788 } 13789 } 13790 } 13791 13792 long nativeProcTotalPss = 0; 13793 13794 if (!isCheckinRequest && procs.size() > 1) { 13795 // If we are showing aggregations, also look for native processes to 13796 // include so that our aggregations are more accurate. 13797 updateCpuStatsNow(); 13798 synchronized (mProcessCpuThread) { 13799 final int N = mProcessCpuTracker.countStats(); 13800 for (int i=0; i<N; i++) { 13801 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13802 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13803 if (mi == null) { 13804 mi = new Debug.MemoryInfo(); 13805 } 13806 if (!brief && !oomOnly) { 13807 Debug.getMemoryInfo(st.pid, mi); 13808 } else { 13809 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13810 mi.nativePrivateDirty = (int)tmpLong[0]; 13811 } 13812 13813 final long myTotalPss = mi.getTotalPss(); 13814 totalPss += myTotalPss; 13815 nativeProcTotalPss += myTotalPss; 13816 13817 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13818 st.name, myTotalPss, st.pid, false); 13819 procMems.add(pssItem); 13820 13821 nativePss += mi.nativePss; 13822 dalvikPss += mi.dalvikPss; 13823 otherPss += mi.otherPss; 13824 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13825 long mem = mi.getOtherPss(j); 13826 miscPss[j] += mem; 13827 otherPss -= mem; 13828 } 13829 oomPss[0] += myTotalPss; 13830 if (oomProcs[0] == null) { 13831 oomProcs[0] = new ArrayList<MemItem>(); 13832 } 13833 oomProcs[0].add(pssItem); 13834 } 13835 } 13836 } 13837 13838 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13839 13840 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13841 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13842 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13843 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13844 String label = Debug.MemoryInfo.getOtherLabel(j); 13845 catMems.add(new MemItem(label, label, miscPss[j], j)); 13846 } 13847 13848 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13849 for (int j=0; j<oomPss.length; j++) { 13850 if (oomPss[j] != 0) { 13851 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13852 : DUMP_MEM_OOM_LABEL[j]; 13853 MemItem item = new MemItem(label, label, oomPss[j], 13854 DUMP_MEM_OOM_ADJ[j]); 13855 item.subitems = oomProcs[j]; 13856 oomMems.add(item); 13857 } 13858 } 13859 13860 if (!brief && !oomOnly && !isCompact) { 13861 pw.println(); 13862 pw.println("Total PSS by process:"); 13863 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13864 pw.println(); 13865 } 13866 if (!isCompact) { 13867 pw.println("Total PSS by OOM adjustment:"); 13868 } 13869 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13870 if (!brief && !oomOnly) { 13871 PrintWriter out = categoryPw != null ? categoryPw : pw; 13872 if (!isCompact) { 13873 out.println(); 13874 out.println("Total PSS by category:"); 13875 } 13876 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13877 } 13878 if (!isCompact) { 13879 pw.println(); 13880 } 13881 MemInfoReader memInfo = new MemInfoReader(); 13882 memInfo.readMemInfo(); 13883 if (nativeProcTotalPss > 0) { 13884 synchronized (this) { 13885 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13886 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13887 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13888 nativeProcTotalPss); 13889 } 13890 } 13891 if (!brief) { 13892 if (!isCompact) { 13893 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13894 pw.print(" kB (status "); 13895 switch (mLastMemoryLevel) { 13896 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13897 pw.println("normal)"); 13898 break; 13899 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13900 pw.println("moderate)"); 13901 break; 13902 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13903 pw.println("low)"); 13904 break; 13905 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13906 pw.println("critical)"); 13907 break; 13908 default: 13909 pw.print(mLastMemoryLevel); 13910 pw.println(")"); 13911 break; 13912 } 13913 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13914 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13915 pw.print(cachedPss); pw.print(" cached pss + "); 13916 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13917 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13918 } else { 13919 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13920 pw.print(cachedPss + memInfo.getCachedSizeKb() 13921 + memInfo.getFreeSizeKb()); pw.print(","); 13922 pw.println(totalPss - cachedPss); 13923 } 13924 } 13925 if (!isCompact) { 13926 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13927 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13928 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13929 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13930 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13931 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13932 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13933 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13934 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13935 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13936 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13937 } 13938 if (!brief) { 13939 if (memInfo.getZramTotalSizeKb() != 0) { 13940 if (!isCompact) { 13941 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13942 pw.print(" kB physical used for "); 13943 pw.print(memInfo.getSwapTotalSizeKb() 13944 - memInfo.getSwapFreeSizeKb()); 13945 pw.print(" kB in swap ("); 13946 pw.print(memInfo.getSwapTotalSizeKb()); 13947 pw.println(" kB total swap)"); 13948 } else { 13949 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13950 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13951 pw.println(memInfo.getSwapFreeSizeKb()); 13952 } 13953 } 13954 final int[] SINGLE_LONG_FORMAT = new int[] { 13955 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13956 }; 13957 long[] longOut = new long[1]; 13958 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13959 SINGLE_LONG_FORMAT, null, longOut, null); 13960 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13961 longOut[0] = 0; 13962 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13963 SINGLE_LONG_FORMAT, null, longOut, null); 13964 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13965 longOut[0] = 0; 13966 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13967 SINGLE_LONG_FORMAT, null, longOut, null); 13968 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13969 longOut[0] = 0; 13970 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13971 SINGLE_LONG_FORMAT, null, longOut, null); 13972 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13973 if (!isCompact) { 13974 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13975 pw.print(" KSM: "); pw.print(sharing); 13976 pw.print(" kB saved from shared "); 13977 pw.print(shared); pw.println(" kB"); 13978 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13979 pw.print(voltile); pw.println(" kB volatile"); 13980 } 13981 pw.print(" Tuning: "); 13982 pw.print(ActivityManager.staticGetMemoryClass()); 13983 pw.print(" (large "); 13984 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13985 pw.print("), oom "); 13986 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13987 pw.print(" kB"); 13988 pw.print(", restore limit "); 13989 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13990 pw.print(" kB"); 13991 if (ActivityManager.isLowRamDeviceStatic()) { 13992 pw.print(" (low-ram)"); 13993 } 13994 if (ActivityManager.isHighEndGfx()) { 13995 pw.print(" (high-end-gfx)"); 13996 } 13997 pw.println(); 13998 } else { 13999 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14000 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14001 pw.println(voltile); 14002 pw.print("tuning,"); 14003 pw.print(ActivityManager.staticGetMemoryClass()); 14004 pw.print(','); 14005 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14006 pw.print(','); 14007 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14008 if (ActivityManager.isLowRamDeviceStatic()) { 14009 pw.print(",low-ram"); 14010 } 14011 if (ActivityManager.isHighEndGfx()) { 14012 pw.print(",high-end-gfx"); 14013 } 14014 pw.println(); 14015 } 14016 } 14017 } 14018 } 14019 14020 /** 14021 * Searches array of arguments for the specified string 14022 * @param args array of argument strings 14023 * @param value value to search for 14024 * @return true if the value is contained in the array 14025 */ 14026 private static boolean scanArgs(String[] args, String value) { 14027 if (args != null) { 14028 for (String arg : args) { 14029 if (value.equals(arg)) { 14030 return true; 14031 } 14032 } 14033 } 14034 return false; 14035 } 14036 14037 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14038 ContentProviderRecord cpr, boolean always) { 14039 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14040 14041 if (!inLaunching || always) { 14042 synchronized (cpr) { 14043 cpr.launchingApp = null; 14044 cpr.notifyAll(); 14045 } 14046 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14047 String names[] = cpr.info.authority.split(";"); 14048 for (int j = 0; j < names.length; j++) { 14049 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14050 } 14051 } 14052 14053 for (int i=0; i<cpr.connections.size(); i++) { 14054 ContentProviderConnection conn = cpr.connections.get(i); 14055 if (conn.waiting) { 14056 // If this connection is waiting for the provider, then we don't 14057 // need to mess with its process unless we are always removing 14058 // or for some reason the provider is not currently launching. 14059 if (inLaunching && !always) { 14060 continue; 14061 } 14062 } 14063 ProcessRecord capp = conn.client; 14064 conn.dead = true; 14065 if (conn.stableCount > 0) { 14066 if (!capp.persistent && capp.thread != null 14067 && capp.pid != 0 14068 && capp.pid != MY_PID) { 14069 capp.kill("depends on provider " 14070 + cpr.name.flattenToShortString() 14071 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14072 } 14073 } else if (capp.thread != null && conn.provider.provider != null) { 14074 try { 14075 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14076 } catch (RemoteException e) { 14077 } 14078 // In the protocol here, we don't expect the client to correctly 14079 // clean up this connection, we'll just remove it. 14080 cpr.connections.remove(i); 14081 conn.client.conProviders.remove(conn); 14082 } 14083 } 14084 14085 if (inLaunching && always) { 14086 mLaunchingProviders.remove(cpr); 14087 } 14088 return inLaunching; 14089 } 14090 14091 /** 14092 * Main code for cleaning up a process when it has gone away. This is 14093 * called both as a result of the process dying, or directly when stopping 14094 * a process when running in single process mode. 14095 */ 14096 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14097 boolean restarting, boolean allowRestart, int index) { 14098 if (index >= 0) { 14099 removeLruProcessLocked(app); 14100 ProcessList.remove(app.pid); 14101 } 14102 14103 mProcessesToGc.remove(app); 14104 mPendingPssProcesses.remove(app); 14105 14106 // Dismiss any open dialogs. 14107 if (app.crashDialog != null && !app.forceCrashReport) { 14108 app.crashDialog.dismiss(); 14109 app.crashDialog = null; 14110 } 14111 if (app.anrDialog != null) { 14112 app.anrDialog.dismiss(); 14113 app.anrDialog = null; 14114 } 14115 if (app.waitDialog != null) { 14116 app.waitDialog.dismiss(); 14117 app.waitDialog = null; 14118 } 14119 14120 app.crashing = false; 14121 app.notResponding = false; 14122 14123 app.resetPackageList(mProcessStats); 14124 app.unlinkDeathRecipient(); 14125 app.makeInactive(mProcessStats); 14126 app.waitingToKill = null; 14127 app.forcingToForeground = null; 14128 updateProcessForegroundLocked(app, false, false); 14129 app.foregroundActivities = false; 14130 app.hasShownUi = false; 14131 app.treatLikeActivity = false; 14132 app.hasAboveClient = false; 14133 app.hasClientActivities = false; 14134 14135 mServices.killServicesLocked(app, allowRestart); 14136 14137 boolean restart = false; 14138 14139 // Remove published content providers. 14140 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14141 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14142 final boolean always = app.bad || !allowRestart; 14143 if (removeDyingProviderLocked(app, cpr, always) || always) { 14144 // We left the provider in the launching list, need to 14145 // restart it. 14146 restart = true; 14147 } 14148 14149 cpr.provider = null; 14150 cpr.proc = null; 14151 } 14152 app.pubProviders.clear(); 14153 14154 // Take care of any launching providers waiting for this process. 14155 if (checkAppInLaunchingProvidersLocked(app, false)) { 14156 restart = true; 14157 } 14158 14159 // Unregister from connected content providers. 14160 if (!app.conProviders.isEmpty()) { 14161 for (int i=0; i<app.conProviders.size(); i++) { 14162 ContentProviderConnection conn = app.conProviders.get(i); 14163 conn.provider.connections.remove(conn); 14164 } 14165 app.conProviders.clear(); 14166 } 14167 14168 // At this point there may be remaining entries in mLaunchingProviders 14169 // where we were the only one waiting, so they are no longer of use. 14170 // Look for these and clean up if found. 14171 // XXX Commented out for now. Trying to figure out a way to reproduce 14172 // the actual situation to identify what is actually going on. 14173 if (false) { 14174 for (int i=0; i<mLaunchingProviders.size(); i++) { 14175 ContentProviderRecord cpr = (ContentProviderRecord) 14176 mLaunchingProviders.get(i); 14177 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14178 synchronized (cpr) { 14179 cpr.launchingApp = null; 14180 cpr.notifyAll(); 14181 } 14182 } 14183 } 14184 } 14185 14186 skipCurrentReceiverLocked(app); 14187 14188 // Unregister any receivers. 14189 for (int i=app.receivers.size()-1; i>=0; i--) { 14190 removeReceiverLocked(app.receivers.valueAt(i)); 14191 } 14192 app.receivers.clear(); 14193 14194 // If the app is undergoing backup, tell the backup manager about it 14195 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14196 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14197 + mBackupTarget.appInfo + " died during backup"); 14198 try { 14199 IBackupManager bm = IBackupManager.Stub.asInterface( 14200 ServiceManager.getService(Context.BACKUP_SERVICE)); 14201 bm.agentDisconnected(app.info.packageName); 14202 } catch (RemoteException e) { 14203 // can't happen; backup manager is local 14204 } 14205 } 14206 14207 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14208 ProcessChangeItem item = mPendingProcessChanges.get(i); 14209 if (item.pid == app.pid) { 14210 mPendingProcessChanges.remove(i); 14211 mAvailProcessChanges.add(item); 14212 } 14213 } 14214 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14215 14216 // If the caller is restarting this app, then leave it in its 14217 // current lists and let the caller take care of it. 14218 if (restarting) { 14219 return; 14220 } 14221 14222 if (!app.persistent || app.isolated) { 14223 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14224 "Removing non-persistent process during cleanup: " + app); 14225 mProcessNames.remove(app.processName, app.uid); 14226 mIsolatedProcesses.remove(app.uid); 14227 if (mHeavyWeightProcess == app) { 14228 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14229 mHeavyWeightProcess.userId, 0)); 14230 mHeavyWeightProcess = null; 14231 } 14232 } else if (!app.removed) { 14233 // This app is persistent, so we need to keep its record around. 14234 // If it is not already on the pending app list, add it there 14235 // and start a new process for it. 14236 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14237 mPersistentStartingProcesses.add(app); 14238 restart = true; 14239 } 14240 } 14241 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14242 "Clean-up removing on hold: " + app); 14243 mProcessesOnHold.remove(app); 14244 14245 if (app == mHomeProcess) { 14246 mHomeProcess = null; 14247 } 14248 if (app == mPreviousProcess) { 14249 mPreviousProcess = null; 14250 } 14251 14252 if (restart && !app.isolated) { 14253 // We have components that still need to be running in the 14254 // process, so re-launch it. 14255 mProcessNames.put(app.processName, app.uid, app); 14256 startProcessLocked(app, "restart", app.processName); 14257 } else if (app.pid > 0 && app.pid != MY_PID) { 14258 // Goodbye! 14259 boolean removed; 14260 synchronized (mPidsSelfLocked) { 14261 mPidsSelfLocked.remove(app.pid); 14262 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14263 } 14264 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14265 if (app.isolated) { 14266 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14267 } 14268 app.setPid(0); 14269 } 14270 } 14271 14272 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14273 // Look through the content providers we are waiting to have launched, 14274 // and if any run in this process then either schedule a restart of 14275 // the process or kill the client waiting for it if this process has 14276 // gone bad. 14277 int NL = mLaunchingProviders.size(); 14278 boolean restart = false; 14279 for (int i=0; i<NL; i++) { 14280 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14281 if (cpr.launchingApp == app) { 14282 if (!alwaysBad && !app.bad) { 14283 restart = true; 14284 } else { 14285 removeDyingProviderLocked(app, cpr, true); 14286 // cpr should have been removed from mLaunchingProviders 14287 NL = mLaunchingProviders.size(); 14288 i--; 14289 } 14290 } 14291 } 14292 return restart; 14293 } 14294 14295 // ========================================================= 14296 // SERVICES 14297 // ========================================================= 14298 14299 @Override 14300 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14301 int flags) { 14302 enforceNotIsolatedCaller("getServices"); 14303 synchronized (this) { 14304 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14305 } 14306 } 14307 14308 @Override 14309 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14310 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14311 synchronized (this) { 14312 return mServices.getRunningServiceControlPanelLocked(name); 14313 } 14314 } 14315 14316 @Override 14317 public ComponentName startService(IApplicationThread caller, Intent service, 14318 String resolvedType, int userId) { 14319 enforceNotIsolatedCaller("startService"); 14320 // Refuse possible leaked file descriptors 14321 if (service != null && service.hasFileDescriptors() == true) { 14322 throw new IllegalArgumentException("File descriptors passed in Intent"); 14323 } 14324 14325 if (DEBUG_SERVICE) 14326 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14327 synchronized(this) { 14328 final int callingPid = Binder.getCallingPid(); 14329 final int callingUid = Binder.getCallingUid(); 14330 final long origId = Binder.clearCallingIdentity(); 14331 ComponentName res = mServices.startServiceLocked(caller, service, 14332 resolvedType, callingPid, callingUid, userId); 14333 Binder.restoreCallingIdentity(origId); 14334 return res; 14335 } 14336 } 14337 14338 ComponentName startServiceInPackage(int uid, 14339 Intent service, String resolvedType, int userId) { 14340 synchronized(this) { 14341 if (DEBUG_SERVICE) 14342 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14343 final long origId = Binder.clearCallingIdentity(); 14344 ComponentName res = mServices.startServiceLocked(null, service, 14345 resolvedType, -1, uid, userId); 14346 Binder.restoreCallingIdentity(origId); 14347 return res; 14348 } 14349 } 14350 14351 @Override 14352 public int stopService(IApplicationThread caller, Intent service, 14353 String resolvedType, int userId) { 14354 enforceNotIsolatedCaller("stopService"); 14355 // Refuse possible leaked file descriptors 14356 if (service != null && service.hasFileDescriptors() == true) { 14357 throw new IllegalArgumentException("File descriptors passed in Intent"); 14358 } 14359 14360 synchronized(this) { 14361 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14362 } 14363 } 14364 14365 @Override 14366 public IBinder peekService(Intent service, String resolvedType) { 14367 enforceNotIsolatedCaller("peekService"); 14368 // Refuse possible leaked file descriptors 14369 if (service != null && service.hasFileDescriptors() == true) { 14370 throw new IllegalArgumentException("File descriptors passed in Intent"); 14371 } 14372 synchronized(this) { 14373 return mServices.peekServiceLocked(service, resolvedType); 14374 } 14375 } 14376 14377 @Override 14378 public boolean stopServiceToken(ComponentName className, IBinder token, 14379 int startId) { 14380 synchronized(this) { 14381 return mServices.stopServiceTokenLocked(className, token, startId); 14382 } 14383 } 14384 14385 @Override 14386 public void setServiceForeground(ComponentName className, IBinder token, 14387 int id, Notification notification, boolean removeNotification) { 14388 synchronized(this) { 14389 mServices.setServiceForegroundLocked(className, token, id, notification, 14390 removeNotification); 14391 } 14392 } 14393 14394 @Override 14395 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14396 boolean requireFull, String name, String callerPackage) { 14397 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14398 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14399 } 14400 14401 int unsafeConvertIncomingUser(int userId) { 14402 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14403 ? mCurrentUserId : userId; 14404 } 14405 14406 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14407 int allowMode, String name, String callerPackage) { 14408 final int callingUserId = UserHandle.getUserId(callingUid); 14409 if (callingUserId == userId) { 14410 return userId; 14411 } 14412 14413 // Note that we may be accessing mCurrentUserId outside of a lock... 14414 // shouldn't be a big deal, if this is being called outside 14415 // of a locked context there is intrinsically a race with 14416 // the value the caller will receive and someone else changing it. 14417 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14418 // we will switch to the calling user if access to the current user fails. 14419 int targetUserId = unsafeConvertIncomingUser(userId); 14420 14421 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14422 final boolean allow; 14423 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14424 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14425 // If the caller has this permission, they always pass go. And collect $200. 14426 allow = true; 14427 } else if (allowMode == ALLOW_FULL_ONLY) { 14428 // We require full access, sucks to be you. 14429 allow = false; 14430 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14431 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14432 // If the caller does not have either permission, they are always doomed. 14433 allow = false; 14434 } else if (allowMode == ALLOW_NON_FULL) { 14435 // We are blanket allowing non-full access, you lucky caller! 14436 allow = true; 14437 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14438 // We may or may not allow this depending on whether the two users are 14439 // in the same profile. 14440 synchronized (mUserProfileGroupIdsSelfLocked) { 14441 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14442 UserInfo.NO_PROFILE_GROUP_ID); 14443 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14444 UserInfo.NO_PROFILE_GROUP_ID); 14445 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14446 && callingProfile == targetProfile; 14447 } 14448 } else { 14449 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14450 } 14451 if (!allow) { 14452 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14453 // In this case, they would like to just execute as their 14454 // owner user instead of failing. 14455 targetUserId = callingUserId; 14456 } else { 14457 StringBuilder builder = new StringBuilder(128); 14458 builder.append("Permission Denial: "); 14459 builder.append(name); 14460 if (callerPackage != null) { 14461 builder.append(" from "); 14462 builder.append(callerPackage); 14463 } 14464 builder.append(" asks to run as user "); 14465 builder.append(userId); 14466 builder.append(" but is calling from user "); 14467 builder.append(UserHandle.getUserId(callingUid)); 14468 builder.append("; this requires "); 14469 builder.append(INTERACT_ACROSS_USERS_FULL); 14470 if (allowMode != ALLOW_FULL_ONLY) { 14471 builder.append(" or "); 14472 builder.append(INTERACT_ACROSS_USERS); 14473 } 14474 String msg = builder.toString(); 14475 Slog.w(TAG, msg); 14476 throw new SecurityException(msg); 14477 } 14478 } 14479 } 14480 if (!allowAll && targetUserId < 0) { 14481 throw new IllegalArgumentException( 14482 "Call does not support special user #" + targetUserId); 14483 } 14484 return targetUserId; 14485 } 14486 14487 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14488 String className, int flags) { 14489 boolean result = false; 14490 // For apps that don't have pre-defined UIDs, check for permission 14491 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14492 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14493 if (ActivityManager.checkUidPermission( 14494 INTERACT_ACROSS_USERS, 14495 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14496 ComponentName comp = new ComponentName(aInfo.packageName, className); 14497 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14498 + " requests FLAG_SINGLE_USER, but app does not hold " 14499 + INTERACT_ACROSS_USERS; 14500 Slog.w(TAG, msg); 14501 throw new SecurityException(msg); 14502 } 14503 // Permission passed 14504 result = true; 14505 } 14506 } else if ("system".equals(componentProcessName)) { 14507 result = true; 14508 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14509 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14510 // Phone app is allowed to export singleuser providers. 14511 result = true; 14512 } else { 14513 // App with pre-defined UID, check if it's a persistent app 14514 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14515 } 14516 if (DEBUG_MU) { 14517 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14518 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14519 } 14520 return result; 14521 } 14522 14523 /** 14524 * Checks to see if the caller is in the same app as the singleton 14525 * component, or the component is in a special app. It allows special apps 14526 * to export singleton components but prevents exporting singleton 14527 * components for regular apps. 14528 */ 14529 boolean isValidSingletonCall(int callingUid, int componentUid) { 14530 int componentAppId = UserHandle.getAppId(componentUid); 14531 return UserHandle.isSameApp(callingUid, componentUid) 14532 || componentAppId == Process.SYSTEM_UID 14533 || componentAppId == Process.PHONE_UID 14534 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14535 == PackageManager.PERMISSION_GRANTED; 14536 } 14537 14538 public int bindService(IApplicationThread caller, IBinder token, 14539 Intent service, String resolvedType, 14540 IServiceConnection connection, int flags, int userId) { 14541 enforceNotIsolatedCaller("bindService"); 14542 // Refuse possible leaked file descriptors 14543 if (service != null && service.hasFileDescriptors() == true) { 14544 throw new IllegalArgumentException("File descriptors passed in Intent"); 14545 } 14546 14547 synchronized(this) { 14548 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14549 connection, flags, userId); 14550 } 14551 } 14552 14553 public boolean unbindService(IServiceConnection connection) { 14554 synchronized (this) { 14555 return mServices.unbindServiceLocked(connection); 14556 } 14557 } 14558 14559 public void publishService(IBinder token, Intent intent, IBinder service) { 14560 // Refuse possible leaked file descriptors 14561 if (intent != null && intent.hasFileDescriptors() == true) { 14562 throw new IllegalArgumentException("File descriptors passed in Intent"); 14563 } 14564 14565 synchronized(this) { 14566 if (!(token instanceof ServiceRecord)) { 14567 throw new IllegalArgumentException("Invalid service token"); 14568 } 14569 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14570 } 14571 } 14572 14573 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14574 // Refuse possible leaked file descriptors 14575 if (intent != null && intent.hasFileDescriptors() == true) { 14576 throw new IllegalArgumentException("File descriptors passed in Intent"); 14577 } 14578 14579 synchronized(this) { 14580 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14581 } 14582 } 14583 14584 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14585 synchronized(this) { 14586 if (!(token instanceof ServiceRecord)) { 14587 throw new IllegalArgumentException("Invalid service token"); 14588 } 14589 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14590 } 14591 } 14592 14593 // ========================================================= 14594 // BACKUP AND RESTORE 14595 // ========================================================= 14596 14597 // Cause the target app to be launched if necessary and its backup agent 14598 // instantiated. The backup agent will invoke backupAgentCreated() on the 14599 // activity manager to announce its creation. 14600 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14601 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14602 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14603 14604 synchronized(this) { 14605 // !!! TODO: currently no check here that we're already bound 14606 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14607 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14608 synchronized (stats) { 14609 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14610 } 14611 14612 // Backup agent is now in use, its package can't be stopped. 14613 try { 14614 AppGlobals.getPackageManager().setPackageStoppedState( 14615 app.packageName, false, UserHandle.getUserId(app.uid)); 14616 } catch (RemoteException e) { 14617 } catch (IllegalArgumentException e) { 14618 Slog.w(TAG, "Failed trying to unstop package " 14619 + app.packageName + ": " + e); 14620 } 14621 14622 BackupRecord r = new BackupRecord(ss, app, backupMode); 14623 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14624 ? new ComponentName(app.packageName, app.backupAgentName) 14625 : new ComponentName("android", "FullBackupAgent"); 14626 // startProcessLocked() returns existing proc's record if it's already running 14627 ProcessRecord proc = startProcessLocked(app.processName, app, 14628 false, 0, "backup", hostingName, false, false, false); 14629 if (proc == null) { 14630 Slog.e(TAG, "Unable to start backup agent process " + r); 14631 return false; 14632 } 14633 14634 r.app = proc; 14635 mBackupTarget = r; 14636 mBackupAppName = app.packageName; 14637 14638 // Try not to kill the process during backup 14639 updateOomAdjLocked(proc); 14640 14641 // If the process is already attached, schedule the creation of the backup agent now. 14642 // If it is not yet live, this will be done when it attaches to the framework. 14643 if (proc.thread != null) { 14644 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14645 try { 14646 proc.thread.scheduleCreateBackupAgent(app, 14647 compatibilityInfoForPackageLocked(app), backupMode); 14648 } catch (RemoteException e) { 14649 // Will time out on the backup manager side 14650 } 14651 } else { 14652 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14653 } 14654 // Invariants: at this point, the target app process exists and the application 14655 // is either already running or in the process of coming up. mBackupTarget and 14656 // mBackupAppName describe the app, so that when it binds back to the AM we 14657 // know that it's scheduled for a backup-agent operation. 14658 } 14659 14660 return true; 14661 } 14662 14663 @Override 14664 public void clearPendingBackup() { 14665 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14666 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14667 14668 synchronized (this) { 14669 mBackupTarget = null; 14670 mBackupAppName = null; 14671 } 14672 } 14673 14674 // A backup agent has just come up 14675 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14676 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14677 + " = " + agent); 14678 14679 synchronized(this) { 14680 if (!agentPackageName.equals(mBackupAppName)) { 14681 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14682 return; 14683 } 14684 } 14685 14686 long oldIdent = Binder.clearCallingIdentity(); 14687 try { 14688 IBackupManager bm = IBackupManager.Stub.asInterface( 14689 ServiceManager.getService(Context.BACKUP_SERVICE)); 14690 bm.agentConnected(agentPackageName, agent); 14691 } catch (RemoteException e) { 14692 // can't happen; the backup manager service is local 14693 } catch (Exception e) { 14694 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14695 e.printStackTrace(); 14696 } finally { 14697 Binder.restoreCallingIdentity(oldIdent); 14698 } 14699 } 14700 14701 // done with this agent 14702 public void unbindBackupAgent(ApplicationInfo appInfo) { 14703 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14704 if (appInfo == null) { 14705 Slog.w(TAG, "unbind backup agent for null app"); 14706 return; 14707 } 14708 14709 synchronized(this) { 14710 try { 14711 if (mBackupAppName == null) { 14712 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14713 return; 14714 } 14715 14716 if (!mBackupAppName.equals(appInfo.packageName)) { 14717 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14718 return; 14719 } 14720 14721 // Not backing this app up any more; reset its OOM adjustment 14722 final ProcessRecord proc = mBackupTarget.app; 14723 updateOomAdjLocked(proc); 14724 14725 // If the app crashed during backup, 'thread' will be null here 14726 if (proc.thread != null) { 14727 try { 14728 proc.thread.scheduleDestroyBackupAgent(appInfo, 14729 compatibilityInfoForPackageLocked(appInfo)); 14730 } catch (Exception e) { 14731 Slog.e(TAG, "Exception when unbinding backup agent:"); 14732 e.printStackTrace(); 14733 } 14734 } 14735 } finally { 14736 mBackupTarget = null; 14737 mBackupAppName = null; 14738 } 14739 } 14740 } 14741 // ========================================================= 14742 // BROADCASTS 14743 // ========================================================= 14744 14745 private final List getStickiesLocked(String action, IntentFilter filter, 14746 List cur, int userId) { 14747 final ContentResolver resolver = mContext.getContentResolver(); 14748 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14749 if (stickies == null) { 14750 return cur; 14751 } 14752 final ArrayList<Intent> list = stickies.get(action); 14753 if (list == null) { 14754 return cur; 14755 } 14756 int N = list.size(); 14757 for (int i=0; i<N; i++) { 14758 Intent intent = list.get(i); 14759 if (filter.match(resolver, intent, true, TAG) >= 0) { 14760 if (cur == null) { 14761 cur = new ArrayList<Intent>(); 14762 } 14763 cur.add(intent); 14764 } 14765 } 14766 return cur; 14767 } 14768 14769 boolean isPendingBroadcastProcessLocked(int pid) { 14770 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14771 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14772 } 14773 14774 void skipPendingBroadcastLocked(int pid) { 14775 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14776 for (BroadcastQueue queue : mBroadcastQueues) { 14777 queue.skipPendingBroadcastLocked(pid); 14778 } 14779 } 14780 14781 // The app just attached; send any pending broadcasts that it should receive 14782 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14783 boolean didSomething = false; 14784 for (BroadcastQueue queue : mBroadcastQueues) { 14785 didSomething |= queue.sendPendingBroadcastsLocked(app); 14786 } 14787 return didSomething; 14788 } 14789 14790 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14791 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14792 enforceNotIsolatedCaller("registerReceiver"); 14793 int callingUid; 14794 int callingPid; 14795 synchronized(this) { 14796 ProcessRecord callerApp = null; 14797 if (caller != null) { 14798 callerApp = getRecordForAppLocked(caller); 14799 if (callerApp == null) { 14800 throw new SecurityException( 14801 "Unable to find app for caller " + caller 14802 + " (pid=" + Binder.getCallingPid() 14803 + ") when registering receiver " + receiver); 14804 } 14805 if (callerApp.info.uid != Process.SYSTEM_UID && 14806 !callerApp.pkgList.containsKey(callerPackage) && 14807 !"android".equals(callerPackage)) { 14808 throw new SecurityException("Given caller package " + callerPackage 14809 + " is not running in process " + callerApp); 14810 } 14811 callingUid = callerApp.info.uid; 14812 callingPid = callerApp.pid; 14813 } else { 14814 callerPackage = null; 14815 callingUid = Binder.getCallingUid(); 14816 callingPid = Binder.getCallingPid(); 14817 } 14818 14819 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14820 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14821 14822 List allSticky = null; 14823 14824 // Look for any matching sticky broadcasts... 14825 Iterator actions = filter.actionsIterator(); 14826 if (actions != null) { 14827 while (actions.hasNext()) { 14828 String action = (String)actions.next(); 14829 allSticky = getStickiesLocked(action, filter, allSticky, 14830 UserHandle.USER_ALL); 14831 allSticky = getStickiesLocked(action, filter, allSticky, 14832 UserHandle.getUserId(callingUid)); 14833 } 14834 } else { 14835 allSticky = getStickiesLocked(null, filter, allSticky, 14836 UserHandle.USER_ALL); 14837 allSticky = getStickiesLocked(null, filter, allSticky, 14838 UserHandle.getUserId(callingUid)); 14839 } 14840 14841 // The first sticky in the list is returned directly back to 14842 // the client. 14843 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14844 14845 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14846 + ": " + sticky); 14847 14848 if (receiver == null) { 14849 return sticky; 14850 } 14851 14852 ReceiverList rl 14853 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14854 if (rl == null) { 14855 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14856 userId, receiver); 14857 if (rl.app != null) { 14858 rl.app.receivers.add(rl); 14859 } else { 14860 try { 14861 receiver.asBinder().linkToDeath(rl, 0); 14862 } catch (RemoteException e) { 14863 return sticky; 14864 } 14865 rl.linkedToDeath = true; 14866 } 14867 mRegisteredReceivers.put(receiver.asBinder(), rl); 14868 } else if (rl.uid != callingUid) { 14869 throw new IllegalArgumentException( 14870 "Receiver requested to register for uid " + callingUid 14871 + " was previously registered for uid " + rl.uid); 14872 } else if (rl.pid != callingPid) { 14873 throw new IllegalArgumentException( 14874 "Receiver requested to register for pid " + callingPid 14875 + " was previously registered for pid " + rl.pid); 14876 } else if (rl.userId != userId) { 14877 throw new IllegalArgumentException( 14878 "Receiver requested to register for user " + userId 14879 + " was previously registered for user " + rl.userId); 14880 } 14881 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14882 permission, callingUid, userId); 14883 rl.add(bf); 14884 if (!bf.debugCheck()) { 14885 Slog.w(TAG, "==> For Dynamic broadast"); 14886 } 14887 mReceiverResolver.addFilter(bf); 14888 14889 // Enqueue broadcasts for all existing stickies that match 14890 // this filter. 14891 if (allSticky != null) { 14892 ArrayList receivers = new ArrayList(); 14893 receivers.add(bf); 14894 14895 int N = allSticky.size(); 14896 for (int i=0; i<N; i++) { 14897 Intent intent = (Intent)allSticky.get(i); 14898 BroadcastQueue queue = broadcastQueueForIntent(intent); 14899 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14900 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14901 null, null, false, true, true, -1); 14902 queue.enqueueParallelBroadcastLocked(r); 14903 queue.scheduleBroadcastsLocked(); 14904 } 14905 } 14906 14907 return sticky; 14908 } 14909 } 14910 14911 public void unregisterReceiver(IIntentReceiver receiver) { 14912 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14913 14914 final long origId = Binder.clearCallingIdentity(); 14915 try { 14916 boolean doTrim = false; 14917 14918 synchronized(this) { 14919 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14920 if (rl != null) { 14921 if (rl.curBroadcast != null) { 14922 BroadcastRecord r = rl.curBroadcast; 14923 final boolean doNext = finishReceiverLocked( 14924 receiver.asBinder(), r.resultCode, r.resultData, 14925 r.resultExtras, r.resultAbort); 14926 if (doNext) { 14927 doTrim = true; 14928 r.queue.processNextBroadcast(false); 14929 } 14930 } 14931 14932 if (rl.app != null) { 14933 rl.app.receivers.remove(rl); 14934 } 14935 removeReceiverLocked(rl); 14936 if (rl.linkedToDeath) { 14937 rl.linkedToDeath = false; 14938 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14939 } 14940 } 14941 } 14942 14943 // If we actually concluded any broadcasts, we might now be able 14944 // to trim the recipients' apps from our working set 14945 if (doTrim) { 14946 trimApplications(); 14947 return; 14948 } 14949 14950 } finally { 14951 Binder.restoreCallingIdentity(origId); 14952 } 14953 } 14954 14955 void removeReceiverLocked(ReceiverList rl) { 14956 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14957 int N = rl.size(); 14958 for (int i=0; i<N; i++) { 14959 mReceiverResolver.removeFilter(rl.get(i)); 14960 } 14961 } 14962 14963 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14964 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14965 ProcessRecord r = mLruProcesses.get(i); 14966 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14967 try { 14968 r.thread.dispatchPackageBroadcast(cmd, packages); 14969 } catch (RemoteException ex) { 14970 } 14971 } 14972 } 14973 } 14974 14975 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14976 int[] users) { 14977 List<ResolveInfo> receivers = null; 14978 try { 14979 HashSet<ComponentName> singleUserReceivers = null; 14980 boolean scannedFirstReceivers = false; 14981 for (int user : users) { 14982 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14983 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14984 if (user != 0 && newReceivers != null) { 14985 // If this is not the primary user, we need to check for 14986 // any receivers that should be filtered out. 14987 for (int i=0; i<newReceivers.size(); i++) { 14988 ResolveInfo ri = newReceivers.get(i); 14989 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14990 newReceivers.remove(i); 14991 i--; 14992 } 14993 } 14994 } 14995 if (newReceivers != null && newReceivers.size() == 0) { 14996 newReceivers = null; 14997 } 14998 if (receivers == null) { 14999 receivers = newReceivers; 15000 } else if (newReceivers != null) { 15001 // We need to concatenate the additional receivers 15002 // found with what we have do far. This would be easy, 15003 // but we also need to de-dup any receivers that are 15004 // singleUser. 15005 if (!scannedFirstReceivers) { 15006 // Collect any single user receivers we had already retrieved. 15007 scannedFirstReceivers = true; 15008 for (int i=0; i<receivers.size(); i++) { 15009 ResolveInfo ri = receivers.get(i); 15010 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15011 ComponentName cn = new ComponentName( 15012 ri.activityInfo.packageName, ri.activityInfo.name); 15013 if (singleUserReceivers == null) { 15014 singleUserReceivers = new HashSet<ComponentName>(); 15015 } 15016 singleUserReceivers.add(cn); 15017 } 15018 } 15019 } 15020 // Add the new results to the existing results, tracking 15021 // and de-dupping single user receivers. 15022 for (int i=0; i<newReceivers.size(); i++) { 15023 ResolveInfo ri = newReceivers.get(i); 15024 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15025 ComponentName cn = new ComponentName( 15026 ri.activityInfo.packageName, ri.activityInfo.name); 15027 if (singleUserReceivers == null) { 15028 singleUserReceivers = new HashSet<ComponentName>(); 15029 } 15030 if (!singleUserReceivers.contains(cn)) { 15031 singleUserReceivers.add(cn); 15032 receivers.add(ri); 15033 } 15034 } else { 15035 receivers.add(ri); 15036 } 15037 } 15038 } 15039 } 15040 } catch (RemoteException ex) { 15041 // pm is in same process, this will never happen. 15042 } 15043 return receivers; 15044 } 15045 15046 private final int broadcastIntentLocked(ProcessRecord callerApp, 15047 String callerPackage, Intent intent, String resolvedType, 15048 IIntentReceiver resultTo, int resultCode, String resultData, 15049 Bundle map, String requiredPermission, int appOp, 15050 boolean ordered, boolean sticky, int callingPid, int callingUid, 15051 int userId) { 15052 intent = new Intent(intent); 15053 15054 // By default broadcasts do not go to stopped apps. 15055 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15056 15057 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15058 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15059 + " ordered=" + ordered + " userid=" + userId); 15060 if ((resultTo != null) && !ordered) { 15061 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15062 } 15063 15064 userId = handleIncomingUser(callingPid, callingUid, userId, 15065 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15066 15067 // Make sure that the user who is receiving this broadcast is started. 15068 // If not, we will just skip it. 15069 15070 15071 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15072 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15073 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15074 Slog.w(TAG, "Skipping broadcast of " + intent 15075 + ": user " + userId + " is stopped"); 15076 return ActivityManager.BROADCAST_SUCCESS; 15077 } 15078 } 15079 15080 /* 15081 * Prevent non-system code (defined here to be non-persistent 15082 * processes) from sending protected broadcasts. 15083 */ 15084 int callingAppId = UserHandle.getAppId(callingUid); 15085 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15086 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15087 || callingAppId == Process.NFC_UID || callingUid == 0) { 15088 // Always okay. 15089 } else if (callerApp == null || !callerApp.persistent) { 15090 try { 15091 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15092 intent.getAction())) { 15093 String msg = "Permission Denial: not allowed to send broadcast " 15094 + intent.getAction() + " from pid=" 15095 + callingPid + ", uid=" + callingUid; 15096 Slog.w(TAG, msg); 15097 throw new SecurityException(msg); 15098 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15099 // Special case for compatibility: we don't want apps to send this, 15100 // but historically it has not been protected and apps may be using it 15101 // to poke their own app widget. So, instead of making it protected, 15102 // just limit it to the caller. 15103 if (callerApp == null) { 15104 String msg = "Permission Denial: not allowed to send broadcast " 15105 + intent.getAction() + " from unknown caller."; 15106 Slog.w(TAG, msg); 15107 throw new SecurityException(msg); 15108 } else if (intent.getComponent() != null) { 15109 // They are good enough to send to an explicit component... verify 15110 // it is being sent to the calling app. 15111 if (!intent.getComponent().getPackageName().equals( 15112 callerApp.info.packageName)) { 15113 String msg = "Permission Denial: not allowed to send broadcast " 15114 + intent.getAction() + " to " 15115 + intent.getComponent().getPackageName() + " from " 15116 + callerApp.info.packageName; 15117 Slog.w(TAG, msg); 15118 throw new SecurityException(msg); 15119 } 15120 } else { 15121 // Limit broadcast to their own package. 15122 intent.setPackage(callerApp.info.packageName); 15123 } 15124 } 15125 } catch (RemoteException e) { 15126 Slog.w(TAG, "Remote exception", e); 15127 return ActivityManager.BROADCAST_SUCCESS; 15128 } 15129 } 15130 15131 // Handle special intents: if this broadcast is from the package 15132 // manager about a package being removed, we need to remove all of 15133 // its activities from the history stack. 15134 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15135 intent.getAction()); 15136 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15137 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15138 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15139 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15140 || uidRemoved) { 15141 if (checkComponentPermission( 15142 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15143 callingPid, callingUid, -1, true) 15144 == PackageManager.PERMISSION_GRANTED) { 15145 if (uidRemoved) { 15146 final Bundle intentExtras = intent.getExtras(); 15147 final int uid = intentExtras != null 15148 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15149 if (uid >= 0) { 15150 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15151 synchronized (bs) { 15152 bs.removeUidStatsLocked(uid); 15153 } 15154 mAppOpsService.uidRemoved(uid); 15155 } 15156 } else { 15157 // If resources are unavailable just force stop all 15158 // those packages and flush the attribute cache as well. 15159 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15160 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15161 if (list != null && (list.length > 0)) { 15162 for (String pkg : list) { 15163 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15164 "storage unmount"); 15165 } 15166 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15167 sendPackageBroadcastLocked( 15168 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15169 } 15170 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15171 intent.getAction())) { 15172 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15173 } else { 15174 Uri data = intent.getData(); 15175 String ssp; 15176 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15177 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15178 intent.getAction()); 15179 boolean fullUninstall = removed && 15180 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15181 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15182 forceStopPackageLocked(ssp, UserHandle.getAppId( 15183 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15184 false, fullUninstall, userId, 15185 removed ? "pkg removed" : "pkg changed"); 15186 } 15187 if (removed) { 15188 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15189 new String[] {ssp}, userId); 15190 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15191 mAppOpsService.packageRemoved( 15192 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15193 15194 // Remove all permissions granted from/to this package 15195 removeUriPermissionsForPackageLocked(ssp, userId, true); 15196 } 15197 } 15198 } 15199 } 15200 } 15201 } else { 15202 String msg = "Permission Denial: " + intent.getAction() 15203 + " broadcast from " + callerPackage + " (pid=" + callingPid 15204 + ", uid=" + callingUid + ")" 15205 + " requires " 15206 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15207 Slog.w(TAG, msg); 15208 throw new SecurityException(msg); 15209 } 15210 15211 // Special case for adding a package: by default turn on compatibility 15212 // mode. 15213 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15214 Uri data = intent.getData(); 15215 String ssp; 15216 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15217 mCompatModePackages.handlePackageAddedLocked(ssp, 15218 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15219 } 15220 } 15221 15222 /* 15223 * If this is the time zone changed action, queue up a message that will reset the timezone 15224 * of all currently running processes. This message will get queued up before the broadcast 15225 * happens. 15226 */ 15227 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15228 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15229 } 15230 15231 /* 15232 * If the user set the time, let all running processes know. 15233 */ 15234 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15235 final int is24Hour = intent.getBooleanExtra( 15236 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15237 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15238 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15239 synchronized (stats) { 15240 stats.noteCurrentTimeChangedLocked(); 15241 } 15242 } 15243 15244 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15245 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15246 } 15247 15248 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15249 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15250 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15251 } 15252 15253 // Add to the sticky list if requested. 15254 if (sticky) { 15255 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15256 callingPid, callingUid) 15257 != PackageManager.PERMISSION_GRANTED) { 15258 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15259 + callingPid + ", uid=" + callingUid 15260 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15261 Slog.w(TAG, msg); 15262 throw new SecurityException(msg); 15263 } 15264 if (requiredPermission != null) { 15265 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15266 + " and enforce permission " + requiredPermission); 15267 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15268 } 15269 if (intent.getComponent() != null) { 15270 throw new SecurityException( 15271 "Sticky broadcasts can't target a specific component"); 15272 } 15273 // We use userId directly here, since the "all" target is maintained 15274 // as a separate set of sticky broadcasts. 15275 if (userId != UserHandle.USER_ALL) { 15276 // But first, if this is not a broadcast to all users, then 15277 // make sure it doesn't conflict with an existing broadcast to 15278 // all users. 15279 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15280 UserHandle.USER_ALL); 15281 if (stickies != null) { 15282 ArrayList<Intent> list = stickies.get(intent.getAction()); 15283 if (list != null) { 15284 int N = list.size(); 15285 int i; 15286 for (i=0; i<N; i++) { 15287 if (intent.filterEquals(list.get(i))) { 15288 throw new IllegalArgumentException( 15289 "Sticky broadcast " + intent + " for user " 15290 + userId + " conflicts with existing global broadcast"); 15291 } 15292 } 15293 } 15294 } 15295 } 15296 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15297 if (stickies == null) { 15298 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15299 mStickyBroadcasts.put(userId, stickies); 15300 } 15301 ArrayList<Intent> list = stickies.get(intent.getAction()); 15302 if (list == null) { 15303 list = new ArrayList<Intent>(); 15304 stickies.put(intent.getAction(), list); 15305 } 15306 int N = list.size(); 15307 int i; 15308 for (i=0; i<N; i++) { 15309 if (intent.filterEquals(list.get(i))) { 15310 // This sticky already exists, replace it. 15311 list.set(i, new Intent(intent)); 15312 break; 15313 } 15314 } 15315 if (i >= N) { 15316 list.add(new Intent(intent)); 15317 } 15318 } 15319 15320 int[] users; 15321 if (userId == UserHandle.USER_ALL) { 15322 // Caller wants broadcast to go to all started users. 15323 users = mStartedUserArray; 15324 } else { 15325 // Caller wants broadcast to go to one specific user. 15326 users = new int[] {userId}; 15327 } 15328 15329 // Figure out who all will receive this broadcast. 15330 List receivers = null; 15331 List<BroadcastFilter> registeredReceivers = null; 15332 // Need to resolve the intent to interested receivers... 15333 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15334 == 0) { 15335 receivers = collectReceiverComponents(intent, resolvedType, users); 15336 } 15337 if (intent.getComponent() == null) { 15338 registeredReceivers = mReceiverResolver.queryIntent(intent, 15339 resolvedType, false, userId); 15340 } 15341 15342 final boolean replacePending = 15343 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15344 15345 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15346 + " replacePending=" + replacePending); 15347 15348 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15349 if (!ordered && NR > 0) { 15350 // If we are not serializing this broadcast, then send the 15351 // registered receivers separately so they don't wait for the 15352 // components to be launched. 15353 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15354 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15355 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15356 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15357 ordered, sticky, false, userId); 15358 if (DEBUG_BROADCAST) Slog.v( 15359 TAG, "Enqueueing parallel broadcast " + r); 15360 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15361 if (!replaced) { 15362 queue.enqueueParallelBroadcastLocked(r); 15363 queue.scheduleBroadcastsLocked(); 15364 } 15365 registeredReceivers = null; 15366 NR = 0; 15367 } 15368 15369 // Merge into one list. 15370 int ir = 0; 15371 if (receivers != null) { 15372 // A special case for PACKAGE_ADDED: do not allow the package 15373 // being added to see this broadcast. This prevents them from 15374 // using this as a back door to get run as soon as they are 15375 // installed. Maybe in the future we want to have a special install 15376 // broadcast or such for apps, but we'd like to deliberately make 15377 // this decision. 15378 String skipPackages[] = null; 15379 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15380 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15381 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15382 Uri data = intent.getData(); 15383 if (data != null) { 15384 String pkgName = data.getSchemeSpecificPart(); 15385 if (pkgName != null) { 15386 skipPackages = new String[] { pkgName }; 15387 } 15388 } 15389 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15390 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15391 } 15392 if (skipPackages != null && (skipPackages.length > 0)) { 15393 for (String skipPackage : skipPackages) { 15394 if (skipPackage != null) { 15395 int NT = receivers.size(); 15396 for (int it=0; it<NT; it++) { 15397 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15398 if (curt.activityInfo.packageName.equals(skipPackage)) { 15399 receivers.remove(it); 15400 it--; 15401 NT--; 15402 } 15403 } 15404 } 15405 } 15406 } 15407 15408 int NT = receivers != null ? receivers.size() : 0; 15409 int it = 0; 15410 ResolveInfo curt = null; 15411 BroadcastFilter curr = null; 15412 while (it < NT && ir < NR) { 15413 if (curt == null) { 15414 curt = (ResolveInfo)receivers.get(it); 15415 } 15416 if (curr == null) { 15417 curr = registeredReceivers.get(ir); 15418 } 15419 if (curr.getPriority() >= curt.priority) { 15420 // Insert this broadcast record into the final list. 15421 receivers.add(it, curr); 15422 ir++; 15423 curr = null; 15424 it++; 15425 NT++; 15426 } else { 15427 // Skip to the next ResolveInfo in the final list. 15428 it++; 15429 curt = null; 15430 } 15431 } 15432 } 15433 while (ir < NR) { 15434 if (receivers == null) { 15435 receivers = new ArrayList(); 15436 } 15437 receivers.add(registeredReceivers.get(ir)); 15438 ir++; 15439 } 15440 15441 if ((receivers != null && receivers.size() > 0) 15442 || resultTo != null) { 15443 BroadcastQueue queue = broadcastQueueForIntent(intent); 15444 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15445 callerPackage, callingPid, callingUid, resolvedType, 15446 requiredPermission, appOp, receivers, resultTo, resultCode, 15447 resultData, map, ordered, sticky, false, userId); 15448 if (DEBUG_BROADCAST) Slog.v( 15449 TAG, "Enqueueing ordered broadcast " + r 15450 + ": prev had " + queue.mOrderedBroadcasts.size()); 15451 if (DEBUG_BROADCAST) { 15452 int seq = r.intent.getIntExtra("seq", -1); 15453 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15454 } 15455 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15456 if (!replaced) { 15457 queue.enqueueOrderedBroadcastLocked(r); 15458 queue.scheduleBroadcastsLocked(); 15459 } 15460 } 15461 15462 return ActivityManager.BROADCAST_SUCCESS; 15463 } 15464 15465 final Intent verifyBroadcastLocked(Intent intent) { 15466 // Refuse possible leaked file descriptors 15467 if (intent != null && intent.hasFileDescriptors() == true) { 15468 throw new IllegalArgumentException("File descriptors passed in Intent"); 15469 } 15470 15471 int flags = intent.getFlags(); 15472 15473 if (!mProcessesReady) { 15474 // if the caller really truly claims to know what they're doing, go 15475 // ahead and allow the broadcast without launching any receivers 15476 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15477 intent = new Intent(intent); 15478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15479 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15480 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15481 + " before boot completion"); 15482 throw new IllegalStateException("Cannot broadcast before boot completed"); 15483 } 15484 } 15485 15486 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15487 throw new IllegalArgumentException( 15488 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15489 } 15490 15491 return intent; 15492 } 15493 15494 public final int broadcastIntent(IApplicationThread caller, 15495 Intent intent, String resolvedType, IIntentReceiver resultTo, 15496 int resultCode, String resultData, Bundle map, 15497 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15498 enforceNotIsolatedCaller("broadcastIntent"); 15499 synchronized(this) { 15500 intent = verifyBroadcastLocked(intent); 15501 15502 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15503 final int callingPid = Binder.getCallingPid(); 15504 final int callingUid = Binder.getCallingUid(); 15505 final long origId = Binder.clearCallingIdentity(); 15506 int res = broadcastIntentLocked(callerApp, 15507 callerApp != null ? callerApp.info.packageName : null, 15508 intent, resolvedType, resultTo, 15509 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15510 callingPid, callingUid, userId); 15511 Binder.restoreCallingIdentity(origId); 15512 return res; 15513 } 15514 } 15515 15516 int broadcastIntentInPackage(String packageName, int uid, 15517 Intent intent, String resolvedType, IIntentReceiver resultTo, 15518 int resultCode, String resultData, Bundle map, 15519 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15520 synchronized(this) { 15521 intent = verifyBroadcastLocked(intent); 15522 15523 final long origId = Binder.clearCallingIdentity(); 15524 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15525 resultTo, resultCode, resultData, map, requiredPermission, 15526 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15527 Binder.restoreCallingIdentity(origId); 15528 return res; 15529 } 15530 } 15531 15532 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15533 // Refuse possible leaked file descriptors 15534 if (intent != null && intent.hasFileDescriptors() == true) { 15535 throw new IllegalArgumentException("File descriptors passed in Intent"); 15536 } 15537 15538 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15539 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15540 15541 synchronized(this) { 15542 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15543 != PackageManager.PERMISSION_GRANTED) { 15544 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15545 + Binder.getCallingPid() 15546 + ", uid=" + Binder.getCallingUid() 15547 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15548 Slog.w(TAG, msg); 15549 throw new SecurityException(msg); 15550 } 15551 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15552 if (stickies != null) { 15553 ArrayList<Intent> list = stickies.get(intent.getAction()); 15554 if (list != null) { 15555 int N = list.size(); 15556 int i; 15557 for (i=0; i<N; i++) { 15558 if (intent.filterEquals(list.get(i))) { 15559 list.remove(i); 15560 break; 15561 } 15562 } 15563 if (list.size() <= 0) { 15564 stickies.remove(intent.getAction()); 15565 } 15566 } 15567 if (stickies.size() <= 0) { 15568 mStickyBroadcasts.remove(userId); 15569 } 15570 } 15571 } 15572 } 15573 15574 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15575 String resultData, Bundle resultExtras, boolean resultAbort) { 15576 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15577 if (r == null) { 15578 Slog.w(TAG, "finishReceiver called but not found on queue"); 15579 return false; 15580 } 15581 15582 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15583 } 15584 15585 void backgroundServicesFinishedLocked(int userId) { 15586 for (BroadcastQueue queue : mBroadcastQueues) { 15587 queue.backgroundServicesFinishedLocked(userId); 15588 } 15589 } 15590 15591 public void finishReceiver(IBinder who, int resultCode, String resultData, 15592 Bundle resultExtras, boolean resultAbort) { 15593 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15594 15595 // Refuse possible leaked file descriptors 15596 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15597 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15598 } 15599 15600 final long origId = Binder.clearCallingIdentity(); 15601 try { 15602 boolean doNext = false; 15603 BroadcastRecord r; 15604 15605 synchronized(this) { 15606 r = broadcastRecordForReceiverLocked(who); 15607 if (r != null) { 15608 doNext = r.queue.finishReceiverLocked(r, resultCode, 15609 resultData, resultExtras, resultAbort, true); 15610 } 15611 } 15612 15613 if (doNext) { 15614 r.queue.processNextBroadcast(false); 15615 } 15616 trimApplications(); 15617 } finally { 15618 Binder.restoreCallingIdentity(origId); 15619 } 15620 } 15621 15622 // ========================================================= 15623 // INSTRUMENTATION 15624 // ========================================================= 15625 15626 public boolean startInstrumentation(ComponentName className, 15627 String profileFile, int flags, Bundle arguments, 15628 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15629 int userId, String abiOverride) { 15630 enforceNotIsolatedCaller("startInstrumentation"); 15631 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15632 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15633 // Refuse possible leaked file descriptors 15634 if (arguments != null && arguments.hasFileDescriptors()) { 15635 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15636 } 15637 15638 synchronized(this) { 15639 InstrumentationInfo ii = null; 15640 ApplicationInfo ai = null; 15641 try { 15642 ii = mContext.getPackageManager().getInstrumentationInfo( 15643 className, STOCK_PM_FLAGS); 15644 ai = AppGlobals.getPackageManager().getApplicationInfo( 15645 ii.targetPackage, STOCK_PM_FLAGS, userId); 15646 } catch (PackageManager.NameNotFoundException e) { 15647 } catch (RemoteException e) { 15648 } 15649 if (ii == null) { 15650 reportStartInstrumentationFailure(watcher, className, 15651 "Unable to find instrumentation info for: " + className); 15652 return false; 15653 } 15654 if (ai == null) { 15655 reportStartInstrumentationFailure(watcher, className, 15656 "Unable to find instrumentation target package: " + ii.targetPackage); 15657 return false; 15658 } 15659 15660 int match = mContext.getPackageManager().checkSignatures( 15661 ii.targetPackage, ii.packageName); 15662 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15663 String msg = "Permission Denial: starting instrumentation " 15664 + className + " from pid=" 15665 + Binder.getCallingPid() 15666 + ", uid=" + Binder.getCallingPid() 15667 + " not allowed because package " + ii.packageName 15668 + " does not have a signature matching the target " 15669 + ii.targetPackage; 15670 reportStartInstrumentationFailure(watcher, className, msg); 15671 throw new SecurityException(msg); 15672 } 15673 15674 final long origId = Binder.clearCallingIdentity(); 15675 // Instrumentation can kill and relaunch even persistent processes 15676 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15677 "start instr"); 15678 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15679 app.instrumentationClass = className; 15680 app.instrumentationInfo = ai; 15681 app.instrumentationProfileFile = profileFile; 15682 app.instrumentationArguments = arguments; 15683 app.instrumentationWatcher = watcher; 15684 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15685 app.instrumentationResultClass = className; 15686 Binder.restoreCallingIdentity(origId); 15687 } 15688 15689 return true; 15690 } 15691 15692 /** 15693 * Report errors that occur while attempting to start Instrumentation. Always writes the 15694 * error to the logs, but if somebody is watching, send the report there too. This enables 15695 * the "am" command to report errors with more information. 15696 * 15697 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15698 * @param cn The component name of the instrumentation. 15699 * @param report The error report. 15700 */ 15701 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15702 ComponentName cn, String report) { 15703 Slog.w(TAG, report); 15704 try { 15705 if (watcher != null) { 15706 Bundle results = new Bundle(); 15707 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15708 results.putString("Error", report); 15709 watcher.instrumentationStatus(cn, -1, results); 15710 } 15711 } catch (RemoteException e) { 15712 Slog.w(TAG, e); 15713 } 15714 } 15715 15716 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15717 if (app.instrumentationWatcher != null) { 15718 try { 15719 // NOTE: IInstrumentationWatcher *must* be oneway here 15720 app.instrumentationWatcher.instrumentationFinished( 15721 app.instrumentationClass, 15722 resultCode, 15723 results); 15724 } catch (RemoteException e) { 15725 } 15726 } 15727 if (app.instrumentationUiAutomationConnection != null) { 15728 try { 15729 app.instrumentationUiAutomationConnection.shutdown(); 15730 } catch (RemoteException re) { 15731 /* ignore */ 15732 } 15733 // Only a UiAutomation can set this flag and now that 15734 // it is finished we make sure it is reset to its default. 15735 mUserIsMonkey = false; 15736 } 15737 app.instrumentationWatcher = null; 15738 app.instrumentationUiAutomationConnection = null; 15739 app.instrumentationClass = null; 15740 app.instrumentationInfo = null; 15741 app.instrumentationProfileFile = null; 15742 app.instrumentationArguments = null; 15743 15744 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15745 "finished inst"); 15746 } 15747 15748 public void finishInstrumentation(IApplicationThread target, 15749 int resultCode, Bundle results) { 15750 int userId = UserHandle.getCallingUserId(); 15751 // Refuse possible leaked file descriptors 15752 if (results != null && results.hasFileDescriptors()) { 15753 throw new IllegalArgumentException("File descriptors passed in Intent"); 15754 } 15755 15756 synchronized(this) { 15757 ProcessRecord app = getRecordForAppLocked(target); 15758 if (app == null) { 15759 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15760 return; 15761 } 15762 final long origId = Binder.clearCallingIdentity(); 15763 finishInstrumentationLocked(app, resultCode, results); 15764 Binder.restoreCallingIdentity(origId); 15765 } 15766 } 15767 15768 // ========================================================= 15769 // CONFIGURATION 15770 // ========================================================= 15771 15772 public ConfigurationInfo getDeviceConfigurationInfo() { 15773 ConfigurationInfo config = new ConfigurationInfo(); 15774 synchronized (this) { 15775 config.reqTouchScreen = mConfiguration.touchscreen; 15776 config.reqKeyboardType = mConfiguration.keyboard; 15777 config.reqNavigation = mConfiguration.navigation; 15778 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15779 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15780 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15781 } 15782 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15783 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15784 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15785 } 15786 config.reqGlEsVersion = GL_ES_VERSION; 15787 } 15788 return config; 15789 } 15790 15791 ActivityStack getFocusedStack() { 15792 return mStackSupervisor.getFocusedStack(); 15793 } 15794 15795 public Configuration getConfiguration() { 15796 Configuration ci; 15797 synchronized(this) { 15798 ci = new Configuration(mConfiguration); 15799 } 15800 return ci; 15801 } 15802 15803 public void updatePersistentConfiguration(Configuration values) { 15804 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15805 "updateConfiguration()"); 15806 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15807 "updateConfiguration()"); 15808 if (values == null) { 15809 throw new NullPointerException("Configuration must not be null"); 15810 } 15811 15812 synchronized(this) { 15813 final long origId = Binder.clearCallingIdentity(); 15814 updateConfigurationLocked(values, null, true, false); 15815 Binder.restoreCallingIdentity(origId); 15816 } 15817 } 15818 15819 public void updateConfiguration(Configuration values) { 15820 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15821 "updateConfiguration()"); 15822 15823 synchronized(this) { 15824 if (values == null && mWindowManager != null) { 15825 // sentinel: fetch the current configuration from the window manager 15826 values = mWindowManager.computeNewConfiguration(); 15827 } 15828 15829 if (mWindowManager != null) { 15830 mProcessList.applyDisplaySize(mWindowManager); 15831 } 15832 15833 final long origId = Binder.clearCallingIdentity(); 15834 if (values != null) { 15835 Settings.System.clearConfiguration(values); 15836 } 15837 updateConfigurationLocked(values, null, false, false); 15838 Binder.restoreCallingIdentity(origId); 15839 } 15840 } 15841 15842 /** 15843 * Do either or both things: (1) change the current configuration, and (2) 15844 * make sure the given activity is running with the (now) current 15845 * configuration. Returns true if the activity has been left running, or 15846 * false if <var>starting</var> is being destroyed to match the new 15847 * configuration. 15848 * @param persistent TODO 15849 */ 15850 boolean updateConfigurationLocked(Configuration values, 15851 ActivityRecord starting, boolean persistent, boolean initLocale) { 15852 int changes = 0; 15853 15854 if (values != null) { 15855 Configuration newConfig = new Configuration(mConfiguration); 15856 changes = newConfig.updateFrom(values); 15857 if (changes != 0) { 15858 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15859 Slog.i(TAG, "Updating configuration to: " + values); 15860 } 15861 15862 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15863 15864 if (values.locale != null && !initLocale) { 15865 saveLocaleLocked(values.locale, 15866 !values.locale.equals(mConfiguration.locale), 15867 values.userSetLocale); 15868 } 15869 15870 mConfigurationSeq++; 15871 if (mConfigurationSeq <= 0) { 15872 mConfigurationSeq = 1; 15873 } 15874 newConfig.seq = mConfigurationSeq; 15875 mConfiguration = newConfig; 15876 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15877 //mUsageStatsService.noteStartConfig(newConfig); 15878 15879 final Configuration configCopy = new Configuration(mConfiguration); 15880 15881 // TODO: If our config changes, should we auto dismiss any currently 15882 // showing dialogs? 15883 mShowDialogs = shouldShowDialogs(newConfig); 15884 15885 AttributeCache ac = AttributeCache.instance(); 15886 if (ac != null) { 15887 ac.updateConfiguration(configCopy); 15888 } 15889 15890 // Make sure all resources in our process are updated 15891 // right now, so that anyone who is going to retrieve 15892 // resource values after we return will be sure to get 15893 // the new ones. This is especially important during 15894 // boot, where the first config change needs to guarantee 15895 // all resources have that config before following boot 15896 // code is executed. 15897 mSystemThread.applyConfigurationToResources(configCopy); 15898 15899 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15900 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15901 msg.obj = new Configuration(configCopy); 15902 mHandler.sendMessage(msg); 15903 } 15904 15905 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15906 ProcessRecord app = mLruProcesses.get(i); 15907 try { 15908 if (app.thread != null) { 15909 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15910 + app.processName + " new config " + mConfiguration); 15911 app.thread.scheduleConfigurationChanged(configCopy); 15912 } 15913 } catch (Exception e) { 15914 } 15915 } 15916 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15917 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15918 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15919 | Intent.FLAG_RECEIVER_FOREGROUND); 15920 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15921 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15922 Process.SYSTEM_UID, UserHandle.USER_ALL); 15923 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15924 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15925 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15926 broadcastIntentLocked(null, null, intent, 15927 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15928 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15929 } 15930 } 15931 } 15932 15933 boolean kept = true; 15934 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15935 // mainStack is null during startup. 15936 if (mainStack != null) { 15937 if (changes != 0 && starting == null) { 15938 // If the configuration changed, and the caller is not already 15939 // in the process of starting an activity, then find the top 15940 // activity to check if its configuration needs to change. 15941 starting = mainStack.topRunningActivityLocked(null); 15942 } 15943 15944 if (starting != null) { 15945 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15946 // And we need to make sure at this point that all other activities 15947 // are made visible with the correct configuration. 15948 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15949 } 15950 } 15951 15952 if (values != null && mWindowManager != null) { 15953 mWindowManager.setNewConfiguration(mConfiguration); 15954 } 15955 15956 return kept; 15957 } 15958 15959 /** 15960 * Decide based on the configuration whether we should shouw the ANR, 15961 * crash, etc dialogs. The idea is that if there is no affordnace to 15962 * press the on-screen buttons, we shouldn't show the dialog. 15963 * 15964 * A thought: SystemUI might also want to get told about this, the Power 15965 * dialog / global actions also might want different behaviors. 15966 */ 15967 private static final boolean shouldShowDialogs(Configuration config) { 15968 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15969 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15970 } 15971 15972 /** 15973 * Save the locale. You must be inside a synchronized (this) block. 15974 */ 15975 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15976 if(isDiff) { 15977 SystemProperties.set("user.language", l.getLanguage()); 15978 SystemProperties.set("user.region", l.getCountry()); 15979 } 15980 15981 if(isPersist) { 15982 SystemProperties.set("persist.sys.language", l.getLanguage()); 15983 SystemProperties.set("persist.sys.country", l.getCountry()); 15984 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15985 } 15986 } 15987 15988 @Override 15989 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 15990 synchronized (this) { 15991 ActivityRecord srec = ActivityRecord.forToken(token); 15992 if (srec.task != null && srec.task.stack != null) { 15993 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 15994 } 15995 } 15996 return false; 15997 } 15998 15999 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16000 Intent resultData) { 16001 16002 synchronized (this) { 16003 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16004 if (stack != null) { 16005 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16006 } 16007 return false; 16008 } 16009 } 16010 16011 public int getLaunchedFromUid(IBinder activityToken) { 16012 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16013 if (srec == null) { 16014 return -1; 16015 } 16016 return srec.launchedFromUid; 16017 } 16018 16019 public String getLaunchedFromPackage(IBinder activityToken) { 16020 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16021 if (srec == null) { 16022 return null; 16023 } 16024 return srec.launchedFromPackage; 16025 } 16026 16027 // ========================================================= 16028 // LIFETIME MANAGEMENT 16029 // ========================================================= 16030 16031 // Returns which broadcast queue the app is the current [or imminent] receiver 16032 // on, or 'null' if the app is not an active broadcast recipient. 16033 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16034 BroadcastRecord r = app.curReceiver; 16035 if (r != null) { 16036 return r.queue; 16037 } 16038 16039 // It's not the current receiver, but it might be starting up to become one 16040 synchronized (this) { 16041 for (BroadcastQueue queue : mBroadcastQueues) { 16042 r = queue.mPendingBroadcast; 16043 if (r != null && r.curApp == app) { 16044 // found it; report which queue it's in 16045 return queue; 16046 } 16047 } 16048 } 16049 16050 return null; 16051 } 16052 16053 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16054 boolean doingAll, long now) { 16055 if (mAdjSeq == app.adjSeq) { 16056 // This adjustment has already been computed. 16057 return app.curRawAdj; 16058 } 16059 16060 if (app.thread == null) { 16061 app.adjSeq = mAdjSeq; 16062 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16063 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16064 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16065 } 16066 16067 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16068 app.adjSource = null; 16069 app.adjTarget = null; 16070 app.empty = false; 16071 app.cached = false; 16072 16073 final int activitiesSize = app.activities.size(); 16074 16075 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16076 // The max adjustment doesn't allow this app to be anything 16077 // below foreground, so it is not worth doing work for it. 16078 app.adjType = "fixed"; 16079 app.adjSeq = mAdjSeq; 16080 app.curRawAdj = app.maxAdj; 16081 app.foregroundActivities = false; 16082 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16083 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16084 // System processes can do UI, and when they do we want to have 16085 // them trim their memory after the user leaves the UI. To 16086 // facilitate this, here we need to determine whether or not it 16087 // is currently showing UI. 16088 app.systemNoUi = true; 16089 if (app == TOP_APP) { 16090 app.systemNoUi = false; 16091 } else if (activitiesSize > 0) { 16092 for (int j = 0; j < activitiesSize; j++) { 16093 final ActivityRecord r = app.activities.get(j); 16094 if (r.visible) { 16095 app.systemNoUi = false; 16096 } 16097 } 16098 } 16099 if (!app.systemNoUi) { 16100 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16101 } 16102 return (app.curAdj=app.maxAdj); 16103 } 16104 16105 app.systemNoUi = false; 16106 16107 // Determine the importance of the process, starting with most 16108 // important to least, and assign an appropriate OOM adjustment. 16109 int adj; 16110 int schedGroup; 16111 int procState; 16112 boolean foregroundActivities = false; 16113 BroadcastQueue queue; 16114 if (app == TOP_APP) { 16115 // The last app on the list is the foreground app. 16116 adj = ProcessList.FOREGROUND_APP_ADJ; 16117 schedGroup = Process.THREAD_GROUP_DEFAULT; 16118 app.adjType = "top-activity"; 16119 foregroundActivities = true; 16120 procState = ActivityManager.PROCESS_STATE_TOP; 16121 } else if (app.instrumentationClass != null) { 16122 // Don't want to kill running instrumentation. 16123 adj = ProcessList.FOREGROUND_APP_ADJ; 16124 schedGroup = Process.THREAD_GROUP_DEFAULT; 16125 app.adjType = "instrumentation"; 16126 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16127 } else if ((queue = isReceivingBroadcast(app)) != null) { 16128 // An app that is currently receiving a broadcast also 16129 // counts as being in the foreground for OOM killer purposes. 16130 // It's placed in a sched group based on the nature of the 16131 // broadcast as reflected by which queue it's active in. 16132 adj = ProcessList.FOREGROUND_APP_ADJ; 16133 schedGroup = (queue == mFgBroadcastQueue) 16134 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16135 app.adjType = "broadcast"; 16136 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16137 } else if (app.executingServices.size() > 0) { 16138 // An app that is currently executing a service callback also 16139 // counts as being in the foreground. 16140 adj = ProcessList.FOREGROUND_APP_ADJ; 16141 schedGroup = app.execServicesFg ? 16142 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16143 app.adjType = "exec-service"; 16144 procState = ActivityManager.PROCESS_STATE_SERVICE; 16145 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16146 } else { 16147 // As far as we know the process is empty. We may change our mind later. 16148 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16149 // At this point we don't actually know the adjustment. Use the cached adj 16150 // value that the caller wants us to. 16151 adj = cachedAdj; 16152 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16153 app.cached = true; 16154 app.empty = true; 16155 app.adjType = "cch-empty"; 16156 } 16157 16158 // Examine all activities if not already foreground. 16159 if (!foregroundActivities && activitiesSize > 0) { 16160 for (int j = 0; j < activitiesSize; j++) { 16161 final ActivityRecord r = app.activities.get(j); 16162 if (r.app != app) { 16163 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16164 + app + "?!?"); 16165 continue; 16166 } 16167 if (r.visible) { 16168 // App has a visible activity; only upgrade adjustment. 16169 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16170 adj = ProcessList.VISIBLE_APP_ADJ; 16171 app.adjType = "visible"; 16172 } 16173 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16174 procState = ActivityManager.PROCESS_STATE_TOP; 16175 } 16176 schedGroup = Process.THREAD_GROUP_DEFAULT; 16177 app.cached = false; 16178 app.empty = false; 16179 foregroundActivities = true; 16180 break; 16181 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16182 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16183 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16184 app.adjType = "pausing"; 16185 } 16186 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16187 procState = ActivityManager.PROCESS_STATE_TOP; 16188 } 16189 schedGroup = Process.THREAD_GROUP_DEFAULT; 16190 app.cached = false; 16191 app.empty = false; 16192 foregroundActivities = true; 16193 } else if (r.state == ActivityState.STOPPING) { 16194 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16195 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16196 app.adjType = "stopping"; 16197 } 16198 // For the process state, we will at this point consider the 16199 // process to be cached. It will be cached either as an activity 16200 // or empty depending on whether the activity is finishing. We do 16201 // this so that we can treat the process as cached for purposes of 16202 // memory trimming (determing current memory level, trim command to 16203 // send to process) since there can be an arbitrary number of stopping 16204 // processes and they should soon all go into the cached state. 16205 if (!r.finishing) { 16206 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16207 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16208 } 16209 } 16210 app.cached = false; 16211 app.empty = false; 16212 foregroundActivities = true; 16213 } else { 16214 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16215 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16216 app.adjType = "cch-act"; 16217 } 16218 } 16219 } 16220 } 16221 16222 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16223 if (app.foregroundServices) { 16224 // The user is aware of this app, so make it visible. 16225 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16226 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16227 app.cached = false; 16228 app.adjType = "fg-service"; 16229 schedGroup = Process.THREAD_GROUP_DEFAULT; 16230 } else if (app.forcingToForeground != null) { 16231 // The user is aware of this app, so make it visible. 16232 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16233 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16234 app.cached = false; 16235 app.adjType = "force-fg"; 16236 app.adjSource = app.forcingToForeground; 16237 schedGroup = Process.THREAD_GROUP_DEFAULT; 16238 } 16239 } 16240 16241 if (app == mHeavyWeightProcess) { 16242 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16243 // We don't want to kill the current heavy-weight process. 16244 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16245 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16246 app.cached = false; 16247 app.adjType = "heavy"; 16248 } 16249 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16250 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16251 } 16252 } 16253 16254 if (app == mHomeProcess) { 16255 if (adj > ProcessList.HOME_APP_ADJ) { 16256 // This process is hosting what we currently consider to be the 16257 // home app, so we don't want to let it go into the background. 16258 adj = ProcessList.HOME_APP_ADJ; 16259 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16260 app.cached = false; 16261 app.adjType = "home"; 16262 } 16263 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16264 procState = ActivityManager.PROCESS_STATE_HOME; 16265 } 16266 } 16267 16268 if (app == mPreviousProcess && app.activities.size() > 0) { 16269 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16270 // This was the previous process that showed UI to the user. 16271 // We want to try to keep it around more aggressively, to give 16272 // a good experience around switching between two apps. 16273 adj = ProcessList.PREVIOUS_APP_ADJ; 16274 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16275 app.cached = false; 16276 app.adjType = "previous"; 16277 } 16278 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16279 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16280 } 16281 } 16282 16283 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16284 + " reason=" + app.adjType); 16285 16286 // By default, we use the computed adjustment. It may be changed if 16287 // there are applications dependent on our services or providers, but 16288 // this gives us a baseline and makes sure we don't get into an 16289 // infinite recursion. 16290 app.adjSeq = mAdjSeq; 16291 app.curRawAdj = adj; 16292 app.hasStartedServices = false; 16293 16294 if (mBackupTarget != null && app == mBackupTarget.app) { 16295 // If possible we want to avoid killing apps while they're being backed up 16296 if (adj > ProcessList.BACKUP_APP_ADJ) { 16297 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16298 adj = ProcessList.BACKUP_APP_ADJ; 16299 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16300 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16301 } 16302 app.adjType = "backup"; 16303 app.cached = false; 16304 } 16305 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16306 procState = ActivityManager.PROCESS_STATE_BACKUP; 16307 } 16308 } 16309 16310 boolean mayBeTop = false; 16311 16312 for (int is = app.services.size()-1; 16313 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16314 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16315 || procState > ActivityManager.PROCESS_STATE_TOP); 16316 is--) { 16317 ServiceRecord s = app.services.valueAt(is); 16318 if (s.startRequested) { 16319 app.hasStartedServices = true; 16320 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16321 procState = ActivityManager.PROCESS_STATE_SERVICE; 16322 } 16323 if (app.hasShownUi && app != mHomeProcess) { 16324 // If this process has shown some UI, let it immediately 16325 // go to the LRU list because it may be pretty heavy with 16326 // UI stuff. We'll tag it with a label just to help 16327 // debug and understand what is going on. 16328 if (adj > ProcessList.SERVICE_ADJ) { 16329 app.adjType = "cch-started-ui-services"; 16330 } 16331 } else { 16332 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16333 // This service has seen some activity within 16334 // recent memory, so we will keep its process ahead 16335 // of the background processes. 16336 if (adj > ProcessList.SERVICE_ADJ) { 16337 adj = ProcessList.SERVICE_ADJ; 16338 app.adjType = "started-services"; 16339 app.cached = false; 16340 } 16341 } 16342 // If we have let the service slide into the background 16343 // state, still have some text describing what it is doing 16344 // even though the service no longer has an impact. 16345 if (adj > ProcessList.SERVICE_ADJ) { 16346 app.adjType = "cch-started-services"; 16347 } 16348 } 16349 } 16350 for (int conni = s.connections.size()-1; 16351 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16352 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16353 || procState > ActivityManager.PROCESS_STATE_TOP); 16354 conni--) { 16355 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16356 for (int i = 0; 16357 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16358 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16359 || procState > ActivityManager.PROCESS_STATE_TOP); 16360 i++) { 16361 // XXX should compute this based on the max of 16362 // all connected clients. 16363 ConnectionRecord cr = clist.get(i); 16364 if (cr.binding.client == app) { 16365 // Binding to ourself is not interesting. 16366 continue; 16367 } 16368 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16369 ProcessRecord client = cr.binding.client; 16370 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16371 TOP_APP, doingAll, now); 16372 int clientProcState = client.curProcState; 16373 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16374 // If the other app is cached for any reason, for purposes here 16375 // we are going to consider it empty. The specific cached state 16376 // doesn't propagate except under certain conditions. 16377 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16378 } 16379 String adjType = null; 16380 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16381 // Not doing bind OOM management, so treat 16382 // this guy more like a started service. 16383 if (app.hasShownUi && app != mHomeProcess) { 16384 // If this process has shown some UI, let it immediately 16385 // go to the LRU list because it may be pretty heavy with 16386 // UI stuff. We'll tag it with a label just to help 16387 // debug and understand what is going on. 16388 if (adj > clientAdj) { 16389 adjType = "cch-bound-ui-services"; 16390 } 16391 app.cached = false; 16392 clientAdj = adj; 16393 clientProcState = procState; 16394 } else { 16395 if (now >= (s.lastActivity 16396 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16397 // This service has not seen activity within 16398 // recent memory, so allow it to drop to the 16399 // LRU list if there is no other reason to keep 16400 // it around. We'll also tag it with a label just 16401 // to help debug and undertand what is going on. 16402 if (adj > clientAdj) { 16403 adjType = "cch-bound-services"; 16404 } 16405 clientAdj = adj; 16406 } 16407 } 16408 } 16409 if (adj > clientAdj) { 16410 // If this process has recently shown UI, and 16411 // the process that is binding to it is less 16412 // important than being visible, then we don't 16413 // care about the binding as much as we care 16414 // about letting this process get into the LRU 16415 // list to be killed and restarted if needed for 16416 // memory. 16417 if (app.hasShownUi && app != mHomeProcess 16418 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16419 adjType = "cch-bound-ui-services"; 16420 } else { 16421 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16422 |Context.BIND_IMPORTANT)) != 0) { 16423 adj = clientAdj; 16424 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16425 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16426 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16427 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16428 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16429 adj = clientAdj; 16430 } else { 16431 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16432 adj = ProcessList.VISIBLE_APP_ADJ; 16433 } 16434 } 16435 if (!client.cached) { 16436 app.cached = false; 16437 } 16438 adjType = "service"; 16439 } 16440 } 16441 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16442 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16443 schedGroup = Process.THREAD_GROUP_DEFAULT; 16444 } 16445 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16446 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16447 // Special handling of clients who are in the top state. 16448 // We *may* want to consider this process to be in the 16449 // top state as well, but only if there is not another 16450 // reason for it to be running. Being on the top is a 16451 // special state, meaning you are specifically running 16452 // for the current top app. If the process is already 16453 // running in the background for some other reason, it 16454 // is more important to continue considering it to be 16455 // in the background state. 16456 mayBeTop = true; 16457 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16458 } else { 16459 // Special handling for above-top states (persistent 16460 // processes). These should not bring the current process 16461 // into the top state, since they are not on top. Instead 16462 // give them the best state after that. 16463 clientProcState = 16464 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16465 } 16466 } 16467 } else { 16468 if (clientProcState < 16469 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16470 clientProcState = 16471 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16472 } 16473 } 16474 if (procState > clientProcState) { 16475 procState = clientProcState; 16476 } 16477 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16478 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16479 app.pendingUiClean = true; 16480 } 16481 if (adjType != null) { 16482 app.adjType = adjType; 16483 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16484 .REASON_SERVICE_IN_USE; 16485 app.adjSource = cr.binding.client; 16486 app.adjSourceProcState = clientProcState; 16487 app.adjTarget = s.name; 16488 } 16489 } 16490 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16491 app.treatLikeActivity = true; 16492 } 16493 final ActivityRecord a = cr.activity; 16494 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16495 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16496 (a.visible || a.state == ActivityState.RESUMED 16497 || a.state == ActivityState.PAUSING)) { 16498 adj = ProcessList.FOREGROUND_APP_ADJ; 16499 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16500 schedGroup = Process.THREAD_GROUP_DEFAULT; 16501 } 16502 app.cached = false; 16503 app.adjType = "service"; 16504 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16505 .REASON_SERVICE_IN_USE; 16506 app.adjSource = a; 16507 app.adjSourceProcState = procState; 16508 app.adjTarget = s.name; 16509 } 16510 } 16511 } 16512 } 16513 } 16514 16515 for (int provi = app.pubProviders.size()-1; 16516 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16517 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16518 || procState > ActivityManager.PROCESS_STATE_TOP); 16519 provi--) { 16520 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16521 for (int i = cpr.connections.size()-1; 16522 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16523 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16524 || procState > ActivityManager.PROCESS_STATE_TOP); 16525 i--) { 16526 ContentProviderConnection conn = cpr.connections.get(i); 16527 ProcessRecord client = conn.client; 16528 if (client == app) { 16529 // Being our own client is not interesting. 16530 continue; 16531 } 16532 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16533 int clientProcState = client.curProcState; 16534 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16535 // If the other app is cached for any reason, for purposes here 16536 // we are going to consider it empty. 16537 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16538 } 16539 if (adj > clientAdj) { 16540 if (app.hasShownUi && app != mHomeProcess 16541 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16542 app.adjType = "cch-ui-provider"; 16543 } else { 16544 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16545 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16546 app.adjType = "provider"; 16547 } 16548 app.cached &= client.cached; 16549 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16550 .REASON_PROVIDER_IN_USE; 16551 app.adjSource = client; 16552 app.adjSourceProcState = clientProcState; 16553 app.adjTarget = cpr.name; 16554 } 16555 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16556 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16557 // Special handling of clients who are in the top state. 16558 // We *may* want to consider this process to be in the 16559 // top state as well, but only if there is not another 16560 // reason for it to be running. Being on the top is a 16561 // special state, meaning you are specifically running 16562 // for the current top app. If the process is already 16563 // running in the background for some other reason, it 16564 // is more important to continue considering it to be 16565 // in the background state. 16566 mayBeTop = true; 16567 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16568 } else { 16569 // Special handling for above-top states (persistent 16570 // processes). These should not bring the current process 16571 // into the top state, since they are not on top. Instead 16572 // give them the best state after that. 16573 clientProcState = 16574 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16575 } 16576 } 16577 if (procState > clientProcState) { 16578 procState = clientProcState; 16579 } 16580 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16581 schedGroup = Process.THREAD_GROUP_DEFAULT; 16582 } 16583 } 16584 // If the provider has external (non-framework) process 16585 // dependencies, ensure that its adjustment is at least 16586 // FOREGROUND_APP_ADJ. 16587 if (cpr.hasExternalProcessHandles()) { 16588 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16589 adj = ProcessList.FOREGROUND_APP_ADJ; 16590 schedGroup = Process.THREAD_GROUP_DEFAULT; 16591 app.cached = false; 16592 app.adjType = "provider"; 16593 app.adjTarget = cpr.name; 16594 } 16595 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16596 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16597 } 16598 } 16599 } 16600 16601 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16602 // A client of one of our services or providers is in the top state. We 16603 // *may* want to be in the top state, but not if we are already running in 16604 // the background for some other reason. For the decision here, we are going 16605 // to pick out a few specific states that we want to remain in when a client 16606 // is top (states that tend to be longer-term) and otherwise allow it to go 16607 // to the top state. 16608 switch (procState) { 16609 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16610 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16611 case ActivityManager.PROCESS_STATE_SERVICE: 16612 // These all are longer-term states, so pull them up to the top 16613 // of the background states, but not all the way to the top state. 16614 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16615 break; 16616 default: 16617 // Otherwise, top is a better choice, so take it. 16618 procState = ActivityManager.PROCESS_STATE_TOP; 16619 break; 16620 } 16621 } 16622 16623 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16624 if (app.hasClientActivities) { 16625 // This is a cached process, but with client activities. Mark it so. 16626 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16627 app.adjType = "cch-client-act"; 16628 } else if (app.treatLikeActivity) { 16629 // This is a cached process, but somebody wants us to treat it like it has 16630 // an activity, okay! 16631 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16632 app.adjType = "cch-as-act"; 16633 } 16634 } 16635 16636 if (adj == ProcessList.SERVICE_ADJ) { 16637 if (doingAll) { 16638 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16639 mNewNumServiceProcs++; 16640 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16641 if (!app.serviceb) { 16642 // This service isn't far enough down on the LRU list to 16643 // normally be a B service, but if we are low on RAM and it 16644 // is large we want to force it down since we would prefer to 16645 // keep launcher over it. 16646 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16647 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16648 app.serviceHighRam = true; 16649 app.serviceb = true; 16650 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16651 } else { 16652 mNewNumAServiceProcs++; 16653 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16654 } 16655 } else { 16656 app.serviceHighRam = false; 16657 } 16658 } 16659 if (app.serviceb) { 16660 adj = ProcessList.SERVICE_B_ADJ; 16661 } 16662 } 16663 16664 app.curRawAdj = adj; 16665 16666 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16667 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16668 if (adj > app.maxAdj) { 16669 adj = app.maxAdj; 16670 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16671 schedGroup = Process.THREAD_GROUP_DEFAULT; 16672 } 16673 } 16674 16675 // Do final modification to adj. Everything we do between here and applying 16676 // the final setAdj must be done in this function, because we will also use 16677 // it when computing the final cached adj later. Note that we don't need to 16678 // worry about this for max adj above, since max adj will always be used to 16679 // keep it out of the cached vaues. 16680 app.curAdj = app.modifyRawOomAdj(adj); 16681 app.curSchedGroup = schedGroup; 16682 app.curProcState = procState; 16683 app.foregroundActivities = foregroundActivities; 16684 16685 return app.curRawAdj; 16686 } 16687 16688 /** 16689 * Schedule PSS collection of a process. 16690 */ 16691 void requestPssLocked(ProcessRecord proc, int procState) { 16692 if (mPendingPssProcesses.contains(proc)) { 16693 return; 16694 } 16695 if (mPendingPssProcesses.size() == 0) { 16696 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16697 } 16698 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16699 proc.pssProcState = procState; 16700 mPendingPssProcesses.add(proc); 16701 } 16702 16703 /** 16704 * Schedule PSS collection of all processes. 16705 */ 16706 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16707 if (!always) { 16708 if (now < (mLastFullPssTime + 16709 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16710 return; 16711 } 16712 } 16713 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16714 mLastFullPssTime = now; 16715 mFullPssPending = true; 16716 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16717 mPendingPssProcesses.clear(); 16718 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16719 ProcessRecord app = mLruProcesses.get(i); 16720 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16721 app.pssProcState = app.setProcState; 16722 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16723 isSleeping(), now); 16724 mPendingPssProcesses.add(app); 16725 } 16726 } 16727 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16728 } 16729 16730 /** 16731 * Ask a given process to GC right now. 16732 */ 16733 final void performAppGcLocked(ProcessRecord app) { 16734 try { 16735 app.lastRequestedGc = SystemClock.uptimeMillis(); 16736 if (app.thread != null) { 16737 if (app.reportLowMemory) { 16738 app.reportLowMemory = false; 16739 app.thread.scheduleLowMemory(); 16740 } else { 16741 app.thread.processInBackground(); 16742 } 16743 } 16744 } catch (Exception e) { 16745 // whatever. 16746 } 16747 } 16748 16749 /** 16750 * Returns true if things are idle enough to perform GCs. 16751 */ 16752 private final boolean canGcNowLocked() { 16753 boolean processingBroadcasts = false; 16754 for (BroadcastQueue q : mBroadcastQueues) { 16755 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16756 processingBroadcasts = true; 16757 } 16758 } 16759 return !processingBroadcasts 16760 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16761 } 16762 16763 /** 16764 * Perform GCs on all processes that are waiting for it, but only 16765 * if things are idle. 16766 */ 16767 final void performAppGcsLocked() { 16768 final int N = mProcessesToGc.size(); 16769 if (N <= 0) { 16770 return; 16771 } 16772 if (canGcNowLocked()) { 16773 while (mProcessesToGc.size() > 0) { 16774 ProcessRecord proc = mProcessesToGc.remove(0); 16775 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16776 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16777 <= SystemClock.uptimeMillis()) { 16778 // To avoid spamming the system, we will GC processes one 16779 // at a time, waiting a few seconds between each. 16780 performAppGcLocked(proc); 16781 scheduleAppGcsLocked(); 16782 return; 16783 } else { 16784 // It hasn't been long enough since we last GCed this 16785 // process... put it in the list to wait for its time. 16786 addProcessToGcListLocked(proc); 16787 break; 16788 } 16789 } 16790 } 16791 16792 scheduleAppGcsLocked(); 16793 } 16794 } 16795 16796 /** 16797 * If all looks good, perform GCs on all processes waiting for them. 16798 */ 16799 final void performAppGcsIfAppropriateLocked() { 16800 if (canGcNowLocked()) { 16801 performAppGcsLocked(); 16802 return; 16803 } 16804 // Still not idle, wait some more. 16805 scheduleAppGcsLocked(); 16806 } 16807 16808 /** 16809 * Schedule the execution of all pending app GCs. 16810 */ 16811 final void scheduleAppGcsLocked() { 16812 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16813 16814 if (mProcessesToGc.size() > 0) { 16815 // Schedule a GC for the time to the next process. 16816 ProcessRecord proc = mProcessesToGc.get(0); 16817 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16818 16819 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16820 long now = SystemClock.uptimeMillis(); 16821 if (when < (now+GC_TIMEOUT)) { 16822 when = now + GC_TIMEOUT; 16823 } 16824 mHandler.sendMessageAtTime(msg, when); 16825 } 16826 } 16827 16828 /** 16829 * Add a process to the array of processes waiting to be GCed. Keeps the 16830 * list in sorted order by the last GC time. The process can't already be 16831 * on the list. 16832 */ 16833 final void addProcessToGcListLocked(ProcessRecord proc) { 16834 boolean added = false; 16835 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16836 if (mProcessesToGc.get(i).lastRequestedGc < 16837 proc.lastRequestedGc) { 16838 added = true; 16839 mProcessesToGc.add(i+1, proc); 16840 break; 16841 } 16842 } 16843 if (!added) { 16844 mProcessesToGc.add(0, proc); 16845 } 16846 } 16847 16848 /** 16849 * Set up to ask a process to GC itself. This will either do it 16850 * immediately, or put it on the list of processes to gc the next 16851 * time things are idle. 16852 */ 16853 final void scheduleAppGcLocked(ProcessRecord app) { 16854 long now = SystemClock.uptimeMillis(); 16855 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16856 return; 16857 } 16858 if (!mProcessesToGc.contains(app)) { 16859 addProcessToGcListLocked(app); 16860 scheduleAppGcsLocked(); 16861 } 16862 } 16863 16864 final void checkExcessivePowerUsageLocked(boolean doKills) { 16865 updateCpuStatsNow(); 16866 16867 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16868 boolean doWakeKills = doKills; 16869 boolean doCpuKills = doKills; 16870 if (mLastPowerCheckRealtime == 0) { 16871 doWakeKills = false; 16872 } 16873 if (mLastPowerCheckUptime == 0) { 16874 doCpuKills = false; 16875 } 16876 if (stats.isScreenOn()) { 16877 doWakeKills = false; 16878 } 16879 final long curRealtime = SystemClock.elapsedRealtime(); 16880 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16881 final long curUptime = SystemClock.uptimeMillis(); 16882 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16883 mLastPowerCheckRealtime = curRealtime; 16884 mLastPowerCheckUptime = curUptime; 16885 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16886 doWakeKills = false; 16887 } 16888 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16889 doCpuKills = false; 16890 } 16891 int i = mLruProcesses.size(); 16892 while (i > 0) { 16893 i--; 16894 ProcessRecord app = mLruProcesses.get(i); 16895 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16896 long wtime; 16897 synchronized (stats) { 16898 wtime = stats.getProcessWakeTime(app.info.uid, 16899 app.pid, curRealtime); 16900 } 16901 long wtimeUsed = wtime - app.lastWakeTime; 16902 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16903 if (DEBUG_POWER) { 16904 StringBuilder sb = new StringBuilder(128); 16905 sb.append("Wake for "); 16906 app.toShortString(sb); 16907 sb.append(": over "); 16908 TimeUtils.formatDuration(realtimeSince, sb); 16909 sb.append(" used "); 16910 TimeUtils.formatDuration(wtimeUsed, sb); 16911 sb.append(" ("); 16912 sb.append((wtimeUsed*100)/realtimeSince); 16913 sb.append("%)"); 16914 Slog.i(TAG, sb.toString()); 16915 sb.setLength(0); 16916 sb.append("CPU for "); 16917 app.toShortString(sb); 16918 sb.append(": over "); 16919 TimeUtils.formatDuration(uptimeSince, sb); 16920 sb.append(" used "); 16921 TimeUtils.formatDuration(cputimeUsed, sb); 16922 sb.append(" ("); 16923 sb.append((cputimeUsed*100)/uptimeSince); 16924 sb.append("%)"); 16925 Slog.i(TAG, sb.toString()); 16926 } 16927 // If a process has held a wake lock for more 16928 // than 50% of the time during this period, 16929 // that sounds bad. Kill! 16930 if (doWakeKills && realtimeSince > 0 16931 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16932 synchronized (stats) { 16933 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16934 realtimeSince, wtimeUsed); 16935 } 16936 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16937 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16938 } else if (doCpuKills && uptimeSince > 0 16939 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16940 synchronized (stats) { 16941 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16942 uptimeSince, cputimeUsed); 16943 } 16944 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16945 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16946 } else { 16947 app.lastWakeTime = wtime; 16948 app.lastCpuTime = app.curCpuTime; 16949 } 16950 } 16951 } 16952 } 16953 16954 private final boolean applyOomAdjLocked(ProcessRecord app, 16955 ProcessRecord TOP_APP, boolean doingAll, long now) { 16956 boolean success = true; 16957 16958 if (app.curRawAdj != app.setRawAdj) { 16959 app.setRawAdj = app.curRawAdj; 16960 } 16961 16962 int changes = 0; 16963 16964 if (app.curAdj != app.setAdj) { 16965 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16966 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16967 TAG, "Set " + app.pid + " " + app.processName + 16968 " adj " + app.curAdj + ": " + app.adjType); 16969 app.setAdj = app.curAdj; 16970 } 16971 16972 if (app.setSchedGroup != app.curSchedGroup) { 16973 app.setSchedGroup = app.curSchedGroup; 16974 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16975 "Setting process group of " + app.processName 16976 + " to " + app.curSchedGroup); 16977 if (app.waitingToKill != null && 16978 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16979 app.kill(app.waitingToKill, true); 16980 success = false; 16981 } else { 16982 if (true) { 16983 long oldId = Binder.clearCallingIdentity(); 16984 try { 16985 Process.setProcessGroup(app.pid, app.curSchedGroup); 16986 } catch (Exception e) { 16987 Slog.w(TAG, "Failed setting process group of " + app.pid 16988 + " to " + app.curSchedGroup); 16989 e.printStackTrace(); 16990 } finally { 16991 Binder.restoreCallingIdentity(oldId); 16992 } 16993 } else { 16994 if (app.thread != null) { 16995 try { 16996 app.thread.setSchedulingGroup(app.curSchedGroup); 16997 } catch (RemoteException e) { 16998 } 16999 } 17000 } 17001 Process.setSwappiness(app.pid, 17002 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17003 } 17004 } 17005 if (app.repForegroundActivities != app.foregroundActivities) { 17006 app.repForegroundActivities = app.foregroundActivities; 17007 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17008 } 17009 if (app.repProcState != app.curProcState) { 17010 app.repProcState = app.curProcState; 17011 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17012 if (app.thread != null) { 17013 try { 17014 if (false) { 17015 //RuntimeException h = new RuntimeException("here"); 17016 Slog.i(TAG, "Sending new process state " + app.repProcState 17017 + " to " + app /*, h*/); 17018 } 17019 app.thread.setProcessState(app.repProcState); 17020 } catch (RemoteException e) { 17021 } 17022 } 17023 } 17024 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17025 app.setProcState)) { 17026 app.lastStateTime = now; 17027 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17028 isSleeping(), now); 17029 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17030 + ProcessList.makeProcStateString(app.setProcState) + " to " 17031 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17032 + (app.nextPssTime-now) + ": " + app); 17033 } else { 17034 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17035 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17036 requestPssLocked(app, app.setProcState); 17037 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17038 isSleeping(), now); 17039 } else if (false && DEBUG_PSS) { 17040 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17041 } 17042 } 17043 if (app.setProcState != app.curProcState) { 17044 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17045 "Proc state change of " + app.processName 17046 + " to " + app.curProcState); 17047 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17048 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17049 if (setImportant && !curImportant) { 17050 // This app is no longer something we consider important enough to allow to 17051 // use arbitrary amounts of battery power. Note 17052 // its current wake lock time to later know to kill it if 17053 // it is not behaving well. 17054 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17055 synchronized (stats) { 17056 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17057 app.pid, SystemClock.elapsedRealtime()); 17058 } 17059 app.lastCpuTime = app.curCpuTime; 17060 17061 } 17062 app.setProcState = app.curProcState; 17063 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17064 app.notCachedSinceIdle = false; 17065 } 17066 if (!doingAll) { 17067 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17068 } else { 17069 app.procStateChanged = true; 17070 } 17071 } 17072 17073 if (changes != 0) { 17074 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17075 int i = mPendingProcessChanges.size()-1; 17076 ProcessChangeItem item = null; 17077 while (i >= 0) { 17078 item = mPendingProcessChanges.get(i); 17079 if (item.pid == app.pid) { 17080 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17081 break; 17082 } 17083 i--; 17084 } 17085 if (i < 0) { 17086 // No existing item in pending changes; need a new one. 17087 final int NA = mAvailProcessChanges.size(); 17088 if (NA > 0) { 17089 item = mAvailProcessChanges.remove(NA-1); 17090 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17091 } else { 17092 item = new ProcessChangeItem(); 17093 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17094 } 17095 item.changes = 0; 17096 item.pid = app.pid; 17097 item.uid = app.info.uid; 17098 if (mPendingProcessChanges.size() == 0) { 17099 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17100 "*** Enqueueing dispatch processes changed!"); 17101 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17102 } 17103 mPendingProcessChanges.add(item); 17104 } 17105 item.changes |= changes; 17106 item.processState = app.repProcState; 17107 item.foregroundActivities = app.repForegroundActivities; 17108 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17109 + Integer.toHexString(System.identityHashCode(item)) 17110 + " " + app.toShortString() + ": changes=" + item.changes 17111 + " procState=" + item.processState 17112 + " foreground=" + item.foregroundActivities 17113 + " type=" + app.adjType + " source=" + app.adjSource 17114 + " target=" + app.adjTarget); 17115 } 17116 17117 return success; 17118 } 17119 17120 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17121 if (proc.thread != null) { 17122 if (proc.baseProcessTracker != null) { 17123 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17124 } 17125 if (proc.repProcState >= 0) { 17126 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17127 proc.repProcState); 17128 } 17129 } 17130 } 17131 17132 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17133 ProcessRecord TOP_APP, boolean doingAll, long now) { 17134 if (app.thread == null) { 17135 return false; 17136 } 17137 17138 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17139 17140 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17141 } 17142 17143 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17144 boolean oomAdj) { 17145 if (isForeground != proc.foregroundServices) { 17146 proc.foregroundServices = isForeground; 17147 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17148 proc.info.uid); 17149 if (isForeground) { 17150 if (curProcs == null) { 17151 curProcs = new ArrayList<ProcessRecord>(); 17152 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17153 } 17154 if (!curProcs.contains(proc)) { 17155 curProcs.add(proc); 17156 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17157 proc.info.packageName, proc.info.uid); 17158 } 17159 } else { 17160 if (curProcs != null) { 17161 if (curProcs.remove(proc)) { 17162 mBatteryStatsService.noteEvent( 17163 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17164 proc.info.packageName, proc.info.uid); 17165 if (curProcs.size() <= 0) { 17166 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17167 } 17168 } 17169 } 17170 } 17171 if (oomAdj) { 17172 updateOomAdjLocked(); 17173 } 17174 } 17175 } 17176 17177 private final ActivityRecord resumedAppLocked() { 17178 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17179 String pkg; 17180 int uid; 17181 if (act != null) { 17182 pkg = act.packageName; 17183 uid = act.info.applicationInfo.uid; 17184 } else { 17185 pkg = null; 17186 uid = -1; 17187 } 17188 // Has the UID or resumed package name changed? 17189 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17190 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17191 if (mCurResumedPackage != null) { 17192 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17193 mCurResumedPackage, mCurResumedUid); 17194 } 17195 mCurResumedPackage = pkg; 17196 mCurResumedUid = uid; 17197 if (mCurResumedPackage != null) { 17198 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17199 mCurResumedPackage, mCurResumedUid); 17200 } 17201 } 17202 return act; 17203 } 17204 17205 final boolean updateOomAdjLocked(ProcessRecord app) { 17206 final ActivityRecord TOP_ACT = resumedAppLocked(); 17207 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17208 final boolean wasCached = app.cached; 17209 17210 mAdjSeq++; 17211 17212 // This is the desired cached adjusment we want to tell it to use. 17213 // If our app is currently cached, we know it, and that is it. Otherwise, 17214 // we don't know it yet, and it needs to now be cached we will then 17215 // need to do a complete oom adj. 17216 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17217 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17218 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17219 SystemClock.uptimeMillis()); 17220 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17221 // Changed to/from cached state, so apps after it in the LRU 17222 // list may also be changed. 17223 updateOomAdjLocked(); 17224 } 17225 return success; 17226 } 17227 17228 final void updateOomAdjLocked() { 17229 final ActivityRecord TOP_ACT = resumedAppLocked(); 17230 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17231 final long now = SystemClock.uptimeMillis(); 17232 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17233 final int N = mLruProcesses.size(); 17234 17235 if (false) { 17236 RuntimeException e = new RuntimeException(); 17237 e.fillInStackTrace(); 17238 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17239 } 17240 17241 mAdjSeq++; 17242 mNewNumServiceProcs = 0; 17243 mNewNumAServiceProcs = 0; 17244 17245 final int emptyProcessLimit; 17246 final int cachedProcessLimit; 17247 if (mProcessLimit <= 0) { 17248 emptyProcessLimit = cachedProcessLimit = 0; 17249 } else if (mProcessLimit == 1) { 17250 emptyProcessLimit = 1; 17251 cachedProcessLimit = 0; 17252 } else { 17253 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17254 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17255 } 17256 17257 // Let's determine how many processes we have running vs. 17258 // how many slots we have for background processes; we may want 17259 // to put multiple processes in a slot of there are enough of 17260 // them. 17261 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17262 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17263 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17264 if (numEmptyProcs > cachedProcessLimit) { 17265 // If there are more empty processes than our limit on cached 17266 // processes, then use the cached process limit for the factor. 17267 // This ensures that the really old empty processes get pushed 17268 // down to the bottom, so if we are running low on memory we will 17269 // have a better chance at keeping around more cached processes 17270 // instead of a gazillion empty processes. 17271 numEmptyProcs = cachedProcessLimit; 17272 } 17273 int emptyFactor = numEmptyProcs/numSlots; 17274 if (emptyFactor < 1) emptyFactor = 1; 17275 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17276 if (cachedFactor < 1) cachedFactor = 1; 17277 int stepCached = 0; 17278 int stepEmpty = 0; 17279 int numCached = 0; 17280 int numEmpty = 0; 17281 int numTrimming = 0; 17282 17283 mNumNonCachedProcs = 0; 17284 mNumCachedHiddenProcs = 0; 17285 17286 // First update the OOM adjustment for each of the 17287 // application processes based on their current state. 17288 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17289 int nextCachedAdj = curCachedAdj+1; 17290 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17291 int nextEmptyAdj = curEmptyAdj+2; 17292 for (int i=N-1; i>=0; i--) { 17293 ProcessRecord app = mLruProcesses.get(i); 17294 if (!app.killedByAm && app.thread != null) { 17295 app.procStateChanged = false; 17296 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17297 17298 // If we haven't yet assigned the final cached adj 17299 // to the process, do that now. 17300 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17301 switch (app.curProcState) { 17302 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17303 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17304 // This process is a cached process holding activities... 17305 // assign it the next cached value for that type, and then 17306 // step that cached level. 17307 app.curRawAdj = curCachedAdj; 17308 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17309 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17310 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17311 + ")"); 17312 if (curCachedAdj != nextCachedAdj) { 17313 stepCached++; 17314 if (stepCached >= cachedFactor) { 17315 stepCached = 0; 17316 curCachedAdj = nextCachedAdj; 17317 nextCachedAdj += 2; 17318 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17319 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17320 } 17321 } 17322 } 17323 break; 17324 default: 17325 // For everything else, assign next empty cached process 17326 // level and bump that up. Note that this means that 17327 // long-running services that have dropped down to the 17328 // cached level will be treated as empty (since their process 17329 // state is still as a service), which is what we want. 17330 app.curRawAdj = curEmptyAdj; 17331 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17332 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17333 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17334 + ")"); 17335 if (curEmptyAdj != nextEmptyAdj) { 17336 stepEmpty++; 17337 if (stepEmpty >= emptyFactor) { 17338 stepEmpty = 0; 17339 curEmptyAdj = nextEmptyAdj; 17340 nextEmptyAdj += 2; 17341 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17342 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17343 } 17344 } 17345 } 17346 break; 17347 } 17348 } 17349 17350 applyOomAdjLocked(app, TOP_APP, true, now); 17351 17352 // Count the number of process types. 17353 switch (app.curProcState) { 17354 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17355 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17356 mNumCachedHiddenProcs++; 17357 numCached++; 17358 if (numCached > cachedProcessLimit) { 17359 app.kill("cached #" + numCached, true); 17360 } 17361 break; 17362 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17363 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17364 && app.lastActivityTime < oldTime) { 17365 app.kill("empty for " 17366 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17367 / 1000) + "s", true); 17368 } else { 17369 numEmpty++; 17370 if (numEmpty > emptyProcessLimit) { 17371 app.kill("empty #" + numEmpty, true); 17372 } 17373 } 17374 break; 17375 default: 17376 mNumNonCachedProcs++; 17377 break; 17378 } 17379 17380 if (app.isolated && app.services.size() <= 0) { 17381 // If this is an isolated process, and there are no 17382 // services running in it, then the process is no longer 17383 // needed. We agressively kill these because we can by 17384 // definition not re-use the same process again, and it is 17385 // good to avoid having whatever code was running in them 17386 // left sitting around after no longer needed. 17387 app.kill("isolated not needed", true); 17388 } 17389 17390 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17391 && !app.killedByAm) { 17392 numTrimming++; 17393 } 17394 } 17395 } 17396 17397 mNumServiceProcs = mNewNumServiceProcs; 17398 17399 // Now determine the memory trimming level of background processes. 17400 // Unfortunately we need to start at the back of the list to do this 17401 // properly. We only do this if the number of background apps we 17402 // are managing to keep around is less than half the maximum we desire; 17403 // if we are keeping a good number around, we'll let them use whatever 17404 // memory they want. 17405 final int numCachedAndEmpty = numCached + numEmpty; 17406 int memFactor; 17407 if (numCached <= ProcessList.TRIM_CACHED_APPS 17408 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17409 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17410 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17411 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17412 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17413 } else { 17414 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17415 } 17416 } else { 17417 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17418 } 17419 // We always allow the memory level to go up (better). We only allow it to go 17420 // down if we are in a state where that is allowed, *and* the total number of processes 17421 // has gone down since last time. 17422 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17423 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17424 + " last=" + mLastNumProcesses); 17425 if (memFactor > mLastMemoryLevel) { 17426 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17427 memFactor = mLastMemoryLevel; 17428 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17429 } 17430 } 17431 mLastMemoryLevel = memFactor; 17432 mLastNumProcesses = mLruProcesses.size(); 17433 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17434 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17435 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17436 if (mLowRamStartTime == 0) { 17437 mLowRamStartTime = now; 17438 } 17439 int step = 0; 17440 int fgTrimLevel; 17441 switch (memFactor) { 17442 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17443 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17444 break; 17445 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17446 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17447 break; 17448 default: 17449 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17450 break; 17451 } 17452 int factor = numTrimming/3; 17453 int minFactor = 2; 17454 if (mHomeProcess != null) minFactor++; 17455 if (mPreviousProcess != null) minFactor++; 17456 if (factor < minFactor) factor = minFactor; 17457 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17458 for (int i=N-1; i>=0; i--) { 17459 ProcessRecord app = mLruProcesses.get(i); 17460 if (allChanged || app.procStateChanged) { 17461 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17462 app.procStateChanged = false; 17463 } 17464 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17465 && !app.killedByAm) { 17466 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17467 try { 17468 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17469 "Trimming memory of " + app.processName 17470 + " to " + curLevel); 17471 app.thread.scheduleTrimMemory(curLevel); 17472 } catch (RemoteException e) { 17473 } 17474 if (false) { 17475 // For now we won't do this; our memory trimming seems 17476 // to be good enough at this point that destroying 17477 // activities causes more harm than good. 17478 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17479 && app != mHomeProcess && app != mPreviousProcess) { 17480 // Need to do this on its own message because the stack may not 17481 // be in a consistent state at this point. 17482 // For these apps we will also finish their activities 17483 // to help them free memory. 17484 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17485 } 17486 } 17487 } 17488 app.trimMemoryLevel = curLevel; 17489 step++; 17490 if (step >= factor) { 17491 step = 0; 17492 switch (curLevel) { 17493 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17494 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17495 break; 17496 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17497 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17498 break; 17499 } 17500 } 17501 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17502 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17503 && app.thread != null) { 17504 try { 17505 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17506 "Trimming memory of heavy-weight " + app.processName 17507 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17508 app.thread.scheduleTrimMemory( 17509 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17510 } catch (RemoteException e) { 17511 } 17512 } 17513 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17514 } else { 17515 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17516 || app.systemNoUi) && app.pendingUiClean) { 17517 // If this application is now in the background and it 17518 // had done UI, then give it the special trim level to 17519 // have it free UI resources. 17520 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17521 if (app.trimMemoryLevel < level && app.thread != null) { 17522 try { 17523 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17524 "Trimming memory of bg-ui " + app.processName 17525 + " to " + level); 17526 app.thread.scheduleTrimMemory(level); 17527 } catch (RemoteException e) { 17528 } 17529 } 17530 app.pendingUiClean = false; 17531 } 17532 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17533 try { 17534 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17535 "Trimming memory of fg " + app.processName 17536 + " to " + fgTrimLevel); 17537 app.thread.scheduleTrimMemory(fgTrimLevel); 17538 } catch (RemoteException e) { 17539 } 17540 } 17541 app.trimMemoryLevel = fgTrimLevel; 17542 } 17543 } 17544 } else { 17545 if (mLowRamStartTime != 0) { 17546 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17547 mLowRamStartTime = 0; 17548 } 17549 for (int i=N-1; i>=0; i--) { 17550 ProcessRecord app = mLruProcesses.get(i); 17551 if (allChanged || app.procStateChanged) { 17552 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17553 app.procStateChanged = false; 17554 } 17555 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17556 || app.systemNoUi) && app.pendingUiClean) { 17557 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17558 && app.thread != null) { 17559 try { 17560 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17561 "Trimming memory of ui hidden " + app.processName 17562 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17563 app.thread.scheduleTrimMemory( 17564 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17565 } catch (RemoteException e) { 17566 } 17567 } 17568 app.pendingUiClean = false; 17569 } 17570 app.trimMemoryLevel = 0; 17571 } 17572 } 17573 17574 if (mAlwaysFinishActivities) { 17575 // Need to do this on its own message because the stack may not 17576 // be in a consistent state at this point. 17577 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17578 } 17579 17580 if (allChanged) { 17581 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17582 } 17583 17584 if (mProcessStats.shouldWriteNowLocked(now)) { 17585 mHandler.post(new Runnable() { 17586 @Override public void run() { 17587 synchronized (ActivityManagerService.this) { 17588 mProcessStats.writeStateAsyncLocked(); 17589 } 17590 } 17591 }); 17592 } 17593 17594 if (DEBUG_OOM_ADJ) { 17595 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17596 } 17597 } 17598 17599 final void trimApplications() { 17600 synchronized (this) { 17601 int i; 17602 17603 // First remove any unused application processes whose package 17604 // has been removed. 17605 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17606 final ProcessRecord app = mRemovedProcesses.get(i); 17607 if (app.activities.size() == 0 17608 && app.curReceiver == null && app.services.size() == 0) { 17609 Slog.i( 17610 TAG, "Exiting empty application process " 17611 + app.processName + " (" 17612 + (app.thread != null ? app.thread.asBinder() : null) 17613 + ")\n"); 17614 if (app.pid > 0 && app.pid != MY_PID) { 17615 app.kill("empty", false); 17616 } else { 17617 try { 17618 app.thread.scheduleExit(); 17619 } catch (Exception e) { 17620 // Ignore exceptions. 17621 } 17622 } 17623 cleanUpApplicationRecordLocked(app, false, true, -1); 17624 mRemovedProcesses.remove(i); 17625 17626 if (app.persistent) { 17627 addAppLocked(app.info, false, null /* ABI override */); 17628 } 17629 } 17630 } 17631 17632 // Now update the oom adj for all processes. 17633 updateOomAdjLocked(); 17634 } 17635 } 17636 17637 /** This method sends the specified signal to each of the persistent apps */ 17638 public void signalPersistentProcesses(int sig) throws RemoteException { 17639 if (sig != Process.SIGNAL_USR1) { 17640 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17641 } 17642 17643 synchronized (this) { 17644 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17645 != PackageManager.PERMISSION_GRANTED) { 17646 throw new SecurityException("Requires permission " 17647 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17648 } 17649 17650 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17651 ProcessRecord r = mLruProcesses.get(i); 17652 if (r.thread != null && r.persistent) { 17653 Process.sendSignal(r.pid, sig); 17654 } 17655 } 17656 } 17657 } 17658 17659 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17660 if (proc == null || proc == mProfileProc) { 17661 proc = mProfileProc; 17662 profileType = mProfileType; 17663 clearProfilerLocked(); 17664 } 17665 if (proc == null) { 17666 return; 17667 } 17668 try { 17669 proc.thread.profilerControl(false, null, profileType); 17670 } catch (RemoteException e) { 17671 throw new IllegalStateException("Process disappeared"); 17672 } 17673 } 17674 17675 private void clearProfilerLocked() { 17676 if (mProfileFd != null) { 17677 try { 17678 mProfileFd.close(); 17679 } catch (IOException e) { 17680 } 17681 } 17682 mProfileApp = null; 17683 mProfileProc = null; 17684 mProfileFile = null; 17685 mProfileType = 0; 17686 mAutoStopProfiler = false; 17687 mSamplingInterval = 0; 17688 } 17689 17690 public boolean profileControl(String process, int userId, boolean start, 17691 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17692 17693 try { 17694 synchronized (this) { 17695 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17696 // its own permission. 17697 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17698 != PackageManager.PERMISSION_GRANTED) { 17699 throw new SecurityException("Requires permission " 17700 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17701 } 17702 17703 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17704 throw new IllegalArgumentException("null profile info or fd"); 17705 } 17706 17707 ProcessRecord proc = null; 17708 if (process != null) { 17709 proc = findProcessLocked(process, userId, "profileControl"); 17710 } 17711 17712 if (start && (proc == null || proc.thread == null)) { 17713 throw new IllegalArgumentException("Unknown process: " + process); 17714 } 17715 17716 if (start) { 17717 stopProfilerLocked(null, 0); 17718 setProfileApp(proc.info, proc.processName, profilerInfo); 17719 mProfileProc = proc; 17720 mProfileType = profileType; 17721 ParcelFileDescriptor fd = profilerInfo.profileFd; 17722 try { 17723 fd = fd.dup(); 17724 } catch (IOException e) { 17725 fd = null; 17726 } 17727 profilerInfo.profileFd = fd; 17728 proc.thread.profilerControl(start, profilerInfo, profileType); 17729 fd = null; 17730 mProfileFd = null; 17731 } else { 17732 stopProfilerLocked(proc, profileType); 17733 if (profilerInfo != null && profilerInfo.profileFd != null) { 17734 try { 17735 profilerInfo.profileFd.close(); 17736 } catch (IOException e) { 17737 } 17738 } 17739 } 17740 17741 return true; 17742 } 17743 } catch (RemoteException e) { 17744 throw new IllegalStateException("Process disappeared"); 17745 } finally { 17746 if (profilerInfo != null && profilerInfo.profileFd != null) { 17747 try { 17748 profilerInfo.profileFd.close(); 17749 } catch (IOException e) { 17750 } 17751 } 17752 } 17753 } 17754 17755 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17756 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17757 userId, true, ALLOW_FULL_ONLY, callName, null); 17758 ProcessRecord proc = null; 17759 try { 17760 int pid = Integer.parseInt(process); 17761 synchronized (mPidsSelfLocked) { 17762 proc = mPidsSelfLocked.get(pid); 17763 } 17764 } catch (NumberFormatException e) { 17765 } 17766 17767 if (proc == null) { 17768 ArrayMap<String, SparseArray<ProcessRecord>> all 17769 = mProcessNames.getMap(); 17770 SparseArray<ProcessRecord> procs = all.get(process); 17771 if (procs != null && procs.size() > 0) { 17772 proc = procs.valueAt(0); 17773 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17774 for (int i=1; i<procs.size(); i++) { 17775 ProcessRecord thisProc = procs.valueAt(i); 17776 if (thisProc.userId == userId) { 17777 proc = thisProc; 17778 break; 17779 } 17780 } 17781 } 17782 } 17783 } 17784 17785 return proc; 17786 } 17787 17788 public boolean dumpHeap(String process, int userId, boolean managed, 17789 String path, ParcelFileDescriptor fd) throws RemoteException { 17790 17791 try { 17792 synchronized (this) { 17793 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17794 // its own permission (same as profileControl). 17795 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17796 != PackageManager.PERMISSION_GRANTED) { 17797 throw new SecurityException("Requires permission " 17798 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17799 } 17800 17801 if (fd == null) { 17802 throw new IllegalArgumentException("null fd"); 17803 } 17804 17805 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17806 if (proc == null || proc.thread == null) { 17807 throw new IllegalArgumentException("Unknown process: " + process); 17808 } 17809 17810 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17811 if (!isDebuggable) { 17812 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17813 throw new SecurityException("Process not debuggable: " + proc); 17814 } 17815 } 17816 17817 proc.thread.dumpHeap(managed, path, fd); 17818 fd = null; 17819 return true; 17820 } 17821 } catch (RemoteException e) { 17822 throw new IllegalStateException("Process disappeared"); 17823 } finally { 17824 if (fd != null) { 17825 try { 17826 fd.close(); 17827 } catch (IOException e) { 17828 } 17829 } 17830 } 17831 } 17832 17833 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17834 public void monitor() { 17835 synchronized (this) { } 17836 } 17837 17838 void onCoreSettingsChange(Bundle settings) { 17839 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17840 ProcessRecord processRecord = mLruProcesses.get(i); 17841 try { 17842 if (processRecord.thread != null) { 17843 processRecord.thread.setCoreSettings(settings); 17844 } 17845 } catch (RemoteException re) { 17846 /* ignore */ 17847 } 17848 } 17849 } 17850 17851 // Multi-user methods 17852 17853 /** 17854 * Start user, if its not already running, but don't bring it to foreground. 17855 */ 17856 @Override 17857 public boolean startUserInBackground(final int userId) { 17858 return startUser(userId, /* foreground */ false); 17859 } 17860 17861 /** 17862 * Start user, if its not already running, and bring it to foreground. 17863 */ 17864 boolean startUserInForeground(final int userId, Dialog dlg) { 17865 boolean result = startUser(userId, /* foreground */ true); 17866 dlg.dismiss(); 17867 return result; 17868 } 17869 17870 /** 17871 * Refreshes the list of users related to the current user when either a 17872 * user switch happens or when a new related user is started in the 17873 * background. 17874 */ 17875 private void updateCurrentProfileIdsLocked() { 17876 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17877 mCurrentUserId, false /* enabledOnly */); 17878 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17879 for (int i = 0; i < currentProfileIds.length; i++) { 17880 currentProfileIds[i] = profiles.get(i).id; 17881 } 17882 mCurrentProfileIds = currentProfileIds; 17883 17884 synchronized (mUserProfileGroupIdsSelfLocked) { 17885 mUserProfileGroupIdsSelfLocked.clear(); 17886 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17887 for (int i = 0; i < users.size(); i++) { 17888 UserInfo user = users.get(i); 17889 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17890 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17891 } 17892 } 17893 } 17894 } 17895 17896 private Set getProfileIdsLocked(int userId) { 17897 Set userIds = new HashSet<Integer>(); 17898 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17899 userId, false /* enabledOnly */); 17900 for (UserInfo user : profiles) { 17901 userIds.add(Integer.valueOf(user.id)); 17902 } 17903 return userIds; 17904 } 17905 17906 @Override 17907 public boolean switchUser(final int userId) { 17908 String userName; 17909 synchronized (this) { 17910 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17911 if (userInfo == null) { 17912 Slog.w(TAG, "No user info for user #" + userId); 17913 return false; 17914 } 17915 if (userInfo.isManagedProfile()) { 17916 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17917 return false; 17918 } 17919 userName = userInfo.name; 17920 } 17921 mHandler.removeMessages(START_USER_SWITCH_MSG); 17922 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17923 return true; 17924 } 17925 17926 private void showUserSwitchDialog(int userId, String userName) { 17927 // The dialog will show and then initiate the user switch by calling startUserInForeground 17928 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17929 true /* above system */); 17930 d.show(); 17931 } 17932 17933 private boolean startUser(final int userId, final boolean foreground) { 17934 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17935 != PackageManager.PERMISSION_GRANTED) { 17936 String msg = "Permission Denial: switchUser() from pid=" 17937 + Binder.getCallingPid() 17938 + ", uid=" + Binder.getCallingUid() 17939 + " requires " + INTERACT_ACROSS_USERS_FULL; 17940 Slog.w(TAG, msg); 17941 throw new SecurityException(msg); 17942 } 17943 17944 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17945 17946 final long ident = Binder.clearCallingIdentity(); 17947 try { 17948 synchronized (this) { 17949 final int oldUserId = mCurrentUserId; 17950 if (oldUserId == userId) { 17951 return true; 17952 } 17953 17954 mStackSupervisor.setLockTaskModeLocked(null, false); 17955 17956 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17957 if (userInfo == null) { 17958 Slog.w(TAG, "No user info for user #" + userId); 17959 return false; 17960 } 17961 if (foreground && userInfo.isManagedProfile()) { 17962 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17963 return false; 17964 } 17965 17966 if (foreground) { 17967 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17968 R.anim.screen_user_enter); 17969 } 17970 17971 boolean needStart = false; 17972 17973 // If the user we are switching to is not currently started, then 17974 // we need to start it now. 17975 if (mStartedUsers.get(userId) == null) { 17976 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17977 updateStartedUserArrayLocked(); 17978 needStart = true; 17979 } 17980 17981 final Integer userIdInt = Integer.valueOf(userId); 17982 mUserLru.remove(userIdInt); 17983 mUserLru.add(userIdInt); 17984 17985 if (foreground) { 17986 mCurrentUserId = userId; 17987 updateCurrentProfileIdsLocked(); 17988 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17989 // Once the internal notion of the active user has switched, we lock the device 17990 // with the option to show the user switcher on the keyguard. 17991 mWindowManager.lockNow(null); 17992 } else { 17993 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17994 updateCurrentProfileIdsLocked(); 17995 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17996 mUserLru.remove(currentUserIdInt); 17997 mUserLru.add(currentUserIdInt); 17998 } 17999 18000 final UserStartedState uss = mStartedUsers.get(userId); 18001 18002 // Make sure user is in the started state. If it is currently 18003 // stopping, we need to knock that off. 18004 if (uss.mState == UserStartedState.STATE_STOPPING) { 18005 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18006 // so we can just fairly silently bring the user back from 18007 // the almost-dead. 18008 uss.mState = UserStartedState.STATE_RUNNING; 18009 updateStartedUserArrayLocked(); 18010 needStart = true; 18011 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18012 // This means ACTION_SHUTDOWN has been sent, so we will 18013 // need to treat this as a new boot of the user. 18014 uss.mState = UserStartedState.STATE_BOOTING; 18015 updateStartedUserArrayLocked(); 18016 needStart = true; 18017 } 18018 18019 if (uss.mState == UserStartedState.STATE_BOOTING) { 18020 // Booting up a new user, need to tell system services about it. 18021 // Note that this is on the same handler as scheduling of broadcasts, 18022 // which is important because it needs to go first. 18023 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18024 } 18025 18026 if (foreground) { 18027 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18028 oldUserId)); 18029 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18030 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18031 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18032 oldUserId, userId, uss)); 18033 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18034 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18035 } 18036 18037 if (needStart) { 18038 // Send USER_STARTED broadcast 18039 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18040 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18041 | Intent.FLAG_RECEIVER_FOREGROUND); 18042 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18043 broadcastIntentLocked(null, null, intent, 18044 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18045 false, false, MY_PID, Process.SYSTEM_UID, userId); 18046 } 18047 18048 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18049 if (userId != UserHandle.USER_OWNER) { 18050 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18051 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18052 broadcastIntentLocked(null, null, intent, null, 18053 new IIntentReceiver.Stub() { 18054 public void performReceive(Intent intent, int resultCode, 18055 String data, Bundle extras, boolean ordered, 18056 boolean sticky, int sendingUser) { 18057 onUserInitialized(uss, foreground, oldUserId, userId); 18058 } 18059 }, 0, null, null, null, AppOpsManager.OP_NONE, 18060 true, false, MY_PID, Process.SYSTEM_UID, 18061 userId); 18062 uss.initializing = true; 18063 } else { 18064 getUserManagerLocked().makeInitialized(userInfo.id); 18065 } 18066 } 18067 18068 if (foreground) { 18069 if (!uss.initializing) { 18070 moveUserToForeground(uss, oldUserId, userId); 18071 } 18072 } else { 18073 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18074 } 18075 18076 if (needStart) { 18077 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18078 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18079 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18080 broadcastIntentLocked(null, null, intent, 18081 null, new IIntentReceiver.Stub() { 18082 @Override 18083 public void performReceive(Intent intent, int resultCode, String data, 18084 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18085 throws RemoteException { 18086 } 18087 }, 0, null, null, 18088 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18089 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18090 } 18091 } 18092 } finally { 18093 Binder.restoreCallingIdentity(ident); 18094 } 18095 18096 return true; 18097 } 18098 18099 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18100 long ident = Binder.clearCallingIdentity(); 18101 try { 18102 Intent intent; 18103 if (oldUserId >= 0) { 18104 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18105 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18106 int count = profiles.size(); 18107 for (int i = 0; i < count; i++) { 18108 int profileUserId = profiles.get(i).id; 18109 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18110 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18111 | Intent.FLAG_RECEIVER_FOREGROUND); 18112 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18113 broadcastIntentLocked(null, null, intent, 18114 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18115 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18116 } 18117 } 18118 if (newUserId >= 0) { 18119 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18120 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18121 int count = profiles.size(); 18122 for (int i = 0; i < count; i++) { 18123 int profileUserId = profiles.get(i).id; 18124 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18125 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18126 | Intent.FLAG_RECEIVER_FOREGROUND); 18127 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18128 broadcastIntentLocked(null, null, intent, 18129 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18130 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18131 } 18132 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18133 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18134 | Intent.FLAG_RECEIVER_FOREGROUND); 18135 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18136 broadcastIntentLocked(null, null, intent, 18137 null, null, 0, null, null, 18138 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18139 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18140 } 18141 } finally { 18142 Binder.restoreCallingIdentity(ident); 18143 } 18144 } 18145 18146 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18147 final int newUserId) { 18148 final int N = mUserSwitchObservers.beginBroadcast(); 18149 if (N > 0) { 18150 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18151 int mCount = 0; 18152 @Override 18153 public void sendResult(Bundle data) throws RemoteException { 18154 synchronized (ActivityManagerService.this) { 18155 if (mCurUserSwitchCallback == this) { 18156 mCount++; 18157 if (mCount == N) { 18158 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18159 } 18160 } 18161 } 18162 } 18163 }; 18164 synchronized (this) { 18165 uss.switching = true; 18166 mCurUserSwitchCallback = callback; 18167 } 18168 for (int i=0; i<N; i++) { 18169 try { 18170 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18171 newUserId, callback); 18172 } catch (RemoteException e) { 18173 } 18174 } 18175 } else { 18176 synchronized (this) { 18177 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18178 } 18179 } 18180 mUserSwitchObservers.finishBroadcast(); 18181 } 18182 18183 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18184 synchronized (this) { 18185 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18186 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18187 } 18188 } 18189 18190 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18191 mCurUserSwitchCallback = null; 18192 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18193 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18194 oldUserId, newUserId, uss)); 18195 } 18196 18197 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18198 synchronized (this) { 18199 if (foreground) { 18200 moveUserToForeground(uss, oldUserId, newUserId); 18201 } 18202 } 18203 18204 completeSwitchAndInitalize(uss, newUserId, true, false); 18205 } 18206 18207 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18208 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18209 if (homeInFront) { 18210 startHomeActivityLocked(newUserId); 18211 } else { 18212 mStackSupervisor.resumeTopActivitiesLocked(); 18213 } 18214 EventLogTags.writeAmSwitchUser(newUserId); 18215 getUserManagerLocked().userForeground(newUserId); 18216 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18217 } 18218 18219 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18220 completeSwitchAndInitalize(uss, newUserId, false, true); 18221 } 18222 18223 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18224 boolean clearInitializing, boolean clearSwitching) { 18225 boolean unfrozen = false; 18226 synchronized (this) { 18227 if (clearInitializing) { 18228 uss.initializing = false; 18229 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18230 } 18231 if (clearSwitching) { 18232 uss.switching = false; 18233 } 18234 if (!uss.switching && !uss.initializing) { 18235 mWindowManager.stopFreezingScreen(); 18236 unfrozen = true; 18237 } 18238 } 18239 if (unfrozen) { 18240 final int N = mUserSwitchObservers.beginBroadcast(); 18241 for (int i=0; i<N; i++) { 18242 try { 18243 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18244 } catch (RemoteException e) { 18245 } 18246 } 18247 mUserSwitchObservers.finishBroadcast(); 18248 } 18249 } 18250 18251 void scheduleStartProfilesLocked() { 18252 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18253 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18254 DateUtils.SECOND_IN_MILLIS); 18255 } 18256 } 18257 18258 void startProfilesLocked() { 18259 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18260 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18261 mCurrentUserId, false /* enabledOnly */); 18262 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18263 for (UserInfo user : profiles) { 18264 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18265 && user.id != mCurrentUserId) { 18266 toStart.add(user); 18267 } 18268 } 18269 final int n = toStart.size(); 18270 int i = 0; 18271 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18272 startUserInBackground(toStart.get(i).id); 18273 } 18274 if (i < n) { 18275 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18276 } 18277 } 18278 18279 void finishUserBoot(UserStartedState uss) { 18280 synchronized (this) { 18281 if (uss.mState == UserStartedState.STATE_BOOTING 18282 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18283 uss.mState = UserStartedState.STATE_RUNNING; 18284 final int userId = uss.mHandle.getIdentifier(); 18285 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18286 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18287 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18288 broadcastIntentLocked(null, null, intent, 18289 null, null, 0, null, null, 18290 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18291 true, false, MY_PID, Process.SYSTEM_UID, userId); 18292 } 18293 } 18294 } 18295 18296 void finishUserSwitch(UserStartedState uss) { 18297 synchronized (this) { 18298 finishUserBoot(uss); 18299 18300 startProfilesLocked(); 18301 18302 int num = mUserLru.size(); 18303 int i = 0; 18304 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18305 Integer oldUserId = mUserLru.get(i); 18306 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18307 if (oldUss == null) { 18308 // Shouldn't happen, but be sane if it does. 18309 mUserLru.remove(i); 18310 num--; 18311 continue; 18312 } 18313 if (oldUss.mState == UserStartedState.STATE_STOPPING 18314 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18315 // This user is already stopping, doesn't count. 18316 num--; 18317 i++; 18318 continue; 18319 } 18320 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18321 // Owner and current can't be stopped, but count as running. 18322 i++; 18323 continue; 18324 } 18325 // This is a user to be stopped. 18326 stopUserLocked(oldUserId, null); 18327 num--; 18328 i++; 18329 } 18330 } 18331 } 18332 18333 @Override 18334 public int stopUser(final int userId, final IStopUserCallback callback) { 18335 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18336 != PackageManager.PERMISSION_GRANTED) { 18337 String msg = "Permission Denial: switchUser() from pid=" 18338 + Binder.getCallingPid() 18339 + ", uid=" + Binder.getCallingUid() 18340 + " requires " + INTERACT_ACROSS_USERS_FULL; 18341 Slog.w(TAG, msg); 18342 throw new SecurityException(msg); 18343 } 18344 if (userId <= 0) { 18345 throw new IllegalArgumentException("Can't stop primary user " + userId); 18346 } 18347 synchronized (this) { 18348 return stopUserLocked(userId, callback); 18349 } 18350 } 18351 18352 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18353 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18354 if (mCurrentUserId == userId) { 18355 return ActivityManager.USER_OP_IS_CURRENT; 18356 } 18357 18358 final UserStartedState uss = mStartedUsers.get(userId); 18359 if (uss == null) { 18360 // User is not started, nothing to do... but we do need to 18361 // callback if requested. 18362 if (callback != null) { 18363 mHandler.post(new Runnable() { 18364 @Override 18365 public void run() { 18366 try { 18367 callback.userStopped(userId); 18368 } catch (RemoteException e) { 18369 } 18370 } 18371 }); 18372 } 18373 return ActivityManager.USER_OP_SUCCESS; 18374 } 18375 18376 if (callback != null) { 18377 uss.mStopCallbacks.add(callback); 18378 } 18379 18380 if (uss.mState != UserStartedState.STATE_STOPPING 18381 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18382 uss.mState = UserStartedState.STATE_STOPPING; 18383 updateStartedUserArrayLocked(); 18384 18385 long ident = Binder.clearCallingIdentity(); 18386 try { 18387 // We are going to broadcast ACTION_USER_STOPPING and then 18388 // once that is done send a final ACTION_SHUTDOWN and then 18389 // stop the user. 18390 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18391 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18392 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18393 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18394 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18395 // This is the result receiver for the final shutdown broadcast. 18396 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18397 @Override 18398 public void performReceive(Intent intent, int resultCode, String data, 18399 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18400 finishUserStop(uss); 18401 } 18402 }; 18403 // This is the result receiver for the initial stopping broadcast. 18404 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18405 @Override 18406 public void performReceive(Intent intent, int resultCode, String data, 18407 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18408 // On to the next. 18409 synchronized (ActivityManagerService.this) { 18410 if (uss.mState != UserStartedState.STATE_STOPPING) { 18411 // Whoops, we are being started back up. Abort, abort! 18412 return; 18413 } 18414 uss.mState = UserStartedState.STATE_SHUTDOWN; 18415 } 18416 mBatteryStatsService.noteEvent( 18417 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18418 Integer.toString(userId), userId); 18419 mSystemServiceManager.stopUser(userId); 18420 broadcastIntentLocked(null, null, shutdownIntent, 18421 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18422 true, false, MY_PID, Process.SYSTEM_UID, userId); 18423 } 18424 }; 18425 // Kick things off. 18426 broadcastIntentLocked(null, null, stoppingIntent, 18427 null, stoppingReceiver, 0, null, null, 18428 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18429 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18430 } finally { 18431 Binder.restoreCallingIdentity(ident); 18432 } 18433 } 18434 18435 return ActivityManager.USER_OP_SUCCESS; 18436 } 18437 18438 void finishUserStop(UserStartedState uss) { 18439 final int userId = uss.mHandle.getIdentifier(); 18440 boolean stopped; 18441 ArrayList<IStopUserCallback> callbacks; 18442 synchronized (this) { 18443 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18444 if (mStartedUsers.get(userId) != uss) { 18445 stopped = false; 18446 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18447 stopped = false; 18448 } else { 18449 stopped = true; 18450 // User can no longer run. 18451 mStartedUsers.remove(userId); 18452 mUserLru.remove(Integer.valueOf(userId)); 18453 updateStartedUserArrayLocked(); 18454 18455 // Clean up all state and processes associated with the user. 18456 // Kill all the processes for the user. 18457 forceStopUserLocked(userId, "finish user"); 18458 } 18459 18460 // Explicitly remove the old information in mRecentTasks. 18461 removeRecentTasksForUserLocked(userId); 18462 } 18463 18464 for (int i=0; i<callbacks.size(); i++) { 18465 try { 18466 if (stopped) callbacks.get(i).userStopped(userId); 18467 else callbacks.get(i).userStopAborted(userId); 18468 } catch (RemoteException e) { 18469 } 18470 } 18471 18472 if (stopped) { 18473 mSystemServiceManager.cleanupUser(userId); 18474 synchronized (this) { 18475 mStackSupervisor.removeUserLocked(userId); 18476 } 18477 } 18478 } 18479 18480 @Override 18481 public UserInfo getCurrentUser() { 18482 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18483 != PackageManager.PERMISSION_GRANTED) && ( 18484 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18485 != PackageManager.PERMISSION_GRANTED)) { 18486 String msg = "Permission Denial: getCurrentUser() from pid=" 18487 + Binder.getCallingPid() 18488 + ", uid=" + Binder.getCallingUid() 18489 + " requires " + INTERACT_ACROSS_USERS; 18490 Slog.w(TAG, msg); 18491 throw new SecurityException(msg); 18492 } 18493 synchronized (this) { 18494 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18495 } 18496 } 18497 18498 int getCurrentUserIdLocked() { 18499 return mCurrentUserId; 18500 } 18501 18502 @Override 18503 public boolean isUserRunning(int userId, boolean orStopped) { 18504 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18505 != PackageManager.PERMISSION_GRANTED) { 18506 String msg = "Permission Denial: isUserRunning() from pid=" 18507 + Binder.getCallingPid() 18508 + ", uid=" + Binder.getCallingUid() 18509 + " requires " + INTERACT_ACROSS_USERS; 18510 Slog.w(TAG, msg); 18511 throw new SecurityException(msg); 18512 } 18513 synchronized (this) { 18514 return isUserRunningLocked(userId, orStopped); 18515 } 18516 } 18517 18518 boolean isUserRunningLocked(int userId, boolean orStopped) { 18519 UserStartedState state = mStartedUsers.get(userId); 18520 if (state == null) { 18521 return false; 18522 } 18523 if (orStopped) { 18524 return true; 18525 } 18526 return state.mState != UserStartedState.STATE_STOPPING 18527 && state.mState != UserStartedState.STATE_SHUTDOWN; 18528 } 18529 18530 @Override 18531 public int[] getRunningUserIds() { 18532 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18533 != PackageManager.PERMISSION_GRANTED) { 18534 String msg = "Permission Denial: isUserRunning() from pid=" 18535 + Binder.getCallingPid() 18536 + ", uid=" + Binder.getCallingUid() 18537 + " requires " + INTERACT_ACROSS_USERS; 18538 Slog.w(TAG, msg); 18539 throw new SecurityException(msg); 18540 } 18541 synchronized (this) { 18542 return mStartedUserArray; 18543 } 18544 } 18545 18546 private void updateStartedUserArrayLocked() { 18547 int num = 0; 18548 for (int i=0; i<mStartedUsers.size(); i++) { 18549 UserStartedState uss = mStartedUsers.valueAt(i); 18550 // This list does not include stopping users. 18551 if (uss.mState != UserStartedState.STATE_STOPPING 18552 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18553 num++; 18554 } 18555 } 18556 mStartedUserArray = new int[num]; 18557 num = 0; 18558 for (int i=0; i<mStartedUsers.size(); i++) { 18559 UserStartedState uss = mStartedUsers.valueAt(i); 18560 if (uss.mState != UserStartedState.STATE_STOPPING 18561 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18562 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18563 num++; 18564 } 18565 } 18566 } 18567 18568 @Override 18569 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18570 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18571 != PackageManager.PERMISSION_GRANTED) { 18572 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18573 + Binder.getCallingPid() 18574 + ", uid=" + Binder.getCallingUid() 18575 + " requires " + INTERACT_ACROSS_USERS_FULL; 18576 Slog.w(TAG, msg); 18577 throw new SecurityException(msg); 18578 } 18579 18580 mUserSwitchObservers.register(observer); 18581 } 18582 18583 @Override 18584 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18585 mUserSwitchObservers.unregister(observer); 18586 } 18587 18588 private boolean userExists(int userId) { 18589 if (userId == 0) { 18590 return true; 18591 } 18592 UserManagerService ums = getUserManagerLocked(); 18593 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18594 } 18595 18596 int[] getUsersLocked() { 18597 UserManagerService ums = getUserManagerLocked(); 18598 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18599 } 18600 18601 UserManagerService getUserManagerLocked() { 18602 if (mUserManager == null) { 18603 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18604 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18605 } 18606 return mUserManager; 18607 } 18608 18609 private int applyUserId(int uid, int userId) { 18610 return UserHandle.getUid(userId, uid); 18611 } 18612 18613 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18614 if (info == null) return null; 18615 ApplicationInfo newInfo = new ApplicationInfo(info); 18616 newInfo.uid = applyUserId(info.uid, userId); 18617 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18618 + info.packageName; 18619 return newInfo; 18620 } 18621 18622 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18623 if (aInfo == null 18624 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18625 return aInfo; 18626 } 18627 18628 ActivityInfo info = new ActivityInfo(aInfo); 18629 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18630 return info; 18631 } 18632 18633 private final class LocalService extends ActivityManagerInternal { 18634 @Override 18635 public void goingToSleep() { 18636 ActivityManagerService.this.goingToSleep(); 18637 } 18638 18639 @Override 18640 public void wakingUp() { 18641 ActivityManagerService.this.wakingUp(); 18642 } 18643 18644 @Override 18645 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18646 String processName, String abiOverride, int uid, Runnable crashHandler) { 18647 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18648 processName, abiOverride, uid, crashHandler); 18649 } 18650 } 18651 18652 /** 18653 * An implementation of IAppTask, that allows an app to manage its own tasks via 18654 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18655 * only the process that calls getAppTasks() can call the AppTask methods. 18656 */ 18657 class AppTaskImpl extends IAppTask.Stub { 18658 private int mTaskId; 18659 private int mCallingUid; 18660 18661 public AppTaskImpl(int taskId, int callingUid) { 18662 mTaskId = taskId; 18663 mCallingUid = callingUid; 18664 } 18665 18666 private void checkCaller() { 18667 if (mCallingUid != Binder.getCallingUid()) { 18668 throw new SecurityException("Caller " + mCallingUid 18669 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18670 } 18671 } 18672 18673 @Override 18674 public void finishAndRemoveTask() { 18675 checkCaller(); 18676 18677 synchronized (ActivityManagerService.this) { 18678 long origId = Binder.clearCallingIdentity(); 18679 try { 18680 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18681 if (tr == null) { 18682 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18683 } 18684 // Only kill the process if we are not a new document 18685 int flags = tr.getBaseIntent().getFlags(); 18686 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18687 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18688 removeTaskByIdLocked(mTaskId, 18689 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18690 } finally { 18691 Binder.restoreCallingIdentity(origId); 18692 } 18693 } 18694 } 18695 18696 @Override 18697 public ActivityManager.RecentTaskInfo getTaskInfo() { 18698 checkCaller(); 18699 18700 synchronized (ActivityManagerService.this) { 18701 long origId = Binder.clearCallingIdentity(); 18702 try { 18703 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18704 if (tr == null) { 18705 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18706 } 18707 return createRecentTaskInfoFromTaskRecord(tr); 18708 } finally { 18709 Binder.restoreCallingIdentity(origId); 18710 } 18711 } 18712 } 18713 18714 @Override 18715 public void moveToFront() { 18716 checkCaller(); 18717 18718 final TaskRecord tr; 18719 synchronized (ActivityManagerService.this) { 18720 tr = recentTaskForIdLocked(mTaskId); 18721 if (tr == null) { 18722 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18723 } 18724 if (tr.getRootActivity() != null) { 18725 long origId = Binder.clearCallingIdentity(); 18726 try { 18727 moveTaskToFrontLocked(tr.taskId, 0, null); 18728 return; 18729 } finally { 18730 Binder.restoreCallingIdentity(origId); 18731 } 18732 } 18733 } 18734 18735 startActivityFromRecentsInner(tr.taskId, null); 18736 } 18737 18738 @Override 18739 public int startActivity(IBinder whoThread, String callingPackage, 18740 Intent intent, String resolvedType, Bundle options) { 18741 checkCaller(); 18742 18743 int callingUser = UserHandle.getCallingUserId(); 18744 TaskRecord tr; 18745 IApplicationThread appThread; 18746 synchronized (ActivityManagerService.this) { 18747 tr = recentTaskForIdLocked(mTaskId); 18748 if (tr == null) { 18749 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18750 } 18751 appThread = ApplicationThreadNative.asInterface(whoThread); 18752 if (appThread == null) { 18753 throw new IllegalArgumentException("Bad app thread " + appThread); 18754 } 18755 } 18756 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18757 resolvedType, null, null, null, null, 0, 0, null, null, 18758 null, options, callingUser, null, tr); 18759 } 18760 18761 @Override 18762 public void setExcludeFromRecents(boolean exclude) { 18763 checkCaller(); 18764 18765 synchronized (ActivityManagerService.this) { 18766 long origId = Binder.clearCallingIdentity(); 18767 try { 18768 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18769 if (tr == null) { 18770 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18771 } 18772 Intent intent = tr.getBaseIntent(); 18773 if (exclude) { 18774 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18775 } else { 18776 intent.setFlags(intent.getFlags() 18777 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18778 } 18779 } finally { 18780 Binder.restoreCallingIdentity(origId); 18781 } 18782 } 18783 } 18784 } 18785} 18786