ActivityManagerService.java revision 1df1473008c24487701c5bc15f39ed9f9697f421
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 // Holds the current foreground user's id 1111 int mCurrentUserId = 0; 1112 // Holds the target user's id during a user switch 1113 int mTargetUserId = UserHandle.USER_NULL; 1114 // If there are multiple profiles for the current user, their ids are here 1115 // Currently only the primary user can have managed profiles 1116 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1117 1118 /** 1119 * Mapping from each known user ID to the profile group ID it is associated with. 1120 */ 1121 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1122 1123 private UserManagerService mUserManager; 1124 1125 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1126 final ProcessRecord mApp; 1127 final int mPid; 1128 final IApplicationThread mAppThread; 1129 1130 AppDeathRecipient(ProcessRecord app, int pid, 1131 IApplicationThread thread) { 1132 if (localLOGV) Slog.v( 1133 TAG, "New death recipient " + this 1134 + " for thread " + thread.asBinder()); 1135 mApp = app; 1136 mPid = pid; 1137 mAppThread = thread; 1138 } 1139 1140 @Override 1141 public void binderDied() { 1142 if (localLOGV) Slog.v( 1143 TAG, "Death received in " + this 1144 + " for thread " + mAppThread.asBinder()); 1145 synchronized(ActivityManagerService.this) { 1146 appDiedLocked(mApp, mPid, mAppThread); 1147 } 1148 } 1149 } 1150 1151 static final int SHOW_ERROR_MSG = 1; 1152 static final int SHOW_NOT_RESPONDING_MSG = 2; 1153 static final int SHOW_FACTORY_ERROR_MSG = 3; 1154 static final int UPDATE_CONFIGURATION_MSG = 4; 1155 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1156 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1157 static final int SERVICE_TIMEOUT_MSG = 12; 1158 static final int UPDATE_TIME_ZONE = 13; 1159 static final int SHOW_UID_ERROR_MSG = 14; 1160 static final int IM_FEELING_LUCKY_MSG = 15; 1161 static final int PROC_START_TIMEOUT_MSG = 20; 1162 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1163 static final int KILL_APPLICATION_MSG = 22; 1164 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1165 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1166 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1167 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1168 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1169 static final int CLEAR_DNS_CACHE_MSG = 28; 1170 static final int UPDATE_HTTP_PROXY_MSG = 29; 1171 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1172 static final int DISPATCH_PROCESSES_CHANGED = 31; 1173 static final int DISPATCH_PROCESS_DIED = 32; 1174 static final int REPORT_MEM_USAGE_MSG = 33; 1175 static final int REPORT_USER_SWITCH_MSG = 34; 1176 static final int CONTINUE_USER_SWITCH_MSG = 35; 1177 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1178 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1179 static final int PERSIST_URI_GRANTS_MSG = 38; 1180 static final int REQUEST_ALL_PSS_MSG = 39; 1181 static final int START_PROFILES_MSG = 40; 1182 static final int UPDATE_TIME = 41; 1183 static final int SYSTEM_USER_START_MSG = 42; 1184 static final int SYSTEM_USER_CURRENT_MSG = 43; 1185 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1186 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1187 static final int START_USER_SWITCH_MSG = 46; 1188 1189 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1190 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1191 static final int FIRST_COMPAT_MODE_MSG = 300; 1192 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1193 1194 AlertDialog mUidAlert; 1195 CompatModeDialog mCompatModeDialog; 1196 long mLastMemUsageReportTime = 0; 1197 1198 private LockToAppRequestDialog mLockToAppRequest; 1199 1200 /** 1201 * Flag whether the current user is a "monkey", i.e. whether 1202 * the UI is driven by a UI automation tool. 1203 */ 1204 private boolean mUserIsMonkey; 1205 1206 /** Flag whether the device has a Recents UI */ 1207 boolean mHasRecents; 1208 1209 /** The dimensions of the thumbnails in the Recents UI. */ 1210 int mThumbnailWidth; 1211 int mThumbnailHeight; 1212 1213 final ServiceThread mHandlerThread; 1214 final MainHandler mHandler; 1215 1216 final class MainHandler extends Handler { 1217 public MainHandler(Looper looper) { 1218 super(looper, null, true); 1219 } 1220 1221 @Override 1222 public void handleMessage(Message msg) { 1223 switch (msg.what) { 1224 case SHOW_ERROR_MSG: { 1225 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1226 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1227 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord)data.get("app"); 1230 AppErrorResult res = (AppErrorResult) data.get("result"); 1231 if (proc != null && proc.crashDialog != null) { 1232 Slog.e(TAG, "App already has crash dialog: " + proc); 1233 if (res != null) { 1234 res.set(0); 1235 } 1236 return; 1237 } 1238 boolean isBackground = (UserHandle.getAppId(proc.uid) 1239 >= Process.FIRST_APPLICATION_UID 1240 && proc.pid != MY_PID); 1241 for (int userId : mCurrentProfileIds) { 1242 isBackground &= (proc.userId != userId); 1243 } 1244 if (isBackground && !showBackground) { 1245 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1246 if (res != null) { 1247 res.set(0); 1248 } 1249 return; 1250 } 1251 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1252 Dialog d = new AppErrorDialog(mContext, 1253 ActivityManagerService.this, res, proc); 1254 d.show(); 1255 proc.crashDialog = d; 1256 } else { 1257 // The device is asleep, so just pretend that the user 1258 // saw a crash dialog and hit "force quit". 1259 if (res != null) { 1260 res.set(0); 1261 } 1262 } 1263 } 1264 1265 ensureBootCompleted(); 1266 } break; 1267 case SHOW_NOT_RESPONDING_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1270 ProcessRecord proc = (ProcessRecord)data.get("app"); 1271 if (proc != null && proc.anrDialog != null) { 1272 Slog.e(TAG, "App already has anr dialog: " + proc); 1273 return; 1274 } 1275 1276 Intent intent = new Intent("android.intent.action.ANR"); 1277 if (!mProcessesReady) { 1278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1279 | Intent.FLAG_RECEIVER_FOREGROUND); 1280 } 1281 broadcastIntentLocked(null, null, intent, 1282 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1283 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1284 1285 if (mShowDialogs) { 1286 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1287 mContext, proc, (ActivityRecord)data.get("activity"), 1288 msg.arg1 != 0); 1289 d.show(); 1290 proc.anrDialog = d; 1291 } else { 1292 // Just kill the app if there is no dialog to be shown. 1293 killAppAtUsersRequest(proc, null); 1294 } 1295 } 1296 1297 ensureBootCompleted(); 1298 } break; 1299 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1300 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1301 synchronized (ActivityManagerService.this) { 1302 ProcessRecord proc = (ProcessRecord) data.get("app"); 1303 if (proc == null) { 1304 Slog.e(TAG, "App not found when showing strict mode dialog."); 1305 break; 1306 } 1307 if (proc.crashDialog != null) { 1308 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1309 return; 1310 } 1311 AppErrorResult res = (AppErrorResult) data.get("result"); 1312 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1313 Dialog d = new StrictModeViolationDialog(mContext, 1314 ActivityManagerService.this, res, proc); 1315 d.show(); 1316 proc.crashDialog = d; 1317 } else { 1318 // The device is asleep, so just pretend that the user 1319 // saw a crash dialog and hit "force quit". 1320 res.set(0); 1321 } 1322 } 1323 ensureBootCompleted(); 1324 } break; 1325 case SHOW_FACTORY_ERROR_MSG: { 1326 Dialog d = new FactoryErrorDialog( 1327 mContext, msg.getData().getCharSequence("msg")); 1328 d.show(); 1329 ensureBootCompleted(); 1330 } break; 1331 case UPDATE_CONFIGURATION_MSG: { 1332 final ContentResolver resolver = mContext.getContentResolver(); 1333 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1334 } break; 1335 case GC_BACKGROUND_PROCESSES_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 performAppGcsIfAppropriateLocked(); 1338 } 1339 } break; 1340 case WAIT_FOR_DEBUGGER_MSG: { 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord app = (ProcessRecord)msg.obj; 1343 if (msg.arg1 != 0) { 1344 if (!app.waitedForDebugger) { 1345 Dialog d = new AppWaitingForDebuggerDialog( 1346 ActivityManagerService.this, 1347 mContext, app); 1348 app.waitDialog = d; 1349 app.waitedForDebugger = true; 1350 d.show(); 1351 } 1352 } else { 1353 if (app.waitDialog != null) { 1354 app.waitDialog.dismiss(); 1355 app.waitDialog = null; 1356 } 1357 } 1358 } 1359 } break; 1360 case SERVICE_TIMEOUT_MSG: { 1361 if (mDidDexOpt) { 1362 mDidDexOpt = false; 1363 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1364 nmsg.obj = msg.obj; 1365 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1366 return; 1367 } 1368 mServices.serviceTimeout((ProcessRecord)msg.obj); 1369 } break; 1370 case UPDATE_TIME_ZONE: { 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.updateTimeZone(); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1379 } 1380 } 1381 } 1382 } 1383 } break; 1384 case CLEAR_DNS_CACHE_MSG: { 1385 synchronized (ActivityManagerService.this) { 1386 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1387 ProcessRecord r = mLruProcesses.get(i); 1388 if (r.thread != null) { 1389 try { 1390 r.thread.clearDnsCache(); 1391 } catch (RemoteException ex) { 1392 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1393 } 1394 } 1395 } 1396 } 1397 } break; 1398 case UPDATE_HTTP_PROXY_MSG: { 1399 ProxyInfo proxy = (ProxyInfo)msg.obj; 1400 String host = ""; 1401 String port = ""; 1402 String exclList = ""; 1403 Uri pacFileUrl = Uri.EMPTY; 1404 if (proxy != null) { 1405 host = proxy.getHost(); 1406 port = Integer.toString(proxy.getPort()); 1407 exclList = proxy.getExclusionListAsString(); 1408 pacFileUrl = proxy.getPacFileUrl(); 1409 } 1410 synchronized (ActivityManagerService.this) { 1411 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1412 ProcessRecord r = mLruProcesses.get(i); 1413 if (r.thread != null) { 1414 try { 1415 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1416 } catch (RemoteException ex) { 1417 Slog.w(TAG, "Failed to update http proxy for: " + 1418 r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case SHOW_UID_ERROR_MSG: { 1425 String title = "System UIDs Inconsistent"; 1426 String text = "UIDs on the system are inconsistent, you need to wipe your" 1427 + " data partition or your device will be unstable."; 1428 Log.e(TAG, title + ": " + text); 1429 if (mShowDialogs) { 1430 // XXX This is a temporary dialog, no need to localize. 1431 AlertDialog d = new BaseErrorDialog(mContext); 1432 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1433 d.setCancelable(false); 1434 d.setTitle(title); 1435 d.setMessage(text); 1436 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1437 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1438 mUidAlert = d; 1439 d.show(); 1440 } 1441 } break; 1442 case IM_FEELING_LUCKY_MSG: { 1443 if (mUidAlert != null) { 1444 mUidAlert.dismiss(); 1445 mUidAlert = null; 1446 } 1447 } break; 1448 case PROC_START_TIMEOUT_MSG: { 1449 if (mDidDexOpt) { 1450 mDidDexOpt = false; 1451 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1452 nmsg.obj = msg.obj; 1453 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1454 return; 1455 } 1456 ProcessRecord app = (ProcessRecord)msg.obj; 1457 synchronized (ActivityManagerService.this) { 1458 processStartTimedOutLocked(app); 1459 } 1460 } break; 1461 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1464 } 1465 } break; 1466 case KILL_APPLICATION_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 int appid = msg.arg1; 1469 boolean restart = (msg.arg2 == 1); 1470 Bundle bundle = (Bundle)msg.obj; 1471 String pkg = bundle.getString("pkg"); 1472 String reason = bundle.getString("reason"); 1473 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1474 false, UserHandle.USER_ALL, reason); 1475 } 1476 } break; 1477 case FINALIZE_PENDING_INTENT_MSG: { 1478 ((PendingIntentRecord)msg.obj).completeFinalize(); 1479 } break; 1480 case POST_HEAVY_NOTIFICATION_MSG: { 1481 INotificationManager inm = NotificationManager.getService(); 1482 if (inm == null) { 1483 return; 1484 } 1485 1486 ActivityRecord root = (ActivityRecord)msg.obj; 1487 ProcessRecord process = root.app; 1488 if (process == null) { 1489 return; 1490 } 1491 1492 try { 1493 Context context = mContext.createPackageContext(process.info.packageName, 0); 1494 String text = mContext.getString(R.string.heavy_weight_notification, 1495 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1496 Notification notification = new Notification(); 1497 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1498 notification.when = 0; 1499 notification.flags = Notification.FLAG_ONGOING_EVENT; 1500 notification.tickerText = text; 1501 notification.defaults = 0; // please be quiet 1502 notification.sound = null; 1503 notification.vibrate = null; 1504 notification.color = mContext.getResources().getColor( 1505 com.android.internal.R.color.system_notification_accent_color); 1506 notification.setLatestEventInfo(context, text, 1507 mContext.getText(R.string.heavy_weight_notification_detail), 1508 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1509 PendingIntent.FLAG_CANCEL_CURRENT, null, 1510 new UserHandle(root.userId))); 1511 1512 try { 1513 int[] outId = new int[1]; 1514 inm.enqueueNotificationWithTag("android", "android", null, 1515 R.string.heavy_weight_notification, 1516 notification, outId, root.userId); 1517 } catch (RuntimeException e) { 1518 Slog.w(ActivityManagerService.TAG, 1519 "Error showing notification for heavy-weight app", e); 1520 } catch (RemoteException e) { 1521 } 1522 } catch (NameNotFoundException e) { 1523 Slog.w(TAG, "Unable to create context for heavy notification", e); 1524 } 1525 } break; 1526 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1527 INotificationManager inm = NotificationManager.getService(); 1528 if (inm == null) { 1529 return; 1530 } 1531 try { 1532 inm.cancelNotificationWithTag("android", null, 1533 R.string.heavy_weight_notification, msg.arg1); 1534 } catch (RuntimeException e) { 1535 Slog.w(ActivityManagerService.TAG, 1536 "Error canceling notification for service", e); 1537 } catch (RemoteException e) { 1538 } 1539 } break; 1540 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1541 synchronized (ActivityManagerService.this) { 1542 checkExcessivePowerUsageLocked(true); 1543 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1544 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1546 } 1547 } break; 1548 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 ActivityRecord ar = (ActivityRecord)msg.obj; 1551 if (mCompatModeDialog != null) { 1552 if (mCompatModeDialog.mAppInfo.packageName.equals( 1553 ar.info.applicationInfo.packageName)) { 1554 return; 1555 } 1556 mCompatModeDialog.dismiss(); 1557 mCompatModeDialog = null; 1558 } 1559 if (ar != null && false) { 1560 if (mCompatModePackages.getPackageAskCompatModeLocked( 1561 ar.packageName)) { 1562 int mode = mCompatModePackages.computeCompatModeLocked( 1563 ar.info.applicationInfo); 1564 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1565 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1566 mCompatModeDialog = new CompatModeDialog( 1567 ActivityManagerService.this, mContext, 1568 ar.info.applicationInfo); 1569 mCompatModeDialog.show(); 1570 } 1571 } 1572 } 1573 } 1574 break; 1575 } 1576 case DISPATCH_PROCESSES_CHANGED: { 1577 dispatchProcessesChanged(); 1578 break; 1579 } 1580 case DISPATCH_PROCESS_DIED: { 1581 final int pid = msg.arg1; 1582 final int uid = msg.arg2; 1583 dispatchProcessDied(pid, uid); 1584 break; 1585 } 1586 case REPORT_MEM_USAGE_MSG: { 1587 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1588 Thread thread = new Thread() { 1589 @Override public void run() { 1590 final SparseArray<ProcessMemInfo> infoMap 1591 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1592 for (int i=0, N=memInfos.size(); i<N; i++) { 1593 ProcessMemInfo mi = memInfos.get(i); 1594 infoMap.put(mi.pid, mi); 1595 } 1596 updateCpuStatsNow(); 1597 synchronized (mProcessCpuThread) { 1598 final int N = mProcessCpuTracker.countStats(); 1599 for (int i=0; i<N; i++) { 1600 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1601 if (st.vsize > 0) { 1602 long pss = Debug.getPss(st.pid, null); 1603 if (pss > 0) { 1604 if (infoMap.indexOfKey(st.pid) < 0) { 1605 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1606 ProcessList.NATIVE_ADJ, -1, "native", null); 1607 mi.pss = pss; 1608 memInfos.add(mi); 1609 } 1610 } 1611 } 1612 } 1613 } 1614 1615 long totalPss = 0; 1616 for (int i=0, N=memInfos.size(); i<N; i++) { 1617 ProcessMemInfo mi = memInfos.get(i); 1618 if (mi.pss == 0) { 1619 mi.pss = Debug.getPss(mi.pid, null); 1620 } 1621 totalPss += mi.pss; 1622 } 1623 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1624 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1625 if (lhs.oomAdj != rhs.oomAdj) { 1626 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1627 } 1628 if (lhs.pss != rhs.pss) { 1629 return lhs.pss < rhs.pss ? 1 : -1; 1630 } 1631 return 0; 1632 } 1633 }); 1634 1635 StringBuilder tag = new StringBuilder(128); 1636 StringBuilder stack = new StringBuilder(128); 1637 tag.append("Low on memory -- "); 1638 appendMemBucket(tag, totalPss, "total", false); 1639 appendMemBucket(stack, totalPss, "total", true); 1640 1641 StringBuilder logBuilder = new StringBuilder(1024); 1642 logBuilder.append("Low on memory:\n"); 1643 1644 boolean firstLine = true; 1645 int lastOomAdj = Integer.MIN_VALUE; 1646 for (int i=0, N=memInfos.size(); i<N; i++) { 1647 ProcessMemInfo mi = memInfos.get(i); 1648 1649 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1650 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1651 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1652 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1653 if (lastOomAdj != mi.oomAdj) { 1654 lastOomAdj = mi.oomAdj; 1655 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1656 tag.append(" / "); 1657 } 1658 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1659 if (firstLine) { 1660 stack.append(":"); 1661 firstLine = false; 1662 } 1663 stack.append("\n\t at "); 1664 } else { 1665 stack.append("$"); 1666 } 1667 } else { 1668 tag.append(" "); 1669 stack.append("$"); 1670 } 1671 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1672 appendMemBucket(tag, mi.pss, mi.name, false); 1673 } 1674 appendMemBucket(stack, mi.pss, mi.name, true); 1675 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1676 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1677 stack.append("("); 1678 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1679 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1680 stack.append(DUMP_MEM_OOM_LABEL[k]); 1681 stack.append(":"); 1682 stack.append(DUMP_MEM_OOM_ADJ[k]); 1683 } 1684 } 1685 stack.append(")"); 1686 } 1687 } 1688 1689 logBuilder.append(" "); 1690 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1691 logBuilder.append(' '); 1692 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1693 logBuilder.append(' '); 1694 ProcessList.appendRamKb(logBuilder, mi.pss); 1695 logBuilder.append(" kB: "); 1696 logBuilder.append(mi.name); 1697 logBuilder.append(" ("); 1698 logBuilder.append(mi.pid); 1699 logBuilder.append(") "); 1700 logBuilder.append(mi.adjType); 1701 logBuilder.append('\n'); 1702 if (mi.adjReason != null) { 1703 logBuilder.append(" "); 1704 logBuilder.append(mi.adjReason); 1705 logBuilder.append('\n'); 1706 } 1707 } 1708 1709 logBuilder.append(" "); 1710 ProcessList.appendRamKb(logBuilder, totalPss); 1711 logBuilder.append(" kB: TOTAL\n"); 1712 1713 long[] infos = new long[Debug.MEMINFO_COUNT]; 1714 Debug.getMemInfo(infos); 1715 logBuilder.append(" MemInfo: "); 1716 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1717 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1718 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1719 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1720 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1721 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1722 logBuilder.append(" ZRAM: "); 1723 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1724 logBuilder.append(" kB RAM, "); 1725 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1726 logBuilder.append(" kB swap total, "); 1727 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1728 logBuilder.append(" kB swap free\n"); 1729 } 1730 Slog.i(TAG, logBuilder.toString()); 1731 1732 StringBuilder dropBuilder = new StringBuilder(1024); 1733 /* 1734 StringWriter oomSw = new StringWriter(); 1735 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1736 StringWriter catSw = new StringWriter(); 1737 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1738 String[] emptyArgs = new String[] { }; 1739 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1740 oomPw.flush(); 1741 String oomString = oomSw.toString(); 1742 */ 1743 dropBuilder.append(stack); 1744 dropBuilder.append('\n'); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append(logBuilder); 1747 dropBuilder.append('\n'); 1748 /* 1749 dropBuilder.append(oomString); 1750 dropBuilder.append('\n'); 1751 */ 1752 StringWriter catSw = new StringWriter(); 1753 synchronized (ActivityManagerService.this) { 1754 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1755 String[] emptyArgs = new String[] { }; 1756 catPw.println(); 1757 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1758 catPw.println(); 1759 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1760 false, false, null); 1761 catPw.println(); 1762 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1763 catPw.flush(); 1764 } 1765 dropBuilder.append(catSw.toString()); 1766 addErrorToDropBox("lowmem", null, "system_server", null, 1767 null, tag.toString(), dropBuilder.toString(), null, null); 1768 //Slog.i(TAG, "Sent to dropbox:"); 1769 //Slog.i(TAG, dropBuilder.toString()); 1770 synchronized (ActivityManagerService.this) { 1771 long now = SystemClock.uptimeMillis(); 1772 if (mLastMemUsageReportTime < now) { 1773 mLastMemUsageReportTime = now; 1774 } 1775 } 1776 } 1777 }; 1778 thread.start(); 1779 break; 1780 } 1781 case START_USER_SWITCH_MSG: { 1782 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1783 break; 1784 } 1785 case REPORT_USER_SWITCH_MSG: { 1786 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1787 break; 1788 } 1789 case CONTINUE_USER_SWITCH_MSG: { 1790 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1791 break; 1792 } 1793 case USER_SWITCH_TIMEOUT_MSG: { 1794 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1795 break; 1796 } 1797 case IMMERSIVE_MODE_LOCK_MSG: { 1798 final boolean nextState = (msg.arg1 != 0); 1799 if (mUpdateLock.isHeld() != nextState) { 1800 if (DEBUG_IMMERSIVE) { 1801 final ActivityRecord r = (ActivityRecord) msg.obj; 1802 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1803 } 1804 if (nextState) { 1805 mUpdateLock.acquire(); 1806 } else { 1807 mUpdateLock.release(); 1808 } 1809 } 1810 break; 1811 } 1812 case PERSIST_URI_GRANTS_MSG: { 1813 writeGrantedUriPermissions(); 1814 break; 1815 } 1816 case REQUEST_ALL_PSS_MSG: { 1817 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1818 break; 1819 } 1820 case START_PROFILES_MSG: { 1821 synchronized (ActivityManagerService.this) { 1822 startProfilesLocked(); 1823 } 1824 break; 1825 } 1826 case UPDATE_TIME: { 1827 synchronized (ActivityManagerService.this) { 1828 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1829 ProcessRecord r = mLruProcesses.get(i); 1830 if (r.thread != null) { 1831 try { 1832 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1833 } catch (RemoteException ex) { 1834 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1835 } 1836 } 1837 } 1838 } 1839 break; 1840 } 1841 case SYSTEM_USER_START_MSG: { 1842 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1843 Integer.toString(msg.arg1), msg.arg1); 1844 mSystemServiceManager.startUser(msg.arg1); 1845 break; 1846 } 1847 case SYSTEM_USER_CURRENT_MSG: { 1848 mBatteryStatsService.noteEvent( 1849 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1850 Integer.toString(msg.arg2), msg.arg2); 1851 mBatteryStatsService.noteEvent( 1852 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1853 Integer.toString(msg.arg1), msg.arg1); 1854 mSystemServiceManager.switchUser(msg.arg1); 1855 mLockToAppRequest.clearPrompt(); 1856 break; 1857 } 1858 case ENTER_ANIMATION_COMPLETE_MSG: { 1859 synchronized (ActivityManagerService.this) { 1860 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1861 if (r != null && r.app != null && r.app.thread != null) { 1862 try { 1863 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1864 } catch (RemoteException e) { 1865 } 1866 } 1867 } 1868 break; 1869 } 1870 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1871 enableScreenAfterBoot(); 1872 break; 1873 } 1874 } 1875 } 1876 }; 1877 1878 static final int COLLECT_PSS_BG_MSG = 1; 1879 1880 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1881 @Override 1882 public void handleMessage(Message msg) { 1883 switch (msg.what) { 1884 case COLLECT_PSS_BG_MSG: { 1885 long start = SystemClock.uptimeMillis(); 1886 MemInfoReader memInfo = null; 1887 synchronized (ActivityManagerService.this) { 1888 if (mFullPssPending) { 1889 mFullPssPending = false; 1890 memInfo = new MemInfoReader(); 1891 } 1892 } 1893 if (memInfo != null) { 1894 updateCpuStatsNow(); 1895 long nativeTotalPss = 0; 1896 synchronized (mProcessCpuThread) { 1897 final int N = mProcessCpuTracker.countStats(); 1898 for (int j=0; j<N; j++) { 1899 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1900 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1901 // This is definitely an application process; skip it. 1902 continue; 1903 } 1904 synchronized (mPidsSelfLocked) { 1905 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1906 // This is one of our own processes; skip it. 1907 continue; 1908 } 1909 } 1910 nativeTotalPss += Debug.getPss(st.pid, null); 1911 } 1912 } 1913 memInfo.readMemInfo(); 1914 synchronized (this) { 1915 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1916 + (SystemClock.uptimeMillis()-start) + "ms"); 1917 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1918 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1919 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1920 +memInfo.getSlabSizeKb(), 1921 nativeTotalPss); 1922 } 1923 } 1924 1925 int i=0, num=0; 1926 long[] tmp = new long[1]; 1927 do { 1928 ProcessRecord proc; 1929 int procState; 1930 int pid; 1931 synchronized (ActivityManagerService.this) { 1932 if (i >= mPendingPssProcesses.size()) { 1933 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1934 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1935 mPendingPssProcesses.clear(); 1936 return; 1937 } 1938 proc = mPendingPssProcesses.get(i); 1939 procState = proc.pssProcState; 1940 if (proc.thread != null && procState == proc.setProcState) { 1941 pid = proc.pid; 1942 } else { 1943 proc = null; 1944 pid = 0; 1945 } 1946 i++; 1947 } 1948 if (proc != null) { 1949 long pss = Debug.getPss(pid, tmp); 1950 synchronized (ActivityManagerService.this) { 1951 if (proc.thread != null && proc.setProcState == procState 1952 && proc.pid == pid) { 1953 num++; 1954 proc.lastPssTime = SystemClock.uptimeMillis(); 1955 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1956 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1957 + ": " + pss + " lastPss=" + proc.lastPss 1958 + " state=" + ProcessList.makeProcStateString(procState)); 1959 if (proc.initialIdlePss == 0) { 1960 proc.initialIdlePss = pss; 1961 } 1962 proc.lastPss = pss; 1963 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1964 proc.lastCachedPss = pss; 1965 } 1966 } 1967 } 1968 } 1969 } while (true); 1970 } 1971 } 1972 } 1973 }; 1974 1975 /** 1976 * Monitor for package changes and update our internal state. 1977 */ 1978 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1979 @Override 1980 public void onPackageRemoved(String packageName, int uid) { 1981 // Remove all tasks with activities in the specified package from the list of recent tasks 1982 synchronized (ActivityManagerService.this) { 1983 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1984 TaskRecord tr = mRecentTasks.get(i); 1985 ComponentName cn = tr.intent.getComponent(); 1986 if (cn != null && cn.getPackageName().equals(packageName)) { 1987 // If the package name matches, remove the task and kill the process 1988 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1989 } 1990 } 1991 } 1992 } 1993 1994 @Override 1995 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1996 onPackageModified(packageName); 1997 return true; 1998 } 1999 2000 @Override 2001 public void onPackageModified(String packageName) { 2002 final PackageManager pm = mContext.getPackageManager(); 2003 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2004 new ArrayList<Pair<Intent, Integer>>(); 2005 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2006 // Copy the list of recent tasks so that we don't hold onto the lock on 2007 // ActivityManagerService for long periods while checking if components exist. 2008 synchronized (ActivityManagerService.this) { 2009 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2010 TaskRecord tr = mRecentTasks.get(i); 2011 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2012 } 2013 } 2014 // Check the recent tasks and filter out all tasks with components that no longer exist. 2015 Intent tmpI = new Intent(); 2016 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2017 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2018 ComponentName cn = p.first.getComponent(); 2019 if (cn != null && cn.getPackageName().equals(packageName)) { 2020 try { 2021 // Add the task to the list to remove if the component no longer exists 2022 tmpI.setComponent(cn); 2023 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2024 tasksToRemove.add(p.second); 2025 } 2026 } catch (Exception e) {} 2027 } 2028 } 2029 // Prune all the tasks with removed components from the list of recent tasks 2030 synchronized (ActivityManagerService.this) { 2031 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2032 // Remove the task but don't kill the process (since other components in that 2033 // package may still be running and in the background) 2034 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2035 } 2036 } 2037 } 2038 2039 @Override 2040 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2041 // Force stop the specified packages 2042 if (packages != null) { 2043 for (String pkg : packages) { 2044 synchronized (ActivityManagerService.this) { 2045 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2046 "finished booting")) { 2047 return true; 2048 } 2049 } 2050 } 2051 } 2052 return false; 2053 } 2054 }; 2055 2056 public void setSystemProcess() { 2057 try { 2058 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2059 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2060 ServiceManager.addService("meminfo", new MemBinder(this)); 2061 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2062 ServiceManager.addService("dbinfo", new DbBinder(this)); 2063 if (MONITOR_CPU_USAGE) { 2064 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2065 } 2066 ServiceManager.addService("permission", new PermissionController(this)); 2067 2068 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2069 "android", STOCK_PM_FLAGS); 2070 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2071 2072 synchronized (this) { 2073 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2074 app.persistent = true; 2075 app.pid = MY_PID; 2076 app.maxAdj = ProcessList.SYSTEM_ADJ; 2077 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2078 mProcessNames.put(app.processName, app.uid, app); 2079 synchronized (mPidsSelfLocked) { 2080 mPidsSelfLocked.put(app.pid, app); 2081 } 2082 updateLruProcessLocked(app, false, null); 2083 updateOomAdjLocked(); 2084 } 2085 } catch (PackageManager.NameNotFoundException e) { 2086 throw new RuntimeException( 2087 "Unable to find android system package", e); 2088 } 2089 } 2090 2091 public void setWindowManager(WindowManagerService wm) { 2092 mWindowManager = wm; 2093 mStackSupervisor.setWindowManager(wm); 2094 } 2095 2096 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2097 mUsageStatsService = usageStatsManager; 2098 } 2099 2100 public void startObservingNativeCrashes() { 2101 final NativeCrashListener ncl = new NativeCrashListener(this); 2102 ncl.start(); 2103 } 2104 2105 public IAppOpsService getAppOpsService() { 2106 return mAppOpsService; 2107 } 2108 2109 static class MemBinder extends Binder { 2110 ActivityManagerService mActivityManagerService; 2111 MemBinder(ActivityManagerService activityManagerService) { 2112 mActivityManagerService = activityManagerService; 2113 } 2114 2115 @Override 2116 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2117 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2118 != PackageManager.PERMISSION_GRANTED) { 2119 pw.println("Permission Denial: can't dump meminfo from from pid=" 2120 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2121 + " without permission " + android.Manifest.permission.DUMP); 2122 return; 2123 } 2124 2125 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2126 } 2127 } 2128 2129 static class GraphicsBinder extends Binder { 2130 ActivityManagerService mActivityManagerService; 2131 GraphicsBinder(ActivityManagerService activityManagerService) { 2132 mActivityManagerService = activityManagerService; 2133 } 2134 2135 @Override 2136 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2137 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2138 != PackageManager.PERMISSION_GRANTED) { 2139 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2140 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2141 + " without permission " + android.Manifest.permission.DUMP); 2142 return; 2143 } 2144 2145 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2146 } 2147 } 2148 2149 static class DbBinder extends Binder { 2150 ActivityManagerService mActivityManagerService; 2151 DbBinder(ActivityManagerService activityManagerService) { 2152 mActivityManagerService = activityManagerService; 2153 } 2154 2155 @Override 2156 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2157 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2158 != PackageManager.PERMISSION_GRANTED) { 2159 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2160 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2161 + " without permission " + android.Manifest.permission.DUMP); 2162 return; 2163 } 2164 2165 mActivityManagerService.dumpDbInfo(fd, pw, args); 2166 } 2167 } 2168 2169 static class CpuBinder extends Binder { 2170 ActivityManagerService mActivityManagerService; 2171 CpuBinder(ActivityManagerService activityManagerService) { 2172 mActivityManagerService = activityManagerService; 2173 } 2174 2175 @Override 2176 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2177 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2178 != PackageManager.PERMISSION_GRANTED) { 2179 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2180 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2181 + " without permission " + android.Manifest.permission.DUMP); 2182 return; 2183 } 2184 2185 synchronized (mActivityManagerService.mProcessCpuThread) { 2186 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2188 SystemClock.uptimeMillis())); 2189 } 2190 } 2191 } 2192 2193 public static final class Lifecycle extends SystemService { 2194 private final ActivityManagerService mService; 2195 2196 public Lifecycle(Context context) { 2197 super(context); 2198 mService = new ActivityManagerService(context); 2199 } 2200 2201 @Override 2202 public void onStart() { 2203 mService.start(); 2204 } 2205 2206 public ActivityManagerService getService() { 2207 return mService; 2208 } 2209 } 2210 2211 // Note: This method is invoked on the main thread but may need to attach various 2212 // handlers to other threads. So take care to be explicit about the looper. 2213 public ActivityManagerService(Context systemContext) { 2214 mContext = systemContext; 2215 mFactoryTest = FactoryTest.getMode(); 2216 mSystemThread = ActivityThread.currentActivityThread(); 2217 2218 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2219 2220 mHandlerThread = new ServiceThread(TAG, 2221 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2222 mHandlerThread.start(); 2223 mHandler = new MainHandler(mHandlerThread.getLooper()); 2224 2225 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2226 "foreground", BROADCAST_FG_TIMEOUT, false); 2227 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2228 "background", BROADCAST_BG_TIMEOUT, true); 2229 mBroadcastQueues[0] = mFgBroadcastQueue; 2230 mBroadcastQueues[1] = mBgBroadcastQueue; 2231 2232 mServices = new ActiveServices(this); 2233 mProviderMap = new ProviderMap(this); 2234 2235 // TODO: Move creation of battery stats service outside of activity manager service. 2236 File dataDir = Environment.getDataDirectory(); 2237 File systemDir = new File(dataDir, "system"); 2238 systemDir.mkdirs(); 2239 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2240 mBatteryStatsService.getActiveStatistics().readLocked(); 2241 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2242 mOnBattery = DEBUG_POWER ? true 2243 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2244 mBatteryStatsService.getActiveStatistics().setCallback(this); 2245 2246 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2247 2248 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2249 2250 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2251 2252 // User 0 is the first and only user that runs at boot. 2253 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2254 mUserLru.add(Integer.valueOf(0)); 2255 updateStartedUserArrayLocked(); 2256 2257 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2258 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2259 2260 mConfiguration.setToDefaults(); 2261 mConfiguration.setLocale(Locale.getDefault()); 2262 2263 mConfigurationSeq = mConfiguration.seq = 1; 2264 mProcessCpuTracker.init(); 2265 2266 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2267 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2268 mStackSupervisor = new ActivityStackSupervisor(this); 2269 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2270 2271 mProcessCpuThread = new Thread("CpuTracker") { 2272 @Override 2273 public void run() { 2274 while (true) { 2275 try { 2276 try { 2277 synchronized(this) { 2278 final long now = SystemClock.uptimeMillis(); 2279 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2280 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2281 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2282 // + ", write delay=" + nextWriteDelay); 2283 if (nextWriteDelay < nextCpuDelay) { 2284 nextCpuDelay = nextWriteDelay; 2285 } 2286 if (nextCpuDelay > 0) { 2287 mProcessCpuMutexFree.set(true); 2288 this.wait(nextCpuDelay); 2289 } 2290 } 2291 } catch (InterruptedException e) { 2292 } 2293 updateCpuStatsNow(); 2294 } catch (Exception e) { 2295 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2296 } 2297 } 2298 } 2299 }; 2300 2301 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2302 2303 Watchdog.getInstance().addMonitor(this); 2304 Watchdog.getInstance().addThread(mHandler); 2305 } 2306 2307 public void setSystemServiceManager(SystemServiceManager mgr) { 2308 mSystemServiceManager = mgr; 2309 } 2310 2311 private void start() { 2312 Process.removeAllProcessGroups(); 2313 mProcessCpuThread.start(); 2314 2315 mBatteryStatsService.publish(mContext); 2316 mAppOpsService.publish(mContext); 2317 Slog.d("AppOps", "AppOpsService published"); 2318 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2319 } 2320 2321 public void initPowerManagement() { 2322 mStackSupervisor.initPowerManagement(); 2323 mBatteryStatsService.initPowerManagement(); 2324 } 2325 2326 @Override 2327 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2328 throws RemoteException { 2329 if (code == SYSPROPS_TRANSACTION) { 2330 // We need to tell all apps about the system property change. 2331 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2332 synchronized(this) { 2333 final int NP = mProcessNames.getMap().size(); 2334 for (int ip=0; ip<NP; ip++) { 2335 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2336 final int NA = apps.size(); 2337 for (int ia=0; ia<NA; ia++) { 2338 ProcessRecord app = apps.valueAt(ia); 2339 if (app.thread != null) { 2340 procs.add(app.thread.asBinder()); 2341 } 2342 } 2343 } 2344 } 2345 2346 int N = procs.size(); 2347 for (int i=0; i<N; i++) { 2348 Parcel data2 = Parcel.obtain(); 2349 try { 2350 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2351 } catch (RemoteException e) { 2352 } 2353 data2.recycle(); 2354 } 2355 } 2356 try { 2357 return super.onTransact(code, data, reply, flags); 2358 } catch (RuntimeException e) { 2359 // The activity manager only throws security exceptions, so let's 2360 // log all others. 2361 if (!(e instanceof SecurityException)) { 2362 Slog.wtf(TAG, "Activity Manager Crash", e); 2363 } 2364 throw e; 2365 } 2366 } 2367 2368 void updateCpuStats() { 2369 final long now = SystemClock.uptimeMillis(); 2370 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2371 return; 2372 } 2373 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2374 synchronized (mProcessCpuThread) { 2375 mProcessCpuThread.notify(); 2376 } 2377 } 2378 } 2379 2380 void updateCpuStatsNow() { 2381 synchronized (mProcessCpuThread) { 2382 mProcessCpuMutexFree.set(false); 2383 final long now = SystemClock.uptimeMillis(); 2384 boolean haveNewCpuStats = false; 2385 2386 if (MONITOR_CPU_USAGE && 2387 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2388 mLastCpuTime.set(now); 2389 haveNewCpuStats = true; 2390 mProcessCpuTracker.update(); 2391 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2392 //Slog.i(TAG, "Total CPU usage: " 2393 // + mProcessCpu.getTotalCpuPercent() + "%"); 2394 2395 // Slog the cpu usage if the property is set. 2396 if ("true".equals(SystemProperties.get("events.cpu"))) { 2397 int user = mProcessCpuTracker.getLastUserTime(); 2398 int system = mProcessCpuTracker.getLastSystemTime(); 2399 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2400 int irq = mProcessCpuTracker.getLastIrqTime(); 2401 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2402 int idle = mProcessCpuTracker.getLastIdleTime(); 2403 2404 int total = user + system + iowait + irq + softIrq + idle; 2405 if (total == 0) total = 1; 2406 2407 EventLog.writeEvent(EventLogTags.CPU, 2408 ((user+system+iowait+irq+softIrq) * 100) / total, 2409 (user * 100) / total, 2410 (system * 100) / total, 2411 (iowait * 100) / total, 2412 (irq * 100) / total, 2413 (softIrq * 100) / total); 2414 } 2415 } 2416 2417 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2418 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2419 synchronized(bstats) { 2420 synchronized(mPidsSelfLocked) { 2421 if (haveNewCpuStats) { 2422 if (mOnBattery) { 2423 int perc = bstats.startAddingCpuLocked(); 2424 int totalUTime = 0; 2425 int totalSTime = 0; 2426 final int N = mProcessCpuTracker.countStats(); 2427 for (int i=0; i<N; i++) { 2428 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2429 if (!st.working) { 2430 continue; 2431 } 2432 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2433 int otherUTime = (st.rel_utime*perc)/100; 2434 int otherSTime = (st.rel_stime*perc)/100; 2435 totalUTime += otherUTime; 2436 totalSTime += otherSTime; 2437 if (pr != null) { 2438 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2439 if (ps == null || !ps.isActive()) { 2440 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2441 pr.info.uid, pr.processName); 2442 } 2443 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2444 st.rel_stime-otherSTime); 2445 ps.addSpeedStepTimes(cpuSpeedTimes); 2446 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2447 } else { 2448 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2449 if (ps == null || !ps.isActive()) { 2450 st.batteryStats = ps = bstats.getProcessStatsLocked( 2451 bstats.mapUid(st.uid), st.name); 2452 } 2453 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2454 st.rel_stime-otherSTime); 2455 ps.addSpeedStepTimes(cpuSpeedTimes); 2456 } 2457 } 2458 bstats.finishAddingCpuLocked(perc, totalUTime, 2459 totalSTime, cpuSpeedTimes); 2460 } 2461 } 2462 } 2463 2464 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2465 mLastWriteTime = now; 2466 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void batteryNeedsCpuUpdate() { 2474 updateCpuStatsNow(); 2475 } 2476 2477 @Override 2478 public void batteryPowerChanged(boolean onBattery) { 2479 // When plugging in, update the CPU stats first before changing 2480 // the plug state. 2481 updateCpuStatsNow(); 2482 synchronized (this) { 2483 synchronized(mPidsSelfLocked) { 2484 mOnBattery = DEBUG_POWER ? true : onBattery; 2485 } 2486 } 2487 } 2488 2489 /** 2490 * Initialize the application bind args. These are passed to each 2491 * process when the bindApplication() IPC is sent to the process. They're 2492 * lazily setup to make sure the services are running when they're asked for. 2493 */ 2494 private HashMap<String, IBinder> getCommonServicesLocked() { 2495 if (mAppBindArgs == null) { 2496 mAppBindArgs = new HashMap<String, IBinder>(); 2497 2498 // Setup the application init args 2499 mAppBindArgs.put("package", ServiceManager.getService("package")); 2500 mAppBindArgs.put("window", ServiceManager.getService("window")); 2501 mAppBindArgs.put(Context.ALARM_SERVICE, 2502 ServiceManager.getService(Context.ALARM_SERVICE)); 2503 } 2504 return mAppBindArgs; 2505 } 2506 2507 final void setFocusedActivityLocked(ActivityRecord r) { 2508 if (mFocusedActivity != r) { 2509 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2510 mFocusedActivity = r; 2511 if (r.task != null && r.task.voiceInteractor != null) { 2512 startRunningVoiceLocked(); 2513 } else { 2514 finishRunningVoiceLocked(); 2515 } 2516 mStackSupervisor.setFocusedStack(r); 2517 if (r != null) { 2518 mWindowManager.setFocusedApp(r.appToken, true); 2519 } 2520 applyUpdateLockStateLocked(r); 2521 } 2522 } 2523 2524 final void clearFocusedActivity(ActivityRecord r) { 2525 if (mFocusedActivity == r) { 2526 mFocusedActivity = null; 2527 } 2528 } 2529 2530 @Override 2531 public void setFocusedStack(int stackId) { 2532 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2533 synchronized (ActivityManagerService.this) { 2534 ActivityStack stack = mStackSupervisor.getStack(stackId); 2535 if (stack != null) { 2536 ActivityRecord r = stack.topRunningActivityLocked(null); 2537 if (r != null) { 2538 setFocusedActivityLocked(r); 2539 } 2540 } 2541 } 2542 } 2543 2544 @Override 2545 public void notifyActivityDrawn(IBinder token) { 2546 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2547 synchronized (this) { 2548 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2549 if (r != null) { 2550 r.task.stack.notifyActivityDrawnLocked(r); 2551 } 2552 } 2553 } 2554 2555 final void applyUpdateLockStateLocked(ActivityRecord r) { 2556 // Modifications to the UpdateLock state are done on our handler, outside 2557 // the activity manager's locks. The new state is determined based on the 2558 // state *now* of the relevant activity record. The object is passed to 2559 // the handler solely for logging detail, not to be consulted/modified. 2560 final boolean nextState = r != null && r.immersive; 2561 mHandler.sendMessage( 2562 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2563 } 2564 2565 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2566 Message msg = Message.obtain(); 2567 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2568 msg.obj = r.task.askedCompatMode ? null : r; 2569 mHandler.sendMessage(msg); 2570 } 2571 2572 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2573 String what, Object obj, ProcessRecord srcApp) { 2574 app.lastActivityTime = now; 2575 2576 if (app.activities.size() > 0) { 2577 // Don't want to touch dependent processes that are hosting activities. 2578 return index; 2579 } 2580 2581 int lrui = mLruProcesses.lastIndexOf(app); 2582 if (lrui < 0) { 2583 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2584 + what + " " + obj + " from " + srcApp); 2585 return index; 2586 } 2587 2588 if (lrui >= index) { 2589 // Don't want to cause this to move dependent processes *back* in the 2590 // list as if they were less frequently used. 2591 return index; 2592 } 2593 2594 if (lrui >= mLruProcessActivityStart) { 2595 // Don't want to touch dependent processes that are hosting activities. 2596 return index; 2597 } 2598 2599 mLruProcesses.remove(lrui); 2600 if (index > 0) { 2601 index--; 2602 } 2603 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2604 + " in LRU list: " + app); 2605 mLruProcesses.add(index, app); 2606 return index; 2607 } 2608 2609 final void removeLruProcessLocked(ProcessRecord app) { 2610 int lrui = mLruProcesses.lastIndexOf(app); 2611 if (lrui >= 0) { 2612 if (lrui <= mLruProcessActivityStart) { 2613 mLruProcessActivityStart--; 2614 } 2615 if (lrui <= mLruProcessServiceStart) { 2616 mLruProcessServiceStart--; 2617 } 2618 mLruProcesses.remove(lrui); 2619 } 2620 } 2621 2622 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2623 ProcessRecord client) { 2624 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2625 || app.treatLikeActivity; 2626 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2627 if (!activityChange && hasActivity) { 2628 // The process has activities, so we are only allowing activity-based adjustments 2629 // to move it. It should be kept in the front of the list with other 2630 // processes that have activities, and we don't want those to change their 2631 // order except due to activity operations. 2632 return; 2633 } 2634 2635 mLruSeq++; 2636 final long now = SystemClock.uptimeMillis(); 2637 app.lastActivityTime = now; 2638 2639 // First a quick reject: if the app is already at the position we will 2640 // put it, then there is nothing to do. 2641 if (hasActivity) { 2642 final int N = mLruProcesses.size(); 2643 if (N > 0 && mLruProcesses.get(N-1) == app) { 2644 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2645 return; 2646 } 2647 } else { 2648 if (mLruProcessServiceStart > 0 2649 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2650 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2651 return; 2652 } 2653 } 2654 2655 int lrui = mLruProcesses.lastIndexOf(app); 2656 2657 if (app.persistent && lrui >= 0) { 2658 // We don't care about the position of persistent processes, as long as 2659 // they are in the list. 2660 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2661 return; 2662 } 2663 2664 /* In progress: compute new position first, so we can avoid doing work 2665 if the process is not actually going to move. Not yet working. 2666 int addIndex; 2667 int nextIndex; 2668 boolean inActivity = false, inService = false; 2669 if (hasActivity) { 2670 // Process has activities, put it at the very tipsy-top. 2671 addIndex = mLruProcesses.size(); 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 } else if (hasService) { 2675 // Process has services, put it at the top of the service list. 2676 addIndex = mLruProcessActivityStart; 2677 nextIndex = mLruProcessServiceStart; 2678 inActivity = true; 2679 inService = true; 2680 } else { 2681 // Process not otherwise of interest, it goes to the top of the non-service area. 2682 addIndex = mLruProcessServiceStart; 2683 if (client != null) { 2684 int clientIndex = mLruProcesses.lastIndexOf(client); 2685 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2686 + app); 2687 if (clientIndex >= 0 && addIndex > clientIndex) { 2688 addIndex = clientIndex; 2689 } 2690 } 2691 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2692 } 2693 2694 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2695 + mLruProcessActivityStart + "): " + app); 2696 */ 2697 2698 if (lrui >= 0) { 2699 if (lrui < mLruProcessActivityStart) { 2700 mLruProcessActivityStart--; 2701 } 2702 if (lrui < mLruProcessServiceStart) { 2703 mLruProcessServiceStart--; 2704 } 2705 /* 2706 if (addIndex > lrui) { 2707 addIndex--; 2708 } 2709 if (nextIndex > lrui) { 2710 nextIndex--; 2711 } 2712 */ 2713 mLruProcesses.remove(lrui); 2714 } 2715 2716 /* 2717 mLruProcesses.add(addIndex, app); 2718 if (inActivity) { 2719 mLruProcessActivityStart++; 2720 } 2721 if (inService) { 2722 mLruProcessActivityStart++; 2723 } 2724 */ 2725 2726 int nextIndex; 2727 if (hasActivity) { 2728 final int N = mLruProcesses.size(); 2729 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2730 // Process doesn't have activities, but has clients with 2731 // activities... move it up, but one below the top (the top 2732 // should always have a real activity). 2733 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2734 mLruProcesses.add(N-1, app); 2735 // To keep it from spamming the LRU list (by making a bunch of clients), 2736 // we will push down any other entries owned by the app. 2737 final int uid = app.info.uid; 2738 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2739 ProcessRecord subProc = mLruProcesses.get(i); 2740 if (subProc.info.uid == uid) { 2741 // We want to push this one down the list. If the process after 2742 // it is for the same uid, however, don't do so, because we don't 2743 // want them internally to be re-ordered. 2744 if (mLruProcesses.get(i-1).info.uid != uid) { 2745 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2746 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2747 ProcessRecord tmp = mLruProcesses.get(i); 2748 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2749 mLruProcesses.set(i-1, tmp); 2750 i--; 2751 } 2752 } else { 2753 // A gap, we can stop here. 2754 break; 2755 } 2756 } 2757 } else { 2758 // Process has activities, put it at the very tipsy-top. 2759 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2760 mLruProcesses.add(app); 2761 } 2762 nextIndex = mLruProcessServiceStart; 2763 } else if (hasService) { 2764 // Process has services, put it at the top of the service list. 2765 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2766 mLruProcesses.add(mLruProcessActivityStart, app); 2767 nextIndex = mLruProcessServiceStart; 2768 mLruProcessActivityStart++; 2769 } else { 2770 // Process not otherwise of interest, it goes to the top of the non-service area. 2771 int index = mLruProcessServiceStart; 2772 if (client != null) { 2773 // If there is a client, don't allow the process to be moved up higher 2774 // in the list than that client. 2775 int clientIndex = mLruProcesses.lastIndexOf(client); 2776 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2777 + " when updating " + app); 2778 if (clientIndex <= lrui) { 2779 // Don't allow the client index restriction to push it down farther in the 2780 // list than it already is. 2781 clientIndex = lrui; 2782 } 2783 if (clientIndex >= 0 && index > clientIndex) { 2784 index = clientIndex; 2785 } 2786 } 2787 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2788 mLruProcesses.add(index, app); 2789 nextIndex = index-1; 2790 mLruProcessActivityStart++; 2791 mLruProcessServiceStart++; 2792 } 2793 2794 // If the app is currently using a content provider or service, 2795 // bump those processes as well. 2796 for (int j=app.connections.size()-1; j>=0; j--) { 2797 ConnectionRecord cr = app.connections.valueAt(j); 2798 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2799 && cr.binding.service.app != null 2800 && cr.binding.service.app.lruSeq != mLruSeq 2801 && !cr.binding.service.app.persistent) { 2802 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2803 "service connection", cr, app); 2804 } 2805 } 2806 for (int j=app.conProviders.size()-1; j>=0; j--) { 2807 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2808 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2809 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2810 "provider reference", cpr, app); 2811 } 2812 } 2813 } 2814 2815 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2816 if (uid == Process.SYSTEM_UID) { 2817 // The system gets to run in any process. If there are multiple 2818 // processes with the same uid, just pick the first (this 2819 // should never happen). 2820 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2821 if (procs == null) return null; 2822 final int N = procs.size(); 2823 for (int i = 0; i < N; i++) { 2824 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2825 } 2826 } 2827 ProcessRecord proc = mProcessNames.get(processName, uid); 2828 if (false && proc != null && !keepIfLarge 2829 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2830 && proc.lastCachedPss >= 4000) { 2831 // Turn this condition on to cause killing to happen regularly, for testing. 2832 if (proc.baseProcessTracker != null) { 2833 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2834 } 2835 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2836 } else if (proc != null && !keepIfLarge 2837 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2838 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2839 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2840 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2841 if (proc.baseProcessTracker != null) { 2842 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2843 } 2844 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2845 } 2846 } 2847 return proc; 2848 } 2849 2850 void ensurePackageDexOpt(String packageName) { 2851 IPackageManager pm = AppGlobals.getPackageManager(); 2852 try { 2853 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2854 mDidDexOpt = true; 2855 } 2856 } catch (RemoteException e) { 2857 } 2858 } 2859 2860 boolean isNextTransitionForward() { 2861 int transit = mWindowManager.getPendingAppTransition(); 2862 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2863 || transit == AppTransition.TRANSIT_TASK_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2865 } 2866 2867 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2868 String processName, String abiOverride, int uid, Runnable crashHandler) { 2869 synchronized(this) { 2870 ApplicationInfo info = new ApplicationInfo(); 2871 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2872 // For isolated processes, the former contains the parent's uid and the latter the 2873 // actual uid of the isolated process. 2874 // In the special case introduced by this method (which is, starting an isolated 2875 // process directly from the SystemServer without an actual parent app process) the 2876 // closest thing to a parent's uid is SYSTEM_UID. 2877 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2878 // the |isolated| logic in the ProcessRecord constructor. 2879 info.uid = Process.SYSTEM_UID; 2880 info.processName = processName; 2881 info.className = entryPoint; 2882 info.packageName = "android"; 2883 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2884 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2885 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2886 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2887 crashHandler); 2888 return proc != null ? proc.pid : 0; 2889 } 2890 } 2891 2892 final ProcessRecord startProcessLocked(String processName, 2893 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2894 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2895 boolean isolated, boolean keepIfLarge) { 2896 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2897 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2898 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2899 null /* crashHandler */); 2900 } 2901 2902 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2903 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2904 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2905 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2906 ProcessRecord app; 2907 if (!isolated) { 2908 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2909 } else { 2910 // If this is an isolated process, it can't re-use an existing process. 2911 app = null; 2912 } 2913 // We don't have to do anything more if: 2914 // (1) There is an existing application record; and 2915 // (2) The caller doesn't think it is dead, OR there is no thread 2916 // object attached to it so we know it couldn't have crashed; and 2917 // (3) There is a pid assigned to it, so it is either starting or 2918 // already running. 2919 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2920 + " app=" + app + " knownToBeDead=" + knownToBeDead 2921 + " thread=" + (app != null ? app.thread : null) 2922 + " pid=" + (app != null ? app.pid : -1)); 2923 if (app != null && app.pid > 0) { 2924 if (!knownToBeDead || app.thread == null) { 2925 // We already have the app running, or are waiting for it to 2926 // come up (we have a pid but not yet its thread), so keep it. 2927 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2928 // If this is a new package in the process, add the package to the list 2929 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2930 return app; 2931 } 2932 2933 // An application record is attached to a previous process, 2934 // clean it up now. 2935 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2936 Process.killProcessGroup(app.info.uid, app.pid); 2937 handleAppDiedLocked(app, true, true); 2938 } 2939 2940 String hostingNameStr = hostingName != null 2941 ? hostingName.flattenToShortString() : null; 2942 2943 if (!isolated) { 2944 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2945 // If we are in the background, then check to see if this process 2946 // is bad. If so, we will just silently fail. 2947 if (mBadProcesses.get(info.processName, info.uid) != null) { 2948 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2949 + "/" + info.processName); 2950 return null; 2951 } 2952 } else { 2953 // When the user is explicitly starting a process, then clear its 2954 // crash count so that we won't make it bad until they see at 2955 // least one crash dialog again, and make the process good again 2956 // if it had been bad. 2957 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2958 + "/" + info.processName); 2959 mProcessCrashTimes.remove(info.processName, info.uid); 2960 if (mBadProcesses.get(info.processName, info.uid) != null) { 2961 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2962 UserHandle.getUserId(info.uid), info.uid, 2963 info.processName); 2964 mBadProcesses.remove(info.processName, info.uid); 2965 if (app != null) { 2966 app.bad = false; 2967 } 2968 } 2969 } 2970 } 2971 2972 if (app == null) { 2973 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2974 app.crashHandler = crashHandler; 2975 if (app == null) { 2976 Slog.w(TAG, "Failed making new process record for " 2977 + processName + "/" + info.uid + " isolated=" + isolated); 2978 return null; 2979 } 2980 mProcessNames.put(processName, app.uid, app); 2981 if (isolated) { 2982 mIsolatedProcesses.put(app.uid, app); 2983 } 2984 } else { 2985 // If this is a new package in the process, add the package to the list 2986 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2987 } 2988 2989 // If the system is not ready yet, then hold off on starting this 2990 // process until it is. 2991 if (!mProcessesReady 2992 && !isAllowedWhileBooting(info) 2993 && !allowWhileBooting) { 2994 if (!mProcessesOnHold.contains(app)) { 2995 mProcessesOnHold.add(app); 2996 } 2997 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2998 return app; 2999 } 3000 3001 startProcessLocked( 3002 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3003 return (app.pid != 0) ? app : null; 3004 } 3005 3006 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3007 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3008 } 3009 3010 private final void startProcessLocked(ProcessRecord app, 3011 String hostingType, String hostingNameStr) { 3012 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3013 null /* entryPoint */, null /* entryPointArgs */); 3014 } 3015 3016 private final void startProcessLocked(ProcessRecord app, String hostingType, 3017 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3018 if (app.pid > 0 && app.pid != MY_PID) { 3019 synchronized (mPidsSelfLocked) { 3020 mPidsSelfLocked.remove(app.pid); 3021 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3022 } 3023 app.setPid(0); 3024 } 3025 3026 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3027 "startProcessLocked removing on hold: " + app); 3028 mProcessesOnHold.remove(app); 3029 3030 updateCpuStats(); 3031 3032 try { 3033 int uid = app.uid; 3034 3035 int[] gids = null; 3036 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3037 if (!app.isolated) { 3038 int[] permGids = null; 3039 try { 3040 final PackageManager pm = mContext.getPackageManager(); 3041 permGids = pm.getPackageGids(app.info.packageName); 3042 3043 if (Environment.isExternalStorageEmulated()) { 3044 if (pm.checkPermission( 3045 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3046 app.info.packageName) == PERMISSION_GRANTED) { 3047 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3048 } else { 3049 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3050 } 3051 } 3052 } catch (PackageManager.NameNotFoundException e) { 3053 Slog.w(TAG, "Unable to retrieve gids", e); 3054 } 3055 3056 /* 3057 * Add shared application and profile GIDs so applications can share some 3058 * resources like shared libraries and access user-wide resources 3059 */ 3060 if (permGids == null) { 3061 gids = new int[2]; 3062 } else { 3063 gids = new int[permGids.length + 2]; 3064 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3065 } 3066 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3067 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3068 } 3069 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3070 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3071 && mTopComponent != null 3072 && app.processName.equals(mTopComponent.getPackageName())) { 3073 uid = 0; 3074 } 3075 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3076 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3077 uid = 0; 3078 } 3079 } 3080 int debugFlags = 0; 3081 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3082 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3083 // Also turn on CheckJNI for debuggable apps. It's quite 3084 // awkward to turn on otherwise. 3085 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3086 } 3087 // Run the app in safe mode if its manifest requests so or the 3088 // system is booted in safe mode. 3089 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3090 mSafeMode == true) { 3091 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3092 } 3093 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3094 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3095 } 3096 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3097 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3098 } 3099 if ("1".equals(SystemProperties.get("debug.assert"))) { 3100 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3101 } 3102 3103 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3104 if (requiredAbi == null) { 3105 requiredAbi = Build.SUPPORTED_ABIS[0]; 3106 } 3107 3108 // Start the process. It will either succeed and return a result containing 3109 // the PID of the new process, or else throw a RuntimeException. 3110 boolean isActivityProcess = (entryPoint == null); 3111 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3112 Process.ProcessStartResult startResult = Process.start(entryPoint, 3113 app.processName, uid, uid, gids, debugFlags, mountExternal, 3114 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3115 3116 if (app.isolated) { 3117 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3118 } 3119 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3120 3121 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3122 UserHandle.getUserId(uid), startResult.pid, uid, 3123 app.processName, hostingType, 3124 hostingNameStr != null ? hostingNameStr : ""); 3125 3126 if (app.persistent) { 3127 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3128 } 3129 3130 StringBuilder buf = mStringBuilder; 3131 buf.setLength(0); 3132 buf.append("Start proc "); 3133 buf.append(app.processName); 3134 if (!isActivityProcess) { 3135 buf.append(" ["); 3136 buf.append(entryPoint); 3137 buf.append("]"); 3138 } 3139 buf.append(" for "); 3140 buf.append(hostingType); 3141 if (hostingNameStr != null) { 3142 buf.append(" "); 3143 buf.append(hostingNameStr); 3144 } 3145 buf.append(": pid="); 3146 buf.append(startResult.pid); 3147 buf.append(" uid="); 3148 buf.append(uid); 3149 buf.append(" gids={"); 3150 if (gids != null) { 3151 for (int gi=0; gi<gids.length; gi++) { 3152 if (gi != 0) buf.append(", "); 3153 buf.append(gids[gi]); 3154 3155 } 3156 } 3157 buf.append("}"); 3158 if (requiredAbi != null) { 3159 buf.append(" abi="); 3160 buf.append(requiredAbi); 3161 } 3162 Slog.i(TAG, buf.toString()); 3163 app.setPid(startResult.pid); 3164 app.usingWrapper = startResult.usingWrapper; 3165 app.removed = false; 3166 app.killedByAm = false; 3167 synchronized (mPidsSelfLocked) { 3168 this.mPidsSelfLocked.put(startResult.pid, app); 3169 if (isActivityProcess) { 3170 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3171 msg.obj = app; 3172 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3173 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3174 } 3175 } 3176 } catch (RuntimeException e) { 3177 // XXX do better error recovery. 3178 app.setPid(0); 3179 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3180 if (app.isolated) { 3181 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3182 } 3183 Slog.e(TAG, "Failure starting process " + app.processName, e); 3184 } 3185 } 3186 3187 void updateUsageStats(ActivityRecord component, boolean resumed) { 3188 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3189 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3190 if (resumed) { 3191 if (mUsageStatsService != null) { 3192 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3193 System.currentTimeMillis(), 3194 UsageEvents.Event.MOVE_TO_FOREGROUND); 3195 } 3196 synchronized (stats) { 3197 stats.noteActivityResumedLocked(component.app.uid); 3198 } 3199 } else { 3200 if (mUsageStatsService != null) { 3201 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3202 System.currentTimeMillis(), 3203 UsageEvents.Event.MOVE_TO_BACKGROUND); 3204 } 3205 synchronized (stats) { 3206 stats.noteActivityPausedLocked(component.app.uid); 3207 } 3208 } 3209 } 3210 3211 Intent getHomeIntent() { 3212 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3213 intent.setComponent(mTopComponent); 3214 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3215 intent.addCategory(Intent.CATEGORY_HOME); 3216 } 3217 return intent; 3218 } 3219 3220 boolean startHomeActivityLocked(int userId) { 3221 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3222 && mTopAction == null) { 3223 // We are running in factory test mode, but unable to find 3224 // the factory test app, so just sit around displaying the 3225 // error message and don't try to start anything. 3226 return false; 3227 } 3228 Intent intent = getHomeIntent(); 3229 ActivityInfo aInfo = 3230 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3231 if (aInfo != null) { 3232 intent.setComponent(new ComponentName( 3233 aInfo.applicationInfo.packageName, aInfo.name)); 3234 // Don't do this if the home app is currently being 3235 // instrumented. 3236 aInfo = new ActivityInfo(aInfo); 3237 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3238 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3239 aInfo.applicationInfo.uid, true); 3240 if (app == null || app.instrumentationClass == null) { 3241 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3242 mStackSupervisor.startHomeActivity(intent, aInfo); 3243 } 3244 } 3245 3246 return true; 3247 } 3248 3249 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3250 ActivityInfo ai = null; 3251 ComponentName comp = intent.getComponent(); 3252 try { 3253 if (comp != null) { 3254 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3255 } else { 3256 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3257 intent, 3258 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3259 flags, userId); 3260 3261 if (info != null) { 3262 ai = info.activityInfo; 3263 } 3264 } 3265 } catch (RemoteException e) { 3266 // ignore 3267 } 3268 3269 return ai; 3270 } 3271 3272 /** 3273 * Starts the "new version setup screen" if appropriate. 3274 */ 3275 void startSetupActivityLocked() { 3276 // Only do this once per boot. 3277 if (mCheckedForSetup) { 3278 return; 3279 } 3280 3281 // We will show this screen if the current one is a different 3282 // version than the last one shown, and we are not running in 3283 // low-level factory test mode. 3284 final ContentResolver resolver = mContext.getContentResolver(); 3285 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3286 Settings.Global.getInt(resolver, 3287 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3288 mCheckedForSetup = true; 3289 3290 // See if we should be showing the platform update setup UI. 3291 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3292 List<ResolveInfo> ris = mContext.getPackageManager() 3293 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3294 3295 // We don't allow third party apps to replace this. 3296 ResolveInfo ri = null; 3297 for (int i=0; ris != null && i<ris.size(); i++) { 3298 if ((ris.get(i).activityInfo.applicationInfo.flags 3299 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3300 ri = ris.get(i); 3301 break; 3302 } 3303 } 3304 3305 if (ri != null) { 3306 String vers = ri.activityInfo.metaData != null 3307 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3308 : null; 3309 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3310 vers = ri.activityInfo.applicationInfo.metaData.getString( 3311 Intent.METADATA_SETUP_VERSION); 3312 } 3313 String lastVers = Settings.Secure.getString( 3314 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3315 if (vers != null && !vers.equals(lastVers)) { 3316 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3317 intent.setComponent(new ComponentName( 3318 ri.activityInfo.packageName, ri.activityInfo.name)); 3319 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3320 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3321 null); 3322 } 3323 } 3324 } 3325 } 3326 3327 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3328 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3329 } 3330 3331 void enforceNotIsolatedCaller(String caller) { 3332 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3333 throw new SecurityException("Isolated process not allowed to call " + caller); 3334 } 3335 } 3336 3337 @Override 3338 public int getFrontActivityScreenCompatMode() { 3339 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3340 synchronized (this) { 3341 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3342 } 3343 } 3344 3345 @Override 3346 public void setFrontActivityScreenCompatMode(int mode) { 3347 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3348 "setFrontActivityScreenCompatMode"); 3349 synchronized (this) { 3350 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3351 } 3352 } 3353 3354 @Override 3355 public int getPackageScreenCompatMode(String packageName) { 3356 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3357 synchronized (this) { 3358 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3359 } 3360 } 3361 3362 @Override 3363 public void setPackageScreenCompatMode(String packageName, int mode) { 3364 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3365 "setPackageScreenCompatMode"); 3366 synchronized (this) { 3367 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3368 } 3369 } 3370 3371 @Override 3372 public boolean getPackageAskScreenCompat(String packageName) { 3373 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3374 synchronized (this) { 3375 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3376 } 3377 } 3378 3379 @Override 3380 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3381 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3382 "setPackageAskScreenCompat"); 3383 synchronized (this) { 3384 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3385 } 3386 } 3387 3388 private void dispatchProcessesChanged() { 3389 int N; 3390 synchronized (this) { 3391 N = mPendingProcessChanges.size(); 3392 if (mActiveProcessChanges.length < N) { 3393 mActiveProcessChanges = new ProcessChangeItem[N]; 3394 } 3395 mPendingProcessChanges.toArray(mActiveProcessChanges); 3396 mAvailProcessChanges.addAll(mPendingProcessChanges); 3397 mPendingProcessChanges.clear(); 3398 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3399 } 3400 3401 int i = mProcessObservers.beginBroadcast(); 3402 while (i > 0) { 3403 i--; 3404 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3405 if (observer != null) { 3406 try { 3407 for (int j=0; j<N; j++) { 3408 ProcessChangeItem item = mActiveProcessChanges[j]; 3409 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3410 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3411 + item.pid + " uid=" + item.uid + ": " 3412 + item.foregroundActivities); 3413 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3414 item.foregroundActivities); 3415 } 3416 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3417 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3418 + item.pid + " uid=" + item.uid + ": " + item.processState); 3419 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3420 } 3421 } 3422 } catch (RemoteException e) { 3423 } 3424 } 3425 } 3426 mProcessObservers.finishBroadcast(); 3427 } 3428 3429 private void dispatchProcessDied(int pid, int uid) { 3430 int i = mProcessObservers.beginBroadcast(); 3431 while (i > 0) { 3432 i--; 3433 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3434 if (observer != null) { 3435 try { 3436 observer.onProcessDied(pid, uid); 3437 } catch (RemoteException e) { 3438 } 3439 } 3440 } 3441 mProcessObservers.finishBroadcast(); 3442 } 3443 3444 @Override 3445 public final int startActivity(IApplicationThread caller, String callingPackage, 3446 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3447 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3448 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3449 resultWho, requestCode, startFlags, profilerInfo, options, 3450 UserHandle.getCallingUserId()); 3451 } 3452 3453 @Override 3454 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3455 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3456 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3457 enforceNotIsolatedCaller("startActivity"); 3458 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3459 false, ALLOW_FULL_ONLY, "startActivity", null); 3460 // TODO: Switch to user app stacks here. 3461 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3462 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3463 profilerInfo, null, null, options, userId, null, null); 3464 } 3465 3466 @Override 3467 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3468 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3469 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3470 3471 // This is very dangerous -- it allows you to perform a start activity (including 3472 // permission grants) as any app that may launch one of your own activities. So 3473 // we will only allow this to be done from activities that are part of the core framework, 3474 // and then only when they are running as the system. 3475 final ActivityRecord sourceRecord; 3476 final int targetUid; 3477 final String targetPackage; 3478 synchronized (this) { 3479 if (resultTo == null) { 3480 throw new SecurityException("Must be called from an activity"); 3481 } 3482 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3483 if (sourceRecord == null) { 3484 throw new SecurityException("Called with bad activity token: " + resultTo); 3485 } 3486 if (!sourceRecord.info.packageName.equals("android")) { 3487 throw new SecurityException( 3488 "Must be called from an activity that is declared in the android package"); 3489 } 3490 if (sourceRecord.app == null) { 3491 throw new SecurityException("Called without a process attached to activity"); 3492 } 3493 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3494 // This is still okay, as long as this activity is running under the 3495 // uid of the original calling activity. 3496 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3497 throw new SecurityException( 3498 "Calling activity in uid " + sourceRecord.app.uid 3499 + " must be system uid or original calling uid " 3500 + sourceRecord.launchedFromUid); 3501 } 3502 } 3503 targetUid = sourceRecord.launchedFromUid; 3504 targetPackage = sourceRecord.launchedFromPackage; 3505 } 3506 3507 // TODO: Switch to user app stacks here. 3508 try { 3509 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3510 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3511 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3512 return ret; 3513 } catch (SecurityException e) { 3514 // XXX need to figure out how to propagate to original app. 3515 // A SecurityException here is generally actually a fault of the original 3516 // calling activity (such as a fairly granting permissions), so propagate it 3517 // back to them. 3518 /* 3519 StringBuilder msg = new StringBuilder(); 3520 msg.append("While launching"); 3521 msg.append(intent.toString()); 3522 msg.append(": "); 3523 msg.append(e.getMessage()); 3524 */ 3525 throw e; 3526 } 3527 } 3528 3529 @Override 3530 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3531 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3532 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3533 enforceNotIsolatedCaller("startActivityAndWait"); 3534 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3535 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3536 WaitResult res = new WaitResult(); 3537 // TODO: Switch to user app stacks here. 3538 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3539 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3540 options, userId, null, null); 3541 return res; 3542 } 3543 3544 @Override 3545 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3546 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3547 int startFlags, Configuration config, Bundle options, int userId) { 3548 enforceNotIsolatedCaller("startActivityWithConfig"); 3549 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3550 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3551 // TODO: Switch to user app stacks here. 3552 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3553 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3554 null, null, config, options, userId, null, null); 3555 return ret; 3556 } 3557 3558 @Override 3559 public int startActivityIntentSender(IApplicationThread caller, 3560 IntentSender intent, Intent fillInIntent, String resolvedType, 3561 IBinder resultTo, String resultWho, int requestCode, 3562 int flagsMask, int flagsValues, Bundle options) { 3563 enforceNotIsolatedCaller("startActivityIntentSender"); 3564 // Refuse possible leaked file descriptors 3565 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3566 throw new IllegalArgumentException("File descriptors passed in Intent"); 3567 } 3568 3569 IIntentSender sender = intent.getTarget(); 3570 if (!(sender instanceof PendingIntentRecord)) { 3571 throw new IllegalArgumentException("Bad PendingIntent object"); 3572 } 3573 3574 PendingIntentRecord pir = (PendingIntentRecord)sender; 3575 3576 synchronized (this) { 3577 // If this is coming from the currently resumed activity, it is 3578 // effectively saying that app switches are allowed at this point. 3579 final ActivityStack stack = getFocusedStack(); 3580 if (stack.mResumedActivity != null && 3581 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3582 mAppSwitchesAllowedTime = 0; 3583 } 3584 } 3585 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3586 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3587 return ret; 3588 } 3589 3590 @Override 3591 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3592 Intent intent, String resolvedType, IVoiceInteractionSession session, 3593 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3594 Bundle options, int userId) { 3595 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3596 != PackageManager.PERMISSION_GRANTED) { 3597 String msg = "Permission Denial: startVoiceActivity() from pid=" 3598 + Binder.getCallingPid() 3599 + ", uid=" + Binder.getCallingUid() 3600 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3601 Slog.w(TAG, msg); 3602 throw new SecurityException(msg); 3603 } 3604 if (session == null || interactor == null) { 3605 throw new NullPointerException("null session or interactor"); 3606 } 3607 userId = handleIncomingUser(callingPid, callingUid, userId, 3608 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3609 // TODO: Switch to user app stacks here. 3610 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3611 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3612 null, options, userId, null, null); 3613 } 3614 3615 @Override 3616 public boolean startNextMatchingActivity(IBinder callingActivity, 3617 Intent intent, Bundle options) { 3618 // Refuse possible leaked file descriptors 3619 if (intent != null && intent.hasFileDescriptors() == true) { 3620 throw new IllegalArgumentException("File descriptors passed in Intent"); 3621 } 3622 3623 synchronized (this) { 3624 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3625 if (r == null) { 3626 ActivityOptions.abort(options); 3627 return false; 3628 } 3629 if (r.app == null || r.app.thread == null) { 3630 // The caller is not running... d'oh! 3631 ActivityOptions.abort(options); 3632 return false; 3633 } 3634 intent = new Intent(intent); 3635 // The caller is not allowed to change the data. 3636 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3637 // And we are resetting to find the next component... 3638 intent.setComponent(null); 3639 3640 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3641 3642 ActivityInfo aInfo = null; 3643 try { 3644 List<ResolveInfo> resolves = 3645 AppGlobals.getPackageManager().queryIntentActivities( 3646 intent, r.resolvedType, 3647 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3648 UserHandle.getCallingUserId()); 3649 3650 // Look for the original activity in the list... 3651 final int N = resolves != null ? resolves.size() : 0; 3652 for (int i=0; i<N; i++) { 3653 ResolveInfo rInfo = resolves.get(i); 3654 if (rInfo.activityInfo.packageName.equals(r.packageName) 3655 && rInfo.activityInfo.name.equals(r.info.name)) { 3656 // We found the current one... the next matching is 3657 // after it. 3658 i++; 3659 if (i<N) { 3660 aInfo = resolves.get(i).activityInfo; 3661 } 3662 if (debug) { 3663 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3664 + "/" + r.info.name); 3665 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3666 + "/" + aInfo.name); 3667 } 3668 break; 3669 } 3670 } 3671 } catch (RemoteException e) { 3672 } 3673 3674 if (aInfo == null) { 3675 // Nobody who is next! 3676 ActivityOptions.abort(options); 3677 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3678 return false; 3679 } 3680 3681 intent.setComponent(new ComponentName( 3682 aInfo.applicationInfo.packageName, aInfo.name)); 3683 intent.setFlags(intent.getFlags()&~( 3684 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3685 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3686 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3687 Intent.FLAG_ACTIVITY_NEW_TASK)); 3688 3689 // Okay now we need to start the new activity, replacing the 3690 // currently running activity. This is a little tricky because 3691 // we want to start the new one as if the current one is finished, 3692 // but not finish the current one first so that there is no flicker. 3693 // And thus... 3694 final boolean wasFinishing = r.finishing; 3695 r.finishing = true; 3696 3697 // Propagate reply information over to the new activity. 3698 final ActivityRecord resultTo = r.resultTo; 3699 final String resultWho = r.resultWho; 3700 final int requestCode = r.requestCode; 3701 r.resultTo = null; 3702 if (resultTo != null) { 3703 resultTo.removeResultsLocked(r, resultWho, requestCode); 3704 } 3705 3706 final long origId = Binder.clearCallingIdentity(); 3707 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3708 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3709 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3710 options, false, null, null, null); 3711 Binder.restoreCallingIdentity(origId); 3712 3713 r.finishing = wasFinishing; 3714 if (res != ActivityManager.START_SUCCESS) { 3715 return false; 3716 } 3717 return true; 3718 } 3719 } 3720 3721 @Override 3722 public final int startActivityFromRecents(int taskId, Bundle options) { 3723 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3724 String msg = "Permission Denial: startActivityFromRecents called without " + 3725 START_TASKS_FROM_RECENTS; 3726 Slog.w(TAG, msg); 3727 throw new SecurityException(msg); 3728 } 3729 return startActivityFromRecentsInner(taskId, options); 3730 } 3731 3732 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3733 final TaskRecord task; 3734 final int callingUid; 3735 final String callingPackage; 3736 final Intent intent; 3737 final int userId; 3738 synchronized (this) { 3739 task = recentTaskForIdLocked(taskId); 3740 if (task == null) { 3741 throw new IllegalArgumentException("Task " + taskId + " not found."); 3742 } 3743 callingUid = task.mCallingUid; 3744 callingPackage = task.mCallingPackage; 3745 intent = task.intent; 3746 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3747 userId = task.userId; 3748 } 3749 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3750 options, userId, null, task); 3751 } 3752 3753 final int startActivityInPackage(int uid, String callingPackage, 3754 Intent intent, String resolvedType, IBinder resultTo, 3755 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3756 IActivityContainer container, TaskRecord inTask) { 3757 3758 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3759 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3760 3761 // TODO: Switch to user app stacks here. 3762 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3763 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3764 null, null, null, options, userId, container, inTask); 3765 return ret; 3766 } 3767 3768 @Override 3769 public final int startActivities(IApplicationThread caller, String callingPackage, 3770 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3771 int userId) { 3772 enforceNotIsolatedCaller("startActivities"); 3773 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3774 false, ALLOW_FULL_ONLY, "startActivity", null); 3775 // TODO: Switch to user app stacks here. 3776 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3777 resolvedTypes, resultTo, options, userId); 3778 return ret; 3779 } 3780 3781 final int startActivitiesInPackage(int uid, String callingPackage, 3782 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3783 Bundle options, int userId) { 3784 3785 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3786 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3787 // TODO: Switch to user app stacks here. 3788 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3789 resultTo, options, userId); 3790 return ret; 3791 } 3792 3793 //explicitly remove thd old information in mRecentTasks when removing existing user. 3794 private void removeRecentTasksForUserLocked(int userId) { 3795 if(userId <= 0) { 3796 Slog.i(TAG, "Can't remove recent task on user " + userId); 3797 return; 3798 } 3799 3800 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3801 TaskRecord tr = mRecentTasks.get(i); 3802 if (tr.userId == userId) { 3803 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3804 + " when finishing user" + userId); 3805 mRecentTasks.remove(i); 3806 tr.removedFromRecents(mTaskPersister); 3807 } 3808 } 3809 3810 // Remove tasks from persistent storage. 3811 mTaskPersister.wakeup(null, true); 3812 } 3813 3814 /** 3815 * Update the recent tasks lists: make sure tasks should still be here (their 3816 * applications / activities still exist), update their availability, fixup ordering 3817 * of affiliations. 3818 */ 3819 void cleanupRecentTasksLocked(int userId) { 3820 if (mRecentTasks == null) { 3821 // Happens when called from the packagemanager broadcast before boot. 3822 return; 3823 } 3824 3825 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3826 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3827 final IPackageManager pm = AppGlobals.getPackageManager(); 3828 final ActivityInfo dummyAct = new ActivityInfo(); 3829 final ApplicationInfo dummyApp = new ApplicationInfo(); 3830 3831 int N = mRecentTasks.size(); 3832 3833 int[] users = userId == UserHandle.USER_ALL 3834 ? getUsersLocked() : new int[] { userId }; 3835 for (int user : users) { 3836 for (int i = 0; i < N; i++) { 3837 TaskRecord task = mRecentTasks.get(i); 3838 if (task.userId != user) { 3839 // Only look at tasks for the user ID of interest. 3840 continue; 3841 } 3842 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3843 // This situation is broken, and we should just get rid of it now. 3844 mRecentTasks.remove(i); 3845 task.removedFromRecents(mTaskPersister); 3846 i--; 3847 N--; 3848 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3849 continue; 3850 } 3851 // Check whether this activity is currently available. 3852 if (task.realActivity != null) { 3853 ActivityInfo ai = availActCache.get(task.realActivity); 3854 if (ai == null) { 3855 try { 3856 ai = pm.getActivityInfo(task.realActivity, 3857 PackageManager.GET_UNINSTALLED_PACKAGES 3858 | PackageManager.GET_DISABLED_COMPONENTS, user); 3859 } catch (RemoteException e) { 3860 // Will never happen. 3861 continue; 3862 } 3863 if (ai == null) { 3864 ai = dummyAct; 3865 } 3866 availActCache.put(task.realActivity, ai); 3867 } 3868 if (ai == dummyAct) { 3869 // This could be either because the activity no longer exists, or the 3870 // app is temporarily gone. For the former we want to remove the recents 3871 // entry; for the latter we want to mark it as unavailable. 3872 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3873 if (app == null) { 3874 try { 3875 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3876 PackageManager.GET_UNINSTALLED_PACKAGES 3877 | PackageManager.GET_DISABLED_COMPONENTS, user); 3878 } catch (RemoteException e) { 3879 // Will never happen. 3880 continue; 3881 } 3882 if (app == null) { 3883 app = dummyApp; 3884 } 3885 availAppCache.put(task.realActivity.getPackageName(), app); 3886 } 3887 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3888 // Doesn't exist any more! Good-bye. 3889 mRecentTasks.remove(i); 3890 task.removedFromRecents(mTaskPersister); 3891 i--; 3892 N--; 3893 Slog.w(TAG, "Removing no longer valid recent: " + task); 3894 continue; 3895 } else { 3896 // Otherwise just not available for now. 3897 if (task.isAvailable) { 3898 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3899 + task); 3900 } 3901 task.isAvailable = false; 3902 } 3903 } else { 3904 if (!ai.enabled || !ai.applicationInfo.enabled 3905 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3906 if (task.isAvailable) { 3907 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3908 + task + " (enabled=" + ai.enabled + "/" 3909 + ai.applicationInfo.enabled + " flags=" 3910 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3911 } 3912 task.isAvailable = false; 3913 } else { 3914 if (!task.isAvailable) { 3915 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3916 + task); 3917 } 3918 task.isAvailable = true; 3919 } 3920 } 3921 } 3922 } 3923 } 3924 3925 // Verify the affiliate chain for each task. 3926 for (int i = 0; i < N; ) { 3927 TaskRecord task = mRecentTasks.remove(i); 3928 if (mTmpRecents.contains(task)) { 3929 continue; 3930 } 3931 int affiliatedTaskId = task.mAffiliatedTaskId; 3932 while (true) { 3933 TaskRecord next = task.mNextAffiliate; 3934 if (next == null) { 3935 break; 3936 } 3937 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3938 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3939 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3940 task.setNextAffiliate(null); 3941 if (next.mPrevAffiliate == task) { 3942 next.setPrevAffiliate(null); 3943 } 3944 break; 3945 } 3946 if (next.mPrevAffiliate != task) { 3947 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3948 next.mPrevAffiliate + " task=" + task); 3949 next.setPrevAffiliate(null); 3950 task.setNextAffiliate(null); 3951 break; 3952 } 3953 if (!mRecentTasks.contains(next)) { 3954 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3955 task.setNextAffiliate(null); 3956 // We know that next.mPrevAffiliate is always task, from above, so clear 3957 // its previous affiliate. 3958 next.setPrevAffiliate(null); 3959 break; 3960 } 3961 task = next; 3962 } 3963 // task is now the end of the list 3964 do { 3965 mRecentTasks.remove(task); 3966 mRecentTasks.add(i++, task); 3967 mTmpRecents.add(task); 3968 task.inRecents = true; 3969 } while ((task = task.mPrevAffiliate) != null); 3970 } 3971 mTmpRecents.clear(); 3972 // mRecentTasks is now in sorted, affiliated order. 3973 } 3974 3975 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3976 int N = mRecentTasks.size(); 3977 TaskRecord top = task; 3978 int topIndex = taskIndex; 3979 while (top.mNextAffiliate != null && topIndex > 0) { 3980 top = top.mNextAffiliate; 3981 topIndex--; 3982 } 3983 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3984 + topIndex + " from intial " + taskIndex); 3985 // Find the end of the chain, doing a sanity check along the way. 3986 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3987 int endIndex = topIndex; 3988 TaskRecord prev = top; 3989 while (endIndex < N) { 3990 TaskRecord cur = mRecentTasks.get(endIndex); 3991 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3992 + endIndex + " " + cur); 3993 if (cur == top) { 3994 // Verify start of the chain. 3995 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3996 Slog.wtf(TAG, "Bad chain @" + endIndex 3997 + ": first task has next affiliate: " + prev); 3998 sane = false; 3999 break; 4000 } 4001 } else { 4002 // Verify middle of the chain's next points back to the one before. 4003 if (cur.mNextAffiliate != prev 4004 || cur.mNextAffiliateTaskId != prev.taskId) { 4005 Slog.wtf(TAG, "Bad chain @" + endIndex 4006 + ": middle task " + cur + " @" + endIndex 4007 + " has bad next affiliate " 4008 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4009 + ", expected " + prev); 4010 sane = false; 4011 break; 4012 } 4013 } 4014 if (cur.mPrevAffiliateTaskId == -1) { 4015 // Chain ends here. 4016 if (cur.mPrevAffiliate != null) { 4017 Slog.wtf(TAG, "Bad chain @" + endIndex 4018 + ": last task " + cur + " has previous affiliate " 4019 + cur.mPrevAffiliate); 4020 sane = false; 4021 } 4022 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4023 break; 4024 } else { 4025 // Verify middle of the chain's prev points to a valid item. 4026 if (cur.mPrevAffiliate == null) { 4027 Slog.wtf(TAG, "Bad chain @" + endIndex 4028 + ": task " + cur + " has previous affiliate " 4029 + cur.mPrevAffiliate + " but should be id " 4030 + cur.mPrevAffiliate); 4031 sane = false; 4032 break; 4033 } 4034 } 4035 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4036 Slog.wtf(TAG, "Bad chain @" + endIndex 4037 + ": task " + cur + " has affiliated id " 4038 + cur.mAffiliatedTaskId + " but should be " 4039 + task.mAffiliatedTaskId); 4040 sane = false; 4041 break; 4042 } 4043 prev = cur; 4044 endIndex++; 4045 if (endIndex >= N) { 4046 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4047 + ": last task " + prev); 4048 sane = false; 4049 break; 4050 } 4051 } 4052 if (sane) { 4053 if (endIndex < taskIndex) { 4054 Slog.wtf(TAG, "Bad chain @" + endIndex 4055 + ": did not extend to task " + task + " @" + taskIndex); 4056 sane = false; 4057 } 4058 } 4059 if (sane) { 4060 // All looks good, we can just move all of the affiliated tasks 4061 // to the top. 4062 for (int i=topIndex; i<=endIndex; i++) { 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4064 + " from " + i + " to " + (i-topIndex)); 4065 TaskRecord cur = mRecentTasks.remove(i); 4066 mRecentTasks.add(i-topIndex, cur); 4067 } 4068 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4069 + " to " + endIndex); 4070 return true; 4071 } 4072 4073 // Whoops, couldn't do it. 4074 return false; 4075 } 4076 4077 final void addRecentTaskLocked(TaskRecord task) { 4078 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4079 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4080 4081 int N = mRecentTasks.size(); 4082 // Quick case: check if the top-most recent task is the same. 4083 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4084 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4085 return; 4086 } 4087 // Another quick case: check if this is part of a set of affiliated 4088 // tasks that are at the top. 4089 if (isAffiliated && N > 0 && task.inRecents 4090 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4091 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4092 + " at top when adding " + task); 4093 return; 4094 } 4095 // Another quick case: never add voice sessions. 4096 if (task.voiceSession != null) { 4097 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4098 return; 4099 } 4100 4101 boolean needAffiliationFix = false; 4102 4103 // Slightly less quick case: the task is already in recents, so all we need 4104 // to do is move it. 4105 if (task.inRecents) { 4106 int taskIndex = mRecentTasks.indexOf(task); 4107 if (taskIndex >= 0) { 4108 if (!isAffiliated) { 4109 // Simple case: this is not an affiliated task, so we just move it to the front. 4110 mRecentTasks.remove(taskIndex); 4111 mRecentTasks.add(0, task); 4112 notifyTaskPersisterLocked(task, false); 4113 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4114 + " from " + taskIndex); 4115 return; 4116 } else { 4117 // More complicated: need to keep all affiliated tasks together. 4118 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4119 // All went well. 4120 return; 4121 } 4122 4123 // Uh oh... something bad in the affiliation chain, try to rebuild 4124 // everything and then go through our general path of adding a new task. 4125 needAffiliationFix = true; 4126 } 4127 } else { 4128 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4129 needAffiliationFix = true; 4130 } 4131 } 4132 4133 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4134 trimRecentsForTask(task, true); 4135 4136 N = mRecentTasks.size(); 4137 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4138 final TaskRecord tr = mRecentTasks.remove(N - 1); 4139 tr.removedFromRecents(mTaskPersister); 4140 N--; 4141 } 4142 task.inRecents = true; 4143 if (!isAffiliated || needAffiliationFix) { 4144 // If this is a simple non-affiliated task, or we had some failure trying to 4145 // handle it as part of an affilated task, then just place it at the top. 4146 mRecentTasks.add(0, task); 4147 } else if (isAffiliated) { 4148 // If this is a new affiliated task, then move all of the affiliated tasks 4149 // to the front and insert this new one. 4150 TaskRecord other = task.mNextAffiliate; 4151 if (other == null) { 4152 other = task.mPrevAffiliate; 4153 } 4154 if (other != null) { 4155 int otherIndex = mRecentTasks.indexOf(other); 4156 if (otherIndex >= 0) { 4157 // Insert new task at appropriate location. 4158 int taskIndex; 4159 if (other == task.mNextAffiliate) { 4160 // We found the index of our next affiliation, which is who is 4161 // before us in the list, so add after that point. 4162 taskIndex = otherIndex+1; 4163 } else { 4164 // We found the index of our previous affiliation, which is who is 4165 // after us in the list, so add at their position. 4166 taskIndex = otherIndex; 4167 } 4168 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4169 + taskIndex + ": " + task); 4170 mRecentTasks.add(taskIndex, task); 4171 4172 // Now move everything to the front. 4173 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4174 // All went well. 4175 return; 4176 } 4177 4178 // Uh oh... something bad in the affiliation chain, try to rebuild 4179 // everything and then go through our general path of adding a new task. 4180 needAffiliationFix = true; 4181 } else { 4182 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4183 + other); 4184 needAffiliationFix = true; 4185 } 4186 } else { 4187 if (DEBUG_RECENTS) Slog.d(TAG, 4188 "addRecent: adding affiliated task without next/prev:" + task); 4189 needAffiliationFix = true; 4190 } 4191 } 4192 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4193 4194 if (needAffiliationFix) { 4195 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4196 cleanupRecentTasksLocked(task.userId); 4197 } 4198 } 4199 4200 /** 4201 * If needed, remove oldest existing entries in recents that are for the same kind 4202 * of task as the given one. 4203 */ 4204 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4205 int N = mRecentTasks.size(); 4206 final Intent intent = task.intent; 4207 final boolean document = intent != null && intent.isDocument(); 4208 4209 int maxRecents = task.maxRecents - 1; 4210 for (int i=0; i<N; i++) { 4211 final TaskRecord tr = mRecentTasks.get(i); 4212 if (task != tr) { 4213 if (task.userId != tr.userId) { 4214 continue; 4215 } 4216 if (i > MAX_RECENT_BITMAPS) { 4217 tr.freeLastThumbnail(); 4218 } 4219 final Intent trIntent = tr.intent; 4220 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4221 (intent == null || !intent.filterEquals(trIntent))) { 4222 continue; 4223 } 4224 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4225 if (document && trIsDocument) { 4226 // These are the same document activity (not necessarily the same doc). 4227 if (maxRecents > 0) { 4228 --maxRecents; 4229 continue; 4230 } 4231 // Hit the maximum number of documents for this task. Fall through 4232 // and remove this document from recents. 4233 } else if (document || trIsDocument) { 4234 // Only one of these is a document. Not the droid we're looking for. 4235 continue; 4236 } 4237 } 4238 4239 if (!doTrim) { 4240 // If the caller is not actually asking for a trim, just tell them we reached 4241 // a point where the trim would happen. 4242 return i; 4243 } 4244 4245 // Either task and tr are the same or, their affinities match or their intents match 4246 // and neither of them is a document, or they are documents using the same activity 4247 // and their maxRecents has been reached. 4248 tr.disposeThumbnail(); 4249 mRecentTasks.remove(i); 4250 if (task != tr) { 4251 tr.removedFromRecents(mTaskPersister); 4252 } 4253 i--; 4254 N--; 4255 if (task.intent == null) { 4256 // If the new recent task we are adding is not fully 4257 // specified, then replace it with the existing recent task. 4258 task = tr; 4259 } 4260 notifyTaskPersisterLocked(tr, false); 4261 } 4262 4263 return -1; 4264 } 4265 4266 @Override 4267 public void reportActivityFullyDrawn(IBinder token) { 4268 synchronized (this) { 4269 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4270 if (r == null) { 4271 return; 4272 } 4273 r.reportFullyDrawnLocked(); 4274 } 4275 } 4276 4277 @Override 4278 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4279 synchronized (this) { 4280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4281 if (r == null) { 4282 return; 4283 } 4284 final long origId = Binder.clearCallingIdentity(); 4285 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4286 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4287 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4288 if (config != null) { 4289 r.frozenBeforeDestroy = true; 4290 if (!updateConfigurationLocked(config, r, false, false)) { 4291 mStackSupervisor.resumeTopActivitiesLocked(); 4292 } 4293 } 4294 Binder.restoreCallingIdentity(origId); 4295 } 4296 } 4297 4298 @Override 4299 public int getRequestedOrientation(IBinder token) { 4300 synchronized (this) { 4301 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4302 if (r == null) { 4303 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4304 } 4305 return mWindowManager.getAppOrientation(r.appToken); 4306 } 4307 } 4308 4309 /** 4310 * This is the internal entry point for handling Activity.finish(). 4311 * 4312 * @param token The Binder token referencing the Activity we want to finish. 4313 * @param resultCode Result code, if any, from this Activity. 4314 * @param resultData Result data (Intent), if any, from this Activity. 4315 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4316 * the root Activity in the task. 4317 * 4318 * @return Returns true if the activity successfully finished, or false if it is still running. 4319 */ 4320 @Override 4321 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4322 boolean finishTask) { 4323 // Refuse possible leaked file descriptors 4324 if (resultData != null && resultData.hasFileDescriptors() == true) { 4325 throw new IllegalArgumentException("File descriptors passed in Intent"); 4326 } 4327 4328 synchronized(this) { 4329 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4330 if (r == null) { 4331 return true; 4332 } 4333 // Keep track of the root activity of the task before we finish it 4334 TaskRecord tr = r.task; 4335 ActivityRecord rootR = tr.getRootActivity(); 4336 // Do not allow task to finish in Lock Task mode. 4337 if (tr == mStackSupervisor.mLockTaskModeTask) { 4338 if (rootR == r) { 4339 mStackSupervisor.showLockTaskToast(); 4340 return false; 4341 } 4342 } 4343 if (mController != null) { 4344 // Find the first activity that is not finishing. 4345 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4346 if (next != null) { 4347 // ask watcher if this is allowed 4348 boolean resumeOK = true; 4349 try { 4350 resumeOK = mController.activityResuming(next.packageName); 4351 } catch (RemoteException e) { 4352 mController = null; 4353 Watchdog.getInstance().setActivityController(null); 4354 } 4355 4356 if (!resumeOK) { 4357 return false; 4358 } 4359 } 4360 } 4361 final long origId = Binder.clearCallingIdentity(); 4362 try { 4363 boolean res; 4364 if (finishTask && r == rootR) { 4365 // If requested, remove the task that is associated to this activity only if it 4366 // was the root activity in the task. The result code and data is ignored because 4367 // we don't support returning them across task boundaries. 4368 res = removeTaskByIdLocked(tr.taskId, 0); 4369 } else { 4370 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4371 resultData, "app-request", true); 4372 } 4373 return res; 4374 } finally { 4375 Binder.restoreCallingIdentity(origId); 4376 } 4377 } 4378 } 4379 4380 @Override 4381 public final void finishHeavyWeightApp() { 4382 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4383 != PackageManager.PERMISSION_GRANTED) { 4384 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4385 + Binder.getCallingPid() 4386 + ", uid=" + Binder.getCallingUid() 4387 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4388 Slog.w(TAG, msg); 4389 throw new SecurityException(msg); 4390 } 4391 4392 synchronized(this) { 4393 if (mHeavyWeightProcess == null) { 4394 return; 4395 } 4396 4397 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4398 mHeavyWeightProcess.activities); 4399 for (int i=0; i<activities.size(); i++) { 4400 ActivityRecord r = activities.get(i); 4401 if (!r.finishing) { 4402 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4403 null, "finish-heavy", true); 4404 } 4405 } 4406 4407 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4408 mHeavyWeightProcess.userId, 0)); 4409 mHeavyWeightProcess = null; 4410 } 4411 } 4412 4413 @Override 4414 public void crashApplication(int uid, int initialPid, String packageName, 4415 String message) { 4416 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4417 != PackageManager.PERMISSION_GRANTED) { 4418 String msg = "Permission Denial: crashApplication() from pid=" 4419 + Binder.getCallingPid() 4420 + ", uid=" + Binder.getCallingUid() 4421 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4422 Slog.w(TAG, msg); 4423 throw new SecurityException(msg); 4424 } 4425 4426 synchronized(this) { 4427 ProcessRecord proc = null; 4428 4429 // Figure out which process to kill. We don't trust that initialPid 4430 // still has any relation to current pids, so must scan through the 4431 // list. 4432 synchronized (mPidsSelfLocked) { 4433 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4434 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4435 if (p.uid != uid) { 4436 continue; 4437 } 4438 if (p.pid == initialPid) { 4439 proc = p; 4440 break; 4441 } 4442 if (p.pkgList.containsKey(packageName)) { 4443 proc = p; 4444 } 4445 } 4446 } 4447 4448 if (proc == null) { 4449 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4450 + " initialPid=" + initialPid 4451 + " packageName=" + packageName); 4452 return; 4453 } 4454 4455 if (proc.thread != null) { 4456 if (proc.pid == Process.myPid()) { 4457 Log.w(TAG, "crashApplication: trying to crash self!"); 4458 return; 4459 } 4460 long ident = Binder.clearCallingIdentity(); 4461 try { 4462 proc.thread.scheduleCrash(message); 4463 } catch (RemoteException e) { 4464 } 4465 Binder.restoreCallingIdentity(ident); 4466 } 4467 } 4468 } 4469 4470 @Override 4471 public final void finishSubActivity(IBinder token, String resultWho, 4472 int requestCode) { 4473 synchronized(this) { 4474 final long origId = Binder.clearCallingIdentity(); 4475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4476 if (r != null) { 4477 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4478 } 4479 Binder.restoreCallingIdentity(origId); 4480 } 4481 } 4482 4483 @Override 4484 public boolean finishActivityAffinity(IBinder token) { 4485 synchronized(this) { 4486 final long origId = Binder.clearCallingIdentity(); 4487 try { 4488 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4489 4490 ActivityRecord rootR = r.task.getRootActivity(); 4491 // Do not allow task to finish in Lock Task mode. 4492 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4493 if (rootR == r) { 4494 mStackSupervisor.showLockTaskToast(); 4495 return false; 4496 } 4497 } 4498 boolean res = false; 4499 if (r != null) { 4500 res = r.task.stack.finishActivityAffinityLocked(r); 4501 } 4502 return res; 4503 } finally { 4504 Binder.restoreCallingIdentity(origId); 4505 } 4506 } 4507 } 4508 4509 @Override 4510 public void finishVoiceTask(IVoiceInteractionSession session) { 4511 synchronized(this) { 4512 final long origId = Binder.clearCallingIdentity(); 4513 try { 4514 mStackSupervisor.finishVoiceTask(session); 4515 } finally { 4516 Binder.restoreCallingIdentity(origId); 4517 } 4518 } 4519 4520 } 4521 4522 @Override 4523 public boolean releaseActivityInstance(IBinder token) { 4524 synchronized(this) { 4525 final long origId = Binder.clearCallingIdentity(); 4526 try { 4527 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4528 if (r.task == null || r.task.stack == null) { 4529 return false; 4530 } 4531 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4532 } finally { 4533 Binder.restoreCallingIdentity(origId); 4534 } 4535 } 4536 } 4537 4538 @Override 4539 public void releaseSomeActivities(IApplicationThread appInt) { 4540 synchronized(this) { 4541 final long origId = Binder.clearCallingIdentity(); 4542 try { 4543 ProcessRecord app = getRecordForAppLocked(appInt); 4544 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4545 } finally { 4546 Binder.restoreCallingIdentity(origId); 4547 } 4548 } 4549 } 4550 4551 @Override 4552 public boolean willActivityBeVisible(IBinder token) { 4553 synchronized(this) { 4554 ActivityStack stack = ActivityRecord.getStackLocked(token); 4555 if (stack != null) { 4556 return stack.willActivityBeVisibleLocked(token); 4557 } 4558 return false; 4559 } 4560 } 4561 4562 @Override 4563 public void overridePendingTransition(IBinder token, String packageName, 4564 int enterAnim, int exitAnim) { 4565 synchronized(this) { 4566 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4567 if (self == null) { 4568 return; 4569 } 4570 4571 final long origId = Binder.clearCallingIdentity(); 4572 4573 if (self.state == ActivityState.RESUMED 4574 || self.state == ActivityState.PAUSING) { 4575 mWindowManager.overridePendingAppTransition(packageName, 4576 enterAnim, exitAnim, null); 4577 } 4578 4579 Binder.restoreCallingIdentity(origId); 4580 } 4581 } 4582 4583 /** 4584 * Main function for removing an existing process from the activity manager 4585 * as a result of that process going away. Clears out all connections 4586 * to the process. 4587 */ 4588 private final void handleAppDiedLocked(ProcessRecord app, 4589 boolean restarting, boolean allowRestart) { 4590 int pid = app.pid; 4591 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4592 if (!restarting) { 4593 removeLruProcessLocked(app); 4594 if (pid > 0) { 4595 ProcessList.remove(pid); 4596 } 4597 } 4598 4599 if (mProfileProc == app) { 4600 clearProfilerLocked(); 4601 } 4602 4603 // Remove this application's activities from active lists. 4604 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4605 4606 app.activities.clear(); 4607 4608 if (app.instrumentationClass != null) { 4609 Slog.w(TAG, "Crash of app " + app.processName 4610 + " running instrumentation " + app.instrumentationClass); 4611 Bundle info = new Bundle(); 4612 info.putString("shortMsg", "Process crashed."); 4613 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4614 } 4615 4616 if (!restarting) { 4617 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4618 // If there was nothing to resume, and we are not already 4619 // restarting this process, but there is a visible activity that 4620 // is hosted by the process... then make sure all visible 4621 // activities are running, taking care of restarting this 4622 // process. 4623 if (hasVisibleActivities) { 4624 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4625 } 4626 } 4627 } 4628 } 4629 4630 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4631 IBinder threadBinder = thread.asBinder(); 4632 // Find the application record. 4633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4634 ProcessRecord rec = mLruProcesses.get(i); 4635 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4636 return i; 4637 } 4638 } 4639 return -1; 4640 } 4641 4642 final ProcessRecord getRecordForAppLocked( 4643 IApplicationThread thread) { 4644 if (thread == null) { 4645 return null; 4646 } 4647 4648 int appIndex = getLRURecordIndexForAppLocked(thread); 4649 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4650 } 4651 4652 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4653 // If there are no longer any background processes running, 4654 // and the app that died was not running instrumentation, 4655 // then tell everyone we are now low on memory. 4656 boolean haveBg = false; 4657 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4658 ProcessRecord rec = mLruProcesses.get(i); 4659 if (rec.thread != null 4660 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4661 haveBg = true; 4662 break; 4663 } 4664 } 4665 4666 if (!haveBg) { 4667 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4668 if (doReport) { 4669 long now = SystemClock.uptimeMillis(); 4670 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4671 doReport = false; 4672 } else { 4673 mLastMemUsageReportTime = now; 4674 } 4675 } 4676 final ArrayList<ProcessMemInfo> memInfos 4677 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4678 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4679 long now = SystemClock.uptimeMillis(); 4680 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4681 ProcessRecord rec = mLruProcesses.get(i); 4682 if (rec == dyingProc || rec.thread == null) { 4683 continue; 4684 } 4685 if (doReport) { 4686 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4687 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4688 } 4689 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4690 // The low memory report is overriding any current 4691 // state for a GC request. Make sure to do 4692 // heavy/important/visible/foreground processes first. 4693 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4694 rec.lastRequestedGc = 0; 4695 } else { 4696 rec.lastRequestedGc = rec.lastLowMemory; 4697 } 4698 rec.reportLowMemory = true; 4699 rec.lastLowMemory = now; 4700 mProcessesToGc.remove(rec); 4701 addProcessToGcListLocked(rec); 4702 } 4703 } 4704 if (doReport) { 4705 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4706 mHandler.sendMessage(msg); 4707 } 4708 scheduleAppGcsLocked(); 4709 } 4710 } 4711 4712 final void appDiedLocked(ProcessRecord app) { 4713 appDiedLocked(app, app.pid, app.thread); 4714 } 4715 4716 final void appDiedLocked(ProcessRecord app, int pid, 4717 IApplicationThread thread) { 4718 4719 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4720 synchronized (stats) { 4721 stats.noteProcessDiedLocked(app.info.uid, pid); 4722 } 4723 4724 Process.killProcessGroup(app.info.uid, pid); 4725 4726 // Clean up already done if the process has been re-started. 4727 if (app.pid == pid && app.thread != null && 4728 app.thread.asBinder() == thread.asBinder()) { 4729 boolean doLowMem = app.instrumentationClass == null; 4730 boolean doOomAdj = doLowMem; 4731 if (!app.killedByAm) { 4732 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4733 + ") has died."); 4734 mAllowLowerMemLevel = true; 4735 } else { 4736 // Note that we always want to do oom adj to update our state with the 4737 // new number of procs. 4738 mAllowLowerMemLevel = false; 4739 doLowMem = false; 4740 } 4741 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4742 if (DEBUG_CLEANUP) Slog.v( 4743 TAG, "Dying app: " + app + ", pid: " + pid 4744 + ", thread: " + thread.asBinder()); 4745 handleAppDiedLocked(app, false, true); 4746 4747 if (doOomAdj) { 4748 updateOomAdjLocked(); 4749 } 4750 if (doLowMem) { 4751 doLowMemReportIfNeededLocked(app); 4752 } 4753 } else if (app.pid != pid) { 4754 // A new process has already been started. 4755 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4756 + ") has died and restarted (pid " + app.pid + ")."); 4757 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4758 } else if (DEBUG_PROCESSES) { 4759 Slog.d(TAG, "Received spurious death notification for thread " 4760 + thread.asBinder()); 4761 } 4762 } 4763 4764 /** 4765 * If a stack trace dump file is configured, dump process stack traces. 4766 * @param clearTraces causes the dump file to be erased prior to the new 4767 * traces being written, if true; when false, the new traces will be 4768 * appended to any existing file content. 4769 * @param firstPids of dalvik VM processes to dump stack traces for first 4770 * @param lastPids of dalvik VM processes to dump stack traces for last 4771 * @param nativeProcs optional list of native process names to dump stack crawls 4772 * @return file containing stack traces, or null if no dump file is configured 4773 */ 4774 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4775 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4776 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4777 if (tracesPath == null || tracesPath.length() == 0) { 4778 return null; 4779 } 4780 4781 File tracesFile = new File(tracesPath); 4782 try { 4783 File tracesDir = tracesFile.getParentFile(); 4784 if (!tracesDir.exists()) { 4785 tracesFile.mkdirs(); 4786 if (!SELinux.restorecon(tracesDir)) { 4787 return null; 4788 } 4789 } 4790 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4791 4792 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4793 tracesFile.createNewFile(); 4794 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4795 } catch (IOException e) { 4796 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4797 return null; 4798 } 4799 4800 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4801 return tracesFile; 4802 } 4803 4804 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4805 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4806 // Use a FileObserver to detect when traces finish writing. 4807 // The order of traces is considered important to maintain for legibility. 4808 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4809 @Override 4810 public synchronized void onEvent(int event, String path) { notify(); } 4811 }; 4812 4813 try { 4814 observer.startWatching(); 4815 4816 // First collect all of the stacks of the most important pids. 4817 if (firstPids != null) { 4818 try { 4819 int num = firstPids.size(); 4820 for (int i = 0; i < num; i++) { 4821 synchronized (observer) { 4822 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4823 observer.wait(200); // Wait for write-close, give up after 200msec 4824 } 4825 } 4826 } catch (InterruptedException e) { 4827 Log.wtf(TAG, e); 4828 } 4829 } 4830 4831 // Next collect the stacks of the native pids 4832 if (nativeProcs != null) { 4833 int[] pids = Process.getPidsForCommands(nativeProcs); 4834 if (pids != null) { 4835 for (int pid : pids) { 4836 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4837 } 4838 } 4839 } 4840 4841 // Lastly, measure CPU usage. 4842 if (processCpuTracker != null) { 4843 processCpuTracker.init(); 4844 System.gc(); 4845 processCpuTracker.update(); 4846 try { 4847 synchronized (processCpuTracker) { 4848 processCpuTracker.wait(500); // measure over 1/2 second. 4849 } 4850 } catch (InterruptedException e) { 4851 } 4852 processCpuTracker.update(); 4853 4854 // We'll take the stack crawls of just the top apps using CPU. 4855 final int N = processCpuTracker.countWorkingStats(); 4856 int numProcs = 0; 4857 for (int i=0; i<N && numProcs<5; i++) { 4858 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4859 if (lastPids.indexOfKey(stats.pid) >= 0) { 4860 numProcs++; 4861 try { 4862 synchronized (observer) { 4863 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4864 observer.wait(200); // Wait for write-close, give up after 200msec 4865 } 4866 } catch (InterruptedException e) { 4867 Log.wtf(TAG, e); 4868 } 4869 4870 } 4871 } 4872 } 4873 } finally { 4874 observer.stopWatching(); 4875 } 4876 } 4877 4878 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4879 if (true || IS_USER_BUILD) { 4880 return; 4881 } 4882 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4883 if (tracesPath == null || tracesPath.length() == 0) { 4884 return; 4885 } 4886 4887 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4888 StrictMode.allowThreadDiskWrites(); 4889 try { 4890 final File tracesFile = new File(tracesPath); 4891 final File tracesDir = tracesFile.getParentFile(); 4892 final File tracesTmp = new File(tracesDir, "__tmp__"); 4893 try { 4894 if (!tracesDir.exists()) { 4895 tracesFile.mkdirs(); 4896 if (!SELinux.restorecon(tracesDir.getPath())) { 4897 return; 4898 } 4899 } 4900 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4901 4902 if (tracesFile.exists()) { 4903 tracesTmp.delete(); 4904 tracesFile.renameTo(tracesTmp); 4905 } 4906 StringBuilder sb = new StringBuilder(); 4907 Time tobj = new Time(); 4908 tobj.set(System.currentTimeMillis()); 4909 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4910 sb.append(": "); 4911 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4912 sb.append(" since "); 4913 sb.append(msg); 4914 FileOutputStream fos = new FileOutputStream(tracesFile); 4915 fos.write(sb.toString().getBytes()); 4916 if (app == null) { 4917 fos.write("\n*** No application process!".getBytes()); 4918 } 4919 fos.close(); 4920 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4921 } catch (IOException e) { 4922 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4923 return; 4924 } 4925 4926 if (app != null) { 4927 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4928 firstPids.add(app.pid); 4929 dumpStackTraces(tracesPath, firstPids, null, null, null); 4930 } 4931 4932 File lastTracesFile = null; 4933 File curTracesFile = null; 4934 for (int i=9; i>=0; i--) { 4935 String name = String.format(Locale.US, "slow%02d.txt", i); 4936 curTracesFile = new File(tracesDir, name); 4937 if (curTracesFile.exists()) { 4938 if (lastTracesFile != null) { 4939 curTracesFile.renameTo(lastTracesFile); 4940 } else { 4941 curTracesFile.delete(); 4942 } 4943 } 4944 lastTracesFile = curTracesFile; 4945 } 4946 tracesFile.renameTo(curTracesFile); 4947 if (tracesTmp.exists()) { 4948 tracesTmp.renameTo(tracesFile); 4949 } 4950 } finally { 4951 StrictMode.setThreadPolicy(oldPolicy); 4952 } 4953 } 4954 4955 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4956 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4957 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4958 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4959 4960 if (mController != null) { 4961 try { 4962 // 0 == continue, -1 = kill process immediately 4963 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4964 if (res < 0 && app.pid != MY_PID) { 4965 app.kill("anr", true); 4966 } 4967 } catch (RemoteException e) { 4968 mController = null; 4969 Watchdog.getInstance().setActivityController(null); 4970 } 4971 } 4972 4973 long anrTime = SystemClock.uptimeMillis(); 4974 if (MONITOR_CPU_USAGE) { 4975 updateCpuStatsNow(); 4976 } 4977 4978 synchronized (this) { 4979 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4980 if (mShuttingDown) { 4981 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4982 return; 4983 } else if (app.notResponding) { 4984 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4985 return; 4986 } else if (app.crashing) { 4987 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4988 return; 4989 } 4990 4991 // In case we come through here for the same app before completing 4992 // this one, mark as anring now so we will bail out. 4993 app.notResponding = true; 4994 4995 // Log the ANR to the event log. 4996 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4997 app.processName, app.info.flags, annotation); 4998 4999 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5000 firstPids.add(app.pid); 5001 5002 int parentPid = app.pid; 5003 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5004 if (parentPid != app.pid) firstPids.add(parentPid); 5005 5006 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5007 5008 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5009 ProcessRecord r = mLruProcesses.get(i); 5010 if (r != null && r.thread != null) { 5011 int pid = r.pid; 5012 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5013 if (r.persistent) { 5014 firstPids.add(pid); 5015 } else { 5016 lastPids.put(pid, Boolean.TRUE); 5017 } 5018 } 5019 } 5020 } 5021 } 5022 5023 // Log the ANR to the main log. 5024 StringBuilder info = new StringBuilder(); 5025 info.setLength(0); 5026 info.append("ANR in ").append(app.processName); 5027 if (activity != null && activity.shortComponentName != null) { 5028 info.append(" (").append(activity.shortComponentName).append(")"); 5029 } 5030 info.append("\n"); 5031 info.append("PID: ").append(app.pid).append("\n"); 5032 if (annotation != null) { 5033 info.append("Reason: ").append(annotation).append("\n"); 5034 } 5035 if (parent != null && parent != activity) { 5036 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5037 } 5038 5039 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5040 5041 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5042 NATIVE_STACKS_OF_INTEREST); 5043 5044 String cpuInfo = null; 5045 if (MONITOR_CPU_USAGE) { 5046 updateCpuStatsNow(); 5047 synchronized (mProcessCpuThread) { 5048 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5049 } 5050 info.append(processCpuTracker.printCurrentLoad()); 5051 info.append(cpuInfo); 5052 } 5053 5054 info.append(processCpuTracker.printCurrentState(anrTime)); 5055 5056 Slog.e(TAG, info.toString()); 5057 if (tracesFile == null) { 5058 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5059 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5060 } 5061 5062 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5063 cpuInfo, tracesFile, null); 5064 5065 if (mController != null) { 5066 try { 5067 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5068 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5069 if (res != 0) { 5070 if (res < 0 && app.pid != MY_PID) { 5071 app.kill("anr", true); 5072 } else { 5073 synchronized (this) { 5074 mServices.scheduleServiceTimeoutLocked(app); 5075 } 5076 } 5077 return; 5078 } 5079 } catch (RemoteException e) { 5080 mController = null; 5081 Watchdog.getInstance().setActivityController(null); 5082 } 5083 } 5084 5085 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5086 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5087 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5088 5089 synchronized (this) { 5090 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5091 app.kill("bg anr", true); 5092 return; 5093 } 5094 5095 // Set the app's notResponding state, and look up the errorReportReceiver 5096 makeAppNotRespondingLocked(app, 5097 activity != null ? activity.shortComponentName : null, 5098 annotation != null ? "ANR " + annotation : "ANR", 5099 info.toString()); 5100 5101 // Bring up the infamous App Not Responding dialog 5102 Message msg = Message.obtain(); 5103 HashMap<String, Object> map = new HashMap<String, Object>(); 5104 msg.what = SHOW_NOT_RESPONDING_MSG; 5105 msg.obj = map; 5106 msg.arg1 = aboveSystem ? 1 : 0; 5107 map.put("app", app); 5108 if (activity != null) { 5109 map.put("activity", activity); 5110 } 5111 5112 mHandler.sendMessage(msg); 5113 } 5114 } 5115 5116 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5117 if (!mLaunchWarningShown) { 5118 mLaunchWarningShown = true; 5119 mHandler.post(new Runnable() { 5120 @Override 5121 public void run() { 5122 synchronized (ActivityManagerService.this) { 5123 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5124 d.show(); 5125 mHandler.postDelayed(new Runnable() { 5126 @Override 5127 public void run() { 5128 synchronized (ActivityManagerService.this) { 5129 d.dismiss(); 5130 mLaunchWarningShown = false; 5131 } 5132 } 5133 }, 4000); 5134 } 5135 } 5136 }); 5137 } 5138 } 5139 5140 @Override 5141 public boolean clearApplicationUserData(final String packageName, 5142 final IPackageDataObserver observer, int userId) { 5143 enforceNotIsolatedCaller("clearApplicationUserData"); 5144 int uid = Binder.getCallingUid(); 5145 int pid = Binder.getCallingPid(); 5146 userId = handleIncomingUser(pid, uid, 5147 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5148 long callingId = Binder.clearCallingIdentity(); 5149 try { 5150 IPackageManager pm = AppGlobals.getPackageManager(); 5151 int pkgUid = -1; 5152 synchronized(this) { 5153 try { 5154 pkgUid = pm.getPackageUid(packageName, userId); 5155 } catch (RemoteException e) { 5156 } 5157 if (pkgUid == -1) { 5158 Slog.w(TAG, "Invalid packageName: " + packageName); 5159 if (observer != null) { 5160 try { 5161 observer.onRemoveCompleted(packageName, false); 5162 } catch (RemoteException e) { 5163 Slog.i(TAG, "Observer no longer exists."); 5164 } 5165 } 5166 return false; 5167 } 5168 if (uid == pkgUid || checkComponentPermission( 5169 android.Manifest.permission.CLEAR_APP_USER_DATA, 5170 pid, uid, -1, true) 5171 == PackageManager.PERMISSION_GRANTED) { 5172 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5173 } else { 5174 throw new SecurityException("PID " + pid + " does not have permission " 5175 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5176 + " of package " + packageName); 5177 } 5178 5179 // Remove all tasks match the cleared application package and user 5180 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5181 final TaskRecord tr = mRecentTasks.get(i); 5182 final String taskPackageName = 5183 tr.getBaseIntent().getComponent().getPackageName(); 5184 if (tr.userId != userId) continue; 5185 if (!taskPackageName.equals(packageName)) continue; 5186 removeTaskByIdLocked(tr.taskId, 0); 5187 } 5188 } 5189 5190 try { 5191 // Clear application user data 5192 pm.clearApplicationUserData(packageName, observer, userId); 5193 5194 synchronized(this) { 5195 // Remove all permissions granted from/to this package 5196 removeUriPermissionsForPackageLocked(packageName, userId, true); 5197 } 5198 5199 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5200 Uri.fromParts("package", packageName, null)); 5201 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5202 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5203 null, null, 0, null, null, null, false, false, userId); 5204 } catch (RemoteException e) { 5205 } 5206 } finally { 5207 Binder.restoreCallingIdentity(callingId); 5208 } 5209 return true; 5210 } 5211 5212 @Override 5213 public void killBackgroundProcesses(final String packageName, int userId) { 5214 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5215 != PackageManager.PERMISSION_GRANTED && 5216 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5217 != PackageManager.PERMISSION_GRANTED) { 5218 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5219 + Binder.getCallingPid() 5220 + ", uid=" + Binder.getCallingUid() 5221 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5222 Slog.w(TAG, msg); 5223 throw new SecurityException(msg); 5224 } 5225 5226 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5227 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5228 long callingId = Binder.clearCallingIdentity(); 5229 try { 5230 IPackageManager pm = AppGlobals.getPackageManager(); 5231 synchronized(this) { 5232 int appId = -1; 5233 try { 5234 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5235 } catch (RemoteException e) { 5236 } 5237 if (appId == -1) { 5238 Slog.w(TAG, "Invalid packageName: " + packageName); 5239 return; 5240 } 5241 killPackageProcessesLocked(packageName, appId, userId, 5242 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5243 } 5244 } finally { 5245 Binder.restoreCallingIdentity(callingId); 5246 } 5247 } 5248 5249 @Override 5250 public void killAllBackgroundProcesses() { 5251 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5252 != PackageManager.PERMISSION_GRANTED) { 5253 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5254 + Binder.getCallingPid() 5255 + ", uid=" + Binder.getCallingUid() 5256 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5257 Slog.w(TAG, msg); 5258 throw new SecurityException(msg); 5259 } 5260 5261 long callingId = Binder.clearCallingIdentity(); 5262 try { 5263 synchronized(this) { 5264 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5265 final int NP = mProcessNames.getMap().size(); 5266 for (int ip=0; ip<NP; ip++) { 5267 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5268 final int NA = apps.size(); 5269 for (int ia=0; ia<NA; ia++) { 5270 ProcessRecord app = apps.valueAt(ia); 5271 if (app.persistent) { 5272 // we don't kill persistent processes 5273 continue; 5274 } 5275 if (app.removed) { 5276 procs.add(app); 5277 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5278 app.removed = true; 5279 procs.add(app); 5280 } 5281 } 5282 } 5283 5284 int N = procs.size(); 5285 for (int i=0; i<N; i++) { 5286 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5287 } 5288 mAllowLowerMemLevel = true; 5289 updateOomAdjLocked(); 5290 doLowMemReportIfNeededLocked(null); 5291 } 5292 } finally { 5293 Binder.restoreCallingIdentity(callingId); 5294 } 5295 } 5296 5297 @Override 5298 public void forceStopPackage(final String packageName, int userId) { 5299 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5300 != PackageManager.PERMISSION_GRANTED) { 5301 String msg = "Permission Denial: forceStopPackage() from pid=" 5302 + Binder.getCallingPid() 5303 + ", uid=" + Binder.getCallingUid() 5304 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5305 Slog.w(TAG, msg); 5306 throw new SecurityException(msg); 5307 } 5308 final int callingPid = Binder.getCallingPid(); 5309 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5310 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5311 long callingId = Binder.clearCallingIdentity(); 5312 try { 5313 IPackageManager pm = AppGlobals.getPackageManager(); 5314 synchronized(this) { 5315 int[] users = userId == UserHandle.USER_ALL 5316 ? getUsersLocked() : new int[] { userId }; 5317 for (int user : users) { 5318 int pkgUid = -1; 5319 try { 5320 pkgUid = pm.getPackageUid(packageName, user); 5321 } catch (RemoteException e) { 5322 } 5323 if (pkgUid == -1) { 5324 Slog.w(TAG, "Invalid packageName: " + packageName); 5325 continue; 5326 } 5327 try { 5328 pm.setPackageStoppedState(packageName, true, user); 5329 } catch (RemoteException e) { 5330 } catch (IllegalArgumentException e) { 5331 Slog.w(TAG, "Failed trying to unstop package " 5332 + packageName + ": " + e); 5333 } 5334 if (isUserRunningLocked(user, false)) { 5335 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5336 } 5337 } 5338 } 5339 } finally { 5340 Binder.restoreCallingIdentity(callingId); 5341 } 5342 } 5343 5344 @Override 5345 public void addPackageDependency(String packageName) { 5346 synchronized (this) { 5347 int callingPid = Binder.getCallingPid(); 5348 if (callingPid == Process.myPid()) { 5349 // Yeah, um, no. 5350 Slog.w(TAG, "Can't addPackageDependency on system process"); 5351 return; 5352 } 5353 ProcessRecord proc; 5354 synchronized (mPidsSelfLocked) { 5355 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5356 } 5357 if (proc != null) { 5358 if (proc.pkgDeps == null) { 5359 proc.pkgDeps = new ArraySet<String>(1); 5360 } 5361 proc.pkgDeps.add(packageName); 5362 } 5363 } 5364 } 5365 5366 /* 5367 * The pkg name and app id have to be specified. 5368 */ 5369 @Override 5370 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5371 if (pkg == null) { 5372 return; 5373 } 5374 // Make sure the uid is valid. 5375 if (appid < 0) { 5376 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5377 return; 5378 } 5379 int callerUid = Binder.getCallingUid(); 5380 // Only the system server can kill an application 5381 if (callerUid == Process.SYSTEM_UID) { 5382 // Post an aysnc message to kill the application 5383 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5384 msg.arg1 = appid; 5385 msg.arg2 = 0; 5386 Bundle bundle = new Bundle(); 5387 bundle.putString("pkg", pkg); 5388 bundle.putString("reason", reason); 5389 msg.obj = bundle; 5390 mHandler.sendMessage(msg); 5391 } else { 5392 throw new SecurityException(callerUid + " cannot kill pkg: " + 5393 pkg); 5394 } 5395 } 5396 5397 @Override 5398 public void closeSystemDialogs(String reason) { 5399 enforceNotIsolatedCaller("closeSystemDialogs"); 5400 5401 final int pid = Binder.getCallingPid(); 5402 final int uid = Binder.getCallingUid(); 5403 final long origId = Binder.clearCallingIdentity(); 5404 try { 5405 synchronized (this) { 5406 // Only allow this from foreground processes, so that background 5407 // applications can't abuse it to prevent system UI from being shown. 5408 if (uid >= Process.FIRST_APPLICATION_UID) { 5409 ProcessRecord proc; 5410 synchronized (mPidsSelfLocked) { 5411 proc = mPidsSelfLocked.get(pid); 5412 } 5413 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5414 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5415 + " from background process " + proc); 5416 return; 5417 } 5418 } 5419 closeSystemDialogsLocked(reason); 5420 } 5421 } finally { 5422 Binder.restoreCallingIdentity(origId); 5423 } 5424 } 5425 5426 void closeSystemDialogsLocked(String reason) { 5427 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5428 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5429 | Intent.FLAG_RECEIVER_FOREGROUND); 5430 if (reason != null) { 5431 intent.putExtra("reason", reason); 5432 } 5433 mWindowManager.closeSystemDialogs(reason); 5434 5435 mStackSupervisor.closeSystemDialogsLocked(); 5436 5437 broadcastIntentLocked(null, null, intent, null, 5438 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5439 Process.SYSTEM_UID, UserHandle.USER_ALL); 5440 } 5441 5442 @Override 5443 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5444 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5445 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5446 for (int i=pids.length-1; i>=0; i--) { 5447 ProcessRecord proc; 5448 int oomAdj; 5449 synchronized (this) { 5450 synchronized (mPidsSelfLocked) { 5451 proc = mPidsSelfLocked.get(pids[i]); 5452 oomAdj = proc != null ? proc.setAdj : 0; 5453 } 5454 } 5455 infos[i] = new Debug.MemoryInfo(); 5456 Debug.getMemoryInfo(pids[i], infos[i]); 5457 if (proc != null) { 5458 synchronized (this) { 5459 if (proc.thread != null && proc.setAdj == oomAdj) { 5460 // Record this for posterity if the process has been stable. 5461 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5462 infos[i].getTotalUss(), false, proc.pkgList); 5463 } 5464 } 5465 } 5466 } 5467 return infos; 5468 } 5469 5470 @Override 5471 public long[] getProcessPss(int[] pids) { 5472 enforceNotIsolatedCaller("getProcessPss"); 5473 long[] pss = new long[pids.length]; 5474 for (int i=pids.length-1; i>=0; i--) { 5475 ProcessRecord proc; 5476 int oomAdj; 5477 synchronized (this) { 5478 synchronized (mPidsSelfLocked) { 5479 proc = mPidsSelfLocked.get(pids[i]); 5480 oomAdj = proc != null ? proc.setAdj : 0; 5481 } 5482 } 5483 long[] tmpUss = new long[1]; 5484 pss[i] = Debug.getPss(pids[i], tmpUss); 5485 if (proc != null) { 5486 synchronized (this) { 5487 if (proc.thread != null && proc.setAdj == oomAdj) { 5488 // Record this for posterity if the process has been stable. 5489 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5490 } 5491 } 5492 } 5493 } 5494 return pss; 5495 } 5496 5497 @Override 5498 public void killApplicationProcess(String processName, int uid) { 5499 if (processName == null) { 5500 return; 5501 } 5502 5503 int callerUid = Binder.getCallingUid(); 5504 // Only the system server can kill an application 5505 if (callerUid == Process.SYSTEM_UID) { 5506 synchronized (this) { 5507 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5508 if (app != null && app.thread != null) { 5509 try { 5510 app.thread.scheduleSuicide(); 5511 } catch (RemoteException e) { 5512 // If the other end already died, then our work here is done. 5513 } 5514 } else { 5515 Slog.w(TAG, "Process/uid not found attempting kill of " 5516 + processName + " / " + uid); 5517 } 5518 } 5519 } else { 5520 throw new SecurityException(callerUid + " cannot kill app process: " + 5521 processName); 5522 } 5523 } 5524 5525 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5526 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5527 false, true, false, false, UserHandle.getUserId(uid), reason); 5528 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5529 Uri.fromParts("package", packageName, null)); 5530 if (!mProcessesReady) { 5531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5532 | Intent.FLAG_RECEIVER_FOREGROUND); 5533 } 5534 intent.putExtra(Intent.EXTRA_UID, uid); 5535 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5536 broadcastIntentLocked(null, null, intent, 5537 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5538 false, false, 5539 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5540 } 5541 5542 private void forceStopUserLocked(int userId, String reason) { 5543 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5544 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5545 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5546 | Intent.FLAG_RECEIVER_FOREGROUND); 5547 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5548 broadcastIntentLocked(null, null, intent, 5549 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5550 false, false, 5551 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5552 } 5553 5554 private final boolean killPackageProcessesLocked(String packageName, int appId, 5555 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5556 boolean doit, boolean evenPersistent, String reason) { 5557 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5558 5559 // Remove all processes this package may have touched: all with the 5560 // same UID (except for the system or root user), and all whose name 5561 // matches the package name. 5562 final int NP = mProcessNames.getMap().size(); 5563 for (int ip=0; ip<NP; ip++) { 5564 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5565 final int NA = apps.size(); 5566 for (int ia=0; ia<NA; ia++) { 5567 ProcessRecord app = apps.valueAt(ia); 5568 if (app.persistent && !evenPersistent) { 5569 // we don't kill persistent processes 5570 continue; 5571 } 5572 if (app.removed) { 5573 if (doit) { 5574 procs.add(app); 5575 } 5576 continue; 5577 } 5578 5579 // Skip process if it doesn't meet our oom adj requirement. 5580 if (app.setAdj < minOomAdj) { 5581 continue; 5582 } 5583 5584 // If no package is specified, we call all processes under the 5585 // give user id. 5586 if (packageName == null) { 5587 if (app.userId != userId) { 5588 continue; 5589 } 5590 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5591 continue; 5592 } 5593 // Package has been specified, we want to hit all processes 5594 // that match it. We need to qualify this by the processes 5595 // that are running under the specified app and user ID. 5596 } else { 5597 final boolean isDep = app.pkgDeps != null 5598 && app.pkgDeps.contains(packageName); 5599 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5600 continue; 5601 } 5602 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5603 continue; 5604 } 5605 if (!app.pkgList.containsKey(packageName) && !isDep) { 5606 continue; 5607 } 5608 } 5609 5610 // Process has passed all conditions, kill it! 5611 if (!doit) { 5612 return true; 5613 } 5614 app.removed = true; 5615 procs.add(app); 5616 } 5617 } 5618 5619 int N = procs.size(); 5620 for (int i=0; i<N; i++) { 5621 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5622 } 5623 updateOomAdjLocked(); 5624 return N > 0; 5625 } 5626 5627 private final boolean forceStopPackageLocked(String name, int appId, 5628 boolean callerWillRestart, boolean purgeCache, boolean doit, 5629 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5630 int i; 5631 int N; 5632 5633 if (userId == UserHandle.USER_ALL && name == null) { 5634 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5635 } 5636 5637 if (appId < 0 && name != null) { 5638 try { 5639 appId = UserHandle.getAppId( 5640 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5641 } catch (RemoteException e) { 5642 } 5643 } 5644 5645 if (doit) { 5646 if (name != null) { 5647 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5648 + " user=" + userId + ": " + reason); 5649 } else { 5650 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5651 } 5652 5653 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5654 for (int ip=pmap.size()-1; ip>=0; ip--) { 5655 SparseArray<Long> ba = pmap.valueAt(ip); 5656 for (i=ba.size()-1; i>=0; i--) { 5657 boolean remove = false; 5658 final int entUid = ba.keyAt(i); 5659 if (name != null) { 5660 if (userId == UserHandle.USER_ALL) { 5661 if (UserHandle.getAppId(entUid) == appId) { 5662 remove = true; 5663 } 5664 } else { 5665 if (entUid == UserHandle.getUid(userId, appId)) { 5666 remove = true; 5667 } 5668 } 5669 } else if (UserHandle.getUserId(entUid) == userId) { 5670 remove = true; 5671 } 5672 if (remove) { 5673 ba.removeAt(i); 5674 } 5675 } 5676 if (ba.size() == 0) { 5677 pmap.removeAt(ip); 5678 } 5679 } 5680 } 5681 5682 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5683 -100, callerWillRestart, true, doit, evenPersistent, 5684 name == null ? ("stop user " + userId) : ("stop " + name)); 5685 5686 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5687 if (!doit) { 5688 return true; 5689 } 5690 didSomething = true; 5691 } 5692 5693 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5694 if (!doit) { 5695 return true; 5696 } 5697 didSomething = true; 5698 } 5699 5700 if (name == null) { 5701 // Remove all sticky broadcasts from this user. 5702 mStickyBroadcasts.remove(userId); 5703 } 5704 5705 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5706 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5707 userId, providers)) { 5708 if (!doit) { 5709 return true; 5710 } 5711 didSomething = true; 5712 } 5713 N = providers.size(); 5714 for (i=0; i<N; i++) { 5715 removeDyingProviderLocked(null, providers.get(i), true); 5716 } 5717 5718 // Remove transient permissions granted from/to this package/user 5719 removeUriPermissionsForPackageLocked(name, userId, false); 5720 5721 if (name == null || uninstalling) { 5722 // Remove pending intents. For now we only do this when force 5723 // stopping users, because we have some problems when doing this 5724 // for packages -- app widgets are not currently cleaned up for 5725 // such packages, so they can be left with bad pending intents. 5726 if (mIntentSenderRecords.size() > 0) { 5727 Iterator<WeakReference<PendingIntentRecord>> it 5728 = mIntentSenderRecords.values().iterator(); 5729 while (it.hasNext()) { 5730 WeakReference<PendingIntentRecord> wpir = it.next(); 5731 if (wpir == null) { 5732 it.remove(); 5733 continue; 5734 } 5735 PendingIntentRecord pir = wpir.get(); 5736 if (pir == null) { 5737 it.remove(); 5738 continue; 5739 } 5740 if (name == null) { 5741 // Stopping user, remove all objects for the user. 5742 if (pir.key.userId != userId) { 5743 // Not the same user, skip it. 5744 continue; 5745 } 5746 } else { 5747 if (UserHandle.getAppId(pir.uid) != appId) { 5748 // Different app id, skip it. 5749 continue; 5750 } 5751 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5752 // Different user, skip it. 5753 continue; 5754 } 5755 if (!pir.key.packageName.equals(name)) { 5756 // Different package, skip it. 5757 continue; 5758 } 5759 } 5760 if (!doit) { 5761 return true; 5762 } 5763 didSomething = true; 5764 it.remove(); 5765 pir.canceled = true; 5766 if (pir.key.activity != null) { 5767 pir.key.activity.pendingResults.remove(pir.ref); 5768 } 5769 } 5770 } 5771 } 5772 5773 if (doit) { 5774 if (purgeCache && name != null) { 5775 AttributeCache ac = AttributeCache.instance(); 5776 if (ac != null) { 5777 ac.removePackage(name); 5778 } 5779 } 5780 if (mBooted) { 5781 mStackSupervisor.resumeTopActivitiesLocked(); 5782 mStackSupervisor.scheduleIdleLocked(); 5783 } 5784 } 5785 5786 return didSomething; 5787 } 5788 5789 private final boolean removeProcessLocked(ProcessRecord app, 5790 boolean callerWillRestart, boolean allowRestart, String reason) { 5791 final String name = app.processName; 5792 final int uid = app.uid; 5793 if (DEBUG_PROCESSES) Slog.d( 5794 TAG, "Force removing proc " + app.toShortString() + " (" + name 5795 + "/" + uid + ")"); 5796 5797 mProcessNames.remove(name, uid); 5798 mIsolatedProcesses.remove(app.uid); 5799 if (mHeavyWeightProcess == app) { 5800 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5801 mHeavyWeightProcess.userId, 0)); 5802 mHeavyWeightProcess = null; 5803 } 5804 boolean needRestart = false; 5805 if (app.pid > 0 && app.pid != MY_PID) { 5806 int pid = app.pid; 5807 synchronized (mPidsSelfLocked) { 5808 mPidsSelfLocked.remove(pid); 5809 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5810 } 5811 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5812 if (app.isolated) { 5813 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5814 } 5815 app.kill(reason, true); 5816 handleAppDiedLocked(app, true, allowRestart); 5817 removeLruProcessLocked(app); 5818 5819 if (app.persistent && !app.isolated) { 5820 if (!callerWillRestart) { 5821 addAppLocked(app.info, false, null /* ABI override */); 5822 } else { 5823 needRestart = true; 5824 } 5825 } 5826 } else { 5827 mRemovedProcesses.add(app); 5828 } 5829 5830 return needRestart; 5831 } 5832 5833 private final void processStartTimedOutLocked(ProcessRecord app) { 5834 final int pid = app.pid; 5835 boolean gone = false; 5836 synchronized (mPidsSelfLocked) { 5837 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5838 if (knownApp != null && knownApp.thread == null) { 5839 mPidsSelfLocked.remove(pid); 5840 gone = true; 5841 } 5842 } 5843 5844 if (gone) { 5845 Slog.w(TAG, "Process " + app + " failed to attach"); 5846 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5847 pid, app.uid, app.processName); 5848 mProcessNames.remove(app.processName, app.uid); 5849 mIsolatedProcesses.remove(app.uid); 5850 if (mHeavyWeightProcess == app) { 5851 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5852 mHeavyWeightProcess.userId, 0)); 5853 mHeavyWeightProcess = null; 5854 } 5855 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5856 if (app.isolated) { 5857 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5858 } 5859 // Take care of any launching providers waiting for this process. 5860 checkAppInLaunchingProvidersLocked(app, true); 5861 // Take care of any services that are waiting for the process. 5862 mServices.processStartTimedOutLocked(app); 5863 app.kill("start timeout", true); 5864 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5865 Slog.w(TAG, "Unattached app died before backup, skipping"); 5866 try { 5867 IBackupManager bm = IBackupManager.Stub.asInterface( 5868 ServiceManager.getService(Context.BACKUP_SERVICE)); 5869 bm.agentDisconnected(app.info.packageName); 5870 } catch (RemoteException e) { 5871 // Can't happen; the backup manager is local 5872 } 5873 } 5874 if (isPendingBroadcastProcessLocked(pid)) { 5875 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5876 skipPendingBroadcastLocked(pid); 5877 } 5878 } else { 5879 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5880 } 5881 } 5882 5883 private final boolean attachApplicationLocked(IApplicationThread thread, 5884 int pid) { 5885 5886 // Find the application record that is being attached... either via 5887 // the pid if we are running in multiple processes, or just pull the 5888 // next app record if we are emulating process with anonymous threads. 5889 ProcessRecord app; 5890 if (pid != MY_PID && pid >= 0) { 5891 synchronized (mPidsSelfLocked) { 5892 app = mPidsSelfLocked.get(pid); 5893 } 5894 } else { 5895 app = null; 5896 } 5897 5898 if (app == null) { 5899 Slog.w(TAG, "No pending application record for pid " + pid 5900 + " (IApplicationThread " + thread + "); dropping process"); 5901 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5902 if (pid > 0 && pid != MY_PID) { 5903 Process.killProcessQuiet(pid); 5904 //TODO: Process.killProcessGroup(app.info.uid, pid); 5905 } else { 5906 try { 5907 thread.scheduleExit(); 5908 } catch (Exception e) { 5909 // Ignore exceptions. 5910 } 5911 } 5912 return false; 5913 } 5914 5915 // If this application record is still attached to a previous 5916 // process, clean it up now. 5917 if (app.thread != null) { 5918 handleAppDiedLocked(app, true, true); 5919 } 5920 5921 // Tell the process all about itself. 5922 5923 if (localLOGV) Slog.v( 5924 TAG, "Binding process pid " + pid + " to record " + app); 5925 5926 final String processName = app.processName; 5927 try { 5928 AppDeathRecipient adr = new AppDeathRecipient( 5929 app, pid, thread); 5930 thread.asBinder().linkToDeath(adr, 0); 5931 app.deathRecipient = adr; 5932 } catch (RemoteException e) { 5933 app.resetPackageList(mProcessStats); 5934 startProcessLocked(app, "link fail", processName); 5935 return false; 5936 } 5937 5938 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5939 5940 app.makeActive(thread, mProcessStats); 5941 app.curAdj = app.setAdj = -100; 5942 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5943 app.forcingToForeground = null; 5944 updateProcessForegroundLocked(app, false, false); 5945 app.hasShownUi = false; 5946 app.debugging = false; 5947 app.cached = false; 5948 5949 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5950 5951 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5952 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5953 5954 if (!normalMode) { 5955 Slog.i(TAG, "Launching preboot mode app: " + app); 5956 } 5957 5958 if (localLOGV) Slog.v( 5959 TAG, "New app record " + app 5960 + " thread=" + thread.asBinder() + " pid=" + pid); 5961 try { 5962 int testMode = IApplicationThread.DEBUG_OFF; 5963 if (mDebugApp != null && mDebugApp.equals(processName)) { 5964 testMode = mWaitForDebugger 5965 ? IApplicationThread.DEBUG_WAIT 5966 : IApplicationThread.DEBUG_ON; 5967 app.debugging = true; 5968 if (mDebugTransient) { 5969 mDebugApp = mOrigDebugApp; 5970 mWaitForDebugger = mOrigWaitForDebugger; 5971 } 5972 } 5973 String profileFile = app.instrumentationProfileFile; 5974 ParcelFileDescriptor profileFd = null; 5975 int samplingInterval = 0; 5976 boolean profileAutoStop = false; 5977 if (mProfileApp != null && mProfileApp.equals(processName)) { 5978 mProfileProc = app; 5979 profileFile = mProfileFile; 5980 profileFd = mProfileFd; 5981 samplingInterval = mSamplingInterval; 5982 profileAutoStop = mAutoStopProfiler; 5983 } 5984 boolean enableOpenGlTrace = false; 5985 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5986 enableOpenGlTrace = true; 5987 mOpenGlTraceApp = null; 5988 } 5989 5990 // If the app is being launched for restore or full backup, set it up specially 5991 boolean isRestrictedBackupMode = false; 5992 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5993 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5994 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5995 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5996 } 5997 5998 ensurePackageDexOpt(app.instrumentationInfo != null 5999 ? app.instrumentationInfo.packageName 6000 : app.info.packageName); 6001 if (app.instrumentationClass != null) { 6002 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6003 } 6004 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6005 + processName + " with config " + mConfiguration); 6006 ApplicationInfo appInfo = app.instrumentationInfo != null 6007 ? app.instrumentationInfo : app.info; 6008 app.compat = compatibilityInfoForPackageLocked(appInfo); 6009 if (profileFd != null) { 6010 profileFd = profileFd.dup(); 6011 } 6012 ProfilerInfo profilerInfo = profileFile == null ? null 6013 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6014 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6015 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6016 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6017 isRestrictedBackupMode || !normalMode, app.persistent, 6018 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6019 mCoreSettingsObserver.getCoreSettingsLocked()); 6020 updateLruProcessLocked(app, false, null); 6021 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6022 } catch (Exception e) { 6023 // todo: Yikes! What should we do? For now we will try to 6024 // start another process, but that could easily get us in 6025 // an infinite loop of restarting processes... 6026 Slog.w(TAG, "Exception thrown during bind!", e); 6027 6028 app.resetPackageList(mProcessStats); 6029 app.unlinkDeathRecipient(); 6030 startProcessLocked(app, "bind fail", processName); 6031 return false; 6032 } 6033 6034 // Remove this record from the list of starting applications. 6035 mPersistentStartingProcesses.remove(app); 6036 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6037 "Attach application locked removing on hold: " + app); 6038 mProcessesOnHold.remove(app); 6039 6040 boolean badApp = false; 6041 boolean didSomething = false; 6042 6043 // See if the top visible activity is waiting to run in this process... 6044 if (normalMode) { 6045 try { 6046 if (mStackSupervisor.attachApplicationLocked(app)) { 6047 didSomething = true; 6048 } 6049 } catch (Exception e) { 6050 badApp = true; 6051 } 6052 } 6053 6054 // Find any services that should be running in this process... 6055 if (!badApp) { 6056 try { 6057 didSomething |= mServices.attachApplicationLocked(app, processName); 6058 } catch (Exception e) { 6059 badApp = true; 6060 } 6061 } 6062 6063 // Check if a next-broadcast receiver is in this process... 6064 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6065 try { 6066 didSomething |= sendPendingBroadcastsLocked(app); 6067 } catch (Exception e) { 6068 // If the app died trying to launch the receiver we declare it 'bad' 6069 badApp = true; 6070 } 6071 } 6072 6073 // Check whether the next backup agent is in this process... 6074 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6075 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6076 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6077 try { 6078 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6079 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6080 mBackupTarget.backupMode); 6081 } catch (Exception e) { 6082 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6083 e.printStackTrace(); 6084 } 6085 } 6086 6087 if (badApp) { 6088 // todo: Also need to kill application to deal with all 6089 // kinds of exceptions. 6090 handleAppDiedLocked(app, false, true); 6091 return false; 6092 } 6093 6094 if (!didSomething) { 6095 updateOomAdjLocked(); 6096 } 6097 6098 return true; 6099 } 6100 6101 @Override 6102 public final void attachApplication(IApplicationThread thread) { 6103 synchronized (this) { 6104 int callingPid = Binder.getCallingPid(); 6105 final long origId = Binder.clearCallingIdentity(); 6106 attachApplicationLocked(thread, callingPid); 6107 Binder.restoreCallingIdentity(origId); 6108 } 6109 } 6110 6111 @Override 6112 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6113 final long origId = Binder.clearCallingIdentity(); 6114 synchronized (this) { 6115 ActivityStack stack = ActivityRecord.getStackLocked(token); 6116 if (stack != null) { 6117 ActivityRecord r = 6118 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6119 if (stopProfiling) { 6120 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6121 try { 6122 mProfileFd.close(); 6123 } catch (IOException e) { 6124 } 6125 clearProfilerLocked(); 6126 } 6127 } 6128 } 6129 } 6130 Binder.restoreCallingIdentity(origId); 6131 } 6132 6133 void postEnableScreenAfterBootLocked() { 6134 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6135 } 6136 6137 void enableScreenAfterBoot() { 6138 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6139 SystemClock.uptimeMillis()); 6140 mWindowManager.enableScreenAfterBoot(); 6141 6142 synchronized (this) { 6143 updateEventDispatchingLocked(); 6144 } 6145 } 6146 6147 @Override 6148 public void showBootMessage(final CharSequence msg, final boolean always) { 6149 enforceNotIsolatedCaller("showBootMessage"); 6150 mWindowManager.showBootMessage(msg, always); 6151 } 6152 6153 @Override 6154 public void keyguardWaitingForActivityDrawn() { 6155 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6156 final long token = Binder.clearCallingIdentity(); 6157 try { 6158 synchronized (this) { 6159 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6160 mWindowManager.keyguardWaitingForActivityDrawn(); 6161 } 6162 } finally { 6163 Binder.restoreCallingIdentity(token); 6164 } 6165 } 6166 6167 final void finishBooting() { 6168 // Register receivers to handle package update events 6169 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6170 6171 // Let system services know. 6172 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6173 6174 synchronized (this) { 6175 // Ensure that any processes we had put on hold are now started 6176 // up. 6177 final int NP = mProcessesOnHold.size(); 6178 if (NP > 0) { 6179 ArrayList<ProcessRecord> procs = 6180 new ArrayList<ProcessRecord>(mProcessesOnHold); 6181 for (int ip=0; ip<NP; ip++) { 6182 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6183 + procs.get(ip)); 6184 startProcessLocked(procs.get(ip), "on-hold", null); 6185 } 6186 } 6187 6188 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6189 // Start looking for apps that are abusing wake locks. 6190 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6191 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6192 // Tell anyone interested that we are done booting! 6193 SystemProperties.set("sys.boot_completed", "1"); 6194 SystemProperties.set("dev.bootcomplete", "1"); 6195 for (int i=0; i<mStartedUsers.size(); i++) { 6196 UserStartedState uss = mStartedUsers.valueAt(i); 6197 if (uss.mState == UserStartedState.STATE_BOOTING) { 6198 uss.mState = UserStartedState.STATE_RUNNING; 6199 final int userId = mStartedUsers.keyAt(i); 6200 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6201 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6202 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6203 broadcastIntentLocked(null, null, intent, null, 6204 new IIntentReceiver.Stub() { 6205 @Override 6206 public void performReceive(Intent intent, int resultCode, 6207 String data, Bundle extras, boolean ordered, 6208 boolean sticky, int sendingUser) { 6209 synchronized (ActivityManagerService.this) { 6210 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6211 true, false); 6212 } 6213 } 6214 }, 6215 0, null, null, 6216 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6217 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6218 userId); 6219 } 6220 } 6221 scheduleStartProfilesLocked(); 6222 } 6223 } 6224 } 6225 6226 final void ensureBootCompleted() { 6227 boolean booting; 6228 boolean enableScreen; 6229 synchronized (this) { 6230 booting = mBooting; 6231 mBooting = false; 6232 enableScreen = !mBooted; 6233 mBooted = true; 6234 } 6235 6236 if (booting) { 6237 finishBooting(); 6238 } 6239 6240 if (enableScreen) { 6241 enableScreenAfterBoot(); 6242 } 6243 } 6244 6245 @Override 6246 public final void activityResumed(IBinder token) { 6247 final long origId = Binder.clearCallingIdentity(); 6248 synchronized(this) { 6249 ActivityStack stack = ActivityRecord.getStackLocked(token); 6250 if (stack != null) { 6251 ActivityRecord.activityResumedLocked(token); 6252 } 6253 } 6254 Binder.restoreCallingIdentity(origId); 6255 } 6256 6257 @Override 6258 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6259 final long origId = Binder.clearCallingIdentity(); 6260 synchronized(this) { 6261 ActivityStack stack = ActivityRecord.getStackLocked(token); 6262 if (stack != null) { 6263 stack.activityPausedLocked(token, false, persistentState); 6264 } 6265 } 6266 Binder.restoreCallingIdentity(origId); 6267 } 6268 6269 @Override 6270 public final void activityStopped(IBinder token, Bundle icicle, 6271 PersistableBundle persistentState, CharSequence description) { 6272 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6273 6274 // Refuse possible leaked file descriptors 6275 if (icicle != null && icicle.hasFileDescriptors()) { 6276 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6277 } 6278 6279 final long origId = Binder.clearCallingIdentity(); 6280 6281 synchronized (this) { 6282 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6283 if (r != null) { 6284 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6285 } 6286 } 6287 6288 trimApplications(); 6289 6290 Binder.restoreCallingIdentity(origId); 6291 } 6292 6293 @Override 6294 public final void activityDestroyed(IBinder token) { 6295 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6296 synchronized (this) { 6297 ActivityStack stack = ActivityRecord.getStackLocked(token); 6298 if (stack != null) { 6299 stack.activityDestroyedLocked(token); 6300 } 6301 } 6302 } 6303 6304 @Override 6305 public final void backgroundResourcesReleased(IBinder token) { 6306 final long origId = Binder.clearCallingIdentity(); 6307 try { 6308 synchronized (this) { 6309 ActivityStack stack = ActivityRecord.getStackLocked(token); 6310 if (stack != null) { 6311 stack.backgroundResourcesReleased(token); 6312 } 6313 } 6314 } finally { 6315 Binder.restoreCallingIdentity(origId); 6316 } 6317 } 6318 6319 @Override 6320 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6321 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6322 } 6323 6324 @Override 6325 public final void notifyEnterAnimationComplete(IBinder token) { 6326 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6327 } 6328 6329 @Override 6330 public String getCallingPackage(IBinder token) { 6331 synchronized (this) { 6332 ActivityRecord r = getCallingRecordLocked(token); 6333 return r != null ? r.info.packageName : null; 6334 } 6335 } 6336 6337 @Override 6338 public ComponentName getCallingActivity(IBinder token) { 6339 synchronized (this) { 6340 ActivityRecord r = getCallingRecordLocked(token); 6341 return r != null ? r.intent.getComponent() : null; 6342 } 6343 } 6344 6345 private ActivityRecord getCallingRecordLocked(IBinder token) { 6346 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6347 if (r == null) { 6348 return null; 6349 } 6350 return r.resultTo; 6351 } 6352 6353 @Override 6354 public ComponentName getActivityClassForToken(IBinder token) { 6355 synchronized(this) { 6356 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6357 if (r == null) { 6358 return null; 6359 } 6360 return r.intent.getComponent(); 6361 } 6362 } 6363 6364 @Override 6365 public String getPackageForToken(IBinder token) { 6366 synchronized(this) { 6367 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6368 if (r == null) { 6369 return null; 6370 } 6371 return r.packageName; 6372 } 6373 } 6374 6375 @Override 6376 public IIntentSender getIntentSender(int type, 6377 String packageName, IBinder token, String resultWho, 6378 int requestCode, Intent[] intents, String[] resolvedTypes, 6379 int flags, Bundle options, int userId) { 6380 enforceNotIsolatedCaller("getIntentSender"); 6381 // Refuse possible leaked file descriptors 6382 if (intents != null) { 6383 if (intents.length < 1) { 6384 throw new IllegalArgumentException("Intents array length must be >= 1"); 6385 } 6386 for (int i=0; i<intents.length; i++) { 6387 Intent intent = intents[i]; 6388 if (intent != null) { 6389 if (intent.hasFileDescriptors()) { 6390 throw new IllegalArgumentException("File descriptors passed in Intent"); 6391 } 6392 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6393 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6394 throw new IllegalArgumentException( 6395 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6396 } 6397 intents[i] = new Intent(intent); 6398 } 6399 } 6400 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6401 throw new IllegalArgumentException( 6402 "Intent array length does not match resolvedTypes length"); 6403 } 6404 } 6405 if (options != null) { 6406 if (options.hasFileDescriptors()) { 6407 throw new IllegalArgumentException("File descriptors passed in options"); 6408 } 6409 } 6410 6411 synchronized(this) { 6412 int callingUid = Binder.getCallingUid(); 6413 int origUserId = userId; 6414 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6415 type == ActivityManager.INTENT_SENDER_BROADCAST, 6416 ALLOW_NON_FULL, "getIntentSender", null); 6417 if (origUserId == UserHandle.USER_CURRENT) { 6418 // We don't want to evaluate this until the pending intent is 6419 // actually executed. However, we do want to always do the 6420 // security checking for it above. 6421 userId = UserHandle.USER_CURRENT; 6422 } 6423 try { 6424 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6425 int uid = AppGlobals.getPackageManager() 6426 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6427 if (!UserHandle.isSameApp(callingUid, uid)) { 6428 String msg = "Permission Denial: getIntentSender() from pid=" 6429 + Binder.getCallingPid() 6430 + ", uid=" + Binder.getCallingUid() 6431 + ", (need uid=" + uid + ")" 6432 + " is not allowed to send as package " + packageName; 6433 Slog.w(TAG, msg); 6434 throw new SecurityException(msg); 6435 } 6436 } 6437 6438 return getIntentSenderLocked(type, packageName, callingUid, userId, 6439 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6440 6441 } catch (RemoteException e) { 6442 throw new SecurityException(e); 6443 } 6444 } 6445 } 6446 6447 IIntentSender getIntentSenderLocked(int type, String packageName, 6448 int callingUid, int userId, IBinder token, String resultWho, 6449 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6450 Bundle options) { 6451 if (DEBUG_MU) 6452 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6453 ActivityRecord activity = null; 6454 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6455 activity = ActivityRecord.isInStackLocked(token); 6456 if (activity == null) { 6457 return null; 6458 } 6459 if (activity.finishing) { 6460 return null; 6461 } 6462 } 6463 6464 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6465 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6466 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6467 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6468 |PendingIntent.FLAG_UPDATE_CURRENT); 6469 6470 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6471 type, packageName, activity, resultWho, 6472 requestCode, intents, resolvedTypes, flags, options, userId); 6473 WeakReference<PendingIntentRecord> ref; 6474 ref = mIntentSenderRecords.get(key); 6475 PendingIntentRecord rec = ref != null ? ref.get() : null; 6476 if (rec != null) { 6477 if (!cancelCurrent) { 6478 if (updateCurrent) { 6479 if (rec.key.requestIntent != null) { 6480 rec.key.requestIntent.replaceExtras(intents != null ? 6481 intents[intents.length - 1] : null); 6482 } 6483 if (intents != null) { 6484 intents[intents.length-1] = rec.key.requestIntent; 6485 rec.key.allIntents = intents; 6486 rec.key.allResolvedTypes = resolvedTypes; 6487 } else { 6488 rec.key.allIntents = null; 6489 rec.key.allResolvedTypes = null; 6490 } 6491 } 6492 return rec; 6493 } 6494 rec.canceled = true; 6495 mIntentSenderRecords.remove(key); 6496 } 6497 if (noCreate) { 6498 return rec; 6499 } 6500 rec = new PendingIntentRecord(this, key, callingUid); 6501 mIntentSenderRecords.put(key, rec.ref); 6502 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6503 if (activity.pendingResults == null) { 6504 activity.pendingResults 6505 = new HashSet<WeakReference<PendingIntentRecord>>(); 6506 } 6507 activity.pendingResults.add(rec.ref); 6508 } 6509 return rec; 6510 } 6511 6512 @Override 6513 public void cancelIntentSender(IIntentSender sender) { 6514 if (!(sender instanceof PendingIntentRecord)) { 6515 return; 6516 } 6517 synchronized(this) { 6518 PendingIntentRecord rec = (PendingIntentRecord)sender; 6519 try { 6520 int uid = AppGlobals.getPackageManager() 6521 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6522 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6523 String msg = "Permission Denial: cancelIntentSender() from pid=" 6524 + Binder.getCallingPid() 6525 + ", uid=" + Binder.getCallingUid() 6526 + " is not allowed to cancel packges " 6527 + rec.key.packageName; 6528 Slog.w(TAG, msg); 6529 throw new SecurityException(msg); 6530 } 6531 } catch (RemoteException e) { 6532 throw new SecurityException(e); 6533 } 6534 cancelIntentSenderLocked(rec, true); 6535 } 6536 } 6537 6538 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6539 rec.canceled = true; 6540 mIntentSenderRecords.remove(rec.key); 6541 if (cleanActivity && rec.key.activity != null) { 6542 rec.key.activity.pendingResults.remove(rec.ref); 6543 } 6544 } 6545 6546 @Override 6547 public String getPackageForIntentSender(IIntentSender pendingResult) { 6548 if (!(pendingResult instanceof PendingIntentRecord)) { 6549 return null; 6550 } 6551 try { 6552 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6553 return res.key.packageName; 6554 } catch (ClassCastException e) { 6555 } 6556 return null; 6557 } 6558 6559 @Override 6560 public int getUidForIntentSender(IIntentSender sender) { 6561 if (sender instanceof PendingIntentRecord) { 6562 try { 6563 PendingIntentRecord res = (PendingIntentRecord)sender; 6564 return res.uid; 6565 } catch (ClassCastException e) { 6566 } 6567 } 6568 return -1; 6569 } 6570 6571 @Override 6572 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6573 if (!(pendingResult instanceof PendingIntentRecord)) { 6574 return false; 6575 } 6576 try { 6577 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6578 if (res.key.allIntents == null) { 6579 return false; 6580 } 6581 for (int i=0; i<res.key.allIntents.length; i++) { 6582 Intent intent = res.key.allIntents[i]; 6583 if (intent.getPackage() != null && intent.getComponent() != null) { 6584 return false; 6585 } 6586 } 6587 return true; 6588 } catch (ClassCastException e) { 6589 } 6590 return false; 6591 } 6592 6593 @Override 6594 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6595 if (!(pendingResult instanceof PendingIntentRecord)) { 6596 return false; 6597 } 6598 try { 6599 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6600 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6601 return true; 6602 } 6603 return false; 6604 } catch (ClassCastException e) { 6605 } 6606 return false; 6607 } 6608 6609 @Override 6610 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6611 if (!(pendingResult instanceof PendingIntentRecord)) { 6612 return null; 6613 } 6614 try { 6615 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6616 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6617 } catch (ClassCastException e) { 6618 } 6619 return null; 6620 } 6621 6622 @Override 6623 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6624 if (!(pendingResult instanceof PendingIntentRecord)) { 6625 return null; 6626 } 6627 try { 6628 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6629 Intent intent = res.key.requestIntent; 6630 if (intent != null) { 6631 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6632 || res.lastTagPrefix.equals(prefix))) { 6633 return res.lastTag; 6634 } 6635 res.lastTagPrefix = prefix; 6636 StringBuilder sb = new StringBuilder(128); 6637 if (prefix != null) { 6638 sb.append(prefix); 6639 } 6640 if (intent.getAction() != null) { 6641 sb.append(intent.getAction()); 6642 } else if (intent.getComponent() != null) { 6643 intent.getComponent().appendShortString(sb); 6644 } else { 6645 sb.append("?"); 6646 } 6647 return res.lastTag = sb.toString(); 6648 } 6649 } catch (ClassCastException e) { 6650 } 6651 return null; 6652 } 6653 6654 @Override 6655 public void setProcessLimit(int max) { 6656 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6657 "setProcessLimit()"); 6658 synchronized (this) { 6659 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6660 mProcessLimitOverride = max; 6661 } 6662 trimApplications(); 6663 } 6664 6665 @Override 6666 public int getProcessLimit() { 6667 synchronized (this) { 6668 return mProcessLimitOverride; 6669 } 6670 } 6671 6672 void foregroundTokenDied(ForegroundToken token) { 6673 synchronized (ActivityManagerService.this) { 6674 synchronized (mPidsSelfLocked) { 6675 ForegroundToken cur 6676 = mForegroundProcesses.get(token.pid); 6677 if (cur != token) { 6678 return; 6679 } 6680 mForegroundProcesses.remove(token.pid); 6681 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6682 if (pr == null) { 6683 return; 6684 } 6685 pr.forcingToForeground = null; 6686 updateProcessForegroundLocked(pr, false, false); 6687 } 6688 updateOomAdjLocked(); 6689 } 6690 } 6691 6692 @Override 6693 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6694 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6695 "setProcessForeground()"); 6696 synchronized(this) { 6697 boolean changed = false; 6698 6699 synchronized (mPidsSelfLocked) { 6700 ProcessRecord pr = mPidsSelfLocked.get(pid); 6701 if (pr == null && isForeground) { 6702 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6703 return; 6704 } 6705 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6706 if (oldToken != null) { 6707 oldToken.token.unlinkToDeath(oldToken, 0); 6708 mForegroundProcesses.remove(pid); 6709 if (pr != null) { 6710 pr.forcingToForeground = null; 6711 } 6712 changed = true; 6713 } 6714 if (isForeground && token != null) { 6715 ForegroundToken newToken = new ForegroundToken() { 6716 @Override 6717 public void binderDied() { 6718 foregroundTokenDied(this); 6719 } 6720 }; 6721 newToken.pid = pid; 6722 newToken.token = token; 6723 try { 6724 token.linkToDeath(newToken, 0); 6725 mForegroundProcesses.put(pid, newToken); 6726 pr.forcingToForeground = token; 6727 changed = true; 6728 } catch (RemoteException e) { 6729 // If the process died while doing this, we will later 6730 // do the cleanup with the process death link. 6731 } 6732 } 6733 } 6734 6735 if (changed) { 6736 updateOomAdjLocked(); 6737 } 6738 } 6739 } 6740 6741 // ========================================================= 6742 // PERMISSIONS 6743 // ========================================================= 6744 6745 static class PermissionController extends IPermissionController.Stub { 6746 ActivityManagerService mActivityManagerService; 6747 PermissionController(ActivityManagerService activityManagerService) { 6748 mActivityManagerService = activityManagerService; 6749 } 6750 6751 @Override 6752 public boolean checkPermission(String permission, int pid, int uid) { 6753 return mActivityManagerService.checkPermission(permission, pid, 6754 uid) == PackageManager.PERMISSION_GRANTED; 6755 } 6756 } 6757 6758 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6759 @Override 6760 public int checkComponentPermission(String permission, int pid, int uid, 6761 int owningUid, boolean exported) { 6762 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6763 owningUid, exported); 6764 } 6765 6766 @Override 6767 public Object getAMSLock() { 6768 return ActivityManagerService.this; 6769 } 6770 } 6771 6772 /** 6773 * This can be called with or without the global lock held. 6774 */ 6775 int checkComponentPermission(String permission, int pid, int uid, 6776 int owningUid, boolean exported) { 6777 // We might be performing an operation on behalf of an indirect binder 6778 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6779 // client identity accordingly before proceeding. 6780 Identity tlsIdentity = sCallerIdentity.get(); 6781 if (tlsIdentity != null) { 6782 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6783 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6784 uid = tlsIdentity.uid; 6785 pid = tlsIdentity.pid; 6786 } 6787 6788 if (pid == MY_PID) { 6789 return PackageManager.PERMISSION_GRANTED; 6790 } 6791 6792 return ActivityManager.checkComponentPermission(permission, uid, 6793 owningUid, exported); 6794 } 6795 6796 /** 6797 * As the only public entry point for permissions checking, this method 6798 * can enforce the semantic that requesting a check on a null global 6799 * permission is automatically denied. (Internally a null permission 6800 * string is used when calling {@link #checkComponentPermission} in cases 6801 * when only uid-based security is needed.) 6802 * 6803 * This can be called with or without the global lock held. 6804 */ 6805 @Override 6806 public int checkPermission(String permission, int pid, int uid) { 6807 if (permission == null) { 6808 return PackageManager.PERMISSION_DENIED; 6809 } 6810 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6811 } 6812 6813 /** 6814 * Binder IPC calls go through the public entry point. 6815 * This can be called with or without the global lock held. 6816 */ 6817 int checkCallingPermission(String permission) { 6818 return checkPermission(permission, 6819 Binder.getCallingPid(), 6820 UserHandle.getAppId(Binder.getCallingUid())); 6821 } 6822 6823 /** 6824 * This can be called with or without the global lock held. 6825 */ 6826 void enforceCallingPermission(String permission, String func) { 6827 if (checkCallingPermission(permission) 6828 == PackageManager.PERMISSION_GRANTED) { 6829 return; 6830 } 6831 6832 String msg = "Permission Denial: " + func + " from pid=" 6833 + Binder.getCallingPid() 6834 + ", uid=" + Binder.getCallingUid() 6835 + " requires " + permission; 6836 Slog.w(TAG, msg); 6837 throw new SecurityException(msg); 6838 } 6839 6840 /** 6841 * Determine if UID is holding permissions required to access {@link Uri} in 6842 * the given {@link ProviderInfo}. Final permission checking is always done 6843 * in {@link ContentProvider}. 6844 */ 6845 private final boolean checkHoldingPermissionsLocked( 6846 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6847 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6848 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6849 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6850 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6851 != PERMISSION_GRANTED) { 6852 return false; 6853 } 6854 } 6855 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6856 } 6857 6858 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6859 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6860 if (pi.applicationInfo.uid == uid) { 6861 return true; 6862 } else if (!pi.exported) { 6863 return false; 6864 } 6865 6866 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6867 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6868 try { 6869 // check if target holds top-level <provider> permissions 6870 if (!readMet && pi.readPermission != null && considerUidPermissions 6871 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6872 readMet = true; 6873 } 6874 if (!writeMet && pi.writePermission != null && considerUidPermissions 6875 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6876 writeMet = true; 6877 } 6878 6879 // track if unprotected read/write is allowed; any denied 6880 // <path-permission> below removes this ability 6881 boolean allowDefaultRead = pi.readPermission == null; 6882 boolean allowDefaultWrite = pi.writePermission == null; 6883 6884 // check if target holds any <path-permission> that match uri 6885 final PathPermission[] pps = pi.pathPermissions; 6886 if (pps != null) { 6887 final String path = grantUri.uri.getPath(); 6888 int i = pps.length; 6889 while (i > 0 && (!readMet || !writeMet)) { 6890 i--; 6891 PathPermission pp = pps[i]; 6892 if (pp.match(path)) { 6893 if (!readMet) { 6894 final String pprperm = pp.getReadPermission(); 6895 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6896 + pprperm + " for " + pp.getPath() 6897 + ": match=" + pp.match(path) 6898 + " check=" + pm.checkUidPermission(pprperm, uid)); 6899 if (pprperm != null) { 6900 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6901 == PERMISSION_GRANTED) { 6902 readMet = true; 6903 } else { 6904 allowDefaultRead = false; 6905 } 6906 } 6907 } 6908 if (!writeMet) { 6909 final String ppwperm = pp.getWritePermission(); 6910 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6911 + ppwperm + " for " + pp.getPath() 6912 + ": match=" + pp.match(path) 6913 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6914 if (ppwperm != null) { 6915 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6916 == PERMISSION_GRANTED) { 6917 writeMet = true; 6918 } else { 6919 allowDefaultWrite = false; 6920 } 6921 } 6922 } 6923 } 6924 } 6925 } 6926 6927 // grant unprotected <provider> read/write, if not blocked by 6928 // <path-permission> above 6929 if (allowDefaultRead) readMet = true; 6930 if (allowDefaultWrite) writeMet = true; 6931 6932 } catch (RemoteException e) { 6933 return false; 6934 } 6935 6936 return readMet && writeMet; 6937 } 6938 6939 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6940 ProviderInfo pi = null; 6941 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6942 if (cpr != null) { 6943 pi = cpr.info; 6944 } else { 6945 try { 6946 pi = AppGlobals.getPackageManager().resolveContentProvider( 6947 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6948 } catch (RemoteException ex) { 6949 } 6950 } 6951 return pi; 6952 } 6953 6954 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6955 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6956 if (targetUris != null) { 6957 return targetUris.get(grantUri); 6958 } 6959 return null; 6960 } 6961 6962 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6963 String targetPkg, int targetUid, GrantUri grantUri) { 6964 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6965 if (targetUris == null) { 6966 targetUris = Maps.newArrayMap(); 6967 mGrantedUriPermissions.put(targetUid, targetUris); 6968 } 6969 6970 UriPermission perm = targetUris.get(grantUri); 6971 if (perm == null) { 6972 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6973 targetUris.put(grantUri, perm); 6974 } 6975 6976 return perm; 6977 } 6978 6979 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6980 final int modeFlags) { 6981 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6982 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6983 : UriPermission.STRENGTH_OWNED; 6984 6985 // Root gets to do everything. 6986 if (uid == 0) { 6987 return true; 6988 } 6989 6990 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6991 if (perms == null) return false; 6992 6993 // First look for exact match 6994 final UriPermission exactPerm = perms.get(grantUri); 6995 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6996 return true; 6997 } 6998 6999 // No exact match, look for prefixes 7000 final int N = perms.size(); 7001 for (int i = 0; i < N; i++) { 7002 final UriPermission perm = perms.valueAt(i); 7003 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7004 && perm.getStrength(modeFlags) >= minStrength) { 7005 return true; 7006 } 7007 } 7008 7009 return false; 7010 } 7011 7012 /** 7013 * @param uri This uri must NOT contain an embedded userId. 7014 * @param userId The userId in which the uri is to be resolved. 7015 */ 7016 @Override 7017 public int checkUriPermission(Uri uri, int pid, int uid, 7018 final int modeFlags, int userId) { 7019 enforceNotIsolatedCaller("checkUriPermission"); 7020 7021 // Another redirected-binder-call permissions check as in 7022 // {@link checkComponentPermission}. 7023 Identity tlsIdentity = sCallerIdentity.get(); 7024 if (tlsIdentity != null) { 7025 uid = tlsIdentity.uid; 7026 pid = tlsIdentity.pid; 7027 } 7028 7029 // Our own process gets to do everything. 7030 if (pid == MY_PID) { 7031 return PackageManager.PERMISSION_GRANTED; 7032 } 7033 synchronized (this) { 7034 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7035 ? PackageManager.PERMISSION_GRANTED 7036 : PackageManager.PERMISSION_DENIED; 7037 } 7038 } 7039 7040 /** 7041 * Check if the targetPkg can be granted permission to access uri by 7042 * the callingUid using the given modeFlags. Throws a security exception 7043 * if callingUid is not allowed to do this. Returns the uid of the target 7044 * if the URI permission grant should be performed; returns -1 if it is not 7045 * needed (for example targetPkg already has permission to access the URI). 7046 * If you already know the uid of the target, you can supply it in 7047 * lastTargetUid else set that to -1. 7048 */ 7049 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7050 final int modeFlags, int lastTargetUid) { 7051 if (!Intent.isAccessUriMode(modeFlags)) { 7052 return -1; 7053 } 7054 7055 if (targetPkg != null) { 7056 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7057 "Checking grant " + targetPkg + " permission to " + grantUri); 7058 } 7059 7060 final IPackageManager pm = AppGlobals.getPackageManager(); 7061 7062 // If this is not a content: uri, we can't do anything with it. 7063 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7065 "Can't grant URI permission for non-content URI: " + grantUri); 7066 return -1; 7067 } 7068 7069 final String authority = grantUri.uri.getAuthority(); 7070 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7071 if (pi == null) { 7072 Slog.w(TAG, "No content provider found for permission check: " + 7073 grantUri.uri.toSafeString()); 7074 return -1; 7075 } 7076 7077 int targetUid = lastTargetUid; 7078 if (targetUid < 0 && targetPkg != null) { 7079 try { 7080 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7081 if (targetUid < 0) { 7082 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7083 "Can't grant URI permission no uid for: " + targetPkg); 7084 return -1; 7085 } 7086 } catch (RemoteException ex) { 7087 return -1; 7088 } 7089 } 7090 7091 if (targetUid >= 0) { 7092 // First... does the target actually need this permission? 7093 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7094 // No need to grant the target this permission. 7095 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7096 "Target " + targetPkg + " already has full permission to " + grantUri); 7097 return -1; 7098 } 7099 } else { 7100 // First... there is no target package, so can anyone access it? 7101 boolean allowed = pi.exported; 7102 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7103 if (pi.readPermission != null) { 7104 allowed = false; 7105 } 7106 } 7107 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7108 if (pi.writePermission != null) { 7109 allowed = false; 7110 } 7111 } 7112 if (allowed) { 7113 return -1; 7114 } 7115 } 7116 7117 /* There is a special cross user grant if: 7118 * - The target is on another user. 7119 * - Apps on the current user can access the uri without any uid permissions. 7120 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7121 * grant uri permissions. 7122 */ 7123 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7124 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7125 modeFlags, false /*without considering the uid permissions*/); 7126 7127 // Second... is the provider allowing granting of URI permissions? 7128 if (!specialCrossUserGrant) { 7129 if (!pi.grantUriPermissions) { 7130 throw new SecurityException("Provider " + pi.packageName 7131 + "/" + pi.name 7132 + " does not allow granting of Uri permissions (uri " 7133 + grantUri + ")"); 7134 } 7135 if (pi.uriPermissionPatterns != null) { 7136 final int N = pi.uriPermissionPatterns.length; 7137 boolean allowed = false; 7138 for (int i=0; i<N; i++) { 7139 if (pi.uriPermissionPatterns[i] != null 7140 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7141 allowed = true; 7142 break; 7143 } 7144 } 7145 if (!allowed) { 7146 throw new SecurityException("Provider " + pi.packageName 7147 + "/" + pi.name 7148 + " does not allow granting of permission to path of Uri " 7149 + grantUri); 7150 } 7151 } 7152 } 7153 7154 // Third... does the caller itself have permission to access 7155 // this uri? 7156 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7157 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7158 // Require they hold a strong enough Uri permission 7159 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7160 throw new SecurityException("Uid " + callingUid 7161 + " does not have permission to uri " + grantUri); 7162 } 7163 } 7164 } 7165 return targetUid; 7166 } 7167 7168 /** 7169 * @param uri This uri must NOT contain an embedded userId. 7170 * @param userId The userId in which the uri is to be resolved. 7171 */ 7172 @Override 7173 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7174 final int modeFlags, int userId) { 7175 enforceNotIsolatedCaller("checkGrantUriPermission"); 7176 synchronized(this) { 7177 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7178 new GrantUri(userId, uri, false), modeFlags, -1); 7179 } 7180 } 7181 7182 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7183 final int modeFlags, UriPermissionOwner owner) { 7184 if (!Intent.isAccessUriMode(modeFlags)) { 7185 return; 7186 } 7187 7188 // So here we are: the caller has the assumed permission 7189 // to the uri, and the target doesn't. Let's now give this to 7190 // the target. 7191 7192 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7193 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7194 7195 final String authority = grantUri.uri.getAuthority(); 7196 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7197 if (pi == null) { 7198 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7199 return; 7200 } 7201 7202 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7203 grantUri.prefix = true; 7204 } 7205 final UriPermission perm = findOrCreateUriPermissionLocked( 7206 pi.packageName, targetPkg, targetUid, grantUri); 7207 perm.grantModes(modeFlags, owner); 7208 } 7209 7210 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7211 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7212 if (targetPkg == null) { 7213 throw new NullPointerException("targetPkg"); 7214 } 7215 int targetUid; 7216 final IPackageManager pm = AppGlobals.getPackageManager(); 7217 try { 7218 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7219 } catch (RemoteException ex) { 7220 return; 7221 } 7222 7223 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7224 targetUid); 7225 if (targetUid < 0) { 7226 return; 7227 } 7228 7229 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7230 owner); 7231 } 7232 7233 static class NeededUriGrants extends ArrayList<GrantUri> { 7234 final String targetPkg; 7235 final int targetUid; 7236 final int flags; 7237 7238 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7239 this.targetPkg = targetPkg; 7240 this.targetUid = targetUid; 7241 this.flags = flags; 7242 } 7243 } 7244 7245 /** 7246 * Like checkGrantUriPermissionLocked, but takes an Intent. 7247 */ 7248 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7249 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7250 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7251 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7252 + " clip=" + (intent != null ? intent.getClipData() : null) 7253 + " from " + intent + "; flags=0x" 7254 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7255 7256 if (targetPkg == null) { 7257 throw new NullPointerException("targetPkg"); 7258 } 7259 7260 if (intent == null) { 7261 return null; 7262 } 7263 Uri data = intent.getData(); 7264 ClipData clip = intent.getClipData(); 7265 if (data == null && clip == null) { 7266 return null; 7267 } 7268 // Default userId for uris in the intent (if they don't specify it themselves) 7269 int contentUserHint = intent.getContentUserHint(); 7270 if (contentUserHint == UserHandle.USER_CURRENT) { 7271 contentUserHint = UserHandle.getUserId(callingUid); 7272 } 7273 final IPackageManager pm = AppGlobals.getPackageManager(); 7274 int targetUid; 7275 if (needed != null) { 7276 targetUid = needed.targetUid; 7277 } else { 7278 try { 7279 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7280 } catch (RemoteException ex) { 7281 return null; 7282 } 7283 if (targetUid < 0) { 7284 if (DEBUG_URI_PERMISSION) { 7285 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7286 + " on user " + targetUserId); 7287 } 7288 return null; 7289 } 7290 } 7291 if (data != null) { 7292 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7293 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7294 targetUid); 7295 if (targetUid > 0) { 7296 if (needed == null) { 7297 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7298 } 7299 needed.add(grantUri); 7300 } 7301 } 7302 if (clip != null) { 7303 for (int i=0; i<clip.getItemCount(); i++) { 7304 Uri uri = clip.getItemAt(i).getUri(); 7305 if (uri != null) { 7306 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7307 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7308 targetUid); 7309 if (targetUid > 0) { 7310 if (needed == null) { 7311 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7312 } 7313 needed.add(grantUri); 7314 } 7315 } else { 7316 Intent clipIntent = clip.getItemAt(i).getIntent(); 7317 if (clipIntent != null) { 7318 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7319 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7320 if (newNeeded != null) { 7321 needed = newNeeded; 7322 } 7323 } 7324 } 7325 } 7326 } 7327 7328 return needed; 7329 } 7330 7331 /** 7332 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7333 */ 7334 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7335 UriPermissionOwner owner) { 7336 if (needed != null) { 7337 for (int i=0; i<needed.size(); i++) { 7338 GrantUri grantUri = needed.get(i); 7339 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7340 grantUri, needed.flags, owner); 7341 } 7342 } 7343 } 7344 7345 void grantUriPermissionFromIntentLocked(int callingUid, 7346 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7347 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7348 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7349 if (needed == null) { 7350 return; 7351 } 7352 7353 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7354 } 7355 7356 /** 7357 * @param uri This uri must NOT contain an embedded userId. 7358 * @param userId The userId in which the uri is to be resolved. 7359 */ 7360 @Override 7361 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7362 final int modeFlags, int userId) { 7363 enforceNotIsolatedCaller("grantUriPermission"); 7364 GrantUri grantUri = new GrantUri(userId, uri, false); 7365 synchronized(this) { 7366 final ProcessRecord r = getRecordForAppLocked(caller); 7367 if (r == null) { 7368 throw new SecurityException("Unable to find app for caller " 7369 + caller 7370 + " when granting permission to uri " + grantUri); 7371 } 7372 if (targetPkg == null) { 7373 throw new IllegalArgumentException("null target"); 7374 } 7375 if (grantUri == null) { 7376 throw new IllegalArgumentException("null uri"); 7377 } 7378 7379 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7380 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7381 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7382 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7383 7384 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7385 UserHandle.getUserId(r.uid)); 7386 } 7387 } 7388 7389 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7390 if (perm.modeFlags == 0) { 7391 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7392 perm.targetUid); 7393 if (perms != null) { 7394 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7395 "Removing " + perm.targetUid + " permission to " + perm.uri); 7396 7397 perms.remove(perm.uri); 7398 if (perms.isEmpty()) { 7399 mGrantedUriPermissions.remove(perm.targetUid); 7400 } 7401 } 7402 } 7403 } 7404 7405 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7406 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7407 7408 final IPackageManager pm = AppGlobals.getPackageManager(); 7409 final String authority = grantUri.uri.getAuthority(); 7410 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7411 if (pi == null) { 7412 Slog.w(TAG, "No content provider found for permission revoke: " 7413 + grantUri.toSafeString()); 7414 return; 7415 } 7416 7417 // Does the caller have this permission on the URI? 7418 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7419 // Right now, if you are not the original owner of the permission, 7420 // you are not allowed to revoke it. 7421 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7422 throw new SecurityException("Uid " + callingUid 7423 + " does not have permission to uri " + grantUri); 7424 //} 7425 } 7426 7427 boolean persistChanged = false; 7428 7429 // Go through all of the permissions and remove any that match. 7430 int N = mGrantedUriPermissions.size(); 7431 for (int i = 0; i < N; i++) { 7432 final int targetUid = mGrantedUriPermissions.keyAt(i); 7433 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7434 7435 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7436 final UriPermission perm = it.next(); 7437 if (perm.uri.sourceUserId == grantUri.sourceUserId 7438 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7439 if (DEBUG_URI_PERMISSION) 7440 Slog.v(TAG, 7441 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7442 persistChanged |= perm.revokeModes( 7443 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7444 if (perm.modeFlags == 0) { 7445 it.remove(); 7446 } 7447 } 7448 } 7449 7450 if (perms.isEmpty()) { 7451 mGrantedUriPermissions.remove(targetUid); 7452 N--; 7453 i--; 7454 } 7455 } 7456 7457 if (persistChanged) { 7458 schedulePersistUriGrants(); 7459 } 7460 } 7461 7462 /** 7463 * @param uri This uri must NOT contain an embedded userId. 7464 * @param userId The userId in which the uri is to be resolved. 7465 */ 7466 @Override 7467 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7468 int userId) { 7469 enforceNotIsolatedCaller("revokeUriPermission"); 7470 synchronized(this) { 7471 final ProcessRecord r = getRecordForAppLocked(caller); 7472 if (r == null) { 7473 throw new SecurityException("Unable to find app for caller " 7474 + caller 7475 + " when revoking permission to uri " + uri); 7476 } 7477 if (uri == null) { 7478 Slog.w(TAG, "revokeUriPermission: null uri"); 7479 return; 7480 } 7481 7482 if (!Intent.isAccessUriMode(modeFlags)) { 7483 return; 7484 } 7485 7486 final IPackageManager pm = AppGlobals.getPackageManager(); 7487 final String authority = uri.getAuthority(); 7488 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7489 if (pi == null) { 7490 Slog.w(TAG, "No content provider found for permission revoke: " 7491 + uri.toSafeString()); 7492 return; 7493 } 7494 7495 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7496 } 7497 } 7498 7499 /** 7500 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7501 * given package. 7502 * 7503 * @param packageName Package name to match, or {@code null} to apply to all 7504 * packages. 7505 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7506 * to all users. 7507 * @param persistable If persistable grants should be removed. 7508 */ 7509 private void removeUriPermissionsForPackageLocked( 7510 String packageName, int userHandle, boolean persistable) { 7511 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7512 throw new IllegalArgumentException("Must narrow by either package or user"); 7513 } 7514 7515 boolean persistChanged = false; 7516 7517 int N = mGrantedUriPermissions.size(); 7518 for (int i = 0; i < N; i++) { 7519 final int targetUid = mGrantedUriPermissions.keyAt(i); 7520 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7521 7522 // Only inspect grants matching user 7523 if (userHandle == UserHandle.USER_ALL 7524 || userHandle == UserHandle.getUserId(targetUid)) { 7525 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7526 final UriPermission perm = it.next(); 7527 7528 // Only inspect grants matching package 7529 if (packageName == null || perm.sourcePkg.equals(packageName) 7530 || perm.targetPkg.equals(packageName)) { 7531 persistChanged |= perm.revokeModes( 7532 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7533 7534 // Only remove when no modes remain; any persisted grants 7535 // will keep this alive. 7536 if (perm.modeFlags == 0) { 7537 it.remove(); 7538 } 7539 } 7540 } 7541 7542 if (perms.isEmpty()) { 7543 mGrantedUriPermissions.remove(targetUid); 7544 N--; 7545 i--; 7546 } 7547 } 7548 } 7549 7550 if (persistChanged) { 7551 schedulePersistUriGrants(); 7552 } 7553 } 7554 7555 @Override 7556 public IBinder newUriPermissionOwner(String name) { 7557 enforceNotIsolatedCaller("newUriPermissionOwner"); 7558 synchronized(this) { 7559 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7560 return owner.getExternalTokenLocked(); 7561 } 7562 } 7563 7564 /** 7565 * @param uri This uri must NOT contain an embedded userId. 7566 * @param sourceUserId The userId in which the uri is to be resolved. 7567 * @param targetUserId The userId of the app that receives the grant. 7568 */ 7569 @Override 7570 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7571 final int modeFlags, int sourceUserId, int targetUserId) { 7572 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7573 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7574 synchronized(this) { 7575 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7576 if (owner == null) { 7577 throw new IllegalArgumentException("Unknown owner: " + token); 7578 } 7579 if (fromUid != Binder.getCallingUid()) { 7580 if (Binder.getCallingUid() != Process.myUid()) { 7581 // Only system code can grant URI permissions on behalf 7582 // of other users. 7583 throw new SecurityException("nice try"); 7584 } 7585 } 7586 if (targetPkg == null) { 7587 throw new IllegalArgumentException("null target"); 7588 } 7589 if (uri == null) { 7590 throw new IllegalArgumentException("null uri"); 7591 } 7592 7593 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7594 modeFlags, owner, targetUserId); 7595 } 7596 } 7597 7598 /** 7599 * @param uri This uri must NOT contain an embedded userId. 7600 * @param userId The userId in which the uri is to be resolved. 7601 */ 7602 @Override 7603 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7604 synchronized(this) { 7605 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7606 if (owner == null) { 7607 throw new IllegalArgumentException("Unknown owner: " + token); 7608 } 7609 7610 if (uri == null) { 7611 owner.removeUriPermissionsLocked(mode); 7612 } else { 7613 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7614 } 7615 } 7616 } 7617 7618 private void schedulePersistUriGrants() { 7619 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7620 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7621 10 * DateUtils.SECOND_IN_MILLIS); 7622 } 7623 } 7624 7625 private void writeGrantedUriPermissions() { 7626 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7627 7628 // Snapshot permissions so we can persist without lock 7629 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7630 synchronized (this) { 7631 final int size = mGrantedUriPermissions.size(); 7632 for (int i = 0; i < size; i++) { 7633 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7634 for (UriPermission perm : perms.values()) { 7635 if (perm.persistedModeFlags != 0) { 7636 persist.add(perm.snapshot()); 7637 } 7638 } 7639 } 7640 } 7641 7642 FileOutputStream fos = null; 7643 try { 7644 fos = mGrantFile.startWrite(); 7645 7646 XmlSerializer out = new FastXmlSerializer(); 7647 out.setOutput(fos, "utf-8"); 7648 out.startDocument(null, true); 7649 out.startTag(null, TAG_URI_GRANTS); 7650 for (UriPermission.Snapshot perm : persist) { 7651 out.startTag(null, TAG_URI_GRANT); 7652 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7653 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7654 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7655 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7656 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7657 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7658 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7659 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7660 out.endTag(null, TAG_URI_GRANT); 7661 } 7662 out.endTag(null, TAG_URI_GRANTS); 7663 out.endDocument(); 7664 7665 mGrantFile.finishWrite(fos); 7666 } catch (IOException e) { 7667 if (fos != null) { 7668 mGrantFile.failWrite(fos); 7669 } 7670 } 7671 } 7672 7673 private void readGrantedUriPermissionsLocked() { 7674 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7675 7676 final long now = System.currentTimeMillis(); 7677 7678 FileInputStream fis = null; 7679 try { 7680 fis = mGrantFile.openRead(); 7681 final XmlPullParser in = Xml.newPullParser(); 7682 in.setInput(fis, null); 7683 7684 int type; 7685 while ((type = in.next()) != END_DOCUMENT) { 7686 final String tag = in.getName(); 7687 if (type == START_TAG) { 7688 if (TAG_URI_GRANT.equals(tag)) { 7689 final int sourceUserId; 7690 final int targetUserId; 7691 final int userHandle = readIntAttribute(in, 7692 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7693 if (userHandle != UserHandle.USER_NULL) { 7694 // For backwards compatibility. 7695 sourceUserId = userHandle; 7696 targetUserId = userHandle; 7697 } else { 7698 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7699 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7700 } 7701 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7702 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7703 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7704 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7705 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7706 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7707 7708 // Sanity check that provider still belongs to source package 7709 final ProviderInfo pi = getProviderInfoLocked( 7710 uri.getAuthority(), sourceUserId); 7711 if (pi != null && sourcePkg.equals(pi.packageName)) { 7712 int targetUid = -1; 7713 try { 7714 targetUid = AppGlobals.getPackageManager() 7715 .getPackageUid(targetPkg, targetUserId); 7716 } catch (RemoteException e) { 7717 } 7718 if (targetUid != -1) { 7719 final UriPermission perm = findOrCreateUriPermissionLocked( 7720 sourcePkg, targetPkg, targetUid, 7721 new GrantUri(sourceUserId, uri, prefix)); 7722 perm.initPersistedModes(modeFlags, createdTime); 7723 } 7724 } else { 7725 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7726 + " but instead found " + pi); 7727 } 7728 } 7729 } 7730 } 7731 } catch (FileNotFoundException e) { 7732 // Missing grants is okay 7733 } catch (IOException e) { 7734 Log.wtf(TAG, "Failed reading Uri grants", e); 7735 } catch (XmlPullParserException e) { 7736 Log.wtf(TAG, "Failed reading Uri grants", e); 7737 } finally { 7738 IoUtils.closeQuietly(fis); 7739 } 7740 } 7741 7742 /** 7743 * @param uri This uri must NOT contain an embedded userId. 7744 * @param userId The userId in which the uri is to be resolved. 7745 */ 7746 @Override 7747 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7748 enforceNotIsolatedCaller("takePersistableUriPermission"); 7749 7750 Preconditions.checkFlagsArgument(modeFlags, 7751 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7752 7753 synchronized (this) { 7754 final int callingUid = Binder.getCallingUid(); 7755 boolean persistChanged = false; 7756 GrantUri grantUri = new GrantUri(userId, uri, false); 7757 7758 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7759 new GrantUri(userId, uri, false)); 7760 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7761 new GrantUri(userId, uri, true)); 7762 7763 final boolean exactValid = (exactPerm != null) 7764 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7765 final boolean prefixValid = (prefixPerm != null) 7766 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7767 7768 if (!(exactValid || prefixValid)) { 7769 throw new SecurityException("No persistable permission grants found for UID " 7770 + callingUid + " and Uri " + grantUri.toSafeString()); 7771 } 7772 7773 if (exactValid) { 7774 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7775 } 7776 if (prefixValid) { 7777 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7778 } 7779 7780 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7781 7782 if (persistChanged) { 7783 schedulePersistUriGrants(); 7784 } 7785 } 7786 } 7787 7788 /** 7789 * @param uri This uri must NOT contain an embedded userId. 7790 * @param userId The userId in which the uri is to be resolved. 7791 */ 7792 @Override 7793 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7794 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7795 7796 Preconditions.checkFlagsArgument(modeFlags, 7797 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7798 7799 synchronized (this) { 7800 final int callingUid = Binder.getCallingUid(); 7801 boolean persistChanged = false; 7802 7803 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7804 new GrantUri(userId, uri, false)); 7805 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7806 new GrantUri(userId, uri, true)); 7807 if (exactPerm == null && prefixPerm == null) { 7808 throw new SecurityException("No permission grants found for UID " + callingUid 7809 + " and Uri " + uri.toSafeString()); 7810 } 7811 7812 if (exactPerm != null) { 7813 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7814 removeUriPermissionIfNeededLocked(exactPerm); 7815 } 7816 if (prefixPerm != null) { 7817 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7818 removeUriPermissionIfNeededLocked(prefixPerm); 7819 } 7820 7821 if (persistChanged) { 7822 schedulePersistUriGrants(); 7823 } 7824 } 7825 } 7826 7827 /** 7828 * Prune any older {@link UriPermission} for the given UID until outstanding 7829 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7830 * 7831 * @return if any mutations occured that require persisting. 7832 */ 7833 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7834 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7835 if (perms == null) return false; 7836 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7837 7838 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7839 for (UriPermission perm : perms.values()) { 7840 if (perm.persistedModeFlags != 0) { 7841 persisted.add(perm); 7842 } 7843 } 7844 7845 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7846 if (trimCount <= 0) return false; 7847 7848 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7849 for (int i = 0; i < trimCount; i++) { 7850 final UriPermission perm = persisted.get(i); 7851 7852 if (DEBUG_URI_PERMISSION) { 7853 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7854 } 7855 7856 perm.releasePersistableModes(~0); 7857 removeUriPermissionIfNeededLocked(perm); 7858 } 7859 7860 return true; 7861 } 7862 7863 @Override 7864 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7865 String packageName, boolean incoming) { 7866 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7867 Preconditions.checkNotNull(packageName, "packageName"); 7868 7869 final int callingUid = Binder.getCallingUid(); 7870 final IPackageManager pm = AppGlobals.getPackageManager(); 7871 try { 7872 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7873 if (packageUid != callingUid) { 7874 throw new SecurityException( 7875 "Package " + packageName + " does not belong to calling UID " + callingUid); 7876 } 7877 } catch (RemoteException e) { 7878 throw new SecurityException("Failed to verify package name ownership"); 7879 } 7880 7881 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7882 synchronized (this) { 7883 if (incoming) { 7884 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7885 callingUid); 7886 if (perms == null) { 7887 Slog.w(TAG, "No permission grants found for " + packageName); 7888 } else { 7889 for (UriPermission perm : perms.values()) { 7890 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7891 result.add(perm.buildPersistedPublicApiObject()); 7892 } 7893 } 7894 } 7895 } else { 7896 final int size = mGrantedUriPermissions.size(); 7897 for (int i = 0; i < size; i++) { 7898 final ArrayMap<GrantUri, UriPermission> perms = 7899 mGrantedUriPermissions.valueAt(i); 7900 for (UriPermission perm : perms.values()) { 7901 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7902 result.add(perm.buildPersistedPublicApiObject()); 7903 } 7904 } 7905 } 7906 } 7907 } 7908 return new ParceledListSlice<android.content.UriPermission>(result); 7909 } 7910 7911 @Override 7912 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7913 synchronized (this) { 7914 ProcessRecord app = 7915 who != null ? getRecordForAppLocked(who) : null; 7916 if (app == null) return; 7917 7918 Message msg = Message.obtain(); 7919 msg.what = WAIT_FOR_DEBUGGER_MSG; 7920 msg.obj = app; 7921 msg.arg1 = waiting ? 1 : 0; 7922 mHandler.sendMessage(msg); 7923 } 7924 } 7925 7926 @Override 7927 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7928 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7929 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7930 outInfo.availMem = Process.getFreeMemory(); 7931 outInfo.totalMem = Process.getTotalMemory(); 7932 outInfo.threshold = homeAppMem; 7933 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7934 outInfo.hiddenAppThreshold = cachedAppMem; 7935 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7936 ProcessList.SERVICE_ADJ); 7937 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7938 ProcessList.VISIBLE_APP_ADJ); 7939 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7940 ProcessList.FOREGROUND_APP_ADJ); 7941 } 7942 7943 // ========================================================= 7944 // TASK MANAGEMENT 7945 // ========================================================= 7946 7947 @Override 7948 public List<IAppTask> getAppTasks(String callingPackage) { 7949 int callingUid = Binder.getCallingUid(); 7950 long ident = Binder.clearCallingIdentity(); 7951 7952 synchronized(this) { 7953 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7954 try { 7955 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7956 7957 final int N = mRecentTasks.size(); 7958 for (int i = 0; i < N; i++) { 7959 TaskRecord tr = mRecentTasks.get(i); 7960 // Skip tasks that do not match the caller. We don't need to verify 7961 // callingPackage, because we are also limiting to callingUid and know 7962 // that will limit to the correct security sandbox. 7963 if (tr.effectiveUid != callingUid) { 7964 continue; 7965 } 7966 Intent intent = tr.getBaseIntent(); 7967 if (intent == null || 7968 !callingPackage.equals(intent.getComponent().getPackageName())) { 7969 continue; 7970 } 7971 ActivityManager.RecentTaskInfo taskInfo = 7972 createRecentTaskInfoFromTaskRecord(tr); 7973 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7974 list.add(taskImpl); 7975 } 7976 } finally { 7977 Binder.restoreCallingIdentity(ident); 7978 } 7979 return list; 7980 } 7981 } 7982 7983 @Override 7984 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7985 final int callingUid = Binder.getCallingUid(); 7986 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7987 7988 synchronized(this) { 7989 if (localLOGV) Slog.v( 7990 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7991 7992 final boolean allowed = checkCallingPermission( 7993 android.Manifest.permission.GET_TASKS) 7994 == PackageManager.PERMISSION_GRANTED; 7995 if (!allowed) { 7996 Slog.w(TAG, "getTasks: caller " + callingUid 7997 + " does not hold GET_TASKS; limiting output"); 7998 } 7999 8000 // TODO: Improve with MRU list from all ActivityStacks. 8001 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8002 } 8003 8004 return list; 8005 } 8006 8007 TaskRecord getMostRecentTask() { 8008 return mRecentTasks.get(0); 8009 } 8010 8011 /** 8012 * Creates a new RecentTaskInfo from a TaskRecord. 8013 */ 8014 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8015 // Update the task description to reflect any changes in the task stack 8016 tr.updateTaskDescription(); 8017 8018 // Compose the recent task info 8019 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8020 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8021 rti.persistentId = tr.taskId; 8022 rti.baseIntent = new Intent(tr.getBaseIntent()); 8023 rti.origActivity = tr.origActivity; 8024 rti.description = tr.lastDescription; 8025 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8026 rti.userId = tr.userId; 8027 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8028 rti.firstActiveTime = tr.firstActiveTime; 8029 rti.lastActiveTime = tr.lastActiveTime; 8030 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8031 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8032 return rti; 8033 } 8034 8035 @Override 8036 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8037 final int callingUid = Binder.getCallingUid(); 8038 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8039 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8040 8041 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8042 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8043 synchronized (this) { 8044 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8045 == PackageManager.PERMISSION_GRANTED; 8046 if (!allowed) { 8047 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8048 + " does not hold GET_TASKS; limiting output"); 8049 } 8050 final boolean detailed = checkCallingPermission( 8051 android.Manifest.permission.GET_DETAILED_TASKS) 8052 == PackageManager.PERMISSION_GRANTED; 8053 8054 final int N = mRecentTasks.size(); 8055 ArrayList<ActivityManager.RecentTaskInfo> res 8056 = new ArrayList<ActivityManager.RecentTaskInfo>( 8057 maxNum < N ? maxNum : N); 8058 8059 final Set<Integer> includedUsers; 8060 if (includeProfiles) { 8061 includedUsers = getProfileIdsLocked(userId); 8062 } else { 8063 includedUsers = new HashSet<Integer>(); 8064 } 8065 includedUsers.add(Integer.valueOf(userId)); 8066 8067 for (int i=0; i<N && maxNum > 0; i++) { 8068 TaskRecord tr = mRecentTasks.get(i); 8069 // Only add calling user or related users recent tasks 8070 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8071 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8072 continue; 8073 } 8074 8075 // Return the entry if desired by the caller. We always return 8076 // the first entry, because callers always expect this to be the 8077 // foreground app. We may filter others if the caller has 8078 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8079 // we should exclude the entry. 8080 8081 if (i == 0 8082 || withExcluded 8083 || (tr.intent == null) 8084 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8085 == 0)) { 8086 if (!allowed) { 8087 // If the caller doesn't have the GET_TASKS permission, then only 8088 // allow them to see a small subset of tasks -- their own and home. 8089 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8090 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8091 continue; 8092 } 8093 } 8094 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8095 if (tr.stack != null && tr.stack.isHomeStack()) { 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8097 continue; 8098 } 8099 } 8100 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8101 // Don't include auto remove tasks that are finished or finishing. 8102 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8103 + tr); 8104 continue; 8105 } 8106 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8107 && !tr.isAvailable) { 8108 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8109 continue; 8110 } 8111 8112 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8113 if (!detailed) { 8114 rti.baseIntent.replaceExtras((Bundle)null); 8115 } 8116 8117 res.add(rti); 8118 maxNum--; 8119 } 8120 } 8121 return res; 8122 } 8123 } 8124 8125 private TaskRecord recentTaskForIdLocked(int id) { 8126 final int N = mRecentTasks.size(); 8127 for (int i=0; i<N; i++) { 8128 TaskRecord tr = mRecentTasks.get(i); 8129 if (tr.taskId == id) { 8130 return tr; 8131 } 8132 } 8133 return null; 8134 } 8135 8136 @Override 8137 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8138 synchronized (this) { 8139 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8140 "getTaskThumbnail()"); 8141 TaskRecord tr = recentTaskForIdLocked(id); 8142 if (tr != null) { 8143 return tr.getTaskThumbnailLocked(); 8144 } 8145 } 8146 return null; 8147 } 8148 8149 @Override 8150 public int addAppTask(IBinder activityToken, Intent intent, 8151 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8152 final int callingUid = Binder.getCallingUid(); 8153 final long callingIdent = Binder.clearCallingIdentity(); 8154 8155 try { 8156 synchronized (this) { 8157 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8158 if (r == null) { 8159 throw new IllegalArgumentException("Activity does not exist; token=" 8160 + activityToken); 8161 } 8162 ComponentName comp = intent.getComponent(); 8163 if (comp == null) { 8164 throw new IllegalArgumentException("Intent " + intent 8165 + " must specify explicit component"); 8166 } 8167 if (thumbnail.getWidth() != mThumbnailWidth 8168 || thumbnail.getHeight() != mThumbnailHeight) { 8169 throw new IllegalArgumentException("Bad thumbnail size: got " 8170 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8171 + mThumbnailWidth + "x" + mThumbnailHeight); 8172 } 8173 if (intent.getSelector() != null) { 8174 intent.setSelector(null); 8175 } 8176 if (intent.getSourceBounds() != null) { 8177 intent.setSourceBounds(null); 8178 } 8179 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8180 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8181 // The caller has added this as an auto-remove task... that makes no 8182 // sense, so turn off auto-remove. 8183 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8184 } 8185 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8186 // Must be a new task. 8187 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8188 } 8189 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8190 mLastAddedTaskActivity = null; 8191 } 8192 ActivityInfo ainfo = mLastAddedTaskActivity; 8193 if (ainfo == null) { 8194 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8195 comp, 0, UserHandle.getUserId(callingUid)); 8196 if (ainfo.applicationInfo.uid != callingUid) { 8197 throw new SecurityException( 8198 "Can't add task for another application: target uid=" 8199 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8200 } 8201 } 8202 8203 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8204 intent, description); 8205 8206 int trimIdx = trimRecentsForTask(task, false); 8207 if (trimIdx >= 0) { 8208 // If this would have caused a trim, then we'll abort because that 8209 // means it would be added at the end of the list but then just removed. 8210 return -1; 8211 } 8212 8213 final int N = mRecentTasks.size(); 8214 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8215 final TaskRecord tr = mRecentTasks.remove(N - 1); 8216 tr.removedFromRecents(mTaskPersister); 8217 } 8218 8219 task.inRecents = true; 8220 mRecentTasks.add(task); 8221 r.task.stack.addTask(task, false, false); 8222 8223 task.setLastThumbnail(thumbnail); 8224 task.freeLastThumbnail(); 8225 8226 return task.taskId; 8227 } 8228 } finally { 8229 Binder.restoreCallingIdentity(callingIdent); 8230 } 8231 } 8232 8233 @Override 8234 public Point getAppTaskThumbnailSize() { 8235 synchronized (this) { 8236 return new Point(mThumbnailWidth, mThumbnailHeight); 8237 } 8238 } 8239 8240 @Override 8241 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8242 synchronized (this) { 8243 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8244 if (r != null) { 8245 r.taskDescription = td; 8246 r.task.updateTaskDescription(); 8247 } 8248 } 8249 } 8250 8251 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8252 mRecentTasks.remove(tr); 8253 tr.removedFromRecents(mTaskPersister); 8254 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8255 Intent baseIntent = new Intent( 8256 tr.intent != null ? tr.intent : tr.affinityIntent); 8257 ComponentName component = baseIntent.getComponent(); 8258 if (component == null) { 8259 Slog.w(TAG, "Now component for base intent of task: " + tr); 8260 return; 8261 } 8262 8263 // Find any running services associated with this app. 8264 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8265 8266 if (killProcesses) { 8267 // Find any running processes associated with this app. 8268 final String pkg = component.getPackageName(); 8269 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8270 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8271 for (int i=0; i<pmap.size(); i++) { 8272 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8273 for (int j=0; j<uids.size(); j++) { 8274 ProcessRecord proc = uids.valueAt(j); 8275 if (proc.userId != tr.userId) { 8276 continue; 8277 } 8278 if (!proc.pkgList.containsKey(pkg)) { 8279 continue; 8280 } 8281 procs.add(proc); 8282 } 8283 } 8284 8285 // Kill the running processes. 8286 for (int i=0; i<procs.size(); i++) { 8287 ProcessRecord pr = procs.get(i); 8288 if (pr == mHomeProcess) { 8289 // Don't kill the home process along with tasks from the same package. 8290 continue; 8291 } 8292 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8293 pr.kill("remove task", true); 8294 } else { 8295 pr.waitingToKill = "remove task"; 8296 } 8297 } 8298 } 8299 } 8300 8301 /** 8302 * Removes the task with the specified task id. 8303 * 8304 * @param taskId Identifier of the task to be removed. 8305 * @param flags Additional operational flags. May be 0 or 8306 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8307 * @return Returns true if the given task was found and removed. 8308 */ 8309 private boolean removeTaskByIdLocked(int taskId, int flags) { 8310 TaskRecord tr = recentTaskForIdLocked(taskId); 8311 if (tr != null) { 8312 tr.removeTaskActivitiesLocked(); 8313 cleanUpRemovedTaskLocked(tr, flags); 8314 if (tr.isPersistable) { 8315 notifyTaskPersisterLocked(null, true); 8316 } 8317 return true; 8318 } 8319 return false; 8320 } 8321 8322 @Override 8323 public boolean removeTask(int taskId, int flags) { 8324 synchronized (this) { 8325 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8326 "removeTask()"); 8327 long ident = Binder.clearCallingIdentity(); 8328 try { 8329 return removeTaskByIdLocked(taskId, flags); 8330 } finally { 8331 Binder.restoreCallingIdentity(ident); 8332 } 8333 } 8334 } 8335 8336 /** 8337 * TODO: Add mController hook 8338 */ 8339 @Override 8340 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8341 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8342 "moveTaskToFront()"); 8343 8344 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8345 synchronized(this) { 8346 moveTaskToFrontLocked(taskId, flags, options); 8347 } 8348 } 8349 8350 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8351 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8352 Binder.getCallingUid(), "Task to front")) { 8353 ActivityOptions.abort(options); 8354 return; 8355 } 8356 final long origId = Binder.clearCallingIdentity(); 8357 try { 8358 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8359 if (task == null) { 8360 return; 8361 } 8362 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8363 mStackSupervisor.showLockTaskToast(); 8364 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8365 return; 8366 } 8367 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8368 if (prev != null && prev.isRecentsActivity()) { 8369 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8370 } 8371 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8372 } finally { 8373 Binder.restoreCallingIdentity(origId); 8374 } 8375 ActivityOptions.abort(options); 8376 } 8377 8378 @Override 8379 public void moveTaskToBack(int taskId) { 8380 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8381 "moveTaskToBack()"); 8382 8383 synchronized(this) { 8384 TaskRecord tr = recentTaskForIdLocked(taskId); 8385 if (tr != null) { 8386 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8387 ActivityStack stack = tr.stack; 8388 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8389 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8390 Binder.getCallingUid(), "Task to back")) { 8391 return; 8392 } 8393 } 8394 final long origId = Binder.clearCallingIdentity(); 8395 try { 8396 stack.moveTaskToBackLocked(taskId, null); 8397 } finally { 8398 Binder.restoreCallingIdentity(origId); 8399 } 8400 } 8401 } 8402 } 8403 8404 /** 8405 * Moves an activity, and all of the other activities within the same task, to the bottom 8406 * of the history stack. The activity's order within the task is unchanged. 8407 * 8408 * @param token A reference to the activity we wish to move 8409 * @param nonRoot If false then this only works if the activity is the root 8410 * of a task; if true it will work for any activity in a task. 8411 * @return Returns true if the move completed, false if not. 8412 */ 8413 @Override 8414 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8415 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8416 synchronized(this) { 8417 final long origId = Binder.clearCallingIdentity(); 8418 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8419 if (taskId >= 0) { 8420 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8421 } 8422 Binder.restoreCallingIdentity(origId); 8423 } 8424 return false; 8425 } 8426 8427 @Override 8428 public void moveTaskBackwards(int task) { 8429 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8430 "moveTaskBackwards()"); 8431 8432 synchronized(this) { 8433 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8434 Binder.getCallingUid(), "Task backwards")) { 8435 return; 8436 } 8437 final long origId = Binder.clearCallingIdentity(); 8438 moveTaskBackwardsLocked(task); 8439 Binder.restoreCallingIdentity(origId); 8440 } 8441 } 8442 8443 private final void moveTaskBackwardsLocked(int task) { 8444 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8445 } 8446 8447 @Override 8448 public IBinder getHomeActivityToken() throws RemoteException { 8449 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8450 "getHomeActivityToken()"); 8451 synchronized (this) { 8452 return mStackSupervisor.getHomeActivityToken(); 8453 } 8454 } 8455 8456 @Override 8457 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8458 IActivityContainerCallback callback) throws RemoteException { 8459 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8460 "createActivityContainer()"); 8461 synchronized (this) { 8462 if (parentActivityToken == null) { 8463 throw new IllegalArgumentException("parent token must not be null"); 8464 } 8465 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8466 if (r == null) { 8467 return null; 8468 } 8469 if (callback == null) { 8470 throw new IllegalArgumentException("callback must not be null"); 8471 } 8472 return mStackSupervisor.createActivityContainer(r, callback); 8473 } 8474 } 8475 8476 @Override 8477 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8478 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8479 "deleteActivityContainer()"); 8480 synchronized (this) { 8481 mStackSupervisor.deleteActivityContainer(container); 8482 } 8483 } 8484 8485 @Override 8486 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8487 throws RemoteException { 8488 synchronized (this) { 8489 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8490 if (stack != null) { 8491 return stack.mActivityContainer; 8492 } 8493 return null; 8494 } 8495 } 8496 8497 @Override 8498 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8499 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8500 "moveTaskToStack()"); 8501 if (stackId == HOME_STACK_ID) { 8502 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8503 new RuntimeException("here").fillInStackTrace()); 8504 } 8505 synchronized (this) { 8506 long ident = Binder.clearCallingIdentity(); 8507 try { 8508 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8509 + stackId + " toTop=" + toTop); 8510 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8511 } finally { 8512 Binder.restoreCallingIdentity(ident); 8513 } 8514 } 8515 } 8516 8517 @Override 8518 public void resizeStack(int stackBoxId, Rect bounds) { 8519 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8520 "resizeStackBox()"); 8521 long ident = Binder.clearCallingIdentity(); 8522 try { 8523 mWindowManager.resizeStack(stackBoxId, bounds); 8524 } finally { 8525 Binder.restoreCallingIdentity(ident); 8526 } 8527 } 8528 8529 @Override 8530 public List<StackInfo> getAllStackInfos() { 8531 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8532 "getAllStackInfos()"); 8533 long ident = Binder.clearCallingIdentity(); 8534 try { 8535 synchronized (this) { 8536 return mStackSupervisor.getAllStackInfosLocked(); 8537 } 8538 } finally { 8539 Binder.restoreCallingIdentity(ident); 8540 } 8541 } 8542 8543 @Override 8544 public StackInfo getStackInfo(int stackId) { 8545 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8546 "getStackInfo()"); 8547 long ident = Binder.clearCallingIdentity(); 8548 try { 8549 synchronized (this) { 8550 return mStackSupervisor.getStackInfoLocked(stackId); 8551 } 8552 } finally { 8553 Binder.restoreCallingIdentity(ident); 8554 } 8555 } 8556 8557 @Override 8558 public boolean isInHomeStack(int taskId) { 8559 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8560 "getStackInfo()"); 8561 long ident = Binder.clearCallingIdentity(); 8562 try { 8563 synchronized (this) { 8564 TaskRecord tr = recentTaskForIdLocked(taskId); 8565 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8566 } 8567 } finally { 8568 Binder.restoreCallingIdentity(ident); 8569 } 8570 } 8571 8572 @Override 8573 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8574 synchronized(this) { 8575 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8576 } 8577 } 8578 8579 private boolean isLockTaskAuthorized(String pkg) { 8580 final DevicePolicyManager dpm = (DevicePolicyManager) 8581 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8582 try { 8583 int uid = mContext.getPackageManager().getPackageUid(pkg, 8584 Binder.getCallingUserHandle().getIdentifier()); 8585 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8586 } catch (NameNotFoundException e) { 8587 return false; 8588 } 8589 } 8590 8591 void startLockTaskMode(TaskRecord task) { 8592 final String pkg; 8593 synchronized (this) { 8594 pkg = task.intent.getComponent().getPackageName(); 8595 } 8596 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8597 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8598 final TaskRecord taskRecord = task; 8599 mHandler.post(new Runnable() { 8600 @Override 8601 public void run() { 8602 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8603 } 8604 }); 8605 return; 8606 } 8607 long ident = Binder.clearCallingIdentity(); 8608 try { 8609 synchronized (this) { 8610 // Since we lost lock on task, make sure it is still there. 8611 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8612 if (task != null) { 8613 if (!isSystemInitiated 8614 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8615 throw new IllegalArgumentException("Invalid task, not in foreground"); 8616 } 8617 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8618 } 8619 } 8620 } finally { 8621 Binder.restoreCallingIdentity(ident); 8622 } 8623 } 8624 8625 @Override 8626 public void startLockTaskMode(int taskId) { 8627 final TaskRecord task; 8628 long ident = Binder.clearCallingIdentity(); 8629 try { 8630 synchronized (this) { 8631 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8632 } 8633 } finally { 8634 Binder.restoreCallingIdentity(ident); 8635 } 8636 if (task != null) { 8637 startLockTaskMode(task); 8638 } 8639 } 8640 8641 @Override 8642 public void startLockTaskMode(IBinder token) { 8643 final TaskRecord task; 8644 long ident = Binder.clearCallingIdentity(); 8645 try { 8646 synchronized (this) { 8647 final ActivityRecord r = ActivityRecord.forToken(token); 8648 if (r == null) { 8649 return; 8650 } 8651 task = r.task; 8652 } 8653 } finally { 8654 Binder.restoreCallingIdentity(ident); 8655 } 8656 if (task != null) { 8657 startLockTaskMode(task); 8658 } 8659 } 8660 8661 @Override 8662 public void startLockTaskModeOnCurrent() throws RemoteException { 8663 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8664 ActivityRecord r = null; 8665 synchronized (this) { 8666 r = mStackSupervisor.topRunningActivityLocked(); 8667 } 8668 startLockTaskMode(r.task); 8669 } 8670 8671 @Override 8672 public void stopLockTaskMode() { 8673 // Verify that the user matches the package of the intent for the TaskRecord 8674 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8675 // and stopLockTaskMode. 8676 final int callingUid = Binder.getCallingUid(); 8677 if (callingUid != Process.SYSTEM_UID) { 8678 try { 8679 String pkg = 8680 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8681 int uid = mContext.getPackageManager().getPackageUid(pkg, 8682 Binder.getCallingUserHandle().getIdentifier()); 8683 if (uid != callingUid) { 8684 throw new SecurityException("Invalid uid, expected " + uid); 8685 } 8686 } catch (NameNotFoundException e) { 8687 Log.d(TAG, "stopLockTaskMode " + e); 8688 return; 8689 } 8690 } 8691 long ident = Binder.clearCallingIdentity(); 8692 try { 8693 Log.d(TAG, "stopLockTaskMode"); 8694 // Stop lock task 8695 synchronized (this) { 8696 mStackSupervisor.setLockTaskModeLocked(null, false); 8697 } 8698 } finally { 8699 Binder.restoreCallingIdentity(ident); 8700 } 8701 } 8702 8703 @Override 8704 public void stopLockTaskModeOnCurrent() throws RemoteException { 8705 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8706 long ident = Binder.clearCallingIdentity(); 8707 try { 8708 stopLockTaskMode(); 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public boolean isInLockTaskMode() { 8716 synchronized (this) { 8717 return mStackSupervisor.isInLockTaskMode(); 8718 } 8719 } 8720 8721 // ========================================================= 8722 // CONTENT PROVIDERS 8723 // ========================================================= 8724 8725 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8726 List<ProviderInfo> providers = null; 8727 try { 8728 providers = AppGlobals.getPackageManager(). 8729 queryContentProviders(app.processName, app.uid, 8730 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8731 } catch (RemoteException ex) { 8732 } 8733 if (DEBUG_MU) 8734 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8735 int userId = app.userId; 8736 if (providers != null) { 8737 int N = providers.size(); 8738 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8739 for (int i=0; i<N; i++) { 8740 ProviderInfo cpi = 8741 (ProviderInfo)providers.get(i); 8742 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8743 cpi.name, cpi.flags); 8744 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8745 // This is a singleton provider, but a user besides the 8746 // default user is asking to initialize a process it runs 8747 // in... well, no, it doesn't actually run in this process, 8748 // it runs in the process of the default user. Get rid of it. 8749 providers.remove(i); 8750 N--; 8751 i--; 8752 continue; 8753 } 8754 8755 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8756 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8757 if (cpr == null) { 8758 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8759 mProviderMap.putProviderByClass(comp, cpr); 8760 } 8761 if (DEBUG_MU) 8762 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8763 app.pubProviders.put(cpi.name, cpr); 8764 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8765 // Don't add this if it is a platform component that is marked 8766 // to run in multiple processes, because this is actually 8767 // part of the framework so doesn't make sense to track as a 8768 // separate apk in the process. 8769 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8770 mProcessStats); 8771 } 8772 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8773 } 8774 } 8775 return providers; 8776 } 8777 8778 /** 8779 * Check if {@link ProcessRecord} has a possible chance at accessing the 8780 * given {@link ProviderInfo}. Final permission checking is always done 8781 * in {@link ContentProvider}. 8782 */ 8783 private final String checkContentProviderPermissionLocked( 8784 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8785 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8786 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8787 boolean checkedGrants = false; 8788 if (checkUser) { 8789 // Looking for cross-user grants before enforcing the typical cross-users permissions 8790 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8791 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8792 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8793 return null; 8794 } 8795 checkedGrants = true; 8796 } 8797 userId = handleIncomingUser(callingPid, callingUid, userId, 8798 false, ALLOW_NON_FULL, 8799 "checkContentProviderPermissionLocked " + cpi.authority, null); 8800 if (userId != tmpTargetUserId) { 8801 // When we actually went to determine the final targer user ID, this ended 8802 // up different than our initial check for the authority. This is because 8803 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8804 // SELF. So we need to re-check the grants again. 8805 checkedGrants = false; 8806 } 8807 } 8808 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8809 cpi.applicationInfo.uid, cpi.exported) 8810 == PackageManager.PERMISSION_GRANTED) { 8811 return null; 8812 } 8813 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8814 cpi.applicationInfo.uid, cpi.exported) 8815 == PackageManager.PERMISSION_GRANTED) { 8816 return null; 8817 } 8818 8819 PathPermission[] pps = cpi.pathPermissions; 8820 if (pps != null) { 8821 int i = pps.length; 8822 while (i > 0) { 8823 i--; 8824 PathPermission pp = pps[i]; 8825 String pprperm = pp.getReadPermission(); 8826 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8827 cpi.applicationInfo.uid, cpi.exported) 8828 == PackageManager.PERMISSION_GRANTED) { 8829 return null; 8830 } 8831 String ppwperm = pp.getWritePermission(); 8832 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8833 cpi.applicationInfo.uid, cpi.exported) 8834 == PackageManager.PERMISSION_GRANTED) { 8835 return null; 8836 } 8837 } 8838 } 8839 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8840 return null; 8841 } 8842 8843 String msg; 8844 if (!cpi.exported) { 8845 msg = "Permission Denial: opening provider " + cpi.name 8846 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8847 + ", uid=" + callingUid + ") that is not exported from uid " 8848 + cpi.applicationInfo.uid; 8849 } else { 8850 msg = "Permission Denial: opening provider " + cpi.name 8851 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8852 + ", uid=" + callingUid + ") requires " 8853 + cpi.readPermission + " or " + cpi.writePermission; 8854 } 8855 Slog.w(TAG, msg); 8856 return msg; 8857 } 8858 8859 /** 8860 * Returns if the ContentProvider has granted a uri to callingUid 8861 */ 8862 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8863 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8864 if (perms != null) { 8865 for (int i=perms.size()-1; i>=0; i--) { 8866 GrantUri grantUri = perms.keyAt(i); 8867 if (grantUri.sourceUserId == userId || !checkUser) { 8868 if (matchesProvider(grantUri.uri, cpi)) { 8869 return true; 8870 } 8871 } 8872 } 8873 } 8874 return false; 8875 } 8876 8877 /** 8878 * Returns true if the uri authority is one of the authorities specified in the provider. 8879 */ 8880 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8881 String uriAuth = uri.getAuthority(); 8882 String cpiAuth = cpi.authority; 8883 if (cpiAuth.indexOf(';') == -1) { 8884 return cpiAuth.equals(uriAuth); 8885 } 8886 String[] cpiAuths = cpiAuth.split(";"); 8887 int length = cpiAuths.length; 8888 for (int i = 0; i < length; i++) { 8889 if (cpiAuths[i].equals(uriAuth)) return true; 8890 } 8891 return false; 8892 } 8893 8894 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8895 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8896 if (r != null) { 8897 for (int i=0; i<r.conProviders.size(); i++) { 8898 ContentProviderConnection conn = r.conProviders.get(i); 8899 if (conn.provider == cpr) { 8900 if (DEBUG_PROVIDER) Slog.v(TAG, 8901 "Adding provider requested by " 8902 + r.processName + " from process " 8903 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8904 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8905 if (stable) { 8906 conn.stableCount++; 8907 conn.numStableIncs++; 8908 } else { 8909 conn.unstableCount++; 8910 conn.numUnstableIncs++; 8911 } 8912 return conn; 8913 } 8914 } 8915 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8916 if (stable) { 8917 conn.stableCount = 1; 8918 conn.numStableIncs = 1; 8919 } else { 8920 conn.unstableCount = 1; 8921 conn.numUnstableIncs = 1; 8922 } 8923 cpr.connections.add(conn); 8924 r.conProviders.add(conn); 8925 return conn; 8926 } 8927 cpr.addExternalProcessHandleLocked(externalProcessToken); 8928 return null; 8929 } 8930 8931 boolean decProviderCountLocked(ContentProviderConnection conn, 8932 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8933 if (conn != null) { 8934 cpr = conn.provider; 8935 if (DEBUG_PROVIDER) Slog.v(TAG, 8936 "Removing provider requested by " 8937 + conn.client.processName + " from process " 8938 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8939 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8940 if (stable) { 8941 conn.stableCount--; 8942 } else { 8943 conn.unstableCount--; 8944 } 8945 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8946 cpr.connections.remove(conn); 8947 conn.client.conProviders.remove(conn); 8948 return true; 8949 } 8950 return false; 8951 } 8952 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8953 return false; 8954 } 8955 8956 private void checkTime(long startTime, String where) { 8957 long now = SystemClock.elapsedRealtime(); 8958 if ((now-startTime) > 1000) { 8959 // If we are taking more than a second, log about it. 8960 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8961 } 8962 } 8963 8964 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8965 String name, IBinder token, boolean stable, int userId) { 8966 ContentProviderRecord cpr; 8967 ContentProviderConnection conn = null; 8968 ProviderInfo cpi = null; 8969 8970 synchronized(this) { 8971 long startTime = SystemClock.elapsedRealtime(); 8972 8973 ProcessRecord r = null; 8974 if (caller != null) { 8975 r = getRecordForAppLocked(caller); 8976 if (r == null) { 8977 throw new SecurityException( 8978 "Unable to find app for caller " + caller 8979 + " (pid=" + Binder.getCallingPid() 8980 + ") when getting content provider " + name); 8981 } 8982 } 8983 8984 boolean checkCrossUser = true; 8985 8986 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 8987 8988 // First check if this content provider has been published... 8989 cpr = mProviderMap.getProviderByName(name, userId); 8990 // If that didn't work, check if it exists for user 0 and then 8991 // verify that it's a singleton provider before using it. 8992 if (cpr == null && userId != UserHandle.USER_OWNER) { 8993 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8994 if (cpr != null) { 8995 cpi = cpr.info; 8996 if (isSingleton(cpi.processName, cpi.applicationInfo, 8997 cpi.name, cpi.flags) 8998 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8999 userId = UserHandle.USER_OWNER; 9000 checkCrossUser = false; 9001 } else { 9002 cpr = null; 9003 cpi = null; 9004 } 9005 } 9006 } 9007 9008 boolean providerRunning = cpr != null; 9009 if (providerRunning) { 9010 cpi = cpr.info; 9011 String msg; 9012 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9013 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9014 != null) { 9015 throw new SecurityException(msg); 9016 } 9017 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9018 9019 if (r != null && cpr.canRunHere(r)) { 9020 // This provider has been published or is in the process 9021 // of being published... but it is also allowed to run 9022 // in the caller's process, so don't make a connection 9023 // and just let the caller instantiate its own instance. 9024 ContentProviderHolder holder = cpr.newHolder(null); 9025 // don't give caller the provider object, it needs 9026 // to make its own. 9027 holder.provider = null; 9028 return holder; 9029 } 9030 9031 final long origId = Binder.clearCallingIdentity(); 9032 9033 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9034 9035 // In this case the provider instance already exists, so we can 9036 // return it right away. 9037 conn = incProviderCountLocked(r, cpr, token, stable); 9038 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9039 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9040 // If this is a perceptible app accessing the provider, 9041 // make sure to count it as being accessed and thus 9042 // back up on the LRU list. This is good because 9043 // content providers are often expensive to start. 9044 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9045 updateLruProcessLocked(cpr.proc, false, null); 9046 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9047 } 9048 } 9049 9050 if (cpr.proc != null) { 9051 if (false) { 9052 if (cpr.name.flattenToShortString().equals( 9053 "com.android.providers.calendar/.CalendarProvider2")) { 9054 Slog.v(TAG, "****************** KILLING " 9055 + cpr.name.flattenToShortString()); 9056 Process.killProcess(cpr.proc.pid); 9057 } 9058 } 9059 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9060 boolean success = updateOomAdjLocked(cpr.proc); 9061 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9062 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9063 // NOTE: there is still a race here where a signal could be 9064 // pending on the process even though we managed to update its 9065 // adj level. Not sure what to do about this, but at least 9066 // the race is now smaller. 9067 if (!success) { 9068 // Uh oh... it looks like the provider's process 9069 // has been killed on us. We need to wait for a new 9070 // process to be started, and make sure its death 9071 // doesn't kill our process. 9072 Slog.i(TAG, 9073 "Existing provider " + cpr.name.flattenToShortString() 9074 + " is crashing; detaching " + r); 9075 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9076 checkTime(startTime, "getContentProviderImpl: before appDied"); 9077 appDiedLocked(cpr.proc); 9078 checkTime(startTime, "getContentProviderImpl: after appDied"); 9079 if (!lastRef) { 9080 // This wasn't the last ref our process had on 9081 // the provider... we have now been killed, bail. 9082 return null; 9083 } 9084 providerRunning = false; 9085 conn = null; 9086 } 9087 } 9088 9089 Binder.restoreCallingIdentity(origId); 9090 } 9091 9092 boolean singleton; 9093 if (!providerRunning) { 9094 try { 9095 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9096 cpi = AppGlobals.getPackageManager(). 9097 resolveContentProvider(name, 9098 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9099 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9100 } catch (RemoteException ex) { 9101 } 9102 if (cpi == null) { 9103 return null; 9104 } 9105 // If the provider is a singleton AND 9106 // (it's a call within the same user || the provider is a 9107 // privileged app) 9108 // Then allow connecting to the singleton provider 9109 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9110 cpi.name, cpi.flags) 9111 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9112 if (singleton) { 9113 userId = UserHandle.USER_OWNER; 9114 } 9115 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9116 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9117 9118 String msg; 9119 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9120 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9121 != null) { 9122 throw new SecurityException(msg); 9123 } 9124 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9125 9126 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9127 && !cpi.processName.equals("system")) { 9128 // If this content provider does not run in the system 9129 // process, and the system is not yet ready to run other 9130 // processes, then fail fast instead of hanging. 9131 throw new IllegalArgumentException( 9132 "Attempt to launch content provider before system ready"); 9133 } 9134 9135 // Make sure that the user who owns this provider is started. If not, 9136 // we don't want to allow it to run. 9137 if (mStartedUsers.get(userId) == null) { 9138 Slog.w(TAG, "Unable to launch app " 9139 + cpi.applicationInfo.packageName + "/" 9140 + cpi.applicationInfo.uid + " for provider " 9141 + name + ": user " + userId + " is stopped"); 9142 return null; 9143 } 9144 9145 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9146 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9147 cpr = mProviderMap.getProviderByClass(comp, userId); 9148 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9149 final boolean firstClass = cpr == null; 9150 if (firstClass) { 9151 try { 9152 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9153 ApplicationInfo ai = 9154 AppGlobals.getPackageManager(). 9155 getApplicationInfo( 9156 cpi.applicationInfo.packageName, 9157 STOCK_PM_FLAGS, userId); 9158 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9159 if (ai == null) { 9160 Slog.w(TAG, "No package info for content provider " 9161 + cpi.name); 9162 return null; 9163 } 9164 ai = getAppInfoForUser(ai, userId); 9165 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9166 } catch (RemoteException ex) { 9167 // pm is in same process, this will never happen. 9168 } 9169 } 9170 9171 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9172 9173 if (r != null && cpr.canRunHere(r)) { 9174 // If this is a multiprocess provider, then just return its 9175 // info and allow the caller to instantiate it. Only do 9176 // this if the provider is the same user as the caller's 9177 // process, or can run as root (so can be in any process). 9178 return cpr.newHolder(null); 9179 } 9180 9181 if (DEBUG_PROVIDER) { 9182 RuntimeException e = new RuntimeException("here"); 9183 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9184 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9185 } 9186 9187 // This is single process, and our app is now connecting to it. 9188 // See if we are already in the process of launching this 9189 // provider. 9190 final int N = mLaunchingProviders.size(); 9191 int i; 9192 for (i=0; i<N; i++) { 9193 if (mLaunchingProviders.get(i) == cpr) { 9194 break; 9195 } 9196 } 9197 9198 // If the provider is not already being launched, then get it 9199 // started. 9200 if (i >= N) { 9201 final long origId = Binder.clearCallingIdentity(); 9202 9203 try { 9204 // Content provider is now in use, its package can't be stopped. 9205 try { 9206 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9207 AppGlobals.getPackageManager().setPackageStoppedState( 9208 cpr.appInfo.packageName, false, userId); 9209 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9210 } catch (RemoteException e) { 9211 } catch (IllegalArgumentException e) { 9212 Slog.w(TAG, "Failed trying to unstop package " 9213 + cpr.appInfo.packageName + ": " + e); 9214 } 9215 9216 // Use existing process if already started 9217 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9218 ProcessRecord proc = getProcessRecordLocked( 9219 cpi.processName, cpr.appInfo.uid, false); 9220 if (proc != null && proc.thread != null) { 9221 if (DEBUG_PROVIDER) { 9222 Slog.d(TAG, "Installing in existing process " + proc); 9223 } 9224 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9225 proc.pubProviders.put(cpi.name, cpr); 9226 try { 9227 proc.thread.scheduleInstallProvider(cpi); 9228 } catch (RemoteException e) { 9229 } 9230 } else { 9231 checkTime(startTime, "getContentProviderImpl: before start process"); 9232 proc = startProcessLocked(cpi.processName, 9233 cpr.appInfo, false, 0, "content provider", 9234 new ComponentName(cpi.applicationInfo.packageName, 9235 cpi.name), false, false, false); 9236 checkTime(startTime, "getContentProviderImpl: after start process"); 9237 if (proc == null) { 9238 Slog.w(TAG, "Unable to launch app " 9239 + cpi.applicationInfo.packageName + "/" 9240 + cpi.applicationInfo.uid + " for provider " 9241 + name + ": process is bad"); 9242 return null; 9243 } 9244 } 9245 cpr.launchingApp = proc; 9246 mLaunchingProviders.add(cpr); 9247 } finally { 9248 Binder.restoreCallingIdentity(origId); 9249 } 9250 } 9251 9252 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9253 9254 // Make sure the provider is published (the same provider class 9255 // may be published under multiple names). 9256 if (firstClass) { 9257 mProviderMap.putProviderByClass(comp, cpr); 9258 } 9259 9260 mProviderMap.putProviderByName(name, cpr); 9261 conn = incProviderCountLocked(r, cpr, token, stable); 9262 if (conn != null) { 9263 conn.waiting = true; 9264 } 9265 } 9266 checkTime(startTime, "getContentProviderImpl: done!"); 9267 } 9268 9269 // Wait for the provider to be published... 9270 synchronized (cpr) { 9271 while (cpr.provider == null) { 9272 if (cpr.launchingApp == null) { 9273 Slog.w(TAG, "Unable to launch app " 9274 + cpi.applicationInfo.packageName + "/" 9275 + cpi.applicationInfo.uid + " for provider " 9276 + name + ": launching app became null"); 9277 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9278 UserHandle.getUserId(cpi.applicationInfo.uid), 9279 cpi.applicationInfo.packageName, 9280 cpi.applicationInfo.uid, name); 9281 return null; 9282 } 9283 try { 9284 if (DEBUG_MU) { 9285 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9286 + cpr.launchingApp); 9287 } 9288 if (conn != null) { 9289 conn.waiting = true; 9290 } 9291 cpr.wait(); 9292 } catch (InterruptedException ex) { 9293 } finally { 9294 if (conn != null) { 9295 conn.waiting = false; 9296 } 9297 } 9298 } 9299 } 9300 return cpr != null ? cpr.newHolder(conn) : null; 9301 } 9302 9303 @Override 9304 public final ContentProviderHolder getContentProvider( 9305 IApplicationThread caller, String name, int userId, boolean stable) { 9306 enforceNotIsolatedCaller("getContentProvider"); 9307 if (caller == null) { 9308 String msg = "null IApplicationThread when getting content provider " 9309 + name; 9310 Slog.w(TAG, msg); 9311 throw new SecurityException(msg); 9312 } 9313 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9314 // with cross-user grant. 9315 return getContentProviderImpl(caller, name, null, stable, userId); 9316 } 9317 9318 public ContentProviderHolder getContentProviderExternal( 9319 String name, int userId, IBinder token) { 9320 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9321 "Do not have permission in call getContentProviderExternal()"); 9322 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9323 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9324 return getContentProviderExternalUnchecked(name, token, userId); 9325 } 9326 9327 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9328 IBinder token, int userId) { 9329 return getContentProviderImpl(null, name, token, true, userId); 9330 } 9331 9332 /** 9333 * Drop a content provider from a ProcessRecord's bookkeeping 9334 */ 9335 public void removeContentProvider(IBinder connection, boolean stable) { 9336 enforceNotIsolatedCaller("removeContentProvider"); 9337 long ident = Binder.clearCallingIdentity(); 9338 try { 9339 synchronized (this) { 9340 ContentProviderConnection conn; 9341 try { 9342 conn = (ContentProviderConnection)connection; 9343 } catch (ClassCastException e) { 9344 String msg ="removeContentProvider: " + connection 9345 + " not a ContentProviderConnection"; 9346 Slog.w(TAG, msg); 9347 throw new IllegalArgumentException(msg); 9348 } 9349 if (conn == null) { 9350 throw new NullPointerException("connection is null"); 9351 } 9352 if (decProviderCountLocked(conn, null, null, stable)) { 9353 updateOomAdjLocked(); 9354 } 9355 } 9356 } finally { 9357 Binder.restoreCallingIdentity(ident); 9358 } 9359 } 9360 9361 public void removeContentProviderExternal(String name, IBinder token) { 9362 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9363 "Do not have permission in call removeContentProviderExternal()"); 9364 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9365 } 9366 9367 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9368 synchronized (this) { 9369 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9370 if(cpr == null) { 9371 //remove from mProvidersByClass 9372 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9373 return; 9374 } 9375 9376 //update content provider record entry info 9377 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9378 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9379 if (localCpr.hasExternalProcessHandles()) { 9380 if (localCpr.removeExternalProcessHandleLocked(token)) { 9381 updateOomAdjLocked(); 9382 } else { 9383 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9384 + " with no external reference for token: " 9385 + token + "."); 9386 } 9387 } else { 9388 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9389 + " with no external references."); 9390 } 9391 } 9392 } 9393 9394 public final void publishContentProviders(IApplicationThread caller, 9395 List<ContentProviderHolder> providers) { 9396 if (providers == null) { 9397 return; 9398 } 9399 9400 enforceNotIsolatedCaller("publishContentProviders"); 9401 synchronized (this) { 9402 final ProcessRecord r = getRecordForAppLocked(caller); 9403 if (DEBUG_MU) 9404 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9405 if (r == null) { 9406 throw new SecurityException( 9407 "Unable to find app for caller " + caller 9408 + " (pid=" + Binder.getCallingPid() 9409 + ") when publishing content providers"); 9410 } 9411 9412 final long origId = Binder.clearCallingIdentity(); 9413 9414 final int N = providers.size(); 9415 for (int i=0; i<N; i++) { 9416 ContentProviderHolder src = providers.get(i); 9417 if (src == null || src.info == null || src.provider == null) { 9418 continue; 9419 } 9420 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9421 if (DEBUG_MU) 9422 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9423 if (dst != null) { 9424 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9425 mProviderMap.putProviderByClass(comp, dst); 9426 String names[] = dst.info.authority.split(";"); 9427 for (int j = 0; j < names.length; j++) { 9428 mProviderMap.putProviderByName(names[j], dst); 9429 } 9430 9431 int NL = mLaunchingProviders.size(); 9432 int j; 9433 for (j=0; j<NL; j++) { 9434 if (mLaunchingProviders.get(j) == dst) { 9435 mLaunchingProviders.remove(j); 9436 j--; 9437 NL--; 9438 } 9439 } 9440 synchronized (dst) { 9441 dst.provider = src.provider; 9442 dst.proc = r; 9443 dst.notifyAll(); 9444 } 9445 updateOomAdjLocked(r); 9446 } 9447 } 9448 9449 Binder.restoreCallingIdentity(origId); 9450 } 9451 } 9452 9453 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9454 ContentProviderConnection conn; 9455 try { 9456 conn = (ContentProviderConnection)connection; 9457 } catch (ClassCastException e) { 9458 String msg ="refContentProvider: " + connection 9459 + " not a ContentProviderConnection"; 9460 Slog.w(TAG, msg); 9461 throw new IllegalArgumentException(msg); 9462 } 9463 if (conn == null) { 9464 throw new NullPointerException("connection is null"); 9465 } 9466 9467 synchronized (this) { 9468 if (stable > 0) { 9469 conn.numStableIncs += stable; 9470 } 9471 stable = conn.stableCount + stable; 9472 if (stable < 0) { 9473 throw new IllegalStateException("stableCount < 0: " + stable); 9474 } 9475 9476 if (unstable > 0) { 9477 conn.numUnstableIncs += unstable; 9478 } 9479 unstable = conn.unstableCount + unstable; 9480 if (unstable < 0) { 9481 throw new IllegalStateException("unstableCount < 0: " + unstable); 9482 } 9483 9484 if ((stable+unstable) <= 0) { 9485 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9486 + stable + " unstable=" + unstable); 9487 } 9488 conn.stableCount = stable; 9489 conn.unstableCount = unstable; 9490 return !conn.dead; 9491 } 9492 } 9493 9494 public void unstableProviderDied(IBinder connection) { 9495 ContentProviderConnection conn; 9496 try { 9497 conn = (ContentProviderConnection)connection; 9498 } catch (ClassCastException e) { 9499 String msg ="refContentProvider: " + connection 9500 + " not a ContentProviderConnection"; 9501 Slog.w(TAG, msg); 9502 throw new IllegalArgumentException(msg); 9503 } 9504 if (conn == null) { 9505 throw new NullPointerException("connection is null"); 9506 } 9507 9508 // Safely retrieve the content provider associated with the connection. 9509 IContentProvider provider; 9510 synchronized (this) { 9511 provider = conn.provider.provider; 9512 } 9513 9514 if (provider == null) { 9515 // Um, yeah, we're way ahead of you. 9516 return; 9517 } 9518 9519 // Make sure the caller is being honest with us. 9520 if (provider.asBinder().pingBinder()) { 9521 // Er, no, still looks good to us. 9522 synchronized (this) { 9523 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9524 + " says " + conn + " died, but we don't agree"); 9525 return; 9526 } 9527 } 9528 9529 // Well look at that! It's dead! 9530 synchronized (this) { 9531 if (conn.provider.provider != provider) { 9532 // But something changed... good enough. 9533 return; 9534 } 9535 9536 ProcessRecord proc = conn.provider.proc; 9537 if (proc == null || proc.thread == null) { 9538 // Seems like the process is already cleaned up. 9539 return; 9540 } 9541 9542 // As far as we're concerned, this is just like receiving a 9543 // death notification... just a bit prematurely. 9544 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9545 + ") early provider death"); 9546 final long ident = Binder.clearCallingIdentity(); 9547 try { 9548 appDiedLocked(proc); 9549 } finally { 9550 Binder.restoreCallingIdentity(ident); 9551 } 9552 } 9553 } 9554 9555 @Override 9556 public void appNotRespondingViaProvider(IBinder connection) { 9557 enforceCallingPermission( 9558 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9559 9560 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9561 if (conn == null) { 9562 Slog.w(TAG, "ContentProviderConnection is null"); 9563 return; 9564 } 9565 9566 final ProcessRecord host = conn.provider.proc; 9567 if (host == null) { 9568 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9569 return; 9570 } 9571 9572 final long token = Binder.clearCallingIdentity(); 9573 try { 9574 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9575 } finally { 9576 Binder.restoreCallingIdentity(token); 9577 } 9578 } 9579 9580 public final void installSystemProviders() { 9581 List<ProviderInfo> providers; 9582 synchronized (this) { 9583 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9584 providers = generateApplicationProvidersLocked(app); 9585 if (providers != null) { 9586 for (int i=providers.size()-1; i>=0; i--) { 9587 ProviderInfo pi = (ProviderInfo)providers.get(i); 9588 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9589 Slog.w(TAG, "Not installing system proc provider " + pi.name 9590 + ": not system .apk"); 9591 providers.remove(i); 9592 } 9593 } 9594 } 9595 } 9596 if (providers != null) { 9597 mSystemThread.installSystemProviders(providers); 9598 } 9599 9600 mCoreSettingsObserver = new CoreSettingsObserver(this); 9601 9602 //mUsageStatsService.monitorPackages(); 9603 } 9604 9605 /** 9606 * Allows apps to retrieve the MIME type of a URI. 9607 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9608 * users, then it does not need permission to access the ContentProvider. 9609 * Either, it needs cross-user uri grants. 9610 * 9611 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9612 * 9613 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9614 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9615 */ 9616 public String getProviderMimeType(Uri uri, int userId) { 9617 enforceNotIsolatedCaller("getProviderMimeType"); 9618 final String name = uri.getAuthority(); 9619 int callingUid = Binder.getCallingUid(); 9620 int callingPid = Binder.getCallingPid(); 9621 long ident = 0; 9622 boolean clearedIdentity = false; 9623 userId = unsafeConvertIncomingUser(userId); 9624 if (UserHandle.getUserId(callingUid) != userId) { 9625 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9626 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9627 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9628 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9629 clearedIdentity = true; 9630 ident = Binder.clearCallingIdentity(); 9631 } 9632 } 9633 ContentProviderHolder holder = null; 9634 try { 9635 holder = getContentProviderExternalUnchecked(name, null, userId); 9636 if (holder != null) { 9637 return holder.provider.getType(uri); 9638 } 9639 } catch (RemoteException e) { 9640 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9641 return null; 9642 } finally { 9643 // We need to clear the identity to call removeContentProviderExternalUnchecked 9644 if (!clearedIdentity) { 9645 ident = Binder.clearCallingIdentity(); 9646 } 9647 try { 9648 if (holder != null) { 9649 removeContentProviderExternalUnchecked(name, null, userId); 9650 } 9651 } finally { 9652 Binder.restoreCallingIdentity(ident); 9653 } 9654 } 9655 9656 return null; 9657 } 9658 9659 // ========================================================= 9660 // GLOBAL MANAGEMENT 9661 // ========================================================= 9662 9663 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9664 boolean isolated, int isolatedUid) { 9665 String proc = customProcess != null ? customProcess : info.processName; 9666 BatteryStatsImpl.Uid.Proc ps = null; 9667 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9668 int uid = info.uid; 9669 if (isolated) { 9670 if (isolatedUid == 0) { 9671 int userId = UserHandle.getUserId(uid); 9672 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9673 while (true) { 9674 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9675 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9676 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9677 } 9678 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9679 mNextIsolatedProcessUid++; 9680 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9681 // No process for this uid, use it. 9682 break; 9683 } 9684 stepsLeft--; 9685 if (stepsLeft <= 0) { 9686 return null; 9687 } 9688 } 9689 } else { 9690 // Special case for startIsolatedProcess (internal only), where 9691 // the uid of the isolated process is specified by the caller. 9692 uid = isolatedUid; 9693 } 9694 } 9695 return new ProcessRecord(stats, info, proc, uid); 9696 } 9697 9698 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9699 String abiOverride) { 9700 ProcessRecord app; 9701 if (!isolated) { 9702 app = getProcessRecordLocked(info.processName, info.uid, true); 9703 } else { 9704 app = null; 9705 } 9706 9707 if (app == null) { 9708 app = newProcessRecordLocked(info, null, isolated, 0); 9709 mProcessNames.put(info.processName, app.uid, app); 9710 if (isolated) { 9711 mIsolatedProcesses.put(app.uid, app); 9712 } 9713 updateLruProcessLocked(app, false, null); 9714 updateOomAdjLocked(); 9715 } 9716 9717 // This package really, really can not be stopped. 9718 try { 9719 AppGlobals.getPackageManager().setPackageStoppedState( 9720 info.packageName, false, UserHandle.getUserId(app.uid)); 9721 } catch (RemoteException e) { 9722 } catch (IllegalArgumentException e) { 9723 Slog.w(TAG, "Failed trying to unstop package " 9724 + info.packageName + ": " + e); 9725 } 9726 9727 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9728 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9729 app.persistent = true; 9730 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9731 } 9732 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9733 mPersistentStartingProcesses.add(app); 9734 startProcessLocked(app, "added application", app.processName, abiOverride, 9735 null /* entryPoint */, null /* entryPointArgs */); 9736 } 9737 9738 return app; 9739 } 9740 9741 public void unhandledBack() { 9742 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9743 "unhandledBack()"); 9744 9745 synchronized(this) { 9746 final long origId = Binder.clearCallingIdentity(); 9747 try { 9748 getFocusedStack().unhandledBackLocked(); 9749 } finally { 9750 Binder.restoreCallingIdentity(origId); 9751 } 9752 } 9753 } 9754 9755 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9756 enforceNotIsolatedCaller("openContentUri"); 9757 final int userId = UserHandle.getCallingUserId(); 9758 String name = uri.getAuthority(); 9759 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9760 ParcelFileDescriptor pfd = null; 9761 if (cph != null) { 9762 // We record the binder invoker's uid in thread-local storage before 9763 // going to the content provider to open the file. Later, in the code 9764 // that handles all permissions checks, we look for this uid and use 9765 // that rather than the Activity Manager's own uid. The effect is that 9766 // we do the check against the caller's permissions even though it looks 9767 // to the content provider like the Activity Manager itself is making 9768 // the request. 9769 sCallerIdentity.set(new Identity( 9770 Binder.getCallingPid(), Binder.getCallingUid())); 9771 try { 9772 pfd = cph.provider.openFile(null, uri, "r", null); 9773 } catch (FileNotFoundException e) { 9774 // do nothing; pfd will be returned null 9775 } finally { 9776 // Ensure that whatever happens, we clean up the identity state 9777 sCallerIdentity.remove(); 9778 } 9779 9780 // We've got the fd now, so we're done with the provider. 9781 removeContentProviderExternalUnchecked(name, null, userId); 9782 } else { 9783 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9784 } 9785 return pfd; 9786 } 9787 9788 // Actually is sleeping or shutting down or whatever else in the future 9789 // is an inactive state. 9790 public boolean isSleepingOrShuttingDown() { 9791 return mSleeping || mShuttingDown; 9792 } 9793 9794 public boolean isSleeping() { 9795 return mSleeping; 9796 } 9797 9798 void goingToSleep() { 9799 synchronized(this) { 9800 mWentToSleep = true; 9801 updateEventDispatchingLocked(); 9802 goToSleepIfNeededLocked(); 9803 } 9804 } 9805 9806 void finishRunningVoiceLocked() { 9807 if (mRunningVoice) { 9808 mRunningVoice = false; 9809 goToSleepIfNeededLocked(); 9810 } 9811 } 9812 9813 void goToSleepIfNeededLocked() { 9814 if (mWentToSleep && !mRunningVoice) { 9815 if (!mSleeping) { 9816 mSleeping = true; 9817 mStackSupervisor.goingToSleepLocked(); 9818 9819 // Initialize the wake times of all processes. 9820 checkExcessivePowerUsageLocked(false); 9821 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9822 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9823 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9824 } 9825 } 9826 } 9827 9828 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9829 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9830 // Never persist the home stack. 9831 return; 9832 } 9833 mTaskPersister.wakeup(task, flush); 9834 } 9835 9836 @Override 9837 public boolean shutdown(int timeout) { 9838 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9839 != PackageManager.PERMISSION_GRANTED) { 9840 throw new SecurityException("Requires permission " 9841 + android.Manifest.permission.SHUTDOWN); 9842 } 9843 9844 boolean timedout = false; 9845 9846 synchronized(this) { 9847 mShuttingDown = true; 9848 updateEventDispatchingLocked(); 9849 timedout = mStackSupervisor.shutdownLocked(timeout); 9850 } 9851 9852 mAppOpsService.shutdown(); 9853 if (mUsageStatsService != null) { 9854 mUsageStatsService.prepareShutdown(); 9855 } 9856 mBatteryStatsService.shutdown(); 9857 synchronized (this) { 9858 mProcessStats.shutdownLocked(); 9859 } 9860 notifyTaskPersisterLocked(null, true); 9861 9862 return timedout; 9863 } 9864 9865 public final void activitySlept(IBinder token) { 9866 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9867 9868 final long origId = Binder.clearCallingIdentity(); 9869 9870 synchronized (this) { 9871 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9872 if (r != null) { 9873 mStackSupervisor.activitySleptLocked(r); 9874 } 9875 } 9876 9877 Binder.restoreCallingIdentity(origId); 9878 } 9879 9880 void logLockScreen(String msg) { 9881 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9882 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9883 mWentToSleep + " mSleeping=" + mSleeping); 9884 } 9885 9886 private void comeOutOfSleepIfNeededLocked() { 9887 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9888 if (mSleeping) { 9889 mSleeping = false; 9890 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9891 } 9892 } 9893 } 9894 9895 void wakingUp() { 9896 synchronized(this) { 9897 mWentToSleep = false; 9898 updateEventDispatchingLocked(); 9899 comeOutOfSleepIfNeededLocked(); 9900 } 9901 } 9902 9903 void startRunningVoiceLocked() { 9904 if (!mRunningVoice) { 9905 mRunningVoice = true; 9906 comeOutOfSleepIfNeededLocked(); 9907 } 9908 } 9909 9910 private void updateEventDispatchingLocked() { 9911 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9912 } 9913 9914 public void setLockScreenShown(boolean shown) { 9915 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9916 != PackageManager.PERMISSION_GRANTED) { 9917 throw new SecurityException("Requires permission " 9918 + android.Manifest.permission.DEVICE_POWER); 9919 } 9920 9921 synchronized(this) { 9922 long ident = Binder.clearCallingIdentity(); 9923 try { 9924 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9925 mLockScreenShown = shown; 9926 comeOutOfSleepIfNeededLocked(); 9927 } finally { 9928 Binder.restoreCallingIdentity(ident); 9929 } 9930 } 9931 } 9932 9933 @Override 9934 public void stopAppSwitches() { 9935 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9936 != PackageManager.PERMISSION_GRANTED) { 9937 throw new SecurityException("Requires permission " 9938 + android.Manifest.permission.STOP_APP_SWITCHES); 9939 } 9940 9941 synchronized(this) { 9942 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9943 + APP_SWITCH_DELAY_TIME; 9944 mDidAppSwitch = false; 9945 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9946 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9947 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9948 } 9949 } 9950 9951 public void resumeAppSwitches() { 9952 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9953 != PackageManager.PERMISSION_GRANTED) { 9954 throw new SecurityException("Requires permission " 9955 + android.Manifest.permission.STOP_APP_SWITCHES); 9956 } 9957 9958 synchronized(this) { 9959 // Note that we don't execute any pending app switches... we will 9960 // let those wait until either the timeout, or the next start 9961 // activity request. 9962 mAppSwitchesAllowedTime = 0; 9963 } 9964 } 9965 9966 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9967 String name) { 9968 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9969 return true; 9970 } 9971 9972 final int perm = checkComponentPermission( 9973 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9974 callingUid, -1, true); 9975 if (perm == PackageManager.PERMISSION_GRANTED) { 9976 return true; 9977 } 9978 9979 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9980 return false; 9981 } 9982 9983 public void setDebugApp(String packageName, boolean waitForDebugger, 9984 boolean persistent) { 9985 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9986 "setDebugApp()"); 9987 9988 long ident = Binder.clearCallingIdentity(); 9989 try { 9990 // Note that this is not really thread safe if there are multiple 9991 // callers into it at the same time, but that's not a situation we 9992 // care about. 9993 if (persistent) { 9994 final ContentResolver resolver = mContext.getContentResolver(); 9995 Settings.Global.putString( 9996 resolver, Settings.Global.DEBUG_APP, 9997 packageName); 9998 Settings.Global.putInt( 9999 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10000 waitForDebugger ? 1 : 0); 10001 } 10002 10003 synchronized (this) { 10004 if (!persistent) { 10005 mOrigDebugApp = mDebugApp; 10006 mOrigWaitForDebugger = mWaitForDebugger; 10007 } 10008 mDebugApp = packageName; 10009 mWaitForDebugger = waitForDebugger; 10010 mDebugTransient = !persistent; 10011 if (packageName != null) { 10012 forceStopPackageLocked(packageName, -1, false, false, true, true, 10013 false, UserHandle.USER_ALL, "set debug app"); 10014 } 10015 } 10016 } finally { 10017 Binder.restoreCallingIdentity(ident); 10018 } 10019 } 10020 10021 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10022 synchronized (this) { 10023 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10024 if (!isDebuggable) { 10025 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10026 throw new SecurityException("Process not debuggable: " + app.packageName); 10027 } 10028 } 10029 10030 mOpenGlTraceApp = processName; 10031 } 10032 } 10033 10034 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10035 synchronized (this) { 10036 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10037 if (!isDebuggable) { 10038 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10039 throw new SecurityException("Process not debuggable: " + app.packageName); 10040 } 10041 } 10042 mProfileApp = processName; 10043 mProfileFile = profilerInfo.profileFile; 10044 if (mProfileFd != null) { 10045 try { 10046 mProfileFd.close(); 10047 } catch (IOException e) { 10048 } 10049 mProfileFd = null; 10050 } 10051 mProfileFd = profilerInfo.profileFd; 10052 mSamplingInterval = profilerInfo.samplingInterval; 10053 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10054 mProfileType = 0; 10055 } 10056 } 10057 10058 @Override 10059 public void setAlwaysFinish(boolean enabled) { 10060 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10061 "setAlwaysFinish()"); 10062 10063 Settings.Global.putInt( 10064 mContext.getContentResolver(), 10065 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10066 10067 synchronized (this) { 10068 mAlwaysFinishActivities = enabled; 10069 } 10070 } 10071 10072 @Override 10073 public void setActivityController(IActivityController controller) { 10074 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10075 "setActivityController()"); 10076 synchronized (this) { 10077 mController = controller; 10078 Watchdog.getInstance().setActivityController(controller); 10079 } 10080 } 10081 10082 @Override 10083 public void setUserIsMonkey(boolean userIsMonkey) { 10084 synchronized (this) { 10085 synchronized (mPidsSelfLocked) { 10086 final int callingPid = Binder.getCallingPid(); 10087 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10088 if (precessRecord == null) { 10089 throw new SecurityException("Unknown process: " + callingPid); 10090 } 10091 if (precessRecord.instrumentationUiAutomationConnection == null) { 10092 throw new SecurityException("Only an instrumentation process " 10093 + "with a UiAutomation can call setUserIsMonkey"); 10094 } 10095 } 10096 mUserIsMonkey = userIsMonkey; 10097 } 10098 } 10099 10100 @Override 10101 public boolean isUserAMonkey() { 10102 synchronized (this) { 10103 // If there is a controller also implies the user is a monkey. 10104 return (mUserIsMonkey || mController != null); 10105 } 10106 } 10107 10108 public void requestBugReport() { 10109 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10110 SystemProperties.set("ctl.start", "bugreport"); 10111 } 10112 10113 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10114 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10115 } 10116 10117 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10118 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10119 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10120 } 10121 return KEY_DISPATCHING_TIMEOUT; 10122 } 10123 10124 @Override 10125 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10126 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10127 != PackageManager.PERMISSION_GRANTED) { 10128 throw new SecurityException("Requires permission " 10129 + android.Manifest.permission.FILTER_EVENTS); 10130 } 10131 ProcessRecord proc; 10132 long timeout; 10133 synchronized (this) { 10134 synchronized (mPidsSelfLocked) { 10135 proc = mPidsSelfLocked.get(pid); 10136 } 10137 timeout = getInputDispatchingTimeoutLocked(proc); 10138 } 10139 10140 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10141 return -1; 10142 } 10143 10144 return timeout; 10145 } 10146 10147 /** 10148 * Handle input dispatching timeouts. 10149 * Returns whether input dispatching should be aborted or not. 10150 */ 10151 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10152 final ActivityRecord activity, final ActivityRecord parent, 10153 final boolean aboveSystem, String reason) { 10154 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10155 != PackageManager.PERMISSION_GRANTED) { 10156 throw new SecurityException("Requires permission " 10157 + android.Manifest.permission.FILTER_EVENTS); 10158 } 10159 10160 final String annotation; 10161 if (reason == null) { 10162 annotation = "Input dispatching timed out"; 10163 } else { 10164 annotation = "Input dispatching timed out (" + reason + ")"; 10165 } 10166 10167 if (proc != null) { 10168 synchronized (this) { 10169 if (proc.debugging) { 10170 return false; 10171 } 10172 10173 if (mDidDexOpt) { 10174 // Give more time since we were dexopting. 10175 mDidDexOpt = false; 10176 return false; 10177 } 10178 10179 if (proc.instrumentationClass != null) { 10180 Bundle info = new Bundle(); 10181 info.putString("shortMsg", "keyDispatchingTimedOut"); 10182 info.putString("longMsg", annotation); 10183 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10184 return true; 10185 } 10186 } 10187 mHandler.post(new Runnable() { 10188 @Override 10189 public void run() { 10190 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10191 } 10192 }); 10193 } 10194 10195 return true; 10196 } 10197 10198 public Bundle getAssistContextExtras(int requestType) { 10199 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10200 "getAssistContextExtras()"); 10201 PendingAssistExtras pae; 10202 Bundle extras = new Bundle(); 10203 synchronized (this) { 10204 ActivityRecord activity = getFocusedStack().mResumedActivity; 10205 if (activity == null) { 10206 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10207 return null; 10208 } 10209 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10210 if (activity.app == null || activity.app.thread == null) { 10211 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10212 return extras; 10213 } 10214 if (activity.app.pid == Binder.getCallingPid()) { 10215 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10216 return extras; 10217 } 10218 pae = new PendingAssistExtras(activity); 10219 try { 10220 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10221 requestType); 10222 mPendingAssistExtras.add(pae); 10223 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10224 } catch (RemoteException e) { 10225 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10226 return extras; 10227 } 10228 } 10229 synchronized (pae) { 10230 while (!pae.haveResult) { 10231 try { 10232 pae.wait(); 10233 } catch (InterruptedException e) { 10234 } 10235 } 10236 if (pae.result != null) { 10237 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10238 } 10239 } 10240 synchronized (this) { 10241 mPendingAssistExtras.remove(pae); 10242 mHandler.removeCallbacks(pae); 10243 } 10244 return extras; 10245 } 10246 10247 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10248 PendingAssistExtras pae = (PendingAssistExtras)token; 10249 synchronized (pae) { 10250 pae.result = extras; 10251 pae.haveResult = true; 10252 pae.notifyAll(); 10253 } 10254 } 10255 10256 public void registerProcessObserver(IProcessObserver observer) { 10257 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10258 "registerProcessObserver()"); 10259 synchronized (this) { 10260 mProcessObservers.register(observer); 10261 } 10262 } 10263 10264 @Override 10265 public void unregisterProcessObserver(IProcessObserver observer) { 10266 synchronized (this) { 10267 mProcessObservers.unregister(observer); 10268 } 10269 } 10270 10271 @Override 10272 public boolean convertFromTranslucent(IBinder token) { 10273 final long origId = Binder.clearCallingIdentity(); 10274 try { 10275 synchronized (this) { 10276 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10277 if (r == null) { 10278 return false; 10279 } 10280 if (r.changeWindowTranslucency(true)) { 10281 mWindowManager.setAppFullscreen(token, true); 10282 r.task.stack.releaseBackgroundResources(); 10283 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10284 return true; 10285 } 10286 return false; 10287 } 10288 } finally { 10289 Binder.restoreCallingIdentity(origId); 10290 } 10291 } 10292 10293 @Override 10294 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10295 final long origId = Binder.clearCallingIdentity(); 10296 try { 10297 synchronized (this) { 10298 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10299 if (r == null) { 10300 return false; 10301 } 10302 int index = r.task.mActivities.lastIndexOf(r); 10303 if (index > 0) { 10304 ActivityRecord under = r.task.mActivities.get(index - 1); 10305 under.returningOptions = options; 10306 } 10307 if (r.changeWindowTranslucency(false)) { 10308 r.task.stack.convertToTranslucent(r); 10309 mWindowManager.setAppFullscreen(token, false); 10310 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10311 return true; 10312 } else { 10313 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10314 return false; 10315 } 10316 } 10317 } finally { 10318 Binder.restoreCallingIdentity(origId); 10319 } 10320 } 10321 10322 @Override 10323 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10324 final long origId = Binder.clearCallingIdentity(); 10325 try { 10326 synchronized (this) { 10327 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10328 if (r != null) { 10329 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10330 } 10331 } 10332 return false; 10333 } finally { 10334 Binder.restoreCallingIdentity(origId); 10335 } 10336 } 10337 10338 @Override 10339 public boolean isBackgroundVisibleBehind(IBinder token) { 10340 final long origId = Binder.clearCallingIdentity(); 10341 try { 10342 synchronized (this) { 10343 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10344 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10345 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10346 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10347 return visible; 10348 } 10349 } finally { 10350 Binder.restoreCallingIdentity(origId); 10351 } 10352 } 10353 10354 @Override 10355 public ActivityOptions getActivityOptions(IBinder token) { 10356 final long origId = Binder.clearCallingIdentity(); 10357 try { 10358 synchronized (this) { 10359 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10360 if (r != null) { 10361 final ActivityOptions activityOptions = r.pendingOptions; 10362 r.pendingOptions = null; 10363 return activityOptions; 10364 } 10365 return null; 10366 } 10367 } finally { 10368 Binder.restoreCallingIdentity(origId); 10369 } 10370 } 10371 10372 @Override 10373 public void setImmersive(IBinder token, boolean immersive) { 10374 synchronized(this) { 10375 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10376 if (r == null) { 10377 throw new IllegalArgumentException(); 10378 } 10379 r.immersive = immersive; 10380 10381 // update associated state if we're frontmost 10382 if (r == mFocusedActivity) { 10383 if (DEBUG_IMMERSIVE) { 10384 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10385 } 10386 applyUpdateLockStateLocked(r); 10387 } 10388 } 10389 } 10390 10391 @Override 10392 public boolean isImmersive(IBinder token) { 10393 synchronized (this) { 10394 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10395 if (r == null) { 10396 throw new IllegalArgumentException(); 10397 } 10398 return r.immersive; 10399 } 10400 } 10401 10402 public boolean isTopActivityImmersive() { 10403 enforceNotIsolatedCaller("startActivity"); 10404 synchronized (this) { 10405 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10406 return (r != null) ? r.immersive : false; 10407 } 10408 } 10409 10410 @Override 10411 public boolean isTopOfTask(IBinder token) { 10412 synchronized (this) { 10413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10414 if (r == null) { 10415 throw new IllegalArgumentException(); 10416 } 10417 return r.task.getTopActivity() == r; 10418 } 10419 } 10420 10421 public final void enterSafeMode() { 10422 synchronized(this) { 10423 // It only makes sense to do this before the system is ready 10424 // and started launching other packages. 10425 if (!mSystemReady) { 10426 try { 10427 AppGlobals.getPackageManager().enterSafeMode(); 10428 } catch (RemoteException e) { 10429 } 10430 } 10431 10432 mSafeMode = true; 10433 } 10434 } 10435 10436 public final void showSafeModeOverlay() { 10437 View v = LayoutInflater.from(mContext).inflate( 10438 com.android.internal.R.layout.safe_mode, null); 10439 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10440 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10441 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10442 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10443 lp.gravity = Gravity.BOTTOM | Gravity.START; 10444 lp.format = v.getBackground().getOpacity(); 10445 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10446 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10447 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10448 ((WindowManager)mContext.getSystemService( 10449 Context.WINDOW_SERVICE)).addView(v, lp); 10450 } 10451 10452 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10453 if (!(sender instanceof PendingIntentRecord)) { 10454 return; 10455 } 10456 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10457 synchronized (stats) { 10458 if (mBatteryStatsService.isOnBattery()) { 10459 mBatteryStatsService.enforceCallingPermission(); 10460 PendingIntentRecord rec = (PendingIntentRecord)sender; 10461 int MY_UID = Binder.getCallingUid(); 10462 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10463 BatteryStatsImpl.Uid.Pkg pkg = 10464 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10465 sourcePkg != null ? sourcePkg : rec.key.packageName); 10466 pkg.incWakeupsLocked(); 10467 } 10468 } 10469 } 10470 10471 public boolean killPids(int[] pids, String pReason, boolean secure) { 10472 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10473 throw new SecurityException("killPids only available to the system"); 10474 } 10475 String reason = (pReason == null) ? "Unknown" : pReason; 10476 // XXX Note: don't acquire main activity lock here, because the window 10477 // manager calls in with its locks held. 10478 10479 boolean killed = false; 10480 synchronized (mPidsSelfLocked) { 10481 int[] types = new int[pids.length]; 10482 int worstType = 0; 10483 for (int i=0; i<pids.length; i++) { 10484 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10485 if (proc != null) { 10486 int type = proc.setAdj; 10487 types[i] = type; 10488 if (type > worstType) { 10489 worstType = type; 10490 } 10491 } 10492 } 10493 10494 // If the worst oom_adj is somewhere in the cached proc LRU range, 10495 // then constrain it so we will kill all cached procs. 10496 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10497 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10498 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10499 } 10500 10501 // If this is not a secure call, don't let it kill processes that 10502 // are important. 10503 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10504 worstType = ProcessList.SERVICE_ADJ; 10505 } 10506 10507 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10508 for (int i=0; i<pids.length; i++) { 10509 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10510 if (proc == null) { 10511 continue; 10512 } 10513 int adj = proc.setAdj; 10514 if (adj >= worstType && !proc.killedByAm) { 10515 proc.kill(reason, true); 10516 killed = true; 10517 } 10518 } 10519 } 10520 return killed; 10521 } 10522 10523 @Override 10524 public void killUid(int uid, String reason) { 10525 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10526 throw new SecurityException("killUid only available to the system"); 10527 } 10528 synchronized (this) { 10529 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10530 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10531 reason != null ? reason : "kill uid"); 10532 } 10533 } 10534 10535 @Override 10536 public boolean killProcessesBelowForeground(String reason) { 10537 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10538 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10539 } 10540 10541 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10542 } 10543 10544 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10545 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10546 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10547 } 10548 10549 boolean killed = false; 10550 synchronized (mPidsSelfLocked) { 10551 final int size = mPidsSelfLocked.size(); 10552 for (int i = 0; i < size; i++) { 10553 final int pid = mPidsSelfLocked.keyAt(i); 10554 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10555 if (proc == null) continue; 10556 10557 final int adj = proc.setAdj; 10558 if (adj > belowAdj && !proc.killedByAm) { 10559 proc.kill(reason, true); 10560 killed = true; 10561 } 10562 } 10563 } 10564 return killed; 10565 } 10566 10567 @Override 10568 public void hang(final IBinder who, boolean allowRestart) { 10569 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10570 != PackageManager.PERMISSION_GRANTED) { 10571 throw new SecurityException("Requires permission " 10572 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10573 } 10574 10575 final IBinder.DeathRecipient death = new DeathRecipient() { 10576 @Override 10577 public void binderDied() { 10578 synchronized (this) { 10579 notifyAll(); 10580 } 10581 } 10582 }; 10583 10584 try { 10585 who.linkToDeath(death, 0); 10586 } catch (RemoteException e) { 10587 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10588 return; 10589 } 10590 10591 synchronized (this) { 10592 Watchdog.getInstance().setAllowRestart(allowRestart); 10593 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10594 synchronized (death) { 10595 while (who.isBinderAlive()) { 10596 try { 10597 death.wait(); 10598 } catch (InterruptedException e) { 10599 } 10600 } 10601 } 10602 Watchdog.getInstance().setAllowRestart(true); 10603 } 10604 } 10605 10606 @Override 10607 public void restart() { 10608 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10609 != PackageManager.PERMISSION_GRANTED) { 10610 throw new SecurityException("Requires permission " 10611 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10612 } 10613 10614 Log.i(TAG, "Sending shutdown broadcast..."); 10615 10616 BroadcastReceiver br = new BroadcastReceiver() { 10617 @Override public void onReceive(Context context, Intent intent) { 10618 // Now the broadcast is done, finish up the low-level shutdown. 10619 Log.i(TAG, "Shutting down activity manager..."); 10620 shutdown(10000); 10621 Log.i(TAG, "Shutdown complete, restarting!"); 10622 Process.killProcess(Process.myPid()); 10623 System.exit(10); 10624 } 10625 }; 10626 10627 // First send the high-level shut down broadcast. 10628 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10629 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10630 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10631 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10632 mContext.sendOrderedBroadcastAsUser(intent, 10633 UserHandle.ALL, null, br, mHandler, 0, null, null); 10634 */ 10635 br.onReceive(mContext, intent); 10636 } 10637 10638 private long getLowRamTimeSinceIdle(long now) { 10639 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10640 } 10641 10642 @Override 10643 public void performIdleMaintenance() { 10644 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10645 != PackageManager.PERMISSION_GRANTED) { 10646 throw new SecurityException("Requires permission " 10647 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10648 } 10649 10650 synchronized (this) { 10651 final long now = SystemClock.uptimeMillis(); 10652 final long timeSinceLastIdle = now - mLastIdleTime; 10653 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10654 mLastIdleTime = now; 10655 mLowRamTimeSinceLastIdle = 0; 10656 if (mLowRamStartTime != 0) { 10657 mLowRamStartTime = now; 10658 } 10659 10660 StringBuilder sb = new StringBuilder(128); 10661 sb.append("Idle maintenance over "); 10662 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10663 sb.append(" low RAM for "); 10664 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10665 Slog.i(TAG, sb.toString()); 10666 10667 // If at least 1/3 of our time since the last idle period has been spent 10668 // with RAM low, then we want to kill processes. 10669 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10670 10671 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10672 ProcessRecord proc = mLruProcesses.get(i); 10673 if (proc.notCachedSinceIdle) { 10674 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10675 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10676 if (doKilling && proc.initialIdlePss != 0 10677 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10678 proc.kill("idle maint (pss " + proc.lastPss 10679 + " from " + proc.initialIdlePss + ")", true); 10680 } 10681 } 10682 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10683 proc.notCachedSinceIdle = true; 10684 proc.initialIdlePss = 0; 10685 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10686 isSleeping(), now); 10687 } 10688 } 10689 10690 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10691 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10692 } 10693 } 10694 10695 private void retrieveSettings() { 10696 final ContentResolver resolver = mContext.getContentResolver(); 10697 String debugApp = Settings.Global.getString( 10698 resolver, Settings.Global.DEBUG_APP); 10699 boolean waitForDebugger = Settings.Global.getInt( 10700 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10701 boolean alwaysFinishActivities = Settings.Global.getInt( 10702 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10703 boolean forceRtl = Settings.Global.getInt( 10704 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10705 // Transfer any global setting for forcing RTL layout, into a System Property 10706 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10707 10708 Configuration configuration = new Configuration(); 10709 Settings.System.getConfiguration(resolver, configuration); 10710 if (forceRtl) { 10711 // This will take care of setting the correct layout direction flags 10712 configuration.setLayoutDirection(configuration.locale); 10713 } 10714 10715 synchronized (this) { 10716 mDebugApp = mOrigDebugApp = debugApp; 10717 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10718 mAlwaysFinishActivities = alwaysFinishActivities; 10719 // This happens before any activities are started, so we can 10720 // change mConfiguration in-place. 10721 updateConfigurationLocked(configuration, null, false, true); 10722 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10723 } 10724 } 10725 10726 /** Loads resources after the current configuration has been set. */ 10727 private void loadResourcesOnSystemReady() { 10728 final Resources res = mContext.getResources(); 10729 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10730 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10731 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10732 } 10733 10734 public boolean testIsSystemReady() { 10735 // no need to synchronize(this) just to read & return the value 10736 return mSystemReady; 10737 } 10738 10739 private static File getCalledPreBootReceiversFile() { 10740 File dataDir = Environment.getDataDirectory(); 10741 File systemDir = new File(dataDir, "system"); 10742 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10743 return fname; 10744 } 10745 10746 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10747 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10748 File file = getCalledPreBootReceiversFile(); 10749 FileInputStream fis = null; 10750 try { 10751 fis = new FileInputStream(file); 10752 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10753 int fvers = dis.readInt(); 10754 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10755 String vers = dis.readUTF(); 10756 String codename = dis.readUTF(); 10757 String build = dis.readUTF(); 10758 if (android.os.Build.VERSION.RELEASE.equals(vers) 10759 && android.os.Build.VERSION.CODENAME.equals(codename) 10760 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10761 int num = dis.readInt(); 10762 while (num > 0) { 10763 num--; 10764 String pkg = dis.readUTF(); 10765 String cls = dis.readUTF(); 10766 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10767 } 10768 } 10769 } 10770 } catch (FileNotFoundException e) { 10771 } catch (IOException e) { 10772 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10773 } finally { 10774 if (fis != null) { 10775 try { 10776 fis.close(); 10777 } catch (IOException e) { 10778 } 10779 } 10780 } 10781 return lastDoneReceivers; 10782 } 10783 10784 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10785 File file = getCalledPreBootReceiversFile(); 10786 FileOutputStream fos = null; 10787 DataOutputStream dos = null; 10788 try { 10789 fos = new FileOutputStream(file); 10790 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10791 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10792 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10793 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10794 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10795 dos.writeInt(list.size()); 10796 for (int i=0; i<list.size(); i++) { 10797 dos.writeUTF(list.get(i).getPackageName()); 10798 dos.writeUTF(list.get(i).getClassName()); 10799 } 10800 } catch (IOException e) { 10801 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10802 file.delete(); 10803 } finally { 10804 FileUtils.sync(fos); 10805 if (dos != null) { 10806 try { 10807 dos.close(); 10808 } catch (IOException e) { 10809 // TODO Auto-generated catch block 10810 e.printStackTrace(); 10811 } 10812 } 10813 } 10814 } 10815 10816 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10817 ArrayList<ComponentName> doneReceivers, int userId) { 10818 boolean waitingUpdate = false; 10819 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10820 List<ResolveInfo> ris = null; 10821 try { 10822 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10823 intent, null, 0, userId); 10824 } catch (RemoteException e) { 10825 } 10826 if (ris != null) { 10827 for (int i=ris.size()-1; i>=0; i--) { 10828 if ((ris.get(i).activityInfo.applicationInfo.flags 10829 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10830 ris.remove(i); 10831 } 10832 } 10833 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10834 10835 // For User 0, load the version number. When delivering to a new user, deliver 10836 // to all receivers. 10837 if (userId == UserHandle.USER_OWNER) { 10838 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10839 for (int i=0; i<ris.size(); i++) { 10840 ActivityInfo ai = ris.get(i).activityInfo; 10841 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10842 if (lastDoneReceivers.contains(comp)) { 10843 // We already did the pre boot receiver for this app with the current 10844 // platform version, so don't do it again... 10845 ris.remove(i); 10846 i--; 10847 // ...however, do keep it as one that has been done, so we don't 10848 // forget about it when rewriting the file of last done receivers. 10849 doneReceivers.add(comp); 10850 } 10851 } 10852 } 10853 10854 // If primary user, send broadcast to all available users, else just to userId 10855 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10856 : new int[] { userId }; 10857 for (int i = 0; i < ris.size(); i++) { 10858 ActivityInfo ai = ris.get(i).activityInfo; 10859 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10860 doneReceivers.add(comp); 10861 intent.setComponent(comp); 10862 for (int j=0; j<users.length; j++) { 10863 IIntentReceiver finisher = null; 10864 // On last receiver and user, set up a completion callback 10865 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10866 finisher = new IIntentReceiver.Stub() { 10867 public void performReceive(Intent intent, int resultCode, 10868 String data, Bundle extras, boolean ordered, 10869 boolean sticky, int sendingUser) { 10870 // The raw IIntentReceiver interface is called 10871 // with the AM lock held, so redispatch to 10872 // execute our code without the lock. 10873 mHandler.post(onFinishCallback); 10874 } 10875 }; 10876 } 10877 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10878 + " for user " + users[j]); 10879 broadcastIntentLocked(null, null, intent, null, finisher, 10880 0, null, null, null, AppOpsManager.OP_NONE, 10881 true, false, MY_PID, Process.SYSTEM_UID, 10882 users[j]); 10883 if (finisher != null) { 10884 waitingUpdate = true; 10885 } 10886 } 10887 } 10888 } 10889 10890 return waitingUpdate; 10891 } 10892 10893 public void systemReady(final Runnable goingCallback) { 10894 synchronized(this) { 10895 if (mSystemReady) { 10896 // If we're done calling all the receivers, run the next "boot phase" passed in 10897 // by the SystemServer 10898 if (goingCallback != null) { 10899 goingCallback.run(); 10900 } 10901 return; 10902 } 10903 10904 // Make sure we have the current profile info, since it is needed for 10905 // security checks. 10906 updateCurrentProfileIdsLocked(); 10907 10908 if (mRecentTasks == null) { 10909 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10910 if (!mRecentTasks.isEmpty()) { 10911 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10912 } 10913 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10914 mTaskPersister.startPersisting(); 10915 } 10916 10917 // Check to see if there are any update receivers to run. 10918 if (!mDidUpdate) { 10919 if (mWaitingUpdate) { 10920 return; 10921 } 10922 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10923 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10924 public void run() { 10925 synchronized (ActivityManagerService.this) { 10926 mDidUpdate = true; 10927 } 10928 writeLastDonePreBootReceivers(doneReceivers); 10929 showBootMessage(mContext.getText( 10930 R.string.android_upgrading_complete), 10931 false); 10932 systemReady(goingCallback); 10933 } 10934 }, doneReceivers, UserHandle.USER_OWNER); 10935 10936 if (mWaitingUpdate) { 10937 return; 10938 } 10939 mDidUpdate = true; 10940 } 10941 10942 mAppOpsService.systemReady(); 10943 mSystemReady = true; 10944 } 10945 10946 ArrayList<ProcessRecord> procsToKill = null; 10947 synchronized(mPidsSelfLocked) { 10948 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10949 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10950 if (!isAllowedWhileBooting(proc.info)){ 10951 if (procsToKill == null) { 10952 procsToKill = new ArrayList<ProcessRecord>(); 10953 } 10954 procsToKill.add(proc); 10955 } 10956 } 10957 } 10958 10959 synchronized(this) { 10960 if (procsToKill != null) { 10961 for (int i=procsToKill.size()-1; i>=0; i--) { 10962 ProcessRecord proc = procsToKill.get(i); 10963 Slog.i(TAG, "Removing system update proc: " + proc); 10964 removeProcessLocked(proc, true, false, "system update done"); 10965 } 10966 } 10967 10968 // Now that we have cleaned up any update processes, we 10969 // are ready to start launching real processes and know that 10970 // we won't trample on them any more. 10971 mProcessesReady = true; 10972 } 10973 10974 Slog.i(TAG, "System now ready"); 10975 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10976 SystemClock.uptimeMillis()); 10977 10978 synchronized(this) { 10979 // Make sure we have no pre-ready processes sitting around. 10980 10981 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10982 ResolveInfo ri = mContext.getPackageManager() 10983 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10984 STOCK_PM_FLAGS); 10985 CharSequence errorMsg = null; 10986 if (ri != null) { 10987 ActivityInfo ai = ri.activityInfo; 10988 ApplicationInfo app = ai.applicationInfo; 10989 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10990 mTopAction = Intent.ACTION_FACTORY_TEST; 10991 mTopData = null; 10992 mTopComponent = new ComponentName(app.packageName, 10993 ai.name); 10994 } else { 10995 errorMsg = mContext.getResources().getText( 10996 com.android.internal.R.string.factorytest_not_system); 10997 } 10998 } else { 10999 errorMsg = mContext.getResources().getText( 11000 com.android.internal.R.string.factorytest_no_action); 11001 } 11002 if (errorMsg != null) { 11003 mTopAction = null; 11004 mTopData = null; 11005 mTopComponent = null; 11006 Message msg = Message.obtain(); 11007 msg.what = SHOW_FACTORY_ERROR_MSG; 11008 msg.getData().putCharSequence("msg", errorMsg); 11009 mHandler.sendMessage(msg); 11010 } 11011 } 11012 } 11013 11014 retrieveSettings(); 11015 loadResourcesOnSystemReady(); 11016 11017 synchronized (this) { 11018 readGrantedUriPermissionsLocked(); 11019 } 11020 11021 if (goingCallback != null) goingCallback.run(); 11022 11023 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11024 Integer.toString(mCurrentUserId), mCurrentUserId); 11025 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11026 Integer.toString(mCurrentUserId), mCurrentUserId); 11027 mSystemServiceManager.startUser(mCurrentUserId); 11028 11029 synchronized (this) { 11030 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11031 try { 11032 List apps = AppGlobals.getPackageManager(). 11033 getPersistentApplications(STOCK_PM_FLAGS); 11034 if (apps != null) { 11035 int N = apps.size(); 11036 int i; 11037 for (i=0; i<N; i++) { 11038 ApplicationInfo info 11039 = (ApplicationInfo)apps.get(i); 11040 if (info != null && 11041 !info.packageName.equals("android")) { 11042 addAppLocked(info, false, null /* ABI override */); 11043 } 11044 } 11045 } 11046 } catch (RemoteException ex) { 11047 // pm is in same process, this will never happen. 11048 } 11049 } 11050 11051 // Start up initial activity. 11052 mBooting = true; 11053 11054 try { 11055 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11056 Message msg = Message.obtain(); 11057 msg.what = SHOW_UID_ERROR_MSG; 11058 mHandler.sendMessage(msg); 11059 } 11060 } catch (RemoteException e) { 11061 } 11062 11063 long ident = Binder.clearCallingIdentity(); 11064 try { 11065 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11066 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11067 | Intent.FLAG_RECEIVER_FOREGROUND); 11068 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11069 broadcastIntentLocked(null, null, intent, 11070 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11071 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11072 intent = new Intent(Intent.ACTION_USER_STARTING); 11073 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11074 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11075 broadcastIntentLocked(null, null, intent, 11076 null, new IIntentReceiver.Stub() { 11077 @Override 11078 public void performReceive(Intent intent, int resultCode, String data, 11079 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11080 throws RemoteException { 11081 } 11082 }, 0, null, null, 11083 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11084 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11085 } catch (Throwable t) { 11086 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11087 } finally { 11088 Binder.restoreCallingIdentity(ident); 11089 } 11090 mStackSupervisor.resumeTopActivitiesLocked(); 11091 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11092 } 11093 } 11094 11095 private boolean makeAppCrashingLocked(ProcessRecord app, 11096 String shortMsg, String longMsg, String stackTrace) { 11097 app.crashing = true; 11098 app.crashingReport = generateProcessError(app, 11099 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11100 startAppProblemLocked(app); 11101 app.stopFreezingAllLocked(); 11102 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11103 } 11104 11105 private void makeAppNotRespondingLocked(ProcessRecord app, 11106 String activity, String shortMsg, String longMsg) { 11107 app.notResponding = true; 11108 app.notRespondingReport = generateProcessError(app, 11109 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11110 activity, shortMsg, longMsg, null); 11111 startAppProblemLocked(app); 11112 app.stopFreezingAllLocked(); 11113 } 11114 11115 /** 11116 * Generate a process error record, suitable for attachment to a ProcessRecord. 11117 * 11118 * @param app The ProcessRecord in which the error occurred. 11119 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11120 * ActivityManager.AppErrorStateInfo 11121 * @param activity The activity associated with the crash, if known. 11122 * @param shortMsg Short message describing the crash. 11123 * @param longMsg Long message describing the crash. 11124 * @param stackTrace Full crash stack trace, may be null. 11125 * 11126 * @return Returns a fully-formed AppErrorStateInfo record. 11127 */ 11128 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11129 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11130 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11131 11132 report.condition = condition; 11133 report.processName = app.processName; 11134 report.pid = app.pid; 11135 report.uid = app.info.uid; 11136 report.tag = activity; 11137 report.shortMsg = shortMsg; 11138 report.longMsg = longMsg; 11139 report.stackTrace = stackTrace; 11140 11141 return report; 11142 } 11143 11144 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11145 synchronized (this) { 11146 app.crashing = false; 11147 app.crashingReport = null; 11148 app.notResponding = false; 11149 app.notRespondingReport = null; 11150 if (app.anrDialog == fromDialog) { 11151 app.anrDialog = null; 11152 } 11153 if (app.waitDialog == fromDialog) { 11154 app.waitDialog = null; 11155 } 11156 if (app.pid > 0 && app.pid != MY_PID) { 11157 handleAppCrashLocked(app, null, null, null); 11158 app.kill("user request after error", true); 11159 } 11160 } 11161 } 11162 11163 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11164 String stackTrace) { 11165 long now = SystemClock.uptimeMillis(); 11166 11167 Long crashTime; 11168 if (!app.isolated) { 11169 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11170 } else { 11171 crashTime = null; 11172 } 11173 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11174 // This process loses! 11175 Slog.w(TAG, "Process " + app.info.processName 11176 + " has crashed too many times: killing!"); 11177 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11178 app.userId, app.info.processName, app.uid); 11179 mStackSupervisor.handleAppCrashLocked(app); 11180 if (!app.persistent) { 11181 // We don't want to start this process again until the user 11182 // explicitly does so... but for persistent process, we really 11183 // need to keep it running. If a persistent process is actually 11184 // repeatedly crashing, then badness for everyone. 11185 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11186 app.info.processName); 11187 if (!app.isolated) { 11188 // XXX We don't have a way to mark isolated processes 11189 // as bad, since they don't have a peristent identity. 11190 mBadProcesses.put(app.info.processName, app.uid, 11191 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11192 mProcessCrashTimes.remove(app.info.processName, app.uid); 11193 } 11194 app.bad = true; 11195 app.removed = true; 11196 // Don't let services in this process be restarted and potentially 11197 // annoy the user repeatedly. Unless it is persistent, since those 11198 // processes run critical code. 11199 removeProcessLocked(app, false, false, "crash"); 11200 mStackSupervisor.resumeTopActivitiesLocked(); 11201 return false; 11202 } 11203 mStackSupervisor.resumeTopActivitiesLocked(); 11204 } else { 11205 mStackSupervisor.finishTopRunningActivityLocked(app); 11206 } 11207 11208 // Bump up the crash count of any services currently running in the proc. 11209 for (int i=app.services.size()-1; i>=0; i--) { 11210 // Any services running in the application need to be placed 11211 // back in the pending list. 11212 ServiceRecord sr = app.services.valueAt(i); 11213 sr.crashCount++; 11214 } 11215 11216 // If the crashing process is what we consider to be the "home process" and it has been 11217 // replaced by a third-party app, clear the package preferred activities from packages 11218 // with a home activity running in the process to prevent a repeatedly crashing app 11219 // from blocking the user to manually clear the list. 11220 final ArrayList<ActivityRecord> activities = app.activities; 11221 if (app == mHomeProcess && activities.size() > 0 11222 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11223 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11224 final ActivityRecord r = activities.get(activityNdx); 11225 if (r.isHomeActivity()) { 11226 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11227 try { 11228 ActivityThread.getPackageManager() 11229 .clearPackagePreferredActivities(r.packageName); 11230 } catch (RemoteException c) { 11231 // pm is in same process, this will never happen. 11232 } 11233 } 11234 } 11235 } 11236 11237 if (!app.isolated) { 11238 // XXX Can't keep track of crash times for isolated processes, 11239 // because they don't have a perisistent identity. 11240 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11241 } 11242 11243 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11244 return true; 11245 } 11246 11247 void startAppProblemLocked(ProcessRecord app) { 11248 // If this app is not running under the current user, then we 11249 // can't give it a report button because that would require 11250 // launching the report UI under a different user. 11251 app.errorReportReceiver = null; 11252 11253 for (int userId : mCurrentProfileIds) { 11254 if (app.userId == userId) { 11255 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11256 mContext, app.info.packageName, app.info.flags); 11257 } 11258 } 11259 skipCurrentReceiverLocked(app); 11260 } 11261 11262 void skipCurrentReceiverLocked(ProcessRecord app) { 11263 for (BroadcastQueue queue : mBroadcastQueues) { 11264 queue.skipCurrentReceiverLocked(app); 11265 } 11266 } 11267 11268 /** 11269 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11270 * The application process will exit immediately after this call returns. 11271 * @param app object of the crashing app, null for the system server 11272 * @param crashInfo describing the exception 11273 */ 11274 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11275 ProcessRecord r = findAppProcess(app, "Crash"); 11276 final String processName = app == null ? "system_server" 11277 : (r == null ? "unknown" : r.processName); 11278 11279 handleApplicationCrashInner("crash", r, processName, crashInfo); 11280 } 11281 11282 /* Native crash reporting uses this inner version because it needs to be somewhat 11283 * decoupled from the AM-managed cleanup lifecycle 11284 */ 11285 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11286 ApplicationErrorReport.CrashInfo crashInfo) { 11287 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11288 UserHandle.getUserId(Binder.getCallingUid()), processName, 11289 r == null ? -1 : r.info.flags, 11290 crashInfo.exceptionClassName, 11291 crashInfo.exceptionMessage, 11292 crashInfo.throwFileName, 11293 crashInfo.throwLineNumber); 11294 11295 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11296 11297 crashApplication(r, crashInfo); 11298 } 11299 11300 public void handleApplicationStrictModeViolation( 11301 IBinder app, 11302 int violationMask, 11303 StrictMode.ViolationInfo info) { 11304 ProcessRecord r = findAppProcess(app, "StrictMode"); 11305 if (r == null) { 11306 return; 11307 } 11308 11309 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11310 Integer stackFingerprint = info.hashCode(); 11311 boolean logIt = true; 11312 synchronized (mAlreadyLoggedViolatedStacks) { 11313 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11314 logIt = false; 11315 // TODO: sub-sample into EventLog for these, with 11316 // the info.durationMillis? Then we'd get 11317 // the relative pain numbers, without logging all 11318 // the stack traces repeatedly. We'd want to do 11319 // likewise in the client code, which also does 11320 // dup suppression, before the Binder call. 11321 } else { 11322 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11323 mAlreadyLoggedViolatedStacks.clear(); 11324 } 11325 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11326 } 11327 } 11328 if (logIt) { 11329 logStrictModeViolationToDropBox(r, info); 11330 } 11331 } 11332 11333 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11334 AppErrorResult result = new AppErrorResult(); 11335 synchronized (this) { 11336 final long origId = Binder.clearCallingIdentity(); 11337 11338 Message msg = Message.obtain(); 11339 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11340 HashMap<String, Object> data = new HashMap<String, Object>(); 11341 data.put("result", result); 11342 data.put("app", r); 11343 data.put("violationMask", violationMask); 11344 data.put("info", info); 11345 msg.obj = data; 11346 mHandler.sendMessage(msg); 11347 11348 Binder.restoreCallingIdentity(origId); 11349 } 11350 int res = result.get(); 11351 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11352 } 11353 } 11354 11355 // Depending on the policy in effect, there could be a bunch of 11356 // these in quick succession so we try to batch these together to 11357 // minimize disk writes, number of dropbox entries, and maximize 11358 // compression, by having more fewer, larger records. 11359 private void logStrictModeViolationToDropBox( 11360 ProcessRecord process, 11361 StrictMode.ViolationInfo info) { 11362 if (info == null) { 11363 return; 11364 } 11365 final boolean isSystemApp = process == null || 11366 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11367 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11368 final String processName = process == null ? "unknown" : process.processName; 11369 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11370 final DropBoxManager dbox = (DropBoxManager) 11371 mContext.getSystemService(Context.DROPBOX_SERVICE); 11372 11373 // Exit early if the dropbox isn't configured to accept this report type. 11374 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11375 11376 boolean bufferWasEmpty; 11377 boolean needsFlush; 11378 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11379 synchronized (sb) { 11380 bufferWasEmpty = sb.length() == 0; 11381 appendDropBoxProcessHeaders(process, processName, sb); 11382 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11383 sb.append("System-App: ").append(isSystemApp).append("\n"); 11384 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11385 if (info.violationNumThisLoop != 0) { 11386 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11387 } 11388 if (info.numAnimationsRunning != 0) { 11389 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11390 } 11391 if (info.broadcastIntentAction != null) { 11392 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11393 } 11394 if (info.durationMillis != -1) { 11395 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11396 } 11397 if (info.numInstances != -1) { 11398 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11399 } 11400 if (info.tags != null) { 11401 for (String tag : info.tags) { 11402 sb.append("Span-Tag: ").append(tag).append("\n"); 11403 } 11404 } 11405 sb.append("\n"); 11406 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11407 sb.append(info.crashInfo.stackTrace); 11408 } 11409 sb.append("\n"); 11410 11411 // Only buffer up to ~64k. Various logging bits truncate 11412 // things at 128k. 11413 needsFlush = (sb.length() > 64 * 1024); 11414 } 11415 11416 // Flush immediately if the buffer's grown too large, or this 11417 // is a non-system app. Non-system apps are isolated with a 11418 // different tag & policy and not batched. 11419 // 11420 // Batching is useful during internal testing with 11421 // StrictMode settings turned up high. Without batching, 11422 // thousands of separate files could be created on boot. 11423 if (!isSystemApp || needsFlush) { 11424 new Thread("Error dump: " + dropboxTag) { 11425 @Override 11426 public void run() { 11427 String report; 11428 synchronized (sb) { 11429 report = sb.toString(); 11430 sb.delete(0, sb.length()); 11431 sb.trimToSize(); 11432 } 11433 if (report.length() != 0) { 11434 dbox.addText(dropboxTag, report); 11435 } 11436 } 11437 }.start(); 11438 return; 11439 } 11440 11441 // System app batching: 11442 if (!bufferWasEmpty) { 11443 // An existing dropbox-writing thread is outstanding, so 11444 // we don't need to start it up. The existing thread will 11445 // catch the buffer appends we just did. 11446 return; 11447 } 11448 11449 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11450 // (After this point, we shouldn't access AMS internal data structures.) 11451 new Thread("Error dump: " + dropboxTag) { 11452 @Override 11453 public void run() { 11454 // 5 second sleep to let stacks arrive and be batched together 11455 try { 11456 Thread.sleep(5000); // 5 seconds 11457 } catch (InterruptedException e) {} 11458 11459 String errorReport; 11460 synchronized (mStrictModeBuffer) { 11461 errorReport = mStrictModeBuffer.toString(); 11462 if (errorReport.length() == 0) { 11463 return; 11464 } 11465 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11466 mStrictModeBuffer.trimToSize(); 11467 } 11468 dbox.addText(dropboxTag, errorReport); 11469 } 11470 }.start(); 11471 } 11472 11473 /** 11474 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11475 * @param app object of the crashing app, null for the system server 11476 * @param tag reported by the caller 11477 * @param system whether this wtf is coming from the system 11478 * @param crashInfo describing the context of the error 11479 * @return true if the process should exit immediately (WTF is fatal) 11480 */ 11481 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11482 final ApplicationErrorReport.CrashInfo crashInfo) { 11483 final ProcessRecord r = findAppProcess(app, "WTF"); 11484 final String processName = app == null ? "system_server" 11485 : (r == null ? "unknown" : r.processName); 11486 11487 EventLog.writeEvent(EventLogTags.AM_WTF, 11488 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11489 processName, 11490 r == null ? -1 : r.info.flags, 11491 tag, crashInfo.exceptionMessage); 11492 11493 if (system) { 11494 // If this is coming from the system, we could very well have low-level 11495 // system locks held, so we want to do this all asynchronously. And we 11496 // never want this to become fatal, so there is that too. 11497 mHandler.post(new Runnable() { 11498 @Override public void run() { 11499 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11500 crashInfo); 11501 } 11502 }); 11503 return false; 11504 } 11505 11506 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11507 11508 if (r != null && r.pid != Process.myPid() && 11509 Settings.Global.getInt(mContext.getContentResolver(), 11510 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11511 crashApplication(r, crashInfo); 11512 return true; 11513 } else { 11514 return false; 11515 } 11516 } 11517 11518 /** 11519 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11520 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11521 */ 11522 private ProcessRecord findAppProcess(IBinder app, String reason) { 11523 if (app == null) { 11524 return null; 11525 } 11526 11527 synchronized (this) { 11528 final int NP = mProcessNames.getMap().size(); 11529 for (int ip=0; ip<NP; ip++) { 11530 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11531 final int NA = apps.size(); 11532 for (int ia=0; ia<NA; ia++) { 11533 ProcessRecord p = apps.valueAt(ia); 11534 if (p.thread != null && p.thread.asBinder() == app) { 11535 return p; 11536 } 11537 } 11538 } 11539 11540 Slog.w(TAG, "Can't find mystery application for " + reason 11541 + " from pid=" + Binder.getCallingPid() 11542 + " uid=" + Binder.getCallingUid() + ": " + app); 11543 return null; 11544 } 11545 } 11546 11547 /** 11548 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11549 * to append various headers to the dropbox log text. 11550 */ 11551 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11552 StringBuilder sb) { 11553 // Watchdog thread ends up invoking this function (with 11554 // a null ProcessRecord) to add the stack file to dropbox. 11555 // Do not acquire a lock on this (am) in such cases, as it 11556 // could cause a potential deadlock, if and when watchdog 11557 // is invoked due to unavailability of lock on am and it 11558 // would prevent watchdog from killing system_server. 11559 if (process == null) { 11560 sb.append("Process: ").append(processName).append("\n"); 11561 return; 11562 } 11563 // Note: ProcessRecord 'process' is guarded by the service 11564 // instance. (notably process.pkgList, which could otherwise change 11565 // concurrently during execution of this method) 11566 synchronized (this) { 11567 sb.append("Process: ").append(processName).append("\n"); 11568 int flags = process.info.flags; 11569 IPackageManager pm = AppGlobals.getPackageManager(); 11570 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11571 for (int ip=0; ip<process.pkgList.size(); ip++) { 11572 String pkg = process.pkgList.keyAt(ip); 11573 sb.append("Package: ").append(pkg); 11574 try { 11575 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11576 if (pi != null) { 11577 sb.append(" v").append(pi.versionCode); 11578 if (pi.versionName != null) { 11579 sb.append(" (").append(pi.versionName).append(")"); 11580 } 11581 } 11582 } catch (RemoteException e) { 11583 Slog.e(TAG, "Error getting package info: " + pkg, e); 11584 } 11585 sb.append("\n"); 11586 } 11587 } 11588 } 11589 11590 private static String processClass(ProcessRecord process) { 11591 if (process == null || process.pid == MY_PID) { 11592 return "system_server"; 11593 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11594 return "system_app"; 11595 } else { 11596 return "data_app"; 11597 } 11598 } 11599 11600 /** 11601 * Write a description of an error (crash, WTF, ANR) to the drop box. 11602 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11603 * @param process which caused the error, null means the system server 11604 * @param activity which triggered the error, null if unknown 11605 * @param parent activity related to the error, null if unknown 11606 * @param subject line related to the error, null if absent 11607 * @param report in long form describing the error, null if absent 11608 * @param logFile to include in the report, null if none 11609 * @param crashInfo giving an application stack trace, null if absent 11610 */ 11611 public void addErrorToDropBox(String eventType, 11612 ProcessRecord process, String processName, ActivityRecord activity, 11613 ActivityRecord parent, String subject, 11614 final String report, final File logFile, 11615 final ApplicationErrorReport.CrashInfo crashInfo) { 11616 // NOTE -- this must never acquire the ActivityManagerService lock, 11617 // otherwise the watchdog may be prevented from resetting the system. 11618 11619 final String dropboxTag = processClass(process) + "_" + eventType; 11620 final DropBoxManager dbox = (DropBoxManager) 11621 mContext.getSystemService(Context.DROPBOX_SERVICE); 11622 11623 // Exit early if the dropbox isn't configured to accept this report type. 11624 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11625 11626 final StringBuilder sb = new StringBuilder(1024); 11627 appendDropBoxProcessHeaders(process, processName, sb); 11628 if (activity != null) { 11629 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11630 } 11631 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11632 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11633 } 11634 if (parent != null && parent != activity) { 11635 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11636 } 11637 if (subject != null) { 11638 sb.append("Subject: ").append(subject).append("\n"); 11639 } 11640 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11641 if (Debug.isDebuggerConnected()) { 11642 sb.append("Debugger: Connected\n"); 11643 } 11644 sb.append("\n"); 11645 11646 // Do the rest in a worker thread to avoid blocking the caller on I/O 11647 // (After this point, we shouldn't access AMS internal data structures.) 11648 Thread worker = new Thread("Error dump: " + dropboxTag) { 11649 @Override 11650 public void run() { 11651 if (report != null) { 11652 sb.append(report); 11653 } 11654 if (logFile != null) { 11655 try { 11656 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11657 "\n\n[[TRUNCATED]]")); 11658 } catch (IOException e) { 11659 Slog.e(TAG, "Error reading " + logFile, e); 11660 } 11661 } 11662 if (crashInfo != null && crashInfo.stackTrace != null) { 11663 sb.append(crashInfo.stackTrace); 11664 } 11665 11666 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11667 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11668 if (lines > 0) { 11669 sb.append("\n"); 11670 11671 // Merge several logcat streams, and take the last N lines 11672 InputStreamReader input = null; 11673 try { 11674 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11675 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11676 "-b", "crash", 11677 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11678 11679 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11680 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11681 input = new InputStreamReader(logcat.getInputStream()); 11682 11683 int num; 11684 char[] buf = new char[8192]; 11685 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11686 } catch (IOException e) { 11687 Slog.e(TAG, "Error running logcat", e); 11688 } finally { 11689 if (input != null) try { input.close(); } catch (IOException e) {} 11690 } 11691 } 11692 11693 dbox.addText(dropboxTag, sb.toString()); 11694 } 11695 }; 11696 11697 if (process == null) { 11698 // If process is null, we are being called from some internal code 11699 // and may be about to die -- run this synchronously. 11700 worker.run(); 11701 } else { 11702 worker.start(); 11703 } 11704 } 11705 11706 /** 11707 * Bring up the "unexpected error" dialog box for a crashing app. 11708 * Deal with edge cases (intercepts from instrumented applications, 11709 * ActivityController, error intent receivers, that sort of thing). 11710 * @param r the application crashing 11711 * @param crashInfo describing the failure 11712 */ 11713 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11714 long timeMillis = System.currentTimeMillis(); 11715 String shortMsg = crashInfo.exceptionClassName; 11716 String longMsg = crashInfo.exceptionMessage; 11717 String stackTrace = crashInfo.stackTrace; 11718 if (shortMsg != null && longMsg != null) { 11719 longMsg = shortMsg + ": " + longMsg; 11720 } else if (shortMsg != null) { 11721 longMsg = shortMsg; 11722 } 11723 11724 AppErrorResult result = new AppErrorResult(); 11725 synchronized (this) { 11726 if (mController != null) { 11727 try { 11728 String name = r != null ? r.processName : null; 11729 int pid = r != null ? r.pid : Binder.getCallingPid(); 11730 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11731 if (!mController.appCrashed(name, pid, 11732 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11733 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11734 && "Native crash".equals(crashInfo.exceptionClassName)) { 11735 Slog.w(TAG, "Skip killing native crashed app " + name 11736 + "(" + pid + ") during testing"); 11737 } else { 11738 Slog.w(TAG, "Force-killing crashed app " + name 11739 + " at watcher's request"); 11740 if (r != null) { 11741 r.kill("crash", true); 11742 } else { 11743 // Huh. 11744 Process.killProcess(pid); 11745 Process.killProcessGroup(uid, pid); 11746 } 11747 } 11748 return; 11749 } 11750 } catch (RemoteException e) { 11751 mController = null; 11752 Watchdog.getInstance().setActivityController(null); 11753 } 11754 } 11755 11756 final long origId = Binder.clearCallingIdentity(); 11757 11758 // If this process is running instrumentation, finish it. 11759 if (r != null && r.instrumentationClass != null) { 11760 Slog.w(TAG, "Error in app " + r.processName 11761 + " running instrumentation " + r.instrumentationClass + ":"); 11762 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11763 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11764 Bundle info = new Bundle(); 11765 info.putString("shortMsg", shortMsg); 11766 info.putString("longMsg", longMsg); 11767 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11768 Binder.restoreCallingIdentity(origId); 11769 return; 11770 } 11771 11772 // If we can't identify the process or it's already exceeded its crash quota, 11773 // quit right away without showing a crash dialog. 11774 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11775 Binder.restoreCallingIdentity(origId); 11776 return; 11777 } 11778 11779 Message msg = Message.obtain(); 11780 msg.what = SHOW_ERROR_MSG; 11781 HashMap data = new HashMap(); 11782 data.put("result", result); 11783 data.put("app", r); 11784 msg.obj = data; 11785 mHandler.sendMessage(msg); 11786 11787 Binder.restoreCallingIdentity(origId); 11788 } 11789 11790 int res = result.get(); 11791 11792 Intent appErrorIntent = null; 11793 synchronized (this) { 11794 if (r != null && !r.isolated) { 11795 // XXX Can't keep track of crash time for isolated processes, 11796 // since they don't have a persistent identity. 11797 mProcessCrashTimes.put(r.info.processName, r.uid, 11798 SystemClock.uptimeMillis()); 11799 } 11800 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11801 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11802 } 11803 } 11804 11805 if (appErrorIntent != null) { 11806 try { 11807 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11808 } catch (ActivityNotFoundException e) { 11809 Slog.w(TAG, "bug report receiver dissappeared", e); 11810 } 11811 } 11812 } 11813 11814 Intent createAppErrorIntentLocked(ProcessRecord r, 11815 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11816 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11817 if (report == null) { 11818 return null; 11819 } 11820 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11821 result.setComponent(r.errorReportReceiver); 11822 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11823 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11824 return result; 11825 } 11826 11827 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11828 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11829 if (r.errorReportReceiver == null) { 11830 return null; 11831 } 11832 11833 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11834 return null; 11835 } 11836 11837 ApplicationErrorReport report = new ApplicationErrorReport(); 11838 report.packageName = r.info.packageName; 11839 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11840 report.processName = r.processName; 11841 report.time = timeMillis; 11842 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11843 11844 if (r.crashing || r.forceCrashReport) { 11845 report.type = ApplicationErrorReport.TYPE_CRASH; 11846 report.crashInfo = crashInfo; 11847 } else if (r.notResponding) { 11848 report.type = ApplicationErrorReport.TYPE_ANR; 11849 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11850 11851 report.anrInfo.activity = r.notRespondingReport.tag; 11852 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11853 report.anrInfo.info = r.notRespondingReport.longMsg; 11854 } 11855 11856 return report; 11857 } 11858 11859 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11860 enforceNotIsolatedCaller("getProcessesInErrorState"); 11861 // assume our apps are happy - lazy create the list 11862 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11863 11864 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11865 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11866 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11867 11868 synchronized (this) { 11869 11870 // iterate across all processes 11871 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11872 ProcessRecord app = mLruProcesses.get(i); 11873 if (!allUsers && app.userId != userId) { 11874 continue; 11875 } 11876 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11877 // This one's in trouble, so we'll generate a report for it 11878 // crashes are higher priority (in case there's a crash *and* an anr) 11879 ActivityManager.ProcessErrorStateInfo report = null; 11880 if (app.crashing) { 11881 report = app.crashingReport; 11882 } else if (app.notResponding) { 11883 report = app.notRespondingReport; 11884 } 11885 11886 if (report != null) { 11887 if (errList == null) { 11888 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11889 } 11890 errList.add(report); 11891 } else { 11892 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11893 " crashing = " + app.crashing + 11894 " notResponding = " + app.notResponding); 11895 } 11896 } 11897 } 11898 } 11899 11900 return errList; 11901 } 11902 11903 static int procStateToImportance(int procState, int memAdj, 11904 ActivityManager.RunningAppProcessInfo currApp) { 11905 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11906 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11907 currApp.lru = memAdj; 11908 } else { 11909 currApp.lru = 0; 11910 } 11911 return imp; 11912 } 11913 11914 private void fillInProcMemInfo(ProcessRecord app, 11915 ActivityManager.RunningAppProcessInfo outInfo) { 11916 outInfo.pid = app.pid; 11917 outInfo.uid = app.info.uid; 11918 if (mHeavyWeightProcess == app) { 11919 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11920 } 11921 if (app.persistent) { 11922 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11923 } 11924 if (app.activities.size() > 0) { 11925 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11926 } 11927 outInfo.lastTrimLevel = app.trimMemoryLevel; 11928 int adj = app.curAdj; 11929 int procState = app.curProcState; 11930 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11931 outInfo.importanceReasonCode = app.adjTypeCode; 11932 outInfo.processState = app.curProcState; 11933 } 11934 11935 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11936 enforceNotIsolatedCaller("getRunningAppProcesses"); 11937 // Lazy instantiation of list 11938 List<ActivityManager.RunningAppProcessInfo> runList = null; 11939 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11940 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11941 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11942 synchronized (this) { 11943 // Iterate across all processes 11944 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11945 ProcessRecord app = mLruProcesses.get(i); 11946 if (!allUsers && app.userId != userId) { 11947 continue; 11948 } 11949 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11950 // Generate process state info for running application 11951 ActivityManager.RunningAppProcessInfo currApp = 11952 new ActivityManager.RunningAppProcessInfo(app.processName, 11953 app.pid, app.getPackageList()); 11954 fillInProcMemInfo(app, currApp); 11955 if (app.adjSource instanceof ProcessRecord) { 11956 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11957 currApp.importanceReasonImportance = 11958 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11959 app.adjSourceProcState); 11960 } else if (app.adjSource instanceof ActivityRecord) { 11961 ActivityRecord r = (ActivityRecord)app.adjSource; 11962 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11963 } 11964 if (app.adjTarget instanceof ComponentName) { 11965 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11966 } 11967 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11968 // + " lru=" + currApp.lru); 11969 if (runList == null) { 11970 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11971 } 11972 runList.add(currApp); 11973 } 11974 } 11975 } 11976 return runList; 11977 } 11978 11979 public List<ApplicationInfo> getRunningExternalApplications() { 11980 enforceNotIsolatedCaller("getRunningExternalApplications"); 11981 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11982 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11983 if (runningApps != null && runningApps.size() > 0) { 11984 Set<String> extList = new HashSet<String>(); 11985 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11986 if (app.pkgList != null) { 11987 for (String pkg : app.pkgList) { 11988 extList.add(pkg); 11989 } 11990 } 11991 } 11992 IPackageManager pm = AppGlobals.getPackageManager(); 11993 for (String pkg : extList) { 11994 try { 11995 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11996 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11997 retList.add(info); 11998 } 11999 } catch (RemoteException e) { 12000 } 12001 } 12002 } 12003 return retList; 12004 } 12005 12006 @Override 12007 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12008 enforceNotIsolatedCaller("getMyMemoryState"); 12009 synchronized (this) { 12010 ProcessRecord proc; 12011 synchronized (mPidsSelfLocked) { 12012 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12013 } 12014 fillInProcMemInfo(proc, outInfo); 12015 } 12016 } 12017 12018 @Override 12019 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12020 if (checkCallingPermission(android.Manifest.permission.DUMP) 12021 != PackageManager.PERMISSION_GRANTED) { 12022 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12023 + Binder.getCallingPid() 12024 + ", uid=" + Binder.getCallingUid() 12025 + " without permission " 12026 + android.Manifest.permission.DUMP); 12027 return; 12028 } 12029 12030 boolean dumpAll = false; 12031 boolean dumpClient = false; 12032 String dumpPackage = null; 12033 12034 int opti = 0; 12035 while (opti < args.length) { 12036 String opt = args[opti]; 12037 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12038 break; 12039 } 12040 opti++; 12041 if ("-a".equals(opt)) { 12042 dumpAll = true; 12043 } else if ("-c".equals(opt)) { 12044 dumpClient = true; 12045 } else if ("-h".equals(opt)) { 12046 pw.println("Activity manager dump options:"); 12047 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12048 pw.println(" cmd may be one of:"); 12049 pw.println(" a[ctivities]: activity stack state"); 12050 pw.println(" r[recents]: recent activities state"); 12051 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12052 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12053 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12054 pw.println(" o[om]: out of memory management"); 12055 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12056 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12057 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12058 pw.println(" service [COMP_SPEC]: service client-side state"); 12059 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12060 pw.println(" all: dump all activities"); 12061 pw.println(" top: dump the top activity"); 12062 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12063 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12064 pw.println(" a partial substring in a component name, a"); 12065 pw.println(" hex object identifier."); 12066 pw.println(" -a: include all available server state."); 12067 pw.println(" -c: include client state."); 12068 return; 12069 } else { 12070 pw.println("Unknown argument: " + opt + "; use -h for help"); 12071 } 12072 } 12073 12074 long origId = Binder.clearCallingIdentity(); 12075 boolean more = false; 12076 // Is the caller requesting to dump a particular piece of data? 12077 if (opti < args.length) { 12078 String cmd = args[opti]; 12079 opti++; 12080 if ("activities".equals(cmd) || "a".equals(cmd)) { 12081 synchronized (this) { 12082 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12083 } 12084 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12085 synchronized (this) { 12086 dumpRecentsLocked(fd, pw, args, opti, true, null); 12087 } 12088 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12089 String[] newArgs; 12090 String name; 12091 if (opti >= args.length) { 12092 name = null; 12093 newArgs = EMPTY_STRING_ARRAY; 12094 } else { 12095 name = args[opti]; 12096 opti++; 12097 newArgs = new String[args.length - opti]; 12098 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12099 args.length - opti); 12100 } 12101 synchronized (this) { 12102 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12103 } 12104 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12105 String[] newArgs; 12106 String name; 12107 if (opti >= args.length) { 12108 name = null; 12109 newArgs = EMPTY_STRING_ARRAY; 12110 } else { 12111 name = args[opti]; 12112 opti++; 12113 newArgs = new String[args.length - opti]; 12114 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12115 args.length - opti); 12116 } 12117 synchronized (this) { 12118 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12119 } 12120 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12121 String[] newArgs; 12122 String name; 12123 if (opti >= args.length) { 12124 name = null; 12125 newArgs = EMPTY_STRING_ARRAY; 12126 } else { 12127 name = args[opti]; 12128 opti++; 12129 newArgs = new String[args.length - opti]; 12130 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12131 args.length - opti); 12132 } 12133 synchronized (this) { 12134 dumpProcessesLocked(fd, pw, args, opti, true, name); 12135 } 12136 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12137 synchronized (this) { 12138 dumpOomLocked(fd, pw, args, opti, true); 12139 } 12140 } else if ("provider".equals(cmd)) { 12141 String[] newArgs; 12142 String name; 12143 if (opti >= args.length) { 12144 name = null; 12145 newArgs = EMPTY_STRING_ARRAY; 12146 } else { 12147 name = args[opti]; 12148 opti++; 12149 newArgs = new String[args.length - opti]; 12150 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12151 } 12152 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12153 pw.println("No providers match: " + name); 12154 pw.println("Use -h for help."); 12155 } 12156 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12157 synchronized (this) { 12158 dumpProvidersLocked(fd, pw, args, opti, true, null); 12159 } 12160 } else if ("service".equals(cmd)) { 12161 String[] newArgs; 12162 String name; 12163 if (opti >= args.length) { 12164 name = null; 12165 newArgs = EMPTY_STRING_ARRAY; 12166 } else { 12167 name = args[opti]; 12168 opti++; 12169 newArgs = new String[args.length - opti]; 12170 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12171 args.length - opti); 12172 } 12173 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12174 pw.println("No services match: " + name); 12175 pw.println("Use -h for help."); 12176 } 12177 } else if ("package".equals(cmd)) { 12178 String[] newArgs; 12179 if (opti >= args.length) { 12180 pw.println("package: no package name specified"); 12181 pw.println("Use -h for help."); 12182 } else { 12183 dumpPackage = args[opti]; 12184 opti++; 12185 newArgs = new String[args.length - opti]; 12186 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12187 args.length - opti); 12188 args = newArgs; 12189 opti = 0; 12190 more = true; 12191 } 12192 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12193 synchronized (this) { 12194 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12195 } 12196 } else { 12197 // Dumping a single activity? 12198 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12199 pw.println("Bad activity command, or no activities match: " + cmd); 12200 pw.println("Use -h for help."); 12201 } 12202 } 12203 if (!more) { 12204 Binder.restoreCallingIdentity(origId); 12205 return; 12206 } 12207 } 12208 12209 // No piece of data specified, dump everything. 12210 synchronized (this) { 12211 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12212 pw.println(); 12213 if (dumpAll) { 12214 pw.println("-------------------------------------------------------------------------------"); 12215 } 12216 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12217 pw.println(); 12218 if (dumpAll) { 12219 pw.println("-------------------------------------------------------------------------------"); 12220 } 12221 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12222 pw.println(); 12223 if (dumpAll) { 12224 pw.println("-------------------------------------------------------------------------------"); 12225 } 12226 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12227 pw.println(); 12228 if (dumpAll) { 12229 pw.println("-------------------------------------------------------------------------------"); 12230 } 12231 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12232 pw.println(); 12233 if (dumpAll) { 12234 pw.println("-------------------------------------------------------------------------------"); 12235 } 12236 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12237 pw.println(); 12238 if (dumpAll) { 12239 pw.println("-------------------------------------------------------------------------------"); 12240 } 12241 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12242 } 12243 Binder.restoreCallingIdentity(origId); 12244 } 12245 12246 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12247 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12248 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12249 12250 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12251 dumpPackage); 12252 boolean needSep = printedAnything; 12253 12254 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12255 dumpPackage, needSep, " mFocusedActivity: "); 12256 if (printed) { 12257 printedAnything = true; 12258 needSep = false; 12259 } 12260 12261 if (dumpPackage == null) { 12262 if (needSep) { 12263 pw.println(); 12264 } 12265 needSep = true; 12266 printedAnything = true; 12267 mStackSupervisor.dump(pw, " "); 12268 } 12269 12270 if (!printedAnything) { 12271 pw.println(" (nothing)"); 12272 } 12273 } 12274 12275 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12276 int opti, boolean dumpAll, String dumpPackage) { 12277 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12278 12279 boolean printedAnything = false; 12280 12281 if (mRecentTasks.size() > 0) { 12282 boolean printedHeader = false; 12283 12284 final int N = mRecentTasks.size(); 12285 for (int i=0; i<N; i++) { 12286 TaskRecord tr = mRecentTasks.get(i); 12287 if (dumpPackage != null) { 12288 if (tr.realActivity == null || 12289 !dumpPackage.equals(tr.realActivity)) { 12290 continue; 12291 } 12292 } 12293 if (!printedHeader) { 12294 pw.println(" Recent tasks:"); 12295 printedHeader = true; 12296 printedAnything = true; 12297 } 12298 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12299 pw.println(tr); 12300 if (dumpAll) { 12301 mRecentTasks.get(i).dump(pw, " "); 12302 } 12303 } 12304 } 12305 12306 if (!printedAnything) { 12307 pw.println(" (nothing)"); 12308 } 12309 } 12310 12311 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12312 int opti, boolean dumpAll, String dumpPackage) { 12313 boolean needSep = false; 12314 boolean printedAnything = false; 12315 int numPers = 0; 12316 12317 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12318 12319 if (dumpAll) { 12320 final int NP = mProcessNames.getMap().size(); 12321 for (int ip=0; ip<NP; ip++) { 12322 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12323 final int NA = procs.size(); 12324 for (int ia=0; ia<NA; ia++) { 12325 ProcessRecord r = procs.valueAt(ia); 12326 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12327 continue; 12328 } 12329 if (!needSep) { 12330 pw.println(" All known processes:"); 12331 needSep = true; 12332 printedAnything = true; 12333 } 12334 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12335 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12336 pw.print(" "); pw.println(r); 12337 r.dump(pw, " "); 12338 if (r.persistent) { 12339 numPers++; 12340 } 12341 } 12342 } 12343 } 12344 12345 if (mIsolatedProcesses.size() > 0) { 12346 boolean printed = false; 12347 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12348 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12349 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12350 continue; 12351 } 12352 if (!printed) { 12353 if (needSep) { 12354 pw.println(); 12355 } 12356 pw.println(" Isolated process list (sorted by uid):"); 12357 printedAnything = true; 12358 printed = true; 12359 needSep = true; 12360 } 12361 pw.println(String.format("%sIsolated #%2d: %s", 12362 " ", i, r.toString())); 12363 } 12364 } 12365 12366 if (mLruProcesses.size() > 0) { 12367 if (needSep) { 12368 pw.println(); 12369 } 12370 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12371 pw.print(" total, non-act at "); 12372 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12373 pw.print(", non-svc at "); 12374 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12375 pw.println("):"); 12376 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12377 needSep = true; 12378 printedAnything = true; 12379 } 12380 12381 if (dumpAll || dumpPackage != null) { 12382 synchronized (mPidsSelfLocked) { 12383 boolean printed = false; 12384 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12385 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12386 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12387 continue; 12388 } 12389 if (!printed) { 12390 if (needSep) pw.println(); 12391 needSep = true; 12392 pw.println(" PID mappings:"); 12393 printed = true; 12394 printedAnything = true; 12395 } 12396 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12397 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12398 } 12399 } 12400 } 12401 12402 if (mForegroundProcesses.size() > 0) { 12403 synchronized (mPidsSelfLocked) { 12404 boolean printed = false; 12405 for (int i=0; i<mForegroundProcesses.size(); i++) { 12406 ProcessRecord r = mPidsSelfLocked.get( 12407 mForegroundProcesses.valueAt(i).pid); 12408 if (dumpPackage != null && (r == null 12409 || !r.pkgList.containsKey(dumpPackage))) { 12410 continue; 12411 } 12412 if (!printed) { 12413 if (needSep) pw.println(); 12414 needSep = true; 12415 pw.println(" Foreground Processes:"); 12416 printed = true; 12417 printedAnything = true; 12418 } 12419 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12420 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12421 } 12422 } 12423 } 12424 12425 if (mPersistentStartingProcesses.size() > 0) { 12426 if (needSep) pw.println(); 12427 needSep = true; 12428 printedAnything = true; 12429 pw.println(" Persisent processes that are starting:"); 12430 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12431 "Starting Norm", "Restarting PERS", dumpPackage); 12432 } 12433 12434 if (mRemovedProcesses.size() > 0) { 12435 if (needSep) pw.println(); 12436 needSep = true; 12437 printedAnything = true; 12438 pw.println(" Processes that are being removed:"); 12439 dumpProcessList(pw, this, mRemovedProcesses, " ", 12440 "Removed Norm", "Removed PERS", dumpPackage); 12441 } 12442 12443 if (mProcessesOnHold.size() > 0) { 12444 if (needSep) pw.println(); 12445 needSep = true; 12446 printedAnything = true; 12447 pw.println(" Processes that are on old until the system is ready:"); 12448 dumpProcessList(pw, this, mProcessesOnHold, " ", 12449 "OnHold Norm", "OnHold PERS", dumpPackage); 12450 } 12451 12452 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12453 12454 if (mProcessCrashTimes.getMap().size() > 0) { 12455 boolean printed = false; 12456 long now = SystemClock.uptimeMillis(); 12457 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12458 final int NP = pmap.size(); 12459 for (int ip=0; ip<NP; ip++) { 12460 String pname = pmap.keyAt(ip); 12461 SparseArray<Long> uids = pmap.valueAt(ip); 12462 final int N = uids.size(); 12463 for (int i=0; i<N; i++) { 12464 int puid = uids.keyAt(i); 12465 ProcessRecord r = mProcessNames.get(pname, puid); 12466 if (dumpPackage != null && (r == null 12467 || !r.pkgList.containsKey(dumpPackage))) { 12468 continue; 12469 } 12470 if (!printed) { 12471 if (needSep) pw.println(); 12472 needSep = true; 12473 pw.println(" Time since processes crashed:"); 12474 printed = true; 12475 printedAnything = true; 12476 } 12477 pw.print(" Process "); pw.print(pname); 12478 pw.print(" uid "); pw.print(puid); 12479 pw.print(": last crashed "); 12480 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12481 pw.println(" ago"); 12482 } 12483 } 12484 } 12485 12486 if (mBadProcesses.getMap().size() > 0) { 12487 boolean printed = false; 12488 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12489 final int NP = pmap.size(); 12490 for (int ip=0; ip<NP; ip++) { 12491 String pname = pmap.keyAt(ip); 12492 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12493 final int N = uids.size(); 12494 for (int i=0; i<N; i++) { 12495 int puid = uids.keyAt(i); 12496 ProcessRecord r = mProcessNames.get(pname, puid); 12497 if (dumpPackage != null && (r == null 12498 || !r.pkgList.containsKey(dumpPackage))) { 12499 continue; 12500 } 12501 if (!printed) { 12502 if (needSep) pw.println(); 12503 needSep = true; 12504 pw.println(" Bad processes:"); 12505 printedAnything = true; 12506 } 12507 BadProcessInfo info = uids.valueAt(i); 12508 pw.print(" Bad process "); pw.print(pname); 12509 pw.print(" uid "); pw.print(puid); 12510 pw.print(": crashed at time "); pw.println(info.time); 12511 if (info.shortMsg != null) { 12512 pw.print(" Short msg: "); pw.println(info.shortMsg); 12513 } 12514 if (info.longMsg != null) { 12515 pw.print(" Long msg: "); pw.println(info.longMsg); 12516 } 12517 if (info.stack != null) { 12518 pw.println(" Stack:"); 12519 int lastPos = 0; 12520 for (int pos=0; pos<info.stack.length(); pos++) { 12521 if (info.stack.charAt(pos) == '\n') { 12522 pw.print(" "); 12523 pw.write(info.stack, lastPos, pos-lastPos); 12524 pw.println(); 12525 lastPos = pos+1; 12526 } 12527 } 12528 if (lastPos < info.stack.length()) { 12529 pw.print(" "); 12530 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12531 pw.println(); 12532 } 12533 } 12534 } 12535 } 12536 } 12537 12538 if (dumpPackage == null) { 12539 pw.println(); 12540 needSep = false; 12541 pw.println(" mStartedUsers:"); 12542 for (int i=0; i<mStartedUsers.size(); i++) { 12543 UserStartedState uss = mStartedUsers.valueAt(i); 12544 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12545 pw.print(": "); uss.dump("", pw); 12546 } 12547 pw.print(" mStartedUserArray: ["); 12548 for (int i=0; i<mStartedUserArray.length; i++) { 12549 if (i > 0) pw.print(", "); 12550 pw.print(mStartedUserArray[i]); 12551 } 12552 pw.println("]"); 12553 pw.print(" mUserLru: ["); 12554 for (int i=0; i<mUserLru.size(); i++) { 12555 if (i > 0) pw.print(", "); 12556 pw.print(mUserLru.get(i)); 12557 } 12558 pw.println("]"); 12559 if (dumpAll) { 12560 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12561 } 12562 synchronized (mUserProfileGroupIdsSelfLocked) { 12563 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12564 pw.println(" mUserProfileGroupIds:"); 12565 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12566 pw.print(" User #"); 12567 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12568 pw.print(" -> profile #"); 12569 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12570 } 12571 } 12572 } 12573 } 12574 if (mHomeProcess != null && (dumpPackage == null 12575 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12576 if (needSep) { 12577 pw.println(); 12578 needSep = false; 12579 } 12580 pw.println(" mHomeProcess: " + mHomeProcess); 12581 } 12582 if (mPreviousProcess != null && (dumpPackage == null 12583 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12584 if (needSep) { 12585 pw.println(); 12586 needSep = false; 12587 } 12588 pw.println(" mPreviousProcess: " + mPreviousProcess); 12589 } 12590 if (dumpAll) { 12591 StringBuilder sb = new StringBuilder(128); 12592 sb.append(" mPreviousProcessVisibleTime: "); 12593 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12594 pw.println(sb); 12595 } 12596 if (mHeavyWeightProcess != null && (dumpPackage == null 12597 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12598 if (needSep) { 12599 pw.println(); 12600 needSep = false; 12601 } 12602 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12603 } 12604 if (dumpPackage == null) { 12605 pw.println(" mConfiguration: " + mConfiguration); 12606 } 12607 if (dumpAll) { 12608 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12609 if (mCompatModePackages.getPackages().size() > 0) { 12610 boolean printed = false; 12611 for (Map.Entry<String, Integer> entry 12612 : mCompatModePackages.getPackages().entrySet()) { 12613 String pkg = entry.getKey(); 12614 int mode = entry.getValue(); 12615 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12616 continue; 12617 } 12618 if (!printed) { 12619 pw.println(" mScreenCompatPackages:"); 12620 printed = true; 12621 } 12622 pw.print(" "); pw.print(pkg); pw.print(": "); 12623 pw.print(mode); pw.println(); 12624 } 12625 } 12626 } 12627 if (dumpPackage == null) { 12628 if (mSleeping || mWentToSleep || mLockScreenShown) { 12629 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12630 + " mLockScreenShown " + mLockScreenShown); 12631 } 12632 if (mShuttingDown || mRunningVoice) { 12633 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12634 } 12635 } 12636 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12637 || mOrigWaitForDebugger) { 12638 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12639 || dumpPackage.equals(mOrigDebugApp)) { 12640 if (needSep) { 12641 pw.println(); 12642 needSep = false; 12643 } 12644 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12645 + " mDebugTransient=" + mDebugTransient 12646 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12647 } 12648 } 12649 if (mOpenGlTraceApp != null) { 12650 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12651 if (needSep) { 12652 pw.println(); 12653 needSep = false; 12654 } 12655 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12656 } 12657 } 12658 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12659 || mProfileFd != null) { 12660 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12661 if (needSep) { 12662 pw.println(); 12663 needSep = false; 12664 } 12665 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12666 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12667 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12668 + mAutoStopProfiler); 12669 pw.println(" mProfileType=" + mProfileType); 12670 } 12671 } 12672 if (dumpPackage == null) { 12673 if (mAlwaysFinishActivities || mController != null) { 12674 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12675 + " mController=" + mController); 12676 } 12677 if (dumpAll) { 12678 pw.println(" Total persistent processes: " + numPers); 12679 pw.println(" mProcessesReady=" + mProcessesReady 12680 + " mSystemReady=" + mSystemReady); 12681 pw.println(" mBooting=" + mBooting 12682 + " mBooted=" + mBooted 12683 + " mFactoryTest=" + mFactoryTest); 12684 pw.print(" mLastPowerCheckRealtime="); 12685 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12686 pw.println(""); 12687 pw.print(" mLastPowerCheckUptime="); 12688 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12689 pw.println(""); 12690 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12691 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12692 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12693 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12694 + " (" + mLruProcesses.size() + " total)" 12695 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12696 + " mNumServiceProcs=" + mNumServiceProcs 12697 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12698 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12699 + " mLastMemoryLevel" + mLastMemoryLevel 12700 + " mLastNumProcesses" + mLastNumProcesses); 12701 long now = SystemClock.uptimeMillis(); 12702 pw.print(" mLastIdleTime="); 12703 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12704 pw.print(" mLowRamSinceLastIdle="); 12705 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12706 pw.println(); 12707 } 12708 } 12709 12710 if (!printedAnything) { 12711 pw.println(" (nothing)"); 12712 } 12713 } 12714 12715 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12716 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12717 if (mProcessesToGc.size() > 0) { 12718 boolean printed = false; 12719 long now = SystemClock.uptimeMillis(); 12720 for (int i=0; i<mProcessesToGc.size(); i++) { 12721 ProcessRecord proc = mProcessesToGc.get(i); 12722 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12723 continue; 12724 } 12725 if (!printed) { 12726 if (needSep) pw.println(); 12727 needSep = true; 12728 pw.println(" Processes that are waiting to GC:"); 12729 printed = true; 12730 } 12731 pw.print(" Process "); pw.println(proc); 12732 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12733 pw.print(", last gced="); 12734 pw.print(now-proc.lastRequestedGc); 12735 pw.print(" ms ago, last lowMem="); 12736 pw.print(now-proc.lastLowMemory); 12737 pw.println(" ms ago"); 12738 12739 } 12740 } 12741 return needSep; 12742 } 12743 12744 void printOomLevel(PrintWriter pw, String name, int adj) { 12745 pw.print(" "); 12746 if (adj >= 0) { 12747 pw.print(' '); 12748 if (adj < 10) pw.print(' '); 12749 } else { 12750 if (adj > -10) pw.print(' '); 12751 } 12752 pw.print(adj); 12753 pw.print(": "); 12754 pw.print(name); 12755 pw.print(" ("); 12756 pw.print(mProcessList.getMemLevel(adj)/1024); 12757 pw.println(" kB)"); 12758 } 12759 12760 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12761 int opti, boolean dumpAll) { 12762 boolean needSep = false; 12763 12764 if (mLruProcesses.size() > 0) { 12765 if (needSep) pw.println(); 12766 needSep = true; 12767 pw.println(" OOM levels:"); 12768 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12769 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12770 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12771 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12772 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12773 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12774 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12775 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12776 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12777 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12778 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12779 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12780 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12781 12782 if (needSep) pw.println(); 12783 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12784 pw.print(" total, non-act at "); 12785 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12786 pw.print(", non-svc at "); 12787 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12788 pw.println("):"); 12789 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12790 needSep = true; 12791 } 12792 12793 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12794 12795 pw.println(); 12796 pw.println(" mHomeProcess: " + mHomeProcess); 12797 pw.println(" mPreviousProcess: " + mPreviousProcess); 12798 if (mHeavyWeightProcess != null) { 12799 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12800 } 12801 12802 return true; 12803 } 12804 12805 /** 12806 * There are three ways to call this: 12807 * - no provider specified: dump all the providers 12808 * - a flattened component name that matched an existing provider was specified as the 12809 * first arg: dump that one provider 12810 * - the first arg isn't the flattened component name of an existing provider: 12811 * dump all providers whose component contains the first arg as a substring 12812 */ 12813 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12814 int opti, boolean dumpAll) { 12815 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12816 } 12817 12818 static class ItemMatcher { 12819 ArrayList<ComponentName> components; 12820 ArrayList<String> strings; 12821 ArrayList<Integer> objects; 12822 boolean all; 12823 12824 ItemMatcher() { 12825 all = true; 12826 } 12827 12828 void build(String name) { 12829 ComponentName componentName = ComponentName.unflattenFromString(name); 12830 if (componentName != null) { 12831 if (components == null) { 12832 components = new ArrayList<ComponentName>(); 12833 } 12834 components.add(componentName); 12835 all = false; 12836 } else { 12837 int objectId = 0; 12838 // Not a '/' separated full component name; maybe an object ID? 12839 try { 12840 objectId = Integer.parseInt(name, 16); 12841 if (objects == null) { 12842 objects = new ArrayList<Integer>(); 12843 } 12844 objects.add(objectId); 12845 all = false; 12846 } catch (RuntimeException e) { 12847 // Not an integer; just do string match. 12848 if (strings == null) { 12849 strings = new ArrayList<String>(); 12850 } 12851 strings.add(name); 12852 all = false; 12853 } 12854 } 12855 } 12856 12857 int build(String[] args, int opti) { 12858 for (; opti<args.length; opti++) { 12859 String name = args[opti]; 12860 if ("--".equals(name)) { 12861 return opti+1; 12862 } 12863 build(name); 12864 } 12865 return opti; 12866 } 12867 12868 boolean match(Object object, ComponentName comp) { 12869 if (all) { 12870 return true; 12871 } 12872 if (components != null) { 12873 for (int i=0; i<components.size(); i++) { 12874 if (components.get(i).equals(comp)) { 12875 return true; 12876 } 12877 } 12878 } 12879 if (objects != null) { 12880 for (int i=0; i<objects.size(); i++) { 12881 if (System.identityHashCode(object) == objects.get(i)) { 12882 return true; 12883 } 12884 } 12885 } 12886 if (strings != null) { 12887 String flat = comp.flattenToString(); 12888 for (int i=0; i<strings.size(); i++) { 12889 if (flat.contains(strings.get(i))) { 12890 return true; 12891 } 12892 } 12893 } 12894 return false; 12895 } 12896 } 12897 12898 /** 12899 * There are three things that cmd can be: 12900 * - a flattened component name that matches an existing activity 12901 * - the cmd arg isn't the flattened component name of an existing activity: 12902 * dump all activity whose component contains the cmd as a substring 12903 * - A hex number of the ActivityRecord object instance. 12904 */ 12905 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12906 int opti, boolean dumpAll) { 12907 ArrayList<ActivityRecord> activities; 12908 12909 synchronized (this) { 12910 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12911 } 12912 12913 if (activities.size() <= 0) { 12914 return false; 12915 } 12916 12917 String[] newArgs = new String[args.length - opti]; 12918 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12919 12920 TaskRecord lastTask = null; 12921 boolean needSep = false; 12922 for (int i=activities.size()-1; i>=0; i--) { 12923 ActivityRecord r = activities.get(i); 12924 if (needSep) { 12925 pw.println(); 12926 } 12927 needSep = true; 12928 synchronized (this) { 12929 if (lastTask != r.task) { 12930 lastTask = r.task; 12931 pw.print("TASK "); pw.print(lastTask.affinity); 12932 pw.print(" id="); pw.println(lastTask.taskId); 12933 if (dumpAll) { 12934 lastTask.dump(pw, " "); 12935 } 12936 } 12937 } 12938 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12939 } 12940 return true; 12941 } 12942 12943 /** 12944 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12945 * there is a thread associated with the activity. 12946 */ 12947 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12948 final ActivityRecord r, String[] args, boolean dumpAll) { 12949 String innerPrefix = prefix + " "; 12950 synchronized (this) { 12951 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12952 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12953 pw.print(" pid="); 12954 if (r.app != null) pw.println(r.app.pid); 12955 else pw.println("(not running)"); 12956 if (dumpAll) { 12957 r.dump(pw, innerPrefix); 12958 } 12959 } 12960 if (r.app != null && r.app.thread != null) { 12961 // flush anything that is already in the PrintWriter since the thread is going 12962 // to write to the file descriptor directly 12963 pw.flush(); 12964 try { 12965 TransferPipe tp = new TransferPipe(); 12966 try { 12967 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12968 r.appToken, innerPrefix, args); 12969 tp.go(fd); 12970 } finally { 12971 tp.kill(); 12972 } 12973 } catch (IOException e) { 12974 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12975 } catch (RemoteException e) { 12976 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12977 } 12978 } 12979 } 12980 12981 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12982 int opti, boolean dumpAll, String dumpPackage) { 12983 boolean needSep = false; 12984 boolean onlyHistory = false; 12985 boolean printedAnything = false; 12986 12987 if ("history".equals(dumpPackage)) { 12988 if (opti < args.length && "-s".equals(args[opti])) { 12989 dumpAll = false; 12990 } 12991 onlyHistory = true; 12992 dumpPackage = null; 12993 } 12994 12995 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12996 if (!onlyHistory && dumpAll) { 12997 if (mRegisteredReceivers.size() > 0) { 12998 boolean printed = false; 12999 Iterator it = mRegisteredReceivers.values().iterator(); 13000 while (it.hasNext()) { 13001 ReceiverList r = (ReceiverList)it.next(); 13002 if (dumpPackage != null && (r.app == null || 13003 !dumpPackage.equals(r.app.info.packageName))) { 13004 continue; 13005 } 13006 if (!printed) { 13007 pw.println(" Registered Receivers:"); 13008 needSep = true; 13009 printed = true; 13010 printedAnything = true; 13011 } 13012 pw.print(" * "); pw.println(r); 13013 r.dump(pw, " "); 13014 } 13015 } 13016 13017 if (mReceiverResolver.dump(pw, needSep ? 13018 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13019 " ", dumpPackage, false)) { 13020 needSep = true; 13021 printedAnything = true; 13022 } 13023 } 13024 13025 for (BroadcastQueue q : mBroadcastQueues) { 13026 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13027 printedAnything |= needSep; 13028 } 13029 13030 needSep = true; 13031 13032 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13033 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13034 if (needSep) { 13035 pw.println(); 13036 } 13037 needSep = true; 13038 printedAnything = true; 13039 pw.print(" Sticky broadcasts for user "); 13040 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13041 StringBuilder sb = new StringBuilder(128); 13042 for (Map.Entry<String, ArrayList<Intent>> ent 13043 : mStickyBroadcasts.valueAt(user).entrySet()) { 13044 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13045 if (dumpAll) { 13046 pw.println(":"); 13047 ArrayList<Intent> intents = ent.getValue(); 13048 final int N = intents.size(); 13049 for (int i=0; i<N; i++) { 13050 sb.setLength(0); 13051 sb.append(" Intent: "); 13052 intents.get(i).toShortString(sb, false, true, false, false); 13053 pw.println(sb.toString()); 13054 Bundle bundle = intents.get(i).getExtras(); 13055 if (bundle != null) { 13056 pw.print(" "); 13057 pw.println(bundle.toString()); 13058 } 13059 } 13060 } else { 13061 pw.println(""); 13062 } 13063 } 13064 } 13065 } 13066 13067 if (!onlyHistory && dumpAll) { 13068 pw.println(); 13069 for (BroadcastQueue queue : mBroadcastQueues) { 13070 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13071 + queue.mBroadcastsScheduled); 13072 } 13073 pw.println(" mHandler:"); 13074 mHandler.dump(new PrintWriterPrinter(pw), " "); 13075 needSep = true; 13076 printedAnything = true; 13077 } 13078 13079 if (!printedAnything) { 13080 pw.println(" (nothing)"); 13081 } 13082 } 13083 13084 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13085 int opti, boolean dumpAll, String dumpPackage) { 13086 boolean needSep; 13087 boolean printedAnything = false; 13088 13089 ItemMatcher matcher = new ItemMatcher(); 13090 matcher.build(args, opti); 13091 13092 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13093 13094 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13095 printedAnything |= needSep; 13096 13097 if (mLaunchingProviders.size() > 0) { 13098 boolean printed = false; 13099 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13100 ContentProviderRecord r = mLaunchingProviders.get(i); 13101 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13102 continue; 13103 } 13104 if (!printed) { 13105 if (needSep) pw.println(); 13106 needSep = true; 13107 pw.println(" Launching content providers:"); 13108 printed = true; 13109 printedAnything = true; 13110 } 13111 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13112 pw.println(r); 13113 } 13114 } 13115 13116 if (mGrantedUriPermissions.size() > 0) { 13117 boolean printed = false; 13118 int dumpUid = -2; 13119 if (dumpPackage != null) { 13120 try { 13121 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13122 } catch (NameNotFoundException e) { 13123 dumpUid = -1; 13124 } 13125 } 13126 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13127 int uid = mGrantedUriPermissions.keyAt(i); 13128 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13129 continue; 13130 } 13131 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13132 if (!printed) { 13133 if (needSep) pw.println(); 13134 needSep = true; 13135 pw.println(" Granted Uri Permissions:"); 13136 printed = true; 13137 printedAnything = true; 13138 } 13139 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13140 for (UriPermission perm : perms.values()) { 13141 pw.print(" "); pw.println(perm); 13142 if (dumpAll) { 13143 perm.dump(pw, " "); 13144 } 13145 } 13146 } 13147 } 13148 13149 if (!printedAnything) { 13150 pw.println(" (nothing)"); 13151 } 13152 } 13153 13154 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13155 int opti, boolean dumpAll, String dumpPackage) { 13156 boolean printed = false; 13157 13158 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13159 13160 if (mIntentSenderRecords.size() > 0) { 13161 Iterator<WeakReference<PendingIntentRecord>> it 13162 = mIntentSenderRecords.values().iterator(); 13163 while (it.hasNext()) { 13164 WeakReference<PendingIntentRecord> ref = it.next(); 13165 PendingIntentRecord rec = ref != null ? ref.get(): null; 13166 if (dumpPackage != null && (rec == null 13167 || !dumpPackage.equals(rec.key.packageName))) { 13168 continue; 13169 } 13170 printed = true; 13171 if (rec != null) { 13172 pw.print(" * "); pw.println(rec); 13173 if (dumpAll) { 13174 rec.dump(pw, " "); 13175 } 13176 } else { 13177 pw.print(" * "); pw.println(ref); 13178 } 13179 } 13180 } 13181 13182 if (!printed) { 13183 pw.println(" (nothing)"); 13184 } 13185 } 13186 13187 private static final int dumpProcessList(PrintWriter pw, 13188 ActivityManagerService service, List list, 13189 String prefix, String normalLabel, String persistentLabel, 13190 String dumpPackage) { 13191 int numPers = 0; 13192 final int N = list.size()-1; 13193 for (int i=N; i>=0; i--) { 13194 ProcessRecord r = (ProcessRecord)list.get(i); 13195 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13196 continue; 13197 } 13198 pw.println(String.format("%s%s #%2d: %s", 13199 prefix, (r.persistent ? persistentLabel : normalLabel), 13200 i, r.toString())); 13201 if (r.persistent) { 13202 numPers++; 13203 } 13204 } 13205 return numPers; 13206 } 13207 13208 private static final boolean dumpProcessOomList(PrintWriter pw, 13209 ActivityManagerService service, List<ProcessRecord> origList, 13210 String prefix, String normalLabel, String persistentLabel, 13211 boolean inclDetails, String dumpPackage) { 13212 13213 ArrayList<Pair<ProcessRecord, Integer>> list 13214 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13215 for (int i=0; i<origList.size(); i++) { 13216 ProcessRecord r = origList.get(i); 13217 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13218 continue; 13219 } 13220 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13221 } 13222 13223 if (list.size() <= 0) { 13224 return false; 13225 } 13226 13227 Comparator<Pair<ProcessRecord, Integer>> comparator 13228 = new Comparator<Pair<ProcessRecord, Integer>>() { 13229 @Override 13230 public int compare(Pair<ProcessRecord, Integer> object1, 13231 Pair<ProcessRecord, Integer> object2) { 13232 if (object1.first.setAdj != object2.first.setAdj) { 13233 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13234 } 13235 if (object1.second.intValue() != object2.second.intValue()) { 13236 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13237 } 13238 return 0; 13239 } 13240 }; 13241 13242 Collections.sort(list, comparator); 13243 13244 final long curRealtime = SystemClock.elapsedRealtime(); 13245 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13246 final long curUptime = SystemClock.uptimeMillis(); 13247 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13248 13249 for (int i=list.size()-1; i>=0; i--) { 13250 ProcessRecord r = list.get(i).first; 13251 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13252 char schedGroup; 13253 switch (r.setSchedGroup) { 13254 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13255 schedGroup = 'B'; 13256 break; 13257 case Process.THREAD_GROUP_DEFAULT: 13258 schedGroup = 'F'; 13259 break; 13260 default: 13261 schedGroup = '?'; 13262 break; 13263 } 13264 char foreground; 13265 if (r.foregroundActivities) { 13266 foreground = 'A'; 13267 } else if (r.foregroundServices) { 13268 foreground = 'S'; 13269 } else { 13270 foreground = ' '; 13271 } 13272 String procState = ProcessList.makeProcStateString(r.curProcState); 13273 pw.print(prefix); 13274 pw.print(r.persistent ? persistentLabel : normalLabel); 13275 pw.print(" #"); 13276 int num = (origList.size()-1)-list.get(i).second; 13277 if (num < 10) pw.print(' '); 13278 pw.print(num); 13279 pw.print(": "); 13280 pw.print(oomAdj); 13281 pw.print(' '); 13282 pw.print(schedGroup); 13283 pw.print('/'); 13284 pw.print(foreground); 13285 pw.print('/'); 13286 pw.print(procState); 13287 pw.print(" trm:"); 13288 if (r.trimMemoryLevel < 10) pw.print(' '); 13289 pw.print(r.trimMemoryLevel); 13290 pw.print(' '); 13291 pw.print(r.toShortString()); 13292 pw.print(" ("); 13293 pw.print(r.adjType); 13294 pw.println(')'); 13295 if (r.adjSource != null || r.adjTarget != null) { 13296 pw.print(prefix); 13297 pw.print(" "); 13298 if (r.adjTarget instanceof ComponentName) { 13299 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13300 } else if (r.adjTarget != null) { 13301 pw.print(r.adjTarget.toString()); 13302 } else { 13303 pw.print("{null}"); 13304 } 13305 pw.print("<="); 13306 if (r.adjSource instanceof ProcessRecord) { 13307 pw.print("Proc{"); 13308 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13309 pw.println("}"); 13310 } else if (r.adjSource != null) { 13311 pw.println(r.adjSource.toString()); 13312 } else { 13313 pw.println("{null}"); 13314 } 13315 } 13316 if (inclDetails) { 13317 pw.print(prefix); 13318 pw.print(" "); 13319 pw.print("oom: max="); pw.print(r.maxAdj); 13320 pw.print(" curRaw="); pw.print(r.curRawAdj); 13321 pw.print(" setRaw="); pw.print(r.setRawAdj); 13322 pw.print(" cur="); pw.print(r.curAdj); 13323 pw.print(" set="); pw.println(r.setAdj); 13324 pw.print(prefix); 13325 pw.print(" "); 13326 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13327 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13328 pw.print(" lastPss="); pw.print(r.lastPss); 13329 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13330 pw.print(prefix); 13331 pw.print(" "); 13332 pw.print("cached="); pw.print(r.cached); 13333 pw.print(" empty="); pw.print(r.empty); 13334 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13335 13336 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13337 if (r.lastWakeTime != 0) { 13338 long wtime; 13339 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13340 synchronized (stats) { 13341 wtime = stats.getProcessWakeTime(r.info.uid, 13342 r.pid, curRealtime); 13343 } 13344 long timeUsed = wtime - r.lastWakeTime; 13345 pw.print(prefix); 13346 pw.print(" "); 13347 pw.print("keep awake over "); 13348 TimeUtils.formatDuration(realtimeSince, pw); 13349 pw.print(" used "); 13350 TimeUtils.formatDuration(timeUsed, pw); 13351 pw.print(" ("); 13352 pw.print((timeUsed*100)/realtimeSince); 13353 pw.println("%)"); 13354 } 13355 if (r.lastCpuTime != 0) { 13356 long timeUsed = r.curCpuTime - r.lastCpuTime; 13357 pw.print(prefix); 13358 pw.print(" "); 13359 pw.print("run cpu over "); 13360 TimeUtils.formatDuration(uptimeSince, pw); 13361 pw.print(" used "); 13362 TimeUtils.formatDuration(timeUsed, pw); 13363 pw.print(" ("); 13364 pw.print((timeUsed*100)/uptimeSince); 13365 pw.println("%)"); 13366 } 13367 } 13368 } 13369 } 13370 return true; 13371 } 13372 13373 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13374 ArrayList<ProcessRecord> procs; 13375 synchronized (this) { 13376 if (args != null && args.length > start 13377 && args[start].charAt(0) != '-') { 13378 procs = new ArrayList<ProcessRecord>(); 13379 int pid = -1; 13380 try { 13381 pid = Integer.parseInt(args[start]); 13382 } catch (NumberFormatException e) { 13383 } 13384 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13385 ProcessRecord proc = mLruProcesses.get(i); 13386 if (proc.pid == pid) { 13387 procs.add(proc); 13388 } else if (proc.processName.equals(args[start])) { 13389 procs.add(proc); 13390 } 13391 } 13392 if (procs.size() <= 0) { 13393 return null; 13394 } 13395 } else { 13396 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13397 } 13398 } 13399 return procs; 13400 } 13401 13402 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13403 PrintWriter pw, String[] args) { 13404 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13405 if (procs == null) { 13406 pw.println("No process found for: " + args[0]); 13407 return; 13408 } 13409 13410 long uptime = SystemClock.uptimeMillis(); 13411 long realtime = SystemClock.elapsedRealtime(); 13412 pw.println("Applications Graphics Acceleration Info:"); 13413 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13414 13415 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13416 ProcessRecord r = procs.get(i); 13417 if (r.thread != null) { 13418 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13419 pw.flush(); 13420 try { 13421 TransferPipe tp = new TransferPipe(); 13422 try { 13423 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13424 tp.go(fd); 13425 } finally { 13426 tp.kill(); 13427 } 13428 } catch (IOException e) { 13429 pw.println("Failure while dumping the app: " + r); 13430 pw.flush(); 13431 } catch (RemoteException e) { 13432 pw.println("Got a RemoteException while dumping the app " + r); 13433 pw.flush(); 13434 } 13435 } 13436 } 13437 } 13438 13439 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13440 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13441 if (procs == null) { 13442 pw.println("No process found for: " + args[0]); 13443 return; 13444 } 13445 13446 pw.println("Applications Database Info:"); 13447 13448 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13449 ProcessRecord r = procs.get(i); 13450 if (r.thread != null) { 13451 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13452 pw.flush(); 13453 try { 13454 TransferPipe tp = new TransferPipe(); 13455 try { 13456 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13457 tp.go(fd); 13458 } finally { 13459 tp.kill(); 13460 } 13461 } catch (IOException e) { 13462 pw.println("Failure while dumping the app: " + r); 13463 pw.flush(); 13464 } catch (RemoteException e) { 13465 pw.println("Got a RemoteException while dumping the app " + r); 13466 pw.flush(); 13467 } 13468 } 13469 } 13470 } 13471 13472 final static class MemItem { 13473 final boolean isProc; 13474 final String label; 13475 final String shortLabel; 13476 final long pss; 13477 final int id; 13478 final boolean hasActivities; 13479 ArrayList<MemItem> subitems; 13480 13481 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13482 boolean _hasActivities) { 13483 isProc = true; 13484 label = _label; 13485 shortLabel = _shortLabel; 13486 pss = _pss; 13487 id = _id; 13488 hasActivities = _hasActivities; 13489 } 13490 13491 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13492 isProc = false; 13493 label = _label; 13494 shortLabel = _shortLabel; 13495 pss = _pss; 13496 id = _id; 13497 hasActivities = false; 13498 } 13499 } 13500 13501 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13502 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13503 if (sort && !isCompact) { 13504 Collections.sort(items, new Comparator<MemItem>() { 13505 @Override 13506 public int compare(MemItem lhs, MemItem rhs) { 13507 if (lhs.pss < rhs.pss) { 13508 return 1; 13509 } else if (lhs.pss > rhs.pss) { 13510 return -1; 13511 } 13512 return 0; 13513 } 13514 }); 13515 } 13516 13517 for (int i=0; i<items.size(); i++) { 13518 MemItem mi = items.get(i); 13519 if (!isCompact) { 13520 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13521 } else if (mi.isProc) { 13522 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13523 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13524 pw.println(mi.hasActivities ? ",a" : ",e"); 13525 } else { 13526 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13527 pw.println(mi.pss); 13528 } 13529 if (mi.subitems != null) { 13530 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13531 true, isCompact); 13532 } 13533 } 13534 } 13535 13536 // These are in KB. 13537 static final long[] DUMP_MEM_BUCKETS = new long[] { 13538 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13539 120*1024, 160*1024, 200*1024, 13540 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13541 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13542 }; 13543 13544 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13545 boolean stackLike) { 13546 int start = label.lastIndexOf('.'); 13547 if (start >= 0) start++; 13548 else start = 0; 13549 int end = label.length(); 13550 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13551 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13552 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13553 out.append(bucket); 13554 out.append(stackLike ? "MB." : "MB "); 13555 out.append(label, start, end); 13556 return; 13557 } 13558 } 13559 out.append(memKB/1024); 13560 out.append(stackLike ? "MB." : "MB "); 13561 out.append(label, start, end); 13562 } 13563 13564 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13565 ProcessList.NATIVE_ADJ, 13566 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13567 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13568 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13569 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13570 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13571 }; 13572 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13573 "Native", 13574 "System", "Persistent", "Foreground", 13575 "Visible", "Perceptible", 13576 "Heavy Weight", "Backup", 13577 "A Services", "Home", 13578 "Previous", "B Services", "Cached" 13579 }; 13580 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13581 "native", 13582 "sys", "pers", "fore", 13583 "vis", "percept", 13584 "heavy", "backup", 13585 "servicea", "home", 13586 "prev", "serviceb", "cached" 13587 }; 13588 13589 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13590 long realtime, boolean isCheckinRequest, boolean isCompact) { 13591 if (isCheckinRequest || isCompact) { 13592 // short checkin version 13593 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13594 } else { 13595 pw.println("Applications Memory Usage (kB):"); 13596 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13597 } 13598 } 13599 13600 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13601 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13602 boolean dumpDetails = false; 13603 boolean dumpFullDetails = false; 13604 boolean dumpDalvik = false; 13605 boolean oomOnly = false; 13606 boolean isCompact = false; 13607 boolean localOnly = false; 13608 13609 int opti = 0; 13610 while (opti < args.length) { 13611 String opt = args[opti]; 13612 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13613 break; 13614 } 13615 opti++; 13616 if ("-a".equals(opt)) { 13617 dumpDetails = true; 13618 dumpFullDetails = true; 13619 dumpDalvik = true; 13620 } else if ("-d".equals(opt)) { 13621 dumpDalvik = true; 13622 } else if ("-c".equals(opt)) { 13623 isCompact = true; 13624 } else if ("--oom".equals(opt)) { 13625 oomOnly = true; 13626 } else if ("--local".equals(opt)) { 13627 localOnly = true; 13628 } else if ("-h".equals(opt)) { 13629 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13630 pw.println(" -a: include all available information for each process."); 13631 pw.println(" -d: include dalvik details when dumping process details."); 13632 pw.println(" -c: dump in a compact machine-parseable representation."); 13633 pw.println(" --oom: only show processes organized by oom adj."); 13634 pw.println(" --local: only collect details locally, don't call process."); 13635 pw.println("If [process] is specified it can be the name or "); 13636 pw.println("pid of a specific process to dump."); 13637 return; 13638 } else { 13639 pw.println("Unknown argument: " + opt + "; use -h for help"); 13640 } 13641 } 13642 13643 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13644 long uptime = SystemClock.uptimeMillis(); 13645 long realtime = SystemClock.elapsedRealtime(); 13646 final long[] tmpLong = new long[1]; 13647 13648 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13649 if (procs == null) { 13650 // No Java processes. Maybe they want to print a native process. 13651 if (args != null && args.length > opti 13652 && args[opti].charAt(0) != '-') { 13653 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13654 = new ArrayList<ProcessCpuTracker.Stats>(); 13655 updateCpuStatsNow(); 13656 int findPid = -1; 13657 try { 13658 findPid = Integer.parseInt(args[opti]); 13659 } catch (NumberFormatException e) { 13660 } 13661 synchronized (mProcessCpuThread) { 13662 final int N = mProcessCpuTracker.countStats(); 13663 for (int i=0; i<N; i++) { 13664 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13665 if (st.pid == findPid || (st.baseName != null 13666 && st.baseName.equals(args[opti]))) { 13667 nativeProcs.add(st); 13668 } 13669 } 13670 } 13671 if (nativeProcs.size() > 0) { 13672 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13673 isCompact); 13674 Debug.MemoryInfo mi = null; 13675 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13676 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13677 final int pid = r.pid; 13678 if (!isCheckinRequest && dumpDetails) { 13679 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13680 } 13681 if (mi == null) { 13682 mi = new Debug.MemoryInfo(); 13683 } 13684 if (dumpDetails || (!brief && !oomOnly)) { 13685 Debug.getMemoryInfo(pid, mi); 13686 } else { 13687 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13688 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13689 } 13690 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13691 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13692 if (isCheckinRequest) { 13693 pw.println(); 13694 } 13695 } 13696 return; 13697 } 13698 } 13699 pw.println("No process found for: " + args[opti]); 13700 return; 13701 } 13702 13703 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13704 dumpDetails = true; 13705 } 13706 13707 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13708 13709 String[] innerArgs = new String[args.length-opti]; 13710 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13711 13712 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13713 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13714 long nativePss=0, dalvikPss=0, otherPss=0; 13715 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13716 13717 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13718 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13719 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13720 13721 long totalPss = 0; 13722 long cachedPss = 0; 13723 13724 Debug.MemoryInfo mi = null; 13725 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13726 final ProcessRecord r = procs.get(i); 13727 final IApplicationThread thread; 13728 final int pid; 13729 final int oomAdj; 13730 final boolean hasActivities; 13731 synchronized (this) { 13732 thread = r.thread; 13733 pid = r.pid; 13734 oomAdj = r.getSetAdjWithServices(); 13735 hasActivities = r.activities.size() > 0; 13736 } 13737 if (thread != null) { 13738 if (!isCheckinRequest && dumpDetails) { 13739 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13740 } 13741 if (mi == null) { 13742 mi = new Debug.MemoryInfo(); 13743 } 13744 if (dumpDetails || (!brief && !oomOnly)) { 13745 Debug.getMemoryInfo(pid, mi); 13746 } else { 13747 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13748 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13749 } 13750 if (dumpDetails) { 13751 if (localOnly) { 13752 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13753 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13754 if (isCheckinRequest) { 13755 pw.println(); 13756 } 13757 } else { 13758 try { 13759 pw.flush(); 13760 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13761 dumpDalvik, innerArgs); 13762 } catch (RemoteException e) { 13763 if (!isCheckinRequest) { 13764 pw.println("Got RemoteException!"); 13765 pw.flush(); 13766 } 13767 } 13768 } 13769 } 13770 13771 final long myTotalPss = mi.getTotalPss(); 13772 final long myTotalUss = mi.getTotalUss(); 13773 13774 synchronized (this) { 13775 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13776 // Record this for posterity if the process has been stable. 13777 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13778 } 13779 } 13780 13781 if (!isCheckinRequest && mi != null) { 13782 totalPss += myTotalPss; 13783 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13784 (hasActivities ? " / activities)" : ")"), 13785 r.processName, myTotalPss, pid, hasActivities); 13786 procMems.add(pssItem); 13787 procMemsMap.put(pid, pssItem); 13788 13789 nativePss += mi.nativePss; 13790 dalvikPss += mi.dalvikPss; 13791 otherPss += mi.otherPss; 13792 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13793 long mem = mi.getOtherPss(j); 13794 miscPss[j] += mem; 13795 otherPss -= mem; 13796 } 13797 13798 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13799 cachedPss += myTotalPss; 13800 } 13801 13802 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13803 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13804 || oomIndex == (oomPss.length-1)) { 13805 oomPss[oomIndex] += myTotalPss; 13806 if (oomProcs[oomIndex] == null) { 13807 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13808 } 13809 oomProcs[oomIndex].add(pssItem); 13810 break; 13811 } 13812 } 13813 } 13814 } 13815 } 13816 13817 long nativeProcTotalPss = 0; 13818 13819 if (!isCheckinRequest && procs.size() > 1) { 13820 // If we are showing aggregations, also look for native processes to 13821 // include so that our aggregations are more accurate. 13822 updateCpuStatsNow(); 13823 synchronized (mProcessCpuThread) { 13824 final int N = mProcessCpuTracker.countStats(); 13825 for (int i=0; i<N; i++) { 13826 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13827 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13828 if (mi == null) { 13829 mi = new Debug.MemoryInfo(); 13830 } 13831 if (!brief && !oomOnly) { 13832 Debug.getMemoryInfo(st.pid, mi); 13833 } else { 13834 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13835 mi.nativePrivateDirty = (int)tmpLong[0]; 13836 } 13837 13838 final long myTotalPss = mi.getTotalPss(); 13839 totalPss += myTotalPss; 13840 nativeProcTotalPss += myTotalPss; 13841 13842 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13843 st.name, myTotalPss, st.pid, false); 13844 procMems.add(pssItem); 13845 13846 nativePss += mi.nativePss; 13847 dalvikPss += mi.dalvikPss; 13848 otherPss += mi.otherPss; 13849 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13850 long mem = mi.getOtherPss(j); 13851 miscPss[j] += mem; 13852 otherPss -= mem; 13853 } 13854 oomPss[0] += myTotalPss; 13855 if (oomProcs[0] == null) { 13856 oomProcs[0] = new ArrayList<MemItem>(); 13857 } 13858 oomProcs[0].add(pssItem); 13859 } 13860 } 13861 } 13862 13863 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13864 13865 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13866 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13867 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13868 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13869 String label = Debug.MemoryInfo.getOtherLabel(j); 13870 catMems.add(new MemItem(label, label, miscPss[j], j)); 13871 } 13872 13873 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13874 for (int j=0; j<oomPss.length; j++) { 13875 if (oomPss[j] != 0) { 13876 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13877 : DUMP_MEM_OOM_LABEL[j]; 13878 MemItem item = new MemItem(label, label, oomPss[j], 13879 DUMP_MEM_OOM_ADJ[j]); 13880 item.subitems = oomProcs[j]; 13881 oomMems.add(item); 13882 } 13883 } 13884 13885 if (!brief && !oomOnly && !isCompact) { 13886 pw.println(); 13887 pw.println("Total PSS by process:"); 13888 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13889 pw.println(); 13890 } 13891 if (!isCompact) { 13892 pw.println("Total PSS by OOM adjustment:"); 13893 } 13894 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13895 if (!brief && !oomOnly) { 13896 PrintWriter out = categoryPw != null ? categoryPw : pw; 13897 if (!isCompact) { 13898 out.println(); 13899 out.println("Total PSS by category:"); 13900 } 13901 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13902 } 13903 if (!isCompact) { 13904 pw.println(); 13905 } 13906 MemInfoReader memInfo = new MemInfoReader(); 13907 memInfo.readMemInfo(); 13908 if (nativeProcTotalPss > 0) { 13909 synchronized (this) { 13910 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13911 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13912 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13913 nativeProcTotalPss); 13914 } 13915 } 13916 if (!brief) { 13917 if (!isCompact) { 13918 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13919 pw.print(" kB (status "); 13920 switch (mLastMemoryLevel) { 13921 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13922 pw.println("normal)"); 13923 break; 13924 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13925 pw.println("moderate)"); 13926 break; 13927 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13928 pw.println("low)"); 13929 break; 13930 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13931 pw.println("critical)"); 13932 break; 13933 default: 13934 pw.print(mLastMemoryLevel); 13935 pw.println(")"); 13936 break; 13937 } 13938 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13939 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13940 pw.print(cachedPss); pw.print(" cached pss + "); 13941 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13942 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13943 } else { 13944 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13945 pw.print(cachedPss + memInfo.getCachedSizeKb() 13946 + memInfo.getFreeSizeKb()); pw.print(","); 13947 pw.println(totalPss - cachedPss); 13948 } 13949 } 13950 if (!isCompact) { 13951 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13952 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13953 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13954 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13955 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13956 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13957 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13958 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13959 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13960 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13961 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13962 } 13963 if (!brief) { 13964 if (memInfo.getZramTotalSizeKb() != 0) { 13965 if (!isCompact) { 13966 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13967 pw.print(" kB physical used for "); 13968 pw.print(memInfo.getSwapTotalSizeKb() 13969 - memInfo.getSwapFreeSizeKb()); 13970 pw.print(" kB in swap ("); 13971 pw.print(memInfo.getSwapTotalSizeKb()); 13972 pw.println(" kB total swap)"); 13973 } else { 13974 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13975 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13976 pw.println(memInfo.getSwapFreeSizeKb()); 13977 } 13978 } 13979 final int[] SINGLE_LONG_FORMAT = new int[] { 13980 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13981 }; 13982 long[] longOut = new long[1]; 13983 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13984 SINGLE_LONG_FORMAT, null, longOut, null); 13985 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13986 longOut[0] = 0; 13987 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13988 SINGLE_LONG_FORMAT, null, longOut, null); 13989 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13990 longOut[0] = 0; 13991 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13992 SINGLE_LONG_FORMAT, null, longOut, null); 13993 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13994 longOut[0] = 0; 13995 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13996 SINGLE_LONG_FORMAT, null, longOut, null); 13997 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13998 if (!isCompact) { 13999 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14000 pw.print(" KSM: "); pw.print(sharing); 14001 pw.print(" kB saved from shared "); 14002 pw.print(shared); pw.println(" kB"); 14003 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14004 pw.print(voltile); pw.println(" kB volatile"); 14005 } 14006 pw.print(" Tuning: "); 14007 pw.print(ActivityManager.staticGetMemoryClass()); 14008 pw.print(" (large "); 14009 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14010 pw.print("), oom "); 14011 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14012 pw.print(" kB"); 14013 pw.print(", restore limit "); 14014 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14015 pw.print(" kB"); 14016 if (ActivityManager.isLowRamDeviceStatic()) { 14017 pw.print(" (low-ram)"); 14018 } 14019 if (ActivityManager.isHighEndGfx()) { 14020 pw.print(" (high-end-gfx)"); 14021 } 14022 pw.println(); 14023 } else { 14024 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14025 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14026 pw.println(voltile); 14027 pw.print("tuning,"); 14028 pw.print(ActivityManager.staticGetMemoryClass()); 14029 pw.print(','); 14030 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14031 pw.print(','); 14032 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14033 if (ActivityManager.isLowRamDeviceStatic()) { 14034 pw.print(",low-ram"); 14035 } 14036 if (ActivityManager.isHighEndGfx()) { 14037 pw.print(",high-end-gfx"); 14038 } 14039 pw.println(); 14040 } 14041 } 14042 } 14043 } 14044 14045 /** 14046 * Searches array of arguments for the specified string 14047 * @param args array of argument strings 14048 * @param value value to search for 14049 * @return true if the value is contained in the array 14050 */ 14051 private static boolean scanArgs(String[] args, String value) { 14052 if (args != null) { 14053 for (String arg : args) { 14054 if (value.equals(arg)) { 14055 return true; 14056 } 14057 } 14058 } 14059 return false; 14060 } 14061 14062 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14063 ContentProviderRecord cpr, boolean always) { 14064 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14065 14066 if (!inLaunching || always) { 14067 synchronized (cpr) { 14068 cpr.launchingApp = null; 14069 cpr.notifyAll(); 14070 } 14071 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14072 String names[] = cpr.info.authority.split(";"); 14073 for (int j = 0; j < names.length; j++) { 14074 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14075 } 14076 } 14077 14078 for (int i=0; i<cpr.connections.size(); i++) { 14079 ContentProviderConnection conn = cpr.connections.get(i); 14080 if (conn.waiting) { 14081 // If this connection is waiting for the provider, then we don't 14082 // need to mess with its process unless we are always removing 14083 // or for some reason the provider is not currently launching. 14084 if (inLaunching && !always) { 14085 continue; 14086 } 14087 } 14088 ProcessRecord capp = conn.client; 14089 conn.dead = true; 14090 if (conn.stableCount > 0) { 14091 if (!capp.persistent && capp.thread != null 14092 && capp.pid != 0 14093 && capp.pid != MY_PID) { 14094 capp.kill("depends on provider " 14095 + cpr.name.flattenToShortString() 14096 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14097 } 14098 } else if (capp.thread != null && conn.provider.provider != null) { 14099 try { 14100 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14101 } catch (RemoteException e) { 14102 } 14103 // In the protocol here, we don't expect the client to correctly 14104 // clean up this connection, we'll just remove it. 14105 cpr.connections.remove(i); 14106 conn.client.conProviders.remove(conn); 14107 } 14108 } 14109 14110 if (inLaunching && always) { 14111 mLaunchingProviders.remove(cpr); 14112 } 14113 return inLaunching; 14114 } 14115 14116 /** 14117 * Main code for cleaning up a process when it has gone away. This is 14118 * called both as a result of the process dying, or directly when stopping 14119 * a process when running in single process mode. 14120 */ 14121 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14122 boolean restarting, boolean allowRestart, int index) { 14123 if (index >= 0) { 14124 removeLruProcessLocked(app); 14125 ProcessList.remove(app.pid); 14126 } 14127 14128 mProcessesToGc.remove(app); 14129 mPendingPssProcesses.remove(app); 14130 14131 // Dismiss any open dialogs. 14132 if (app.crashDialog != null && !app.forceCrashReport) { 14133 app.crashDialog.dismiss(); 14134 app.crashDialog = null; 14135 } 14136 if (app.anrDialog != null) { 14137 app.anrDialog.dismiss(); 14138 app.anrDialog = null; 14139 } 14140 if (app.waitDialog != null) { 14141 app.waitDialog.dismiss(); 14142 app.waitDialog = null; 14143 } 14144 14145 app.crashing = false; 14146 app.notResponding = false; 14147 14148 app.resetPackageList(mProcessStats); 14149 app.unlinkDeathRecipient(); 14150 app.makeInactive(mProcessStats); 14151 app.waitingToKill = null; 14152 app.forcingToForeground = null; 14153 updateProcessForegroundLocked(app, false, false); 14154 app.foregroundActivities = false; 14155 app.hasShownUi = false; 14156 app.treatLikeActivity = false; 14157 app.hasAboveClient = false; 14158 app.hasClientActivities = false; 14159 14160 mServices.killServicesLocked(app, allowRestart); 14161 14162 boolean restart = false; 14163 14164 // Remove published content providers. 14165 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14166 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14167 final boolean always = app.bad || !allowRestart; 14168 if (removeDyingProviderLocked(app, cpr, always) || always) { 14169 // We left the provider in the launching list, need to 14170 // restart it. 14171 restart = true; 14172 } 14173 14174 cpr.provider = null; 14175 cpr.proc = null; 14176 } 14177 app.pubProviders.clear(); 14178 14179 // Take care of any launching providers waiting for this process. 14180 if (checkAppInLaunchingProvidersLocked(app, false)) { 14181 restart = true; 14182 } 14183 14184 // Unregister from connected content providers. 14185 if (!app.conProviders.isEmpty()) { 14186 for (int i=0; i<app.conProviders.size(); i++) { 14187 ContentProviderConnection conn = app.conProviders.get(i); 14188 conn.provider.connections.remove(conn); 14189 } 14190 app.conProviders.clear(); 14191 } 14192 14193 // At this point there may be remaining entries in mLaunchingProviders 14194 // where we were the only one waiting, so they are no longer of use. 14195 // Look for these and clean up if found. 14196 // XXX Commented out for now. Trying to figure out a way to reproduce 14197 // the actual situation to identify what is actually going on. 14198 if (false) { 14199 for (int i=0; i<mLaunchingProviders.size(); i++) { 14200 ContentProviderRecord cpr = (ContentProviderRecord) 14201 mLaunchingProviders.get(i); 14202 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14203 synchronized (cpr) { 14204 cpr.launchingApp = null; 14205 cpr.notifyAll(); 14206 } 14207 } 14208 } 14209 } 14210 14211 skipCurrentReceiverLocked(app); 14212 14213 // Unregister any receivers. 14214 for (int i=app.receivers.size()-1; i>=0; i--) { 14215 removeReceiverLocked(app.receivers.valueAt(i)); 14216 } 14217 app.receivers.clear(); 14218 14219 // If the app is undergoing backup, tell the backup manager about it 14220 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14221 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14222 + mBackupTarget.appInfo + " died during backup"); 14223 try { 14224 IBackupManager bm = IBackupManager.Stub.asInterface( 14225 ServiceManager.getService(Context.BACKUP_SERVICE)); 14226 bm.agentDisconnected(app.info.packageName); 14227 } catch (RemoteException e) { 14228 // can't happen; backup manager is local 14229 } 14230 } 14231 14232 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14233 ProcessChangeItem item = mPendingProcessChanges.get(i); 14234 if (item.pid == app.pid) { 14235 mPendingProcessChanges.remove(i); 14236 mAvailProcessChanges.add(item); 14237 } 14238 } 14239 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14240 14241 // If the caller is restarting this app, then leave it in its 14242 // current lists and let the caller take care of it. 14243 if (restarting) { 14244 return; 14245 } 14246 14247 if (!app.persistent || app.isolated) { 14248 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14249 "Removing non-persistent process during cleanup: " + app); 14250 mProcessNames.remove(app.processName, app.uid); 14251 mIsolatedProcesses.remove(app.uid); 14252 if (mHeavyWeightProcess == app) { 14253 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14254 mHeavyWeightProcess.userId, 0)); 14255 mHeavyWeightProcess = null; 14256 } 14257 } else if (!app.removed) { 14258 // This app is persistent, so we need to keep its record around. 14259 // If it is not already on the pending app list, add it there 14260 // and start a new process for it. 14261 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14262 mPersistentStartingProcesses.add(app); 14263 restart = true; 14264 } 14265 } 14266 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14267 "Clean-up removing on hold: " + app); 14268 mProcessesOnHold.remove(app); 14269 14270 if (app == mHomeProcess) { 14271 mHomeProcess = null; 14272 } 14273 if (app == mPreviousProcess) { 14274 mPreviousProcess = null; 14275 } 14276 14277 if (restart && !app.isolated) { 14278 // We have components that still need to be running in the 14279 // process, so re-launch it. 14280 mProcessNames.put(app.processName, app.uid, app); 14281 startProcessLocked(app, "restart", app.processName); 14282 } else if (app.pid > 0 && app.pid != MY_PID) { 14283 // Goodbye! 14284 boolean removed; 14285 synchronized (mPidsSelfLocked) { 14286 mPidsSelfLocked.remove(app.pid); 14287 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14288 } 14289 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14290 if (app.isolated) { 14291 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14292 } 14293 app.setPid(0); 14294 } 14295 } 14296 14297 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14298 // Look through the content providers we are waiting to have launched, 14299 // and if any run in this process then either schedule a restart of 14300 // the process or kill the client waiting for it if this process has 14301 // gone bad. 14302 int NL = mLaunchingProviders.size(); 14303 boolean restart = false; 14304 for (int i=0; i<NL; i++) { 14305 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14306 if (cpr.launchingApp == app) { 14307 if (!alwaysBad && !app.bad) { 14308 restart = true; 14309 } else { 14310 removeDyingProviderLocked(app, cpr, true); 14311 // cpr should have been removed from mLaunchingProviders 14312 NL = mLaunchingProviders.size(); 14313 i--; 14314 } 14315 } 14316 } 14317 return restart; 14318 } 14319 14320 // ========================================================= 14321 // SERVICES 14322 // ========================================================= 14323 14324 @Override 14325 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14326 int flags) { 14327 enforceNotIsolatedCaller("getServices"); 14328 synchronized (this) { 14329 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14330 } 14331 } 14332 14333 @Override 14334 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14335 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14336 synchronized (this) { 14337 return mServices.getRunningServiceControlPanelLocked(name); 14338 } 14339 } 14340 14341 @Override 14342 public ComponentName startService(IApplicationThread caller, Intent service, 14343 String resolvedType, int userId) { 14344 enforceNotIsolatedCaller("startService"); 14345 // Refuse possible leaked file descriptors 14346 if (service != null && service.hasFileDescriptors() == true) { 14347 throw new IllegalArgumentException("File descriptors passed in Intent"); 14348 } 14349 14350 if (DEBUG_SERVICE) 14351 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14352 synchronized(this) { 14353 final int callingPid = Binder.getCallingPid(); 14354 final int callingUid = Binder.getCallingUid(); 14355 final long origId = Binder.clearCallingIdentity(); 14356 ComponentName res = mServices.startServiceLocked(caller, service, 14357 resolvedType, callingPid, callingUid, userId); 14358 Binder.restoreCallingIdentity(origId); 14359 return res; 14360 } 14361 } 14362 14363 ComponentName startServiceInPackage(int uid, 14364 Intent service, String resolvedType, int userId) { 14365 synchronized(this) { 14366 if (DEBUG_SERVICE) 14367 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14368 final long origId = Binder.clearCallingIdentity(); 14369 ComponentName res = mServices.startServiceLocked(null, service, 14370 resolvedType, -1, uid, userId); 14371 Binder.restoreCallingIdentity(origId); 14372 return res; 14373 } 14374 } 14375 14376 @Override 14377 public int stopService(IApplicationThread caller, Intent service, 14378 String resolvedType, int userId) { 14379 enforceNotIsolatedCaller("stopService"); 14380 // Refuse possible leaked file descriptors 14381 if (service != null && service.hasFileDescriptors() == true) { 14382 throw new IllegalArgumentException("File descriptors passed in Intent"); 14383 } 14384 14385 synchronized(this) { 14386 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14387 } 14388 } 14389 14390 @Override 14391 public IBinder peekService(Intent service, String resolvedType) { 14392 enforceNotIsolatedCaller("peekService"); 14393 // Refuse possible leaked file descriptors 14394 if (service != null && service.hasFileDescriptors() == true) { 14395 throw new IllegalArgumentException("File descriptors passed in Intent"); 14396 } 14397 synchronized(this) { 14398 return mServices.peekServiceLocked(service, resolvedType); 14399 } 14400 } 14401 14402 @Override 14403 public boolean stopServiceToken(ComponentName className, IBinder token, 14404 int startId) { 14405 synchronized(this) { 14406 return mServices.stopServiceTokenLocked(className, token, startId); 14407 } 14408 } 14409 14410 @Override 14411 public void setServiceForeground(ComponentName className, IBinder token, 14412 int id, Notification notification, boolean removeNotification) { 14413 synchronized(this) { 14414 mServices.setServiceForegroundLocked(className, token, id, notification, 14415 removeNotification); 14416 } 14417 } 14418 14419 @Override 14420 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14421 boolean requireFull, String name, String callerPackage) { 14422 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14423 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14424 } 14425 14426 int unsafeConvertIncomingUser(int userId) { 14427 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14428 ? mCurrentUserId : userId; 14429 } 14430 14431 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14432 int allowMode, String name, String callerPackage) { 14433 final int callingUserId = UserHandle.getUserId(callingUid); 14434 if (callingUserId == userId) { 14435 return userId; 14436 } 14437 14438 // Note that we may be accessing mCurrentUserId outside of a lock... 14439 // shouldn't be a big deal, if this is being called outside 14440 // of a locked context there is intrinsically a race with 14441 // the value the caller will receive and someone else changing it. 14442 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14443 // we will switch to the calling user if access to the current user fails. 14444 int targetUserId = unsafeConvertIncomingUser(userId); 14445 14446 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14447 final boolean allow; 14448 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14449 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14450 // If the caller has this permission, they always pass go. And collect $200. 14451 allow = true; 14452 } else if (allowMode == ALLOW_FULL_ONLY) { 14453 // We require full access, sucks to be you. 14454 allow = false; 14455 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14456 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14457 // If the caller does not have either permission, they are always doomed. 14458 allow = false; 14459 } else if (allowMode == ALLOW_NON_FULL) { 14460 // We are blanket allowing non-full access, you lucky caller! 14461 allow = true; 14462 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14463 // We may or may not allow this depending on whether the two users are 14464 // in the same profile. 14465 synchronized (mUserProfileGroupIdsSelfLocked) { 14466 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14467 UserInfo.NO_PROFILE_GROUP_ID); 14468 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14469 UserInfo.NO_PROFILE_GROUP_ID); 14470 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14471 && callingProfile == targetProfile; 14472 } 14473 } else { 14474 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14475 } 14476 if (!allow) { 14477 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14478 // In this case, they would like to just execute as their 14479 // owner user instead of failing. 14480 targetUserId = callingUserId; 14481 } else { 14482 StringBuilder builder = new StringBuilder(128); 14483 builder.append("Permission Denial: "); 14484 builder.append(name); 14485 if (callerPackage != null) { 14486 builder.append(" from "); 14487 builder.append(callerPackage); 14488 } 14489 builder.append(" asks to run as user "); 14490 builder.append(userId); 14491 builder.append(" but is calling from user "); 14492 builder.append(UserHandle.getUserId(callingUid)); 14493 builder.append("; this requires "); 14494 builder.append(INTERACT_ACROSS_USERS_FULL); 14495 if (allowMode != ALLOW_FULL_ONLY) { 14496 builder.append(" or "); 14497 builder.append(INTERACT_ACROSS_USERS); 14498 } 14499 String msg = builder.toString(); 14500 Slog.w(TAG, msg); 14501 throw new SecurityException(msg); 14502 } 14503 } 14504 } 14505 if (!allowAll && targetUserId < 0) { 14506 throw new IllegalArgumentException( 14507 "Call does not support special user #" + targetUserId); 14508 } 14509 return targetUserId; 14510 } 14511 14512 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14513 String className, int flags) { 14514 boolean result = false; 14515 // For apps that don't have pre-defined UIDs, check for permission 14516 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14517 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14518 if (ActivityManager.checkUidPermission( 14519 INTERACT_ACROSS_USERS, 14520 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14521 ComponentName comp = new ComponentName(aInfo.packageName, className); 14522 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14523 + " requests FLAG_SINGLE_USER, but app does not hold " 14524 + INTERACT_ACROSS_USERS; 14525 Slog.w(TAG, msg); 14526 throw new SecurityException(msg); 14527 } 14528 // Permission passed 14529 result = true; 14530 } 14531 } else if ("system".equals(componentProcessName)) { 14532 result = true; 14533 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14534 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14535 // Phone app is allowed to export singleuser providers. 14536 result = true; 14537 } else { 14538 // App with pre-defined UID, check if it's a persistent app 14539 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14540 } 14541 if (DEBUG_MU) { 14542 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14543 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14544 } 14545 return result; 14546 } 14547 14548 /** 14549 * Checks to see if the caller is in the same app as the singleton 14550 * component, or the component is in a special app. It allows special apps 14551 * to export singleton components but prevents exporting singleton 14552 * components for regular apps. 14553 */ 14554 boolean isValidSingletonCall(int callingUid, int componentUid) { 14555 int componentAppId = UserHandle.getAppId(componentUid); 14556 return UserHandle.isSameApp(callingUid, componentUid) 14557 || componentAppId == Process.SYSTEM_UID 14558 || componentAppId == Process.PHONE_UID 14559 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14560 == PackageManager.PERMISSION_GRANTED; 14561 } 14562 14563 public int bindService(IApplicationThread caller, IBinder token, 14564 Intent service, String resolvedType, 14565 IServiceConnection connection, int flags, int userId) { 14566 enforceNotIsolatedCaller("bindService"); 14567 // Refuse possible leaked file descriptors 14568 if (service != null && service.hasFileDescriptors() == true) { 14569 throw new IllegalArgumentException("File descriptors passed in Intent"); 14570 } 14571 14572 synchronized(this) { 14573 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14574 connection, flags, userId); 14575 } 14576 } 14577 14578 public boolean unbindService(IServiceConnection connection) { 14579 synchronized (this) { 14580 return mServices.unbindServiceLocked(connection); 14581 } 14582 } 14583 14584 public void publishService(IBinder token, Intent intent, IBinder service) { 14585 // Refuse possible leaked file descriptors 14586 if (intent != null && intent.hasFileDescriptors() == true) { 14587 throw new IllegalArgumentException("File descriptors passed in Intent"); 14588 } 14589 14590 synchronized(this) { 14591 if (!(token instanceof ServiceRecord)) { 14592 throw new IllegalArgumentException("Invalid service token"); 14593 } 14594 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14595 } 14596 } 14597 14598 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14599 // Refuse possible leaked file descriptors 14600 if (intent != null && intent.hasFileDescriptors() == true) { 14601 throw new IllegalArgumentException("File descriptors passed in Intent"); 14602 } 14603 14604 synchronized(this) { 14605 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14606 } 14607 } 14608 14609 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14610 synchronized(this) { 14611 if (!(token instanceof ServiceRecord)) { 14612 throw new IllegalArgumentException("Invalid service token"); 14613 } 14614 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14615 } 14616 } 14617 14618 // ========================================================= 14619 // BACKUP AND RESTORE 14620 // ========================================================= 14621 14622 // Cause the target app to be launched if necessary and its backup agent 14623 // instantiated. The backup agent will invoke backupAgentCreated() on the 14624 // activity manager to announce its creation. 14625 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14626 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14627 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14628 14629 synchronized(this) { 14630 // !!! TODO: currently no check here that we're already bound 14631 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14632 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14633 synchronized (stats) { 14634 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14635 } 14636 14637 // Backup agent is now in use, its package can't be stopped. 14638 try { 14639 AppGlobals.getPackageManager().setPackageStoppedState( 14640 app.packageName, false, UserHandle.getUserId(app.uid)); 14641 } catch (RemoteException e) { 14642 } catch (IllegalArgumentException e) { 14643 Slog.w(TAG, "Failed trying to unstop package " 14644 + app.packageName + ": " + e); 14645 } 14646 14647 BackupRecord r = new BackupRecord(ss, app, backupMode); 14648 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14649 ? new ComponentName(app.packageName, app.backupAgentName) 14650 : new ComponentName("android", "FullBackupAgent"); 14651 // startProcessLocked() returns existing proc's record if it's already running 14652 ProcessRecord proc = startProcessLocked(app.processName, app, 14653 false, 0, "backup", hostingName, false, false, false); 14654 if (proc == null) { 14655 Slog.e(TAG, "Unable to start backup agent process " + r); 14656 return false; 14657 } 14658 14659 r.app = proc; 14660 mBackupTarget = r; 14661 mBackupAppName = app.packageName; 14662 14663 // Try not to kill the process during backup 14664 updateOomAdjLocked(proc); 14665 14666 // If the process is already attached, schedule the creation of the backup agent now. 14667 // If it is not yet live, this will be done when it attaches to the framework. 14668 if (proc.thread != null) { 14669 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14670 try { 14671 proc.thread.scheduleCreateBackupAgent(app, 14672 compatibilityInfoForPackageLocked(app), backupMode); 14673 } catch (RemoteException e) { 14674 // Will time out on the backup manager side 14675 } 14676 } else { 14677 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14678 } 14679 // Invariants: at this point, the target app process exists and the application 14680 // is either already running or in the process of coming up. mBackupTarget and 14681 // mBackupAppName describe the app, so that when it binds back to the AM we 14682 // know that it's scheduled for a backup-agent operation. 14683 } 14684 14685 return true; 14686 } 14687 14688 @Override 14689 public void clearPendingBackup() { 14690 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14691 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14692 14693 synchronized (this) { 14694 mBackupTarget = null; 14695 mBackupAppName = null; 14696 } 14697 } 14698 14699 // A backup agent has just come up 14700 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14701 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14702 + " = " + agent); 14703 14704 synchronized(this) { 14705 if (!agentPackageName.equals(mBackupAppName)) { 14706 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14707 return; 14708 } 14709 } 14710 14711 long oldIdent = Binder.clearCallingIdentity(); 14712 try { 14713 IBackupManager bm = IBackupManager.Stub.asInterface( 14714 ServiceManager.getService(Context.BACKUP_SERVICE)); 14715 bm.agentConnected(agentPackageName, agent); 14716 } catch (RemoteException e) { 14717 // can't happen; the backup manager service is local 14718 } catch (Exception e) { 14719 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14720 e.printStackTrace(); 14721 } finally { 14722 Binder.restoreCallingIdentity(oldIdent); 14723 } 14724 } 14725 14726 // done with this agent 14727 public void unbindBackupAgent(ApplicationInfo appInfo) { 14728 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14729 if (appInfo == null) { 14730 Slog.w(TAG, "unbind backup agent for null app"); 14731 return; 14732 } 14733 14734 synchronized(this) { 14735 try { 14736 if (mBackupAppName == null) { 14737 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14738 return; 14739 } 14740 14741 if (!mBackupAppName.equals(appInfo.packageName)) { 14742 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14743 return; 14744 } 14745 14746 // Not backing this app up any more; reset its OOM adjustment 14747 final ProcessRecord proc = mBackupTarget.app; 14748 updateOomAdjLocked(proc); 14749 14750 // If the app crashed during backup, 'thread' will be null here 14751 if (proc.thread != null) { 14752 try { 14753 proc.thread.scheduleDestroyBackupAgent(appInfo, 14754 compatibilityInfoForPackageLocked(appInfo)); 14755 } catch (Exception e) { 14756 Slog.e(TAG, "Exception when unbinding backup agent:"); 14757 e.printStackTrace(); 14758 } 14759 } 14760 } finally { 14761 mBackupTarget = null; 14762 mBackupAppName = null; 14763 } 14764 } 14765 } 14766 // ========================================================= 14767 // BROADCASTS 14768 // ========================================================= 14769 14770 private final List getStickiesLocked(String action, IntentFilter filter, 14771 List cur, int userId) { 14772 final ContentResolver resolver = mContext.getContentResolver(); 14773 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14774 if (stickies == null) { 14775 return cur; 14776 } 14777 final ArrayList<Intent> list = stickies.get(action); 14778 if (list == null) { 14779 return cur; 14780 } 14781 int N = list.size(); 14782 for (int i=0; i<N; i++) { 14783 Intent intent = list.get(i); 14784 if (filter.match(resolver, intent, true, TAG) >= 0) { 14785 if (cur == null) { 14786 cur = new ArrayList<Intent>(); 14787 } 14788 cur.add(intent); 14789 } 14790 } 14791 return cur; 14792 } 14793 14794 boolean isPendingBroadcastProcessLocked(int pid) { 14795 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14796 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14797 } 14798 14799 void skipPendingBroadcastLocked(int pid) { 14800 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14801 for (BroadcastQueue queue : mBroadcastQueues) { 14802 queue.skipPendingBroadcastLocked(pid); 14803 } 14804 } 14805 14806 // The app just attached; send any pending broadcasts that it should receive 14807 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14808 boolean didSomething = false; 14809 for (BroadcastQueue queue : mBroadcastQueues) { 14810 didSomething |= queue.sendPendingBroadcastsLocked(app); 14811 } 14812 return didSomething; 14813 } 14814 14815 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14816 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14817 enforceNotIsolatedCaller("registerReceiver"); 14818 int callingUid; 14819 int callingPid; 14820 synchronized(this) { 14821 ProcessRecord callerApp = null; 14822 if (caller != null) { 14823 callerApp = getRecordForAppLocked(caller); 14824 if (callerApp == null) { 14825 throw new SecurityException( 14826 "Unable to find app for caller " + caller 14827 + " (pid=" + Binder.getCallingPid() 14828 + ") when registering receiver " + receiver); 14829 } 14830 if (callerApp.info.uid != Process.SYSTEM_UID && 14831 !callerApp.pkgList.containsKey(callerPackage) && 14832 !"android".equals(callerPackage)) { 14833 throw new SecurityException("Given caller package " + callerPackage 14834 + " is not running in process " + callerApp); 14835 } 14836 callingUid = callerApp.info.uid; 14837 callingPid = callerApp.pid; 14838 } else { 14839 callerPackage = null; 14840 callingUid = Binder.getCallingUid(); 14841 callingPid = Binder.getCallingPid(); 14842 } 14843 14844 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14845 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14846 14847 List allSticky = null; 14848 14849 // Look for any matching sticky broadcasts... 14850 Iterator actions = filter.actionsIterator(); 14851 if (actions != null) { 14852 while (actions.hasNext()) { 14853 String action = (String)actions.next(); 14854 allSticky = getStickiesLocked(action, filter, allSticky, 14855 UserHandle.USER_ALL); 14856 allSticky = getStickiesLocked(action, filter, allSticky, 14857 UserHandle.getUserId(callingUid)); 14858 } 14859 } else { 14860 allSticky = getStickiesLocked(null, filter, allSticky, 14861 UserHandle.USER_ALL); 14862 allSticky = getStickiesLocked(null, filter, allSticky, 14863 UserHandle.getUserId(callingUid)); 14864 } 14865 14866 // The first sticky in the list is returned directly back to 14867 // the client. 14868 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14869 14870 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14871 + ": " + sticky); 14872 14873 if (receiver == null) { 14874 return sticky; 14875 } 14876 14877 ReceiverList rl 14878 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14879 if (rl == null) { 14880 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14881 userId, receiver); 14882 if (rl.app != null) { 14883 rl.app.receivers.add(rl); 14884 } else { 14885 try { 14886 receiver.asBinder().linkToDeath(rl, 0); 14887 } catch (RemoteException e) { 14888 return sticky; 14889 } 14890 rl.linkedToDeath = true; 14891 } 14892 mRegisteredReceivers.put(receiver.asBinder(), rl); 14893 } else if (rl.uid != callingUid) { 14894 throw new IllegalArgumentException( 14895 "Receiver requested to register for uid " + callingUid 14896 + " was previously registered for uid " + rl.uid); 14897 } else if (rl.pid != callingPid) { 14898 throw new IllegalArgumentException( 14899 "Receiver requested to register for pid " + callingPid 14900 + " was previously registered for pid " + rl.pid); 14901 } else if (rl.userId != userId) { 14902 throw new IllegalArgumentException( 14903 "Receiver requested to register for user " + userId 14904 + " was previously registered for user " + rl.userId); 14905 } 14906 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14907 permission, callingUid, userId); 14908 rl.add(bf); 14909 if (!bf.debugCheck()) { 14910 Slog.w(TAG, "==> For Dynamic broadast"); 14911 } 14912 mReceiverResolver.addFilter(bf); 14913 14914 // Enqueue broadcasts for all existing stickies that match 14915 // this filter. 14916 if (allSticky != null) { 14917 ArrayList receivers = new ArrayList(); 14918 receivers.add(bf); 14919 14920 int N = allSticky.size(); 14921 for (int i=0; i<N; i++) { 14922 Intent intent = (Intent)allSticky.get(i); 14923 BroadcastQueue queue = broadcastQueueForIntent(intent); 14924 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14925 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14926 null, null, false, true, true, -1); 14927 queue.enqueueParallelBroadcastLocked(r); 14928 queue.scheduleBroadcastsLocked(); 14929 } 14930 } 14931 14932 return sticky; 14933 } 14934 } 14935 14936 public void unregisterReceiver(IIntentReceiver receiver) { 14937 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14938 14939 final long origId = Binder.clearCallingIdentity(); 14940 try { 14941 boolean doTrim = false; 14942 14943 synchronized(this) { 14944 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14945 if (rl != null) { 14946 if (rl.curBroadcast != null) { 14947 BroadcastRecord r = rl.curBroadcast; 14948 final boolean doNext = finishReceiverLocked( 14949 receiver.asBinder(), r.resultCode, r.resultData, 14950 r.resultExtras, r.resultAbort); 14951 if (doNext) { 14952 doTrim = true; 14953 r.queue.processNextBroadcast(false); 14954 } 14955 } 14956 14957 if (rl.app != null) { 14958 rl.app.receivers.remove(rl); 14959 } 14960 removeReceiverLocked(rl); 14961 if (rl.linkedToDeath) { 14962 rl.linkedToDeath = false; 14963 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14964 } 14965 } 14966 } 14967 14968 // If we actually concluded any broadcasts, we might now be able 14969 // to trim the recipients' apps from our working set 14970 if (doTrim) { 14971 trimApplications(); 14972 return; 14973 } 14974 14975 } finally { 14976 Binder.restoreCallingIdentity(origId); 14977 } 14978 } 14979 14980 void removeReceiverLocked(ReceiverList rl) { 14981 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14982 int N = rl.size(); 14983 for (int i=0; i<N; i++) { 14984 mReceiverResolver.removeFilter(rl.get(i)); 14985 } 14986 } 14987 14988 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14989 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14990 ProcessRecord r = mLruProcesses.get(i); 14991 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14992 try { 14993 r.thread.dispatchPackageBroadcast(cmd, packages); 14994 } catch (RemoteException ex) { 14995 } 14996 } 14997 } 14998 } 14999 15000 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15001 int[] users) { 15002 List<ResolveInfo> receivers = null; 15003 try { 15004 HashSet<ComponentName> singleUserReceivers = null; 15005 boolean scannedFirstReceivers = false; 15006 for (int user : users) { 15007 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15008 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15009 if (user != 0 && newReceivers != null) { 15010 // If this is not the primary user, we need to check for 15011 // any receivers that should be filtered out. 15012 for (int i=0; i<newReceivers.size(); i++) { 15013 ResolveInfo ri = newReceivers.get(i); 15014 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15015 newReceivers.remove(i); 15016 i--; 15017 } 15018 } 15019 } 15020 if (newReceivers != null && newReceivers.size() == 0) { 15021 newReceivers = null; 15022 } 15023 if (receivers == null) { 15024 receivers = newReceivers; 15025 } else if (newReceivers != null) { 15026 // We need to concatenate the additional receivers 15027 // found with what we have do far. This would be easy, 15028 // but we also need to de-dup any receivers that are 15029 // singleUser. 15030 if (!scannedFirstReceivers) { 15031 // Collect any single user receivers we had already retrieved. 15032 scannedFirstReceivers = true; 15033 for (int i=0; i<receivers.size(); i++) { 15034 ResolveInfo ri = receivers.get(i); 15035 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15036 ComponentName cn = new ComponentName( 15037 ri.activityInfo.packageName, ri.activityInfo.name); 15038 if (singleUserReceivers == null) { 15039 singleUserReceivers = new HashSet<ComponentName>(); 15040 } 15041 singleUserReceivers.add(cn); 15042 } 15043 } 15044 } 15045 // Add the new results to the existing results, tracking 15046 // and de-dupping single user receivers. 15047 for (int i=0; i<newReceivers.size(); i++) { 15048 ResolveInfo ri = newReceivers.get(i); 15049 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15050 ComponentName cn = new ComponentName( 15051 ri.activityInfo.packageName, ri.activityInfo.name); 15052 if (singleUserReceivers == null) { 15053 singleUserReceivers = new HashSet<ComponentName>(); 15054 } 15055 if (!singleUserReceivers.contains(cn)) { 15056 singleUserReceivers.add(cn); 15057 receivers.add(ri); 15058 } 15059 } else { 15060 receivers.add(ri); 15061 } 15062 } 15063 } 15064 } 15065 } catch (RemoteException ex) { 15066 // pm is in same process, this will never happen. 15067 } 15068 return receivers; 15069 } 15070 15071 private final int broadcastIntentLocked(ProcessRecord callerApp, 15072 String callerPackage, Intent intent, String resolvedType, 15073 IIntentReceiver resultTo, int resultCode, String resultData, 15074 Bundle map, String requiredPermission, int appOp, 15075 boolean ordered, boolean sticky, int callingPid, int callingUid, 15076 int userId) { 15077 intent = new Intent(intent); 15078 15079 // By default broadcasts do not go to stopped apps. 15080 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15081 15082 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15083 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15084 + " ordered=" + ordered + " userid=" + userId); 15085 if ((resultTo != null) && !ordered) { 15086 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15087 } 15088 15089 userId = handleIncomingUser(callingPid, callingUid, userId, 15090 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15091 15092 // Make sure that the user who is receiving this broadcast is started. 15093 // If not, we will just skip it. 15094 15095 15096 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15097 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15098 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15099 Slog.w(TAG, "Skipping broadcast of " + intent 15100 + ": user " + userId + " is stopped"); 15101 return ActivityManager.BROADCAST_SUCCESS; 15102 } 15103 } 15104 15105 /* 15106 * Prevent non-system code (defined here to be non-persistent 15107 * processes) from sending protected broadcasts. 15108 */ 15109 int callingAppId = UserHandle.getAppId(callingUid); 15110 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15111 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15112 || callingAppId == Process.NFC_UID || callingUid == 0) { 15113 // Always okay. 15114 } else if (callerApp == null || !callerApp.persistent) { 15115 try { 15116 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15117 intent.getAction())) { 15118 String msg = "Permission Denial: not allowed to send broadcast " 15119 + intent.getAction() + " from pid=" 15120 + callingPid + ", uid=" + callingUid; 15121 Slog.w(TAG, msg); 15122 throw new SecurityException(msg); 15123 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15124 // Special case for compatibility: we don't want apps to send this, 15125 // but historically it has not been protected and apps may be using it 15126 // to poke their own app widget. So, instead of making it protected, 15127 // just limit it to the caller. 15128 if (callerApp == null) { 15129 String msg = "Permission Denial: not allowed to send broadcast " 15130 + intent.getAction() + " from unknown caller."; 15131 Slog.w(TAG, msg); 15132 throw new SecurityException(msg); 15133 } else if (intent.getComponent() != null) { 15134 // They are good enough to send to an explicit component... verify 15135 // it is being sent to the calling app. 15136 if (!intent.getComponent().getPackageName().equals( 15137 callerApp.info.packageName)) { 15138 String msg = "Permission Denial: not allowed to send broadcast " 15139 + intent.getAction() + " to " 15140 + intent.getComponent().getPackageName() + " from " 15141 + callerApp.info.packageName; 15142 Slog.w(TAG, msg); 15143 throw new SecurityException(msg); 15144 } 15145 } else { 15146 // Limit broadcast to their own package. 15147 intent.setPackage(callerApp.info.packageName); 15148 } 15149 } 15150 } catch (RemoteException e) { 15151 Slog.w(TAG, "Remote exception", e); 15152 return ActivityManager.BROADCAST_SUCCESS; 15153 } 15154 } 15155 15156 // Handle special intents: if this broadcast is from the package 15157 // manager about a package being removed, we need to remove all of 15158 // its activities from the history stack. 15159 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15160 intent.getAction()); 15161 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15162 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15163 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15164 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15165 || uidRemoved) { 15166 if (checkComponentPermission( 15167 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15168 callingPid, callingUid, -1, true) 15169 == PackageManager.PERMISSION_GRANTED) { 15170 if (uidRemoved) { 15171 final Bundle intentExtras = intent.getExtras(); 15172 final int uid = intentExtras != null 15173 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15174 if (uid >= 0) { 15175 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15176 synchronized (bs) { 15177 bs.removeUidStatsLocked(uid); 15178 } 15179 mAppOpsService.uidRemoved(uid); 15180 } 15181 } else { 15182 // If resources are unavailable just force stop all 15183 // those packages and flush the attribute cache as well. 15184 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15185 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15186 if (list != null && (list.length > 0)) { 15187 for (String pkg : list) { 15188 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15189 "storage unmount"); 15190 } 15191 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15192 sendPackageBroadcastLocked( 15193 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15194 } 15195 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15196 intent.getAction())) { 15197 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15198 } else { 15199 Uri data = intent.getData(); 15200 String ssp; 15201 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15202 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15203 intent.getAction()); 15204 boolean fullUninstall = removed && 15205 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15206 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15207 forceStopPackageLocked(ssp, UserHandle.getAppId( 15208 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15209 false, fullUninstall, userId, 15210 removed ? "pkg removed" : "pkg changed"); 15211 } 15212 if (removed) { 15213 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15214 new String[] {ssp}, userId); 15215 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15216 mAppOpsService.packageRemoved( 15217 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15218 15219 // Remove all permissions granted from/to this package 15220 removeUriPermissionsForPackageLocked(ssp, userId, true); 15221 } 15222 } 15223 } 15224 } 15225 } 15226 } else { 15227 String msg = "Permission Denial: " + intent.getAction() 15228 + " broadcast from " + callerPackage + " (pid=" + callingPid 15229 + ", uid=" + callingUid + ")" 15230 + " requires " 15231 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15232 Slog.w(TAG, msg); 15233 throw new SecurityException(msg); 15234 } 15235 15236 // Special case for adding a package: by default turn on compatibility 15237 // mode. 15238 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15239 Uri data = intent.getData(); 15240 String ssp; 15241 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15242 mCompatModePackages.handlePackageAddedLocked(ssp, 15243 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15244 } 15245 } 15246 15247 /* 15248 * If this is the time zone changed action, queue up a message that will reset the timezone 15249 * of all currently running processes. This message will get queued up before the broadcast 15250 * happens. 15251 */ 15252 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15253 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15254 } 15255 15256 /* 15257 * If the user set the time, let all running processes know. 15258 */ 15259 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15260 final int is24Hour = intent.getBooleanExtra( 15261 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15262 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15263 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15264 synchronized (stats) { 15265 stats.noteCurrentTimeChangedLocked(); 15266 } 15267 } 15268 15269 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15270 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15271 } 15272 15273 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15274 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15275 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15276 } 15277 15278 // Add to the sticky list if requested. 15279 if (sticky) { 15280 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15281 callingPid, callingUid) 15282 != PackageManager.PERMISSION_GRANTED) { 15283 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15284 + callingPid + ", uid=" + callingUid 15285 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15286 Slog.w(TAG, msg); 15287 throw new SecurityException(msg); 15288 } 15289 if (requiredPermission != null) { 15290 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15291 + " and enforce permission " + requiredPermission); 15292 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15293 } 15294 if (intent.getComponent() != null) { 15295 throw new SecurityException( 15296 "Sticky broadcasts can't target a specific component"); 15297 } 15298 // We use userId directly here, since the "all" target is maintained 15299 // as a separate set of sticky broadcasts. 15300 if (userId != UserHandle.USER_ALL) { 15301 // But first, if this is not a broadcast to all users, then 15302 // make sure it doesn't conflict with an existing broadcast to 15303 // all users. 15304 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15305 UserHandle.USER_ALL); 15306 if (stickies != null) { 15307 ArrayList<Intent> list = stickies.get(intent.getAction()); 15308 if (list != null) { 15309 int N = list.size(); 15310 int i; 15311 for (i=0; i<N; i++) { 15312 if (intent.filterEquals(list.get(i))) { 15313 throw new IllegalArgumentException( 15314 "Sticky broadcast " + intent + " for user " 15315 + userId + " conflicts with existing global broadcast"); 15316 } 15317 } 15318 } 15319 } 15320 } 15321 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15322 if (stickies == null) { 15323 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15324 mStickyBroadcasts.put(userId, stickies); 15325 } 15326 ArrayList<Intent> list = stickies.get(intent.getAction()); 15327 if (list == null) { 15328 list = new ArrayList<Intent>(); 15329 stickies.put(intent.getAction(), list); 15330 } 15331 int N = list.size(); 15332 int i; 15333 for (i=0; i<N; i++) { 15334 if (intent.filterEquals(list.get(i))) { 15335 // This sticky already exists, replace it. 15336 list.set(i, new Intent(intent)); 15337 break; 15338 } 15339 } 15340 if (i >= N) { 15341 list.add(new Intent(intent)); 15342 } 15343 } 15344 15345 int[] users; 15346 if (userId == UserHandle.USER_ALL) { 15347 // Caller wants broadcast to go to all started users. 15348 users = mStartedUserArray; 15349 } else { 15350 // Caller wants broadcast to go to one specific user. 15351 users = new int[] {userId}; 15352 } 15353 15354 // Figure out who all will receive this broadcast. 15355 List receivers = null; 15356 List<BroadcastFilter> registeredReceivers = null; 15357 // Need to resolve the intent to interested receivers... 15358 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15359 == 0) { 15360 receivers = collectReceiverComponents(intent, resolvedType, users); 15361 } 15362 if (intent.getComponent() == null) { 15363 registeredReceivers = mReceiverResolver.queryIntent(intent, 15364 resolvedType, false, userId); 15365 } 15366 15367 final boolean replacePending = 15368 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15369 15370 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15371 + " replacePending=" + replacePending); 15372 15373 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15374 if (!ordered && NR > 0) { 15375 // If we are not serializing this broadcast, then send the 15376 // registered receivers separately so they don't wait for the 15377 // components to be launched. 15378 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15379 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15380 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15381 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15382 ordered, sticky, false, userId); 15383 if (DEBUG_BROADCAST) Slog.v( 15384 TAG, "Enqueueing parallel broadcast " + r); 15385 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15386 if (!replaced) { 15387 queue.enqueueParallelBroadcastLocked(r); 15388 queue.scheduleBroadcastsLocked(); 15389 } 15390 registeredReceivers = null; 15391 NR = 0; 15392 } 15393 15394 // Merge into one list. 15395 int ir = 0; 15396 if (receivers != null) { 15397 // A special case for PACKAGE_ADDED: do not allow the package 15398 // being added to see this broadcast. This prevents them from 15399 // using this as a back door to get run as soon as they are 15400 // installed. Maybe in the future we want to have a special install 15401 // broadcast or such for apps, but we'd like to deliberately make 15402 // this decision. 15403 String skipPackages[] = null; 15404 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15405 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15406 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15407 Uri data = intent.getData(); 15408 if (data != null) { 15409 String pkgName = data.getSchemeSpecificPart(); 15410 if (pkgName != null) { 15411 skipPackages = new String[] { pkgName }; 15412 } 15413 } 15414 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15415 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15416 } 15417 if (skipPackages != null && (skipPackages.length > 0)) { 15418 for (String skipPackage : skipPackages) { 15419 if (skipPackage != null) { 15420 int NT = receivers.size(); 15421 for (int it=0; it<NT; it++) { 15422 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15423 if (curt.activityInfo.packageName.equals(skipPackage)) { 15424 receivers.remove(it); 15425 it--; 15426 NT--; 15427 } 15428 } 15429 } 15430 } 15431 } 15432 15433 int NT = receivers != null ? receivers.size() : 0; 15434 int it = 0; 15435 ResolveInfo curt = null; 15436 BroadcastFilter curr = null; 15437 while (it < NT && ir < NR) { 15438 if (curt == null) { 15439 curt = (ResolveInfo)receivers.get(it); 15440 } 15441 if (curr == null) { 15442 curr = registeredReceivers.get(ir); 15443 } 15444 if (curr.getPriority() >= curt.priority) { 15445 // Insert this broadcast record into the final list. 15446 receivers.add(it, curr); 15447 ir++; 15448 curr = null; 15449 it++; 15450 NT++; 15451 } else { 15452 // Skip to the next ResolveInfo in the final list. 15453 it++; 15454 curt = null; 15455 } 15456 } 15457 } 15458 while (ir < NR) { 15459 if (receivers == null) { 15460 receivers = new ArrayList(); 15461 } 15462 receivers.add(registeredReceivers.get(ir)); 15463 ir++; 15464 } 15465 15466 if ((receivers != null && receivers.size() > 0) 15467 || resultTo != null) { 15468 BroadcastQueue queue = broadcastQueueForIntent(intent); 15469 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15470 callerPackage, callingPid, callingUid, resolvedType, 15471 requiredPermission, appOp, receivers, resultTo, resultCode, 15472 resultData, map, ordered, sticky, false, userId); 15473 if (DEBUG_BROADCAST) Slog.v( 15474 TAG, "Enqueueing ordered broadcast " + r 15475 + ": prev had " + queue.mOrderedBroadcasts.size()); 15476 if (DEBUG_BROADCAST) { 15477 int seq = r.intent.getIntExtra("seq", -1); 15478 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15479 } 15480 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15481 if (!replaced) { 15482 queue.enqueueOrderedBroadcastLocked(r); 15483 queue.scheduleBroadcastsLocked(); 15484 } 15485 } 15486 15487 return ActivityManager.BROADCAST_SUCCESS; 15488 } 15489 15490 final Intent verifyBroadcastLocked(Intent intent) { 15491 // Refuse possible leaked file descriptors 15492 if (intent != null && intent.hasFileDescriptors() == true) { 15493 throw new IllegalArgumentException("File descriptors passed in Intent"); 15494 } 15495 15496 int flags = intent.getFlags(); 15497 15498 if (!mProcessesReady) { 15499 // if the caller really truly claims to know what they're doing, go 15500 // ahead and allow the broadcast without launching any receivers 15501 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15502 intent = new Intent(intent); 15503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15504 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15505 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15506 + " before boot completion"); 15507 throw new IllegalStateException("Cannot broadcast before boot completed"); 15508 } 15509 } 15510 15511 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15512 throw new IllegalArgumentException( 15513 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15514 } 15515 15516 return intent; 15517 } 15518 15519 public final int broadcastIntent(IApplicationThread caller, 15520 Intent intent, String resolvedType, IIntentReceiver resultTo, 15521 int resultCode, String resultData, Bundle map, 15522 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15523 enforceNotIsolatedCaller("broadcastIntent"); 15524 synchronized(this) { 15525 intent = verifyBroadcastLocked(intent); 15526 15527 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15528 final int callingPid = Binder.getCallingPid(); 15529 final int callingUid = Binder.getCallingUid(); 15530 final long origId = Binder.clearCallingIdentity(); 15531 int res = broadcastIntentLocked(callerApp, 15532 callerApp != null ? callerApp.info.packageName : null, 15533 intent, resolvedType, resultTo, 15534 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15535 callingPid, callingUid, userId); 15536 Binder.restoreCallingIdentity(origId); 15537 return res; 15538 } 15539 } 15540 15541 int broadcastIntentInPackage(String packageName, int uid, 15542 Intent intent, String resolvedType, IIntentReceiver resultTo, 15543 int resultCode, String resultData, Bundle map, 15544 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15545 synchronized(this) { 15546 intent = verifyBroadcastLocked(intent); 15547 15548 final long origId = Binder.clearCallingIdentity(); 15549 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15550 resultTo, resultCode, resultData, map, requiredPermission, 15551 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15552 Binder.restoreCallingIdentity(origId); 15553 return res; 15554 } 15555 } 15556 15557 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15558 // Refuse possible leaked file descriptors 15559 if (intent != null && intent.hasFileDescriptors() == true) { 15560 throw new IllegalArgumentException("File descriptors passed in Intent"); 15561 } 15562 15563 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15564 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15565 15566 synchronized(this) { 15567 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15568 != PackageManager.PERMISSION_GRANTED) { 15569 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15570 + Binder.getCallingPid() 15571 + ", uid=" + Binder.getCallingUid() 15572 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15573 Slog.w(TAG, msg); 15574 throw new SecurityException(msg); 15575 } 15576 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15577 if (stickies != null) { 15578 ArrayList<Intent> list = stickies.get(intent.getAction()); 15579 if (list != null) { 15580 int N = list.size(); 15581 int i; 15582 for (i=0; i<N; i++) { 15583 if (intent.filterEquals(list.get(i))) { 15584 list.remove(i); 15585 break; 15586 } 15587 } 15588 if (list.size() <= 0) { 15589 stickies.remove(intent.getAction()); 15590 } 15591 } 15592 if (stickies.size() <= 0) { 15593 mStickyBroadcasts.remove(userId); 15594 } 15595 } 15596 } 15597 } 15598 15599 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15600 String resultData, Bundle resultExtras, boolean resultAbort) { 15601 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15602 if (r == null) { 15603 Slog.w(TAG, "finishReceiver called but not found on queue"); 15604 return false; 15605 } 15606 15607 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15608 } 15609 15610 void backgroundServicesFinishedLocked(int userId) { 15611 for (BroadcastQueue queue : mBroadcastQueues) { 15612 queue.backgroundServicesFinishedLocked(userId); 15613 } 15614 } 15615 15616 public void finishReceiver(IBinder who, int resultCode, String resultData, 15617 Bundle resultExtras, boolean resultAbort) { 15618 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15619 15620 // Refuse possible leaked file descriptors 15621 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15622 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15623 } 15624 15625 final long origId = Binder.clearCallingIdentity(); 15626 try { 15627 boolean doNext = false; 15628 BroadcastRecord r; 15629 15630 synchronized(this) { 15631 r = broadcastRecordForReceiverLocked(who); 15632 if (r != null) { 15633 doNext = r.queue.finishReceiverLocked(r, resultCode, 15634 resultData, resultExtras, resultAbort, true); 15635 } 15636 } 15637 15638 if (doNext) { 15639 r.queue.processNextBroadcast(false); 15640 } 15641 trimApplications(); 15642 } finally { 15643 Binder.restoreCallingIdentity(origId); 15644 } 15645 } 15646 15647 // ========================================================= 15648 // INSTRUMENTATION 15649 // ========================================================= 15650 15651 public boolean startInstrumentation(ComponentName className, 15652 String profileFile, int flags, Bundle arguments, 15653 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15654 int userId, String abiOverride) { 15655 enforceNotIsolatedCaller("startInstrumentation"); 15656 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15657 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15658 // Refuse possible leaked file descriptors 15659 if (arguments != null && arguments.hasFileDescriptors()) { 15660 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15661 } 15662 15663 synchronized(this) { 15664 InstrumentationInfo ii = null; 15665 ApplicationInfo ai = null; 15666 try { 15667 ii = mContext.getPackageManager().getInstrumentationInfo( 15668 className, STOCK_PM_FLAGS); 15669 ai = AppGlobals.getPackageManager().getApplicationInfo( 15670 ii.targetPackage, STOCK_PM_FLAGS, userId); 15671 } catch (PackageManager.NameNotFoundException e) { 15672 } catch (RemoteException e) { 15673 } 15674 if (ii == null) { 15675 reportStartInstrumentationFailure(watcher, className, 15676 "Unable to find instrumentation info for: " + className); 15677 return false; 15678 } 15679 if (ai == null) { 15680 reportStartInstrumentationFailure(watcher, className, 15681 "Unable to find instrumentation target package: " + ii.targetPackage); 15682 return false; 15683 } 15684 15685 int match = mContext.getPackageManager().checkSignatures( 15686 ii.targetPackage, ii.packageName); 15687 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15688 String msg = "Permission Denial: starting instrumentation " 15689 + className + " from pid=" 15690 + Binder.getCallingPid() 15691 + ", uid=" + Binder.getCallingPid() 15692 + " not allowed because package " + ii.packageName 15693 + " does not have a signature matching the target " 15694 + ii.targetPackage; 15695 reportStartInstrumentationFailure(watcher, className, msg); 15696 throw new SecurityException(msg); 15697 } 15698 15699 final long origId = Binder.clearCallingIdentity(); 15700 // Instrumentation can kill and relaunch even persistent processes 15701 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15702 "start instr"); 15703 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15704 app.instrumentationClass = className; 15705 app.instrumentationInfo = ai; 15706 app.instrumentationProfileFile = profileFile; 15707 app.instrumentationArguments = arguments; 15708 app.instrumentationWatcher = watcher; 15709 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15710 app.instrumentationResultClass = className; 15711 Binder.restoreCallingIdentity(origId); 15712 } 15713 15714 return true; 15715 } 15716 15717 /** 15718 * Report errors that occur while attempting to start Instrumentation. Always writes the 15719 * error to the logs, but if somebody is watching, send the report there too. This enables 15720 * the "am" command to report errors with more information. 15721 * 15722 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15723 * @param cn The component name of the instrumentation. 15724 * @param report The error report. 15725 */ 15726 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15727 ComponentName cn, String report) { 15728 Slog.w(TAG, report); 15729 try { 15730 if (watcher != null) { 15731 Bundle results = new Bundle(); 15732 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15733 results.putString("Error", report); 15734 watcher.instrumentationStatus(cn, -1, results); 15735 } 15736 } catch (RemoteException e) { 15737 Slog.w(TAG, e); 15738 } 15739 } 15740 15741 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15742 if (app.instrumentationWatcher != null) { 15743 try { 15744 // NOTE: IInstrumentationWatcher *must* be oneway here 15745 app.instrumentationWatcher.instrumentationFinished( 15746 app.instrumentationClass, 15747 resultCode, 15748 results); 15749 } catch (RemoteException e) { 15750 } 15751 } 15752 if (app.instrumentationUiAutomationConnection != null) { 15753 try { 15754 app.instrumentationUiAutomationConnection.shutdown(); 15755 } catch (RemoteException re) { 15756 /* ignore */ 15757 } 15758 // Only a UiAutomation can set this flag and now that 15759 // it is finished we make sure it is reset to its default. 15760 mUserIsMonkey = false; 15761 } 15762 app.instrumentationWatcher = null; 15763 app.instrumentationUiAutomationConnection = null; 15764 app.instrumentationClass = null; 15765 app.instrumentationInfo = null; 15766 app.instrumentationProfileFile = null; 15767 app.instrumentationArguments = null; 15768 15769 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15770 "finished inst"); 15771 } 15772 15773 public void finishInstrumentation(IApplicationThread target, 15774 int resultCode, Bundle results) { 15775 int userId = UserHandle.getCallingUserId(); 15776 // Refuse possible leaked file descriptors 15777 if (results != null && results.hasFileDescriptors()) { 15778 throw new IllegalArgumentException("File descriptors passed in Intent"); 15779 } 15780 15781 synchronized(this) { 15782 ProcessRecord app = getRecordForAppLocked(target); 15783 if (app == null) { 15784 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15785 return; 15786 } 15787 final long origId = Binder.clearCallingIdentity(); 15788 finishInstrumentationLocked(app, resultCode, results); 15789 Binder.restoreCallingIdentity(origId); 15790 } 15791 } 15792 15793 // ========================================================= 15794 // CONFIGURATION 15795 // ========================================================= 15796 15797 public ConfigurationInfo getDeviceConfigurationInfo() { 15798 ConfigurationInfo config = new ConfigurationInfo(); 15799 synchronized (this) { 15800 config.reqTouchScreen = mConfiguration.touchscreen; 15801 config.reqKeyboardType = mConfiguration.keyboard; 15802 config.reqNavigation = mConfiguration.navigation; 15803 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15804 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15805 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15806 } 15807 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15808 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15809 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15810 } 15811 config.reqGlEsVersion = GL_ES_VERSION; 15812 } 15813 return config; 15814 } 15815 15816 ActivityStack getFocusedStack() { 15817 return mStackSupervisor.getFocusedStack(); 15818 } 15819 15820 public Configuration getConfiguration() { 15821 Configuration ci; 15822 synchronized(this) { 15823 ci = new Configuration(mConfiguration); 15824 } 15825 return ci; 15826 } 15827 15828 public void updatePersistentConfiguration(Configuration values) { 15829 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15830 "updateConfiguration()"); 15831 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15832 "updateConfiguration()"); 15833 if (values == null) { 15834 throw new NullPointerException("Configuration must not be null"); 15835 } 15836 15837 synchronized(this) { 15838 final long origId = Binder.clearCallingIdentity(); 15839 updateConfigurationLocked(values, null, true, false); 15840 Binder.restoreCallingIdentity(origId); 15841 } 15842 } 15843 15844 public void updateConfiguration(Configuration values) { 15845 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15846 "updateConfiguration()"); 15847 15848 synchronized(this) { 15849 if (values == null && mWindowManager != null) { 15850 // sentinel: fetch the current configuration from the window manager 15851 values = mWindowManager.computeNewConfiguration(); 15852 } 15853 15854 if (mWindowManager != null) { 15855 mProcessList.applyDisplaySize(mWindowManager); 15856 } 15857 15858 final long origId = Binder.clearCallingIdentity(); 15859 if (values != null) { 15860 Settings.System.clearConfiguration(values); 15861 } 15862 updateConfigurationLocked(values, null, false, false); 15863 Binder.restoreCallingIdentity(origId); 15864 } 15865 } 15866 15867 /** 15868 * Do either or both things: (1) change the current configuration, and (2) 15869 * make sure the given activity is running with the (now) current 15870 * configuration. Returns true if the activity has been left running, or 15871 * false if <var>starting</var> is being destroyed to match the new 15872 * configuration. 15873 * @param persistent TODO 15874 */ 15875 boolean updateConfigurationLocked(Configuration values, 15876 ActivityRecord starting, boolean persistent, boolean initLocale) { 15877 int changes = 0; 15878 15879 if (values != null) { 15880 Configuration newConfig = new Configuration(mConfiguration); 15881 changes = newConfig.updateFrom(values); 15882 if (changes != 0) { 15883 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15884 Slog.i(TAG, "Updating configuration to: " + values); 15885 } 15886 15887 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15888 15889 if (values.locale != null && !initLocale) { 15890 saveLocaleLocked(values.locale, 15891 !values.locale.equals(mConfiguration.locale), 15892 values.userSetLocale); 15893 } 15894 15895 mConfigurationSeq++; 15896 if (mConfigurationSeq <= 0) { 15897 mConfigurationSeq = 1; 15898 } 15899 newConfig.seq = mConfigurationSeq; 15900 mConfiguration = newConfig; 15901 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15902 //mUsageStatsService.noteStartConfig(newConfig); 15903 15904 final Configuration configCopy = new Configuration(mConfiguration); 15905 15906 // TODO: If our config changes, should we auto dismiss any currently 15907 // showing dialogs? 15908 mShowDialogs = shouldShowDialogs(newConfig); 15909 15910 AttributeCache ac = AttributeCache.instance(); 15911 if (ac != null) { 15912 ac.updateConfiguration(configCopy); 15913 } 15914 15915 // Make sure all resources in our process are updated 15916 // right now, so that anyone who is going to retrieve 15917 // resource values after we return will be sure to get 15918 // the new ones. This is especially important during 15919 // boot, where the first config change needs to guarantee 15920 // all resources have that config before following boot 15921 // code is executed. 15922 mSystemThread.applyConfigurationToResources(configCopy); 15923 15924 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15925 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15926 msg.obj = new Configuration(configCopy); 15927 mHandler.sendMessage(msg); 15928 } 15929 15930 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15931 ProcessRecord app = mLruProcesses.get(i); 15932 try { 15933 if (app.thread != null) { 15934 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15935 + app.processName + " new config " + mConfiguration); 15936 app.thread.scheduleConfigurationChanged(configCopy); 15937 } 15938 } catch (Exception e) { 15939 } 15940 } 15941 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15942 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15943 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15944 | Intent.FLAG_RECEIVER_FOREGROUND); 15945 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15946 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15947 Process.SYSTEM_UID, UserHandle.USER_ALL); 15948 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15949 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15950 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15951 broadcastIntentLocked(null, null, intent, 15952 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15953 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15954 } 15955 } 15956 } 15957 15958 boolean kept = true; 15959 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15960 // mainStack is null during startup. 15961 if (mainStack != null) { 15962 if (changes != 0 && starting == null) { 15963 // If the configuration changed, and the caller is not already 15964 // in the process of starting an activity, then find the top 15965 // activity to check if its configuration needs to change. 15966 starting = mainStack.topRunningActivityLocked(null); 15967 } 15968 15969 if (starting != null) { 15970 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15971 // And we need to make sure at this point that all other activities 15972 // are made visible with the correct configuration. 15973 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15974 } 15975 } 15976 15977 if (values != null && mWindowManager != null) { 15978 mWindowManager.setNewConfiguration(mConfiguration); 15979 } 15980 15981 return kept; 15982 } 15983 15984 /** 15985 * Decide based on the configuration whether we should shouw the ANR, 15986 * crash, etc dialogs. The idea is that if there is no affordnace to 15987 * press the on-screen buttons, we shouldn't show the dialog. 15988 * 15989 * A thought: SystemUI might also want to get told about this, the Power 15990 * dialog / global actions also might want different behaviors. 15991 */ 15992 private static final boolean shouldShowDialogs(Configuration config) { 15993 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15994 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15995 } 15996 15997 /** 15998 * Save the locale. You must be inside a synchronized (this) block. 15999 */ 16000 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16001 if(isDiff) { 16002 SystemProperties.set("user.language", l.getLanguage()); 16003 SystemProperties.set("user.region", l.getCountry()); 16004 } 16005 16006 if(isPersist) { 16007 SystemProperties.set("persist.sys.language", l.getLanguage()); 16008 SystemProperties.set("persist.sys.country", l.getCountry()); 16009 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16010 } 16011 } 16012 16013 @Override 16014 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16015 synchronized (this) { 16016 ActivityRecord srec = ActivityRecord.forToken(token); 16017 if (srec.task != null && srec.task.stack != null) { 16018 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16019 } 16020 } 16021 return false; 16022 } 16023 16024 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16025 Intent resultData) { 16026 16027 synchronized (this) { 16028 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16029 if (stack != null) { 16030 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16031 } 16032 return false; 16033 } 16034 } 16035 16036 public int getLaunchedFromUid(IBinder activityToken) { 16037 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16038 if (srec == null) { 16039 return -1; 16040 } 16041 return srec.launchedFromUid; 16042 } 16043 16044 public String getLaunchedFromPackage(IBinder activityToken) { 16045 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16046 if (srec == null) { 16047 return null; 16048 } 16049 return srec.launchedFromPackage; 16050 } 16051 16052 // ========================================================= 16053 // LIFETIME MANAGEMENT 16054 // ========================================================= 16055 16056 // Returns which broadcast queue the app is the current [or imminent] receiver 16057 // on, or 'null' if the app is not an active broadcast recipient. 16058 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16059 BroadcastRecord r = app.curReceiver; 16060 if (r != null) { 16061 return r.queue; 16062 } 16063 16064 // It's not the current receiver, but it might be starting up to become one 16065 synchronized (this) { 16066 for (BroadcastQueue queue : mBroadcastQueues) { 16067 r = queue.mPendingBroadcast; 16068 if (r != null && r.curApp == app) { 16069 // found it; report which queue it's in 16070 return queue; 16071 } 16072 } 16073 } 16074 16075 return null; 16076 } 16077 16078 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16079 boolean doingAll, long now) { 16080 if (mAdjSeq == app.adjSeq) { 16081 // This adjustment has already been computed. 16082 return app.curRawAdj; 16083 } 16084 16085 if (app.thread == null) { 16086 app.adjSeq = mAdjSeq; 16087 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16088 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16089 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16090 } 16091 16092 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16093 app.adjSource = null; 16094 app.adjTarget = null; 16095 app.empty = false; 16096 app.cached = false; 16097 16098 final int activitiesSize = app.activities.size(); 16099 16100 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16101 // The max adjustment doesn't allow this app to be anything 16102 // below foreground, so it is not worth doing work for it. 16103 app.adjType = "fixed"; 16104 app.adjSeq = mAdjSeq; 16105 app.curRawAdj = app.maxAdj; 16106 app.foregroundActivities = false; 16107 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16108 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16109 // System processes can do UI, and when they do we want to have 16110 // them trim their memory after the user leaves the UI. To 16111 // facilitate this, here we need to determine whether or not it 16112 // is currently showing UI. 16113 app.systemNoUi = true; 16114 if (app == TOP_APP) { 16115 app.systemNoUi = false; 16116 } else if (activitiesSize > 0) { 16117 for (int j = 0; j < activitiesSize; j++) { 16118 final ActivityRecord r = app.activities.get(j); 16119 if (r.visible) { 16120 app.systemNoUi = false; 16121 } 16122 } 16123 } 16124 if (!app.systemNoUi) { 16125 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16126 } 16127 return (app.curAdj=app.maxAdj); 16128 } 16129 16130 app.systemNoUi = false; 16131 16132 // Determine the importance of the process, starting with most 16133 // important to least, and assign an appropriate OOM adjustment. 16134 int adj; 16135 int schedGroup; 16136 int procState; 16137 boolean foregroundActivities = false; 16138 BroadcastQueue queue; 16139 if (app == TOP_APP) { 16140 // The last app on the list is the foreground app. 16141 adj = ProcessList.FOREGROUND_APP_ADJ; 16142 schedGroup = Process.THREAD_GROUP_DEFAULT; 16143 app.adjType = "top-activity"; 16144 foregroundActivities = true; 16145 procState = ActivityManager.PROCESS_STATE_TOP; 16146 } else if (app.instrumentationClass != null) { 16147 // Don't want to kill running instrumentation. 16148 adj = ProcessList.FOREGROUND_APP_ADJ; 16149 schedGroup = Process.THREAD_GROUP_DEFAULT; 16150 app.adjType = "instrumentation"; 16151 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16152 } else if ((queue = isReceivingBroadcast(app)) != null) { 16153 // An app that is currently receiving a broadcast also 16154 // counts as being in the foreground for OOM killer purposes. 16155 // It's placed in a sched group based on the nature of the 16156 // broadcast as reflected by which queue it's active in. 16157 adj = ProcessList.FOREGROUND_APP_ADJ; 16158 schedGroup = (queue == mFgBroadcastQueue) 16159 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16160 app.adjType = "broadcast"; 16161 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16162 } else if (app.executingServices.size() > 0) { 16163 // An app that is currently executing a service callback also 16164 // counts as being in the foreground. 16165 adj = ProcessList.FOREGROUND_APP_ADJ; 16166 schedGroup = app.execServicesFg ? 16167 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16168 app.adjType = "exec-service"; 16169 procState = ActivityManager.PROCESS_STATE_SERVICE; 16170 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16171 } else { 16172 // As far as we know the process is empty. We may change our mind later. 16173 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16174 // At this point we don't actually know the adjustment. Use the cached adj 16175 // value that the caller wants us to. 16176 adj = cachedAdj; 16177 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16178 app.cached = true; 16179 app.empty = true; 16180 app.adjType = "cch-empty"; 16181 } 16182 16183 // Examine all activities if not already foreground. 16184 if (!foregroundActivities && activitiesSize > 0) { 16185 for (int j = 0; j < activitiesSize; j++) { 16186 final ActivityRecord r = app.activities.get(j); 16187 if (r.app != app) { 16188 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16189 + app + "?!?"); 16190 continue; 16191 } 16192 if (r.visible) { 16193 // App has a visible activity; only upgrade adjustment. 16194 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16195 adj = ProcessList.VISIBLE_APP_ADJ; 16196 app.adjType = "visible"; 16197 } 16198 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16199 procState = ActivityManager.PROCESS_STATE_TOP; 16200 } 16201 schedGroup = Process.THREAD_GROUP_DEFAULT; 16202 app.cached = false; 16203 app.empty = false; 16204 foregroundActivities = true; 16205 break; 16206 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16207 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16208 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16209 app.adjType = "pausing"; 16210 } 16211 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16212 procState = ActivityManager.PROCESS_STATE_TOP; 16213 } 16214 schedGroup = Process.THREAD_GROUP_DEFAULT; 16215 app.cached = false; 16216 app.empty = false; 16217 foregroundActivities = true; 16218 } else if (r.state == ActivityState.STOPPING) { 16219 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16220 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16221 app.adjType = "stopping"; 16222 } 16223 // For the process state, we will at this point consider the 16224 // process to be cached. It will be cached either as an activity 16225 // or empty depending on whether the activity is finishing. We do 16226 // this so that we can treat the process as cached for purposes of 16227 // memory trimming (determing current memory level, trim command to 16228 // send to process) since there can be an arbitrary number of stopping 16229 // processes and they should soon all go into the cached state. 16230 if (!r.finishing) { 16231 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16232 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16233 } 16234 } 16235 app.cached = false; 16236 app.empty = false; 16237 foregroundActivities = true; 16238 } else { 16239 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16240 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16241 app.adjType = "cch-act"; 16242 } 16243 } 16244 } 16245 } 16246 16247 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16248 if (app.foregroundServices) { 16249 // The user is aware of this app, so make it visible. 16250 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16251 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16252 app.cached = false; 16253 app.adjType = "fg-service"; 16254 schedGroup = Process.THREAD_GROUP_DEFAULT; 16255 } else if (app.forcingToForeground != null) { 16256 // The user is aware of this app, so make it visible. 16257 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16258 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16259 app.cached = false; 16260 app.adjType = "force-fg"; 16261 app.adjSource = app.forcingToForeground; 16262 schedGroup = Process.THREAD_GROUP_DEFAULT; 16263 } 16264 } 16265 16266 if (app == mHeavyWeightProcess) { 16267 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16268 // We don't want to kill the current heavy-weight process. 16269 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16270 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16271 app.cached = false; 16272 app.adjType = "heavy"; 16273 } 16274 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16275 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16276 } 16277 } 16278 16279 if (app == mHomeProcess) { 16280 if (adj > ProcessList.HOME_APP_ADJ) { 16281 // This process is hosting what we currently consider to be the 16282 // home app, so we don't want to let it go into the background. 16283 adj = ProcessList.HOME_APP_ADJ; 16284 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16285 app.cached = false; 16286 app.adjType = "home"; 16287 } 16288 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16289 procState = ActivityManager.PROCESS_STATE_HOME; 16290 } 16291 } 16292 16293 if (app == mPreviousProcess && app.activities.size() > 0) { 16294 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16295 // This was the previous process that showed UI to the user. 16296 // We want to try to keep it around more aggressively, to give 16297 // a good experience around switching between two apps. 16298 adj = ProcessList.PREVIOUS_APP_ADJ; 16299 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16300 app.cached = false; 16301 app.adjType = "previous"; 16302 } 16303 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16304 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16305 } 16306 } 16307 16308 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16309 + " reason=" + app.adjType); 16310 16311 // By default, we use the computed adjustment. It may be changed if 16312 // there are applications dependent on our services or providers, but 16313 // this gives us a baseline and makes sure we don't get into an 16314 // infinite recursion. 16315 app.adjSeq = mAdjSeq; 16316 app.curRawAdj = adj; 16317 app.hasStartedServices = false; 16318 16319 if (mBackupTarget != null && app == mBackupTarget.app) { 16320 // If possible we want to avoid killing apps while they're being backed up 16321 if (adj > ProcessList.BACKUP_APP_ADJ) { 16322 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16323 adj = ProcessList.BACKUP_APP_ADJ; 16324 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16325 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16326 } 16327 app.adjType = "backup"; 16328 app.cached = false; 16329 } 16330 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16331 procState = ActivityManager.PROCESS_STATE_BACKUP; 16332 } 16333 } 16334 16335 boolean mayBeTop = false; 16336 16337 for (int is = app.services.size()-1; 16338 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16339 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16340 || procState > ActivityManager.PROCESS_STATE_TOP); 16341 is--) { 16342 ServiceRecord s = app.services.valueAt(is); 16343 if (s.startRequested) { 16344 app.hasStartedServices = true; 16345 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16346 procState = ActivityManager.PROCESS_STATE_SERVICE; 16347 } 16348 if (app.hasShownUi && app != mHomeProcess) { 16349 // If this process has shown some UI, let it immediately 16350 // go to the LRU list because it may be pretty heavy with 16351 // UI stuff. We'll tag it with a label just to help 16352 // debug and understand what is going on. 16353 if (adj > ProcessList.SERVICE_ADJ) { 16354 app.adjType = "cch-started-ui-services"; 16355 } 16356 } else { 16357 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16358 // This service has seen some activity within 16359 // recent memory, so we will keep its process ahead 16360 // of the background processes. 16361 if (adj > ProcessList.SERVICE_ADJ) { 16362 adj = ProcessList.SERVICE_ADJ; 16363 app.adjType = "started-services"; 16364 app.cached = false; 16365 } 16366 } 16367 // If we have let the service slide into the background 16368 // state, still have some text describing what it is doing 16369 // even though the service no longer has an impact. 16370 if (adj > ProcessList.SERVICE_ADJ) { 16371 app.adjType = "cch-started-services"; 16372 } 16373 } 16374 } 16375 for (int conni = s.connections.size()-1; 16376 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16377 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16378 || procState > ActivityManager.PROCESS_STATE_TOP); 16379 conni--) { 16380 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16381 for (int i = 0; 16382 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16383 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16384 || procState > ActivityManager.PROCESS_STATE_TOP); 16385 i++) { 16386 // XXX should compute this based on the max of 16387 // all connected clients. 16388 ConnectionRecord cr = clist.get(i); 16389 if (cr.binding.client == app) { 16390 // Binding to ourself is not interesting. 16391 continue; 16392 } 16393 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16394 ProcessRecord client = cr.binding.client; 16395 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16396 TOP_APP, doingAll, now); 16397 int clientProcState = client.curProcState; 16398 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16399 // If the other app is cached for any reason, for purposes here 16400 // we are going to consider it empty. The specific cached state 16401 // doesn't propagate except under certain conditions. 16402 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16403 } 16404 String adjType = null; 16405 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16406 // Not doing bind OOM management, so treat 16407 // this guy more like a started service. 16408 if (app.hasShownUi && app != mHomeProcess) { 16409 // If this process has shown some UI, let it immediately 16410 // go to the LRU list because it may be pretty heavy with 16411 // UI stuff. We'll tag it with a label just to help 16412 // debug and understand what is going on. 16413 if (adj > clientAdj) { 16414 adjType = "cch-bound-ui-services"; 16415 } 16416 app.cached = false; 16417 clientAdj = adj; 16418 clientProcState = procState; 16419 } else { 16420 if (now >= (s.lastActivity 16421 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16422 // This service has not seen activity within 16423 // recent memory, so allow it to drop to the 16424 // LRU list if there is no other reason to keep 16425 // it around. We'll also tag it with a label just 16426 // to help debug and undertand what is going on. 16427 if (adj > clientAdj) { 16428 adjType = "cch-bound-services"; 16429 } 16430 clientAdj = adj; 16431 } 16432 } 16433 } 16434 if (adj > clientAdj) { 16435 // If this process has recently shown UI, and 16436 // the process that is binding to it is less 16437 // important than being visible, then we don't 16438 // care about the binding as much as we care 16439 // about letting this process get into the LRU 16440 // list to be killed and restarted if needed for 16441 // memory. 16442 if (app.hasShownUi && app != mHomeProcess 16443 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16444 adjType = "cch-bound-ui-services"; 16445 } else { 16446 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16447 |Context.BIND_IMPORTANT)) != 0) { 16448 adj = clientAdj; 16449 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16450 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16451 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16452 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16453 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16454 adj = clientAdj; 16455 } else { 16456 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16457 adj = ProcessList.VISIBLE_APP_ADJ; 16458 } 16459 } 16460 if (!client.cached) { 16461 app.cached = false; 16462 } 16463 adjType = "service"; 16464 } 16465 } 16466 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16467 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16468 schedGroup = Process.THREAD_GROUP_DEFAULT; 16469 } 16470 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16471 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16472 // Special handling of clients who are in the top state. 16473 // We *may* want to consider this process to be in the 16474 // top state as well, but only if there is not another 16475 // reason for it to be running. Being on the top is a 16476 // special state, meaning you are specifically running 16477 // for the current top app. If the process is already 16478 // running in the background for some other reason, it 16479 // is more important to continue considering it to be 16480 // in the background state. 16481 mayBeTop = true; 16482 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16483 } else { 16484 // Special handling for above-top states (persistent 16485 // processes). These should not bring the current process 16486 // into the top state, since they are not on top. Instead 16487 // give them the best state after that. 16488 clientProcState = 16489 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16490 } 16491 } 16492 } else { 16493 if (clientProcState < 16494 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16495 clientProcState = 16496 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16497 } 16498 } 16499 if (procState > clientProcState) { 16500 procState = clientProcState; 16501 } 16502 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16503 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16504 app.pendingUiClean = true; 16505 } 16506 if (adjType != null) { 16507 app.adjType = adjType; 16508 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16509 .REASON_SERVICE_IN_USE; 16510 app.adjSource = cr.binding.client; 16511 app.adjSourceProcState = clientProcState; 16512 app.adjTarget = s.name; 16513 } 16514 } 16515 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16516 app.treatLikeActivity = true; 16517 } 16518 final ActivityRecord a = cr.activity; 16519 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16520 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16521 (a.visible || a.state == ActivityState.RESUMED 16522 || a.state == ActivityState.PAUSING)) { 16523 adj = ProcessList.FOREGROUND_APP_ADJ; 16524 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16525 schedGroup = Process.THREAD_GROUP_DEFAULT; 16526 } 16527 app.cached = false; 16528 app.adjType = "service"; 16529 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16530 .REASON_SERVICE_IN_USE; 16531 app.adjSource = a; 16532 app.adjSourceProcState = procState; 16533 app.adjTarget = s.name; 16534 } 16535 } 16536 } 16537 } 16538 } 16539 16540 for (int provi = app.pubProviders.size()-1; 16541 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16542 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16543 || procState > ActivityManager.PROCESS_STATE_TOP); 16544 provi--) { 16545 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16546 for (int i = cpr.connections.size()-1; 16547 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16548 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16549 || procState > ActivityManager.PROCESS_STATE_TOP); 16550 i--) { 16551 ContentProviderConnection conn = cpr.connections.get(i); 16552 ProcessRecord client = conn.client; 16553 if (client == app) { 16554 // Being our own client is not interesting. 16555 continue; 16556 } 16557 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16558 int clientProcState = client.curProcState; 16559 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16560 // If the other app is cached for any reason, for purposes here 16561 // we are going to consider it empty. 16562 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16563 } 16564 if (adj > clientAdj) { 16565 if (app.hasShownUi && app != mHomeProcess 16566 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16567 app.adjType = "cch-ui-provider"; 16568 } else { 16569 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16570 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16571 app.adjType = "provider"; 16572 } 16573 app.cached &= client.cached; 16574 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16575 .REASON_PROVIDER_IN_USE; 16576 app.adjSource = client; 16577 app.adjSourceProcState = clientProcState; 16578 app.adjTarget = cpr.name; 16579 } 16580 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16581 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16582 // Special handling of clients who are in the top state. 16583 // We *may* want to consider this process to be in the 16584 // top state as well, but only if there is not another 16585 // reason for it to be running. Being on the top is a 16586 // special state, meaning you are specifically running 16587 // for the current top app. If the process is already 16588 // running in the background for some other reason, it 16589 // is more important to continue considering it to be 16590 // in the background state. 16591 mayBeTop = true; 16592 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16593 } else { 16594 // Special handling for above-top states (persistent 16595 // processes). These should not bring the current process 16596 // into the top state, since they are not on top. Instead 16597 // give them the best state after that. 16598 clientProcState = 16599 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16600 } 16601 } 16602 if (procState > clientProcState) { 16603 procState = clientProcState; 16604 } 16605 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16606 schedGroup = Process.THREAD_GROUP_DEFAULT; 16607 } 16608 } 16609 // If the provider has external (non-framework) process 16610 // dependencies, ensure that its adjustment is at least 16611 // FOREGROUND_APP_ADJ. 16612 if (cpr.hasExternalProcessHandles()) { 16613 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16614 adj = ProcessList.FOREGROUND_APP_ADJ; 16615 schedGroup = Process.THREAD_GROUP_DEFAULT; 16616 app.cached = false; 16617 app.adjType = "provider"; 16618 app.adjTarget = cpr.name; 16619 } 16620 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16621 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16622 } 16623 } 16624 } 16625 16626 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16627 // A client of one of our services or providers is in the top state. We 16628 // *may* want to be in the top state, but not if we are already running in 16629 // the background for some other reason. For the decision here, we are going 16630 // to pick out a few specific states that we want to remain in when a client 16631 // is top (states that tend to be longer-term) and otherwise allow it to go 16632 // to the top state. 16633 switch (procState) { 16634 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16635 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16636 case ActivityManager.PROCESS_STATE_SERVICE: 16637 // These all are longer-term states, so pull them up to the top 16638 // of the background states, but not all the way to the top state. 16639 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16640 break; 16641 default: 16642 // Otherwise, top is a better choice, so take it. 16643 procState = ActivityManager.PROCESS_STATE_TOP; 16644 break; 16645 } 16646 } 16647 16648 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16649 if (app.hasClientActivities) { 16650 // This is a cached process, but with client activities. Mark it so. 16651 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16652 app.adjType = "cch-client-act"; 16653 } else if (app.treatLikeActivity) { 16654 // This is a cached process, but somebody wants us to treat it like it has 16655 // an activity, okay! 16656 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16657 app.adjType = "cch-as-act"; 16658 } 16659 } 16660 16661 if (adj == ProcessList.SERVICE_ADJ) { 16662 if (doingAll) { 16663 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16664 mNewNumServiceProcs++; 16665 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16666 if (!app.serviceb) { 16667 // This service isn't far enough down on the LRU list to 16668 // normally be a B service, but if we are low on RAM and it 16669 // is large we want to force it down since we would prefer to 16670 // keep launcher over it. 16671 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16672 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16673 app.serviceHighRam = true; 16674 app.serviceb = true; 16675 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16676 } else { 16677 mNewNumAServiceProcs++; 16678 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16679 } 16680 } else { 16681 app.serviceHighRam = false; 16682 } 16683 } 16684 if (app.serviceb) { 16685 adj = ProcessList.SERVICE_B_ADJ; 16686 } 16687 } 16688 16689 app.curRawAdj = adj; 16690 16691 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16692 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16693 if (adj > app.maxAdj) { 16694 adj = app.maxAdj; 16695 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16696 schedGroup = Process.THREAD_GROUP_DEFAULT; 16697 } 16698 } 16699 16700 // Do final modification to adj. Everything we do between here and applying 16701 // the final setAdj must be done in this function, because we will also use 16702 // it when computing the final cached adj later. Note that we don't need to 16703 // worry about this for max adj above, since max adj will always be used to 16704 // keep it out of the cached vaues. 16705 app.curAdj = app.modifyRawOomAdj(adj); 16706 app.curSchedGroup = schedGroup; 16707 app.curProcState = procState; 16708 app.foregroundActivities = foregroundActivities; 16709 16710 return app.curRawAdj; 16711 } 16712 16713 /** 16714 * Schedule PSS collection of a process. 16715 */ 16716 void requestPssLocked(ProcessRecord proc, int procState) { 16717 if (mPendingPssProcesses.contains(proc)) { 16718 return; 16719 } 16720 if (mPendingPssProcesses.size() == 0) { 16721 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16722 } 16723 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16724 proc.pssProcState = procState; 16725 mPendingPssProcesses.add(proc); 16726 } 16727 16728 /** 16729 * Schedule PSS collection of all processes. 16730 */ 16731 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16732 if (!always) { 16733 if (now < (mLastFullPssTime + 16734 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16735 return; 16736 } 16737 } 16738 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16739 mLastFullPssTime = now; 16740 mFullPssPending = true; 16741 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16742 mPendingPssProcesses.clear(); 16743 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16744 ProcessRecord app = mLruProcesses.get(i); 16745 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16746 app.pssProcState = app.setProcState; 16747 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16748 isSleeping(), now); 16749 mPendingPssProcesses.add(app); 16750 } 16751 } 16752 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16753 } 16754 16755 /** 16756 * Ask a given process to GC right now. 16757 */ 16758 final void performAppGcLocked(ProcessRecord app) { 16759 try { 16760 app.lastRequestedGc = SystemClock.uptimeMillis(); 16761 if (app.thread != null) { 16762 if (app.reportLowMemory) { 16763 app.reportLowMemory = false; 16764 app.thread.scheduleLowMemory(); 16765 } else { 16766 app.thread.processInBackground(); 16767 } 16768 } 16769 } catch (Exception e) { 16770 // whatever. 16771 } 16772 } 16773 16774 /** 16775 * Returns true if things are idle enough to perform GCs. 16776 */ 16777 private final boolean canGcNowLocked() { 16778 boolean processingBroadcasts = false; 16779 for (BroadcastQueue q : mBroadcastQueues) { 16780 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16781 processingBroadcasts = true; 16782 } 16783 } 16784 return !processingBroadcasts 16785 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16786 } 16787 16788 /** 16789 * Perform GCs on all processes that are waiting for it, but only 16790 * if things are idle. 16791 */ 16792 final void performAppGcsLocked() { 16793 final int N = mProcessesToGc.size(); 16794 if (N <= 0) { 16795 return; 16796 } 16797 if (canGcNowLocked()) { 16798 while (mProcessesToGc.size() > 0) { 16799 ProcessRecord proc = mProcessesToGc.remove(0); 16800 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16801 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16802 <= SystemClock.uptimeMillis()) { 16803 // To avoid spamming the system, we will GC processes one 16804 // at a time, waiting a few seconds between each. 16805 performAppGcLocked(proc); 16806 scheduleAppGcsLocked(); 16807 return; 16808 } else { 16809 // It hasn't been long enough since we last GCed this 16810 // process... put it in the list to wait for its time. 16811 addProcessToGcListLocked(proc); 16812 break; 16813 } 16814 } 16815 } 16816 16817 scheduleAppGcsLocked(); 16818 } 16819 } 16820 16821 /** 16822 * If all looks good, perform GCs on all processes waiting for them. 16823 */ 16824 final void performAppGcsIfAppropriateLocked() { 16825 if (canGcNowLocked()) { 16826 performAppGcsLocked(); 16827 return; 16828 } 16829 // Still not idle, wait some more. 16830 scheduleAppGcsLocked(); 16831 } 16832 16833 /** 16834 * Schedule the execution of all pending app GCs. 16835 */ 16836 final void scheduleAppGcsLocked() { 16837 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16838 16839 if (mProcessesToGc.size() > 0) { 16840 // Schedule a GC for the time to the next process. 16841 ProcessRecord proc = mProcessesToGc.get(0); 16842 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16843 16844 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16845 long now = SystemClock.uptimeMillis(); 16846 if (when < (now+GC_TIMEOUT)) { 16847 when = now + GC_TIMEOUT; 16848 } 16849 mHandler.sendMessageAtTime(msg, when); 16850 } 16851 } 16852 16853 /** 16854 * Add a process to the array of processes waiting to be GCed. Keeps the 16855 * list in sorted order by the last GC time. The process can't already be 16856 * on the list. 16857 */ 16858 final void addProcessToGcListLocked(ProcessRecord proc) { 16859 boolean added = false; 16860 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16861 if (mProcessesToGc.get(i).lastRequestedGc < 16862 proc.lastRequestedGc) { 16863 added = true; 16864 mProcessesToGc.add(i+1, proc); 16865 break; 16866 } 16867 } 16868 if (!added) { 16869 mProcessesToGc.add(0, proc); 16870 } 16871 } 16872 16873 /** 16874 * Set up to ask a process to GC itself. This will either do it 16875 * immediately, or put it on the list of processes to gc the next 16876 * time things are idle. 16877 */ 16878 final void scheduleAppGcLocked(ProcessRecord app) { 16879 long now = SystemClock.uptimeMillis(); 16880 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16881 return; 16882 } 16883 if (!mProcessesToGc.contains(app)) { 16884 addProcessToGcListLocked(app); 16885 scheduleAppGcsLocked(); 16886 } 16887 } 16888 16889 final void checkExcessivePowerUsageLocked(boolean doKills) { 16890 updateCpuStatsNow(); 16891 16892 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16893 boolean doWakeKills = doKills; 16894 boolean doCpuKills = doKills; 16895 if (mLastPowerCheckRealtime == 0) { 16896 doWakeKills = false; 16897 } 16898 if (mLastPowerCheckUptime == 0) { 16899 doCpuKills = false; 16900 } 16901 if (stats.isScreenOn()) { 16902 doWakeKills = false; 16903 } 16904 final long curRealtime = SystemClock.elapsedRealtime(); 16905 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16906 final long curUptime = SystemClock.uptimeMillis(); 16907 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16908 mLastPowerCheckRealtime = curRealtime; 16909 mLastPowerCheckUptime = curUptime; 16910 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16911 doWakeKills = false; 16912 } 16913 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16914 doCpuKills = false; 16915 } 16916 int i = mLruProcesses.size(); 16917 while (i > 0) { 16918 i--; 16919 ProcessRecord app = mLruProcesses.get(i); 16920 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16921 long wtime; 16922 synchronized (stats) { 16923 wtime = stats.getProcessWakeTime(app.info.uid, 16924 app.pid, curRealtime); 16925 } 16926 long wtimeUsed = wtime - app.lastWakeTime; 16927 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16928 if (DEBUG_POWER) { 16929 StringBuilder sb = new StringBuilder(128); 16930 sb.append("Wake for "); 16931 app.toShortString(sb); 16932 sb.append(": over "); 16933 TimeUtils.formatDuration(realtimeSince, sb); 16934 sb.append(" used "); 16935 TimeUtils.formatDuration(wtimeUsed, sb); 16936 sb.append(" ("); 16937 sb.append((wtimeUsed*100)/realtimeSince); 16938 sb.append("%)"); 16939 Slog.i(TAG, sb.toString()); 16940 sb.setLength(0); 16941 sb.append("CPU for "); 16942 app.toShortString(sb); 16943 sb.append(": over "); 16944 TimeUtils.formatDuration(uptimeSince, sb); 16945 sb.append(" used "); 16946 TimeUtils.formatDuration(cputimeUsed, sb); 16947 sb.append(" ("); 16948 sb.append((cputimeUsed*100)/uptimeSince); 16949 sb.append("%)"); 16950 Slog.i(TAG, sb.toString()); 16951 } 16952 // If a process has held a wake lock for more 16953 // than 50% of the time during this period, 16954 // that sounds bad. Kill! 16955 if (doWakeKills && realtimeSince > 0 16956 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16957 synchronized (stats) { 16958 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16959 realtimeSince, wtimeUsed); 16960 } 16961 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16962 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16963 } else if (doCpuKills && uptimeSince > 0 16964 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16965 synchronized (stats) { 16966 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16967 uptimeSince, cputimeUsed); 16968 } 16969 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16970 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16971 } else { 16972 app.lastWakeTime = wtime; 16973 app.lastCpuTime = app.curCpuTime; 16974 } 16975 } 16976 } 16977 } 16978 16979 private final boolean applyOomAdjLocked(ProcessRecord app, 16980 ProcessRecord TOP_APP, boolean doingAll, long now) { 16981 boolean success = true; 16982 16983 if (app.curRawAdj != app.setRawAdj) { 16984 app.setRawAdj = app.curRawAdj; 16985 } 16986 16987 int changes = 0; 16988 16989 if (app.curAdj != app.setAdj) { 16990 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16991 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16992 TAG, "Set " + app.pid + " " + app.processName + 16993 " adj " + app.curAdj + ": " + app.adjType); 16994 app.setAdj = app.curAdj; 16995 } 16996 16997 if (app.setSchedGroup != app.curSchedGroup) { 16998 app.setSchedGroup = app.curSchedGroup; 16999 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17000 "Setting process group of " + app.processName 17001 + " to " + app.curSchedGroup); 17002 if (app.waitingToKill != null && 17003 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17004 app.kill(app.waitingToKill, true); 17005 success = false; 17006 } else { 17007 if (true) { 17008 long oldId = Binder.clearCallingIdentity(); 17009 try { 17010 Process.setProcessGroup(app.pid, app.curSchedGroup); 17011 } catch (Exception e) { 17012 Slog.w(TAG, "Failed setting process group of " + app.pid 17013 + " to " + app.curSchedGroup); 17014 e.printStackTrace(); 17015 } finally { 17016 Binder.restoreCallingIdentity(oldId); 17017 } 17018 } else { 17019 if (app.thread != null) { 17020 try { 17021 app.thread.setSchedulingGroup(app.curSchedGroup); 17022 } catch (RemoteException e) { 17023 } 17024 } 17025 } 17026 Process.setSwappiness(app.pid, 17027 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17028 } 17029 } 17030 if (app.repForegroundActivities != app.foregroundActivities) { 17031 app.repForegroundActivities = app.foregroundActivities; 17032 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17033 } 17034 if (app.repProcState != app.curProcState) { 17035 app.repProcState = app.curProcState; 17036 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17037 if (app.thread != null) { 17038 try { 17039 if (false) { 17040 //RuntimeException h = new RuntimeException("here"); 17041 Slog.i(TAG, "Sending new process state " + app.repProcState 17042 + " to " + app /*, h*/); 17043 } 17044 app.thread.setProcessState(app.repProcState); 17045 } catch (RemoteException e) { 17046 } 17047 } 17048 } 17049 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17050 app.setProcState)) { 17051 app.lastStateTime = now; 17052 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17053 isSleeping(), now); 17054 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17055 + ProcessList.makeProcStateString(app.setProcState) + " to " 17056 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17057 + (app.nextPssTime-now) + ": " + app); 17058 } else { 17059 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17060 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17061 requestPssLocked(app, app.setProcState); 17062 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17063 isSleeping(), now); 17064 } else if (false && DEBUG_PSS) { 17065 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17066 } 17067 } 17068 if (app.setProcState != app.curProcState) { 17069 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17070 "Proc state change of " + app.processName 17071 + " to " + app.curProcState); 17072 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17073 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17074 if (setImportant && !curImportant) { 17075 // This app is no longer something we consider important enough to allow to 17076 // use arbitrary amounts of battery power. Note 17077 // its current wake lock time to later know to kill it if 17078 // it is not behaving well. 17079 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17080 synchronized (stats) { 17081 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17082 app.pid, SystemClock.elapsedRealtime()); 17083 } 17084 app.lastCpuTime = app.curCpuTime; 17085 17086 } 17087 app.setProcState = app.curProcState; 17088 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17089 app.notCachedSinceIdle = false; 17090 } 17091 if (!doingAll) { 17092 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17093 } else { 17094 app.procStateChanged = true; 17095 } 17096 } 17097 17098 if (changes != 0) { 17099 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17100 int i = mPendingProcessChanges.size()-1; 17101 ProcessChangeItem item = null; 17102 while (i >= 0) { 17103 item = mPendingProcessChanges.get(i); 17104 if (item.pid == app.pid) { 17105 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17106 break; 17107 } 17108 i--; 17109 } 17110 if (i < 0) { 17111 // No existing item in pending changes; need a new one. 17112 final int NA = mAvailProcessChanges.size(); 17113 if (NA > 0) { 17114 item = mAvailProcessChanges.remove(NA-1); 17115 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17116 } else { 17117 item = new ProcessChangeItem(); 17118 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17119 } 17120 item.changes = 0; 17121 item.pid = app.pid; 17122 item.uid = app.info.uid; 17123 if (mPendingProcessChanges.size() == 0) { 17124 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17125 "*** Enqueueing dispatch processes changed!"); 17126 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17127 } 17128 mPendingProcessChanges.add(item); 17129 } 17130 item.changes |= changes; 17131 item.processState = app.repProcState; 17132 item.foregroundActivities = app.repForegroundActivities; 17133 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17134 + Integer.toHexString(System.identityHashCode(item)) 17135 + " " + app.toShortString() + ": changes=" + item.changes 17136 + " procState=" + item.processState 17137 + " foreground=" + item.foregroundActivities 17138 + " type=" + app.adjType + " source=" + app.adjSource 17139 + " target=" + app.adjTarget); 17140 } 17141 17142 return success; 17143 } 17144 17145 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17146 if (proc.thread != null) { 17147 if (proc.baseProcessTracker != null) { 17148 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17149 } 17150 if (proc.repProcState >= 0) { 17151 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17152 proc.repProcState); 17153 } 17154 } 17155 } 17156 17157 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17158 ProcessRecord TOP_APP, boolean doingAll, long now) { 17159 if (app.thread == null) { 17160 return false; 17161 } 17162 17163 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17164 17165 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17166 } 17167 17168 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17169 boolean oomAdj) { 17170 if (isForeground != proc.foregroundServices) { 17171 proc.foregroundServices = isForeground; 17172 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17173 proc.info.uid); 17174 if (isForeground) { 17175 if (curProcs == null) { 17176 curProcs = new ArrayList<ProcessRecord>(); 17177 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17178 } 17179 if (!curProcs.contains(proc)) { 17180 curProcs.add(proc); 17181 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17182 proc.info.packageName, proc.info.uid); 17183 } 17184 } else { 17185 if (curProcs != null) { 17186 if (curProcs.remove(proc)) { 17187 mBatteryStatsService.noteEvent( 17188 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17189 proc.info.packageName, proc.info.uid); 17190 if (curProcs.size() <= 0) { 17191 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17192 } 17193 } 17194 } 17195 } 17196 if (oomAdj) { 17197 updateOomAdjLocked(); 17198 } 17199 } 17200 } 17201 17202 private final ActivityRecord resumedAppLocked() { 17203 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17204 String pkg; 17205 int uid; 17206 if (act != null) { 17207 pkg = act.packageName; 17208 uid = act.info.applicationInfo.uid; 17209 } else { 17210 pkg = null; 17211 uid = -1; 17212 } 17213 // Has the UID or resumed package name changed? 17214 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17215 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17216 if (mCurResumedPackage != null) { 17217 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17218 mCurResumedPackage, mCurResumedUid); 17219 } 17220 mCurResumedPackage = pkg; 17221 mCurResumedUid = uid; 17222 if (mCurResumedPackage != null) { 17223 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17224 mCurResumedPackage, mCurResumedUid); 17225 } 17226 } 17227 return act; 17228 } 17229 17230 final boolean updateOomAdjLocked(ProcessRecord app) { 17231 final ActivityRecord TOP_ACT = resumedAppLocked(); 17232 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17233 final boolean wasCached = app.cached; 17234 17235 mAdjSeq++; 17236 17237 // This is the desired cached adjusment we want to tell it to use. 17238 // If our app is currently cached, we know it, and that is it. Otherwise, 17239 // we don't know it yet, and it needs to now be cached we will then 17240 // need to do a complete oom adj. 17241 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17242 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17243 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17244 SystemClock.uptimeMillis()); 17245 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17246 // Changed to/from cached state, so apps after it in the LRU 17247 // list may also be changed. 17248 updateOomAdjLocked(); 17249 } 17250 return success; 17251 } 17252 17253 final void updateOomAdjLocked() { 17254 final ActivityRecord TOP_ACT = resumedAppLocked(); 17255 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17256 final long now = SystemClock.uptimeMillis(); 17257 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17258 final int N = mLruProcesses.size(); 17259 17260 if (false) { 17261 RuntimeException e = new RuntimeException(); 17262 e.fillInStackTrace(); 17263 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17264 } 17265 17266 mAdjSeq++; 17267 mNewNumServiceProcs = 0; 17268 mNewNumAServiceProcs = 0; 17269 17270 final int emptyProcessLimit; 17271 final int cachedProcessLimit; 17272 if (mProcessLimit <= 0) { 17273 emptyProcessLimit = cachedProcessLimit = 0; 17274 } else if (mProcessLimit == 1) { 17275 emptyProcessLimit = 1; 17276 cachedProcessLimit = 0; 17277 } else { 17278 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17279 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17280 } 17281 17282 // Let's determine how many processes we have running vs. 17283 // how many slots we have for background processes; we may want 17284 // to put multiple processes in a slot of there are enough of 17285 // them. 17286 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17287 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17288 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17289 if (numEmptyProcs > cachedProcessLimit) { 17290 // If there are more empty processes than our limit on cached 17291 // processes, then use the cached process limit for the factor. 17292 // This ensures that the really old empty processes get pushed 17293 // down to the bottom, so if we are running low on memory we will 17294 // have a better chance at keeping around more cached processes 17295 // instead of a gazillion empty processes. 17296 numEmptyProcs = cachedProcessLimit; 17297 } 17298 int emptyFactor = numEmptyProcs/numSlots; 17299 if (emptyFactor < 1) emptyFactor = 1; 17300 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17301 if (cachedFactor < 1) cachedFactor = 1; 17302 int stepCached = 0; 17303 int stepEmpty = 0; 17304 int numCached = 0; 17305 int numEmpty = 0; 17306 int numTrimming = 0; 17307 17308 mNumNonCachedProcs = 0; 17309 mNumCachedHiddenProcs = 0; 17310 17311 // First update the OOM adjustment for each of the 17312 // application processes based on their current state. 17313 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17314 int nextCachedAdj = curCachedAdj+1; 17315 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17316 int nextEmptyAdj = curEmptyAdj+2; 17317 for (int i=N-1; i>=0; i--) { 17318 ProcessRecord app = mLruProcesses.get(i); 17319 if (!app.killedByAm && app.thread != null) { 17320 app.procStateChanged = false; 17321 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17322 17323 // If we haven't yet assigned the final cached adj 17324 // to the process, do that now. 17325 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17326 switch (app.curProcState) { 17327 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17328 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17329 // This process is a cached process holding activities... 17330 // assign it the next cached value for that type, and then 17331 // step that cached level. 17332 app.curRawAdj = curCachedAdj; 17333 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17334 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17335 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17336 + ")"); 17337 if (curCachedAdj != nextCachedAdj) { 17338 stepCached++; 17339 if (stepCached >= cachedFactor) { 17340 stepCached = 0; 17341 curCachedAdj = nextCachedAdj; 17342 nextCachedAdj += 2; 17343 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17344 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17345 } 17346 } 17347 } 17348 break; 17349 default: 17350 // For everything else, assign next empty cached process 17351 // level and bump that up. Note that this means that 17352 // long-running services that have dropped down to the 17353 // cached level will be treated as empty (since their process 17354 // state is still as a service), which is what we want. 17355 app.curRawAdj = curEmptyAdj; 17356 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17357 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17358 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17359 + ")"); 17360 if (curEmptyAdj != nextEmptyAdj) { 17361 stepEmpty++; 17362 if (stepEmpty >= emptyFactor) { 17363 stepEmpty = 0; 17364 curEmptyAdj = nextEmptyAdj; 17365 nextEmptyAdj += 2; 17366 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17367 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17368 } 17369 } 17370 } 17371 break; 17372 } 17373 } 17374 17375 applyOomAdjLocked(app, TOP_APP, true, now); 17376 17377 // Count the number of process types. 17378 switch (app.curProcState) { 17379 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17380 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17381 mNumCachedHiddenProcs++; 17382 numCached++; 17383 if (numCached > cachedProcessLimit) { 17384 app.kill("cached #" + numCached, true); 17385 } 17386 break; 17387 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17388 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17389 && app.lastActivityTime < oldTime) { 17390 app.kill("empty for " 17391 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17392 / 1000) + "s", true); 17393 } else { 17394 numEmpty++; 17395 if (numEmpty > emptyProcessLimit) { 17396 app.kill("empty #" + numEmpty, true); 17397 } 17398 } 17399 break; 17400 default: 17401 mNumNonCachedProcs++; 17402 break; 17403 } 17404 17405 if (app.isolated && app.services.size() <= 0) { 17406 // If this is an isolated process, and there are no 17407 // services running in it, then the process is no longer 17408 // needed. We agressively kill these because we can by 17409 // definition not re-use the same process again, and it is 17410 // good to avoid having whatever code was running in them 17411 // left sitting around after no longer needed. 17412 app.kill("isolated not needed", true); 17413 } 17414 17415 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17416 && !app.killedByAm) { 17417 numTrimming++; 17418 } 17419 } 17420 } 17421 17422 mNumServiceProcs = mNewNumServiceProcs; 17423 17424 // Now determine the memory trimming level of background processes. 17425 // Unfortunately we need to start at the back of the list to do this 17426 // properly. We only do this if the number of background apps we 17427 // are managing to keep around is less than half the maximum we desire; 17428 // if we are keeping a good number around, we'll let them use whatever 17429 // memory they want. 17430 final int numCachedAndEmpty = numCached + numEmpty; 17431 int memFactor; 17432 if (numCached <= ProcessList.TRIM_CACHED_APPS 17433 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17434 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17435 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17436 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17437 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17438 } else { 17439 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17440 } 17441 } else { 17442 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17443 } 17444 // We always allow the memory level to go up (better). We only allow it to go 17445 // down if we are in a state where that is allowed, *and* the total number of processes 17446 // has gone down since last time. 17447 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17448 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17449 + " last=" + mLastNumProcesses); 17450 if (memFactor > mLastMemoryLevel) { 17451 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17452 memFactor = mLastMemoryLevel; 17453 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17454 } 17455 } 17456 mLastMemoryLevel = memFactor; 17457 mLastNumProcesses = mLruProcesses.size(); 17458 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17459 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17460 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17461 if (mLowRamStartTime == 0) { 17462 mLowRamStartTime = now; 17463 } 17464 int step = 0; 17465 int fgTrimLevel; 17466 switch (memFactor) { 17467 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17468 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17469 break; 17470 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17471 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17472 break; 17473 default: 17474 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17475 break; 17476 } 17477 int factor = numTrimming/3; 17478 int minFactor = 2; 17479 if (mHomeProcess != null) minFactor++; 17480 if (mPreviousProcess != null) minFactor++; 17481 if (factor < minFactor) factor = minFactor; 17482 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17483 for (int i=N-1; i>=0; i--) { 17484 ProcessRecord app = mLruProcesses.get(i); 17485 if (allChanged || app.procStateChanged) { 17486 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17487 app.procStateChanged = false; 17488 } 17489 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17490 && !app.killedByAm) { 17491 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17492 try { 17493 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17494 "Trimming memory of " + app.processName 17495 + " to " + curLevel); 17496 app.thread.scheduleTrimMemory(curLevel); 17497 } catch (RemoteException e) { 17498 } 17499 if (false) { 17500 // For now we won't do this; our memory trimming seems 17501 // to be good enough at this point that destroying 17502 // activities causes more harm than good. 17503 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17504 && app != mHomeProcess && app != mPreviousProcess) { 17505 // Need to do this on its own message because the stack may not 17506 // be in a consistent state at this point. 17507 // For these apps we will also finish their activities 17508 // to help them free memory. 17509 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17510 } 17511 } 17512 } 17513 app.trimMemoryLevel = curLevel; 17514 step++; 17515 if (step >= factor) { 17516 step = 0; 17517 switch (curLevel) { 17518 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17519 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17520 break; 17521 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17522 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17523 break; 17524 } 17525 } 17526 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17527 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17528 && app.thread != null) { 17529 try { 17530 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17531 "Trimming memory of heavy-weight " + app.processName 17532 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17533 app.thread.scheduleTrimMemory( 17534 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17535 } catch (RemoteException e) { 17536 } 17537 } 17538 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17539 } else { 17540 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17541 || app.systemNoUi) && app.pendingUiClean) { 17542 // If this application is now in the background and it 17543 // had done UI, then give it the special trim level to 17544 // have it free UI resources. 17545 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17546 if (app.trimMemoryLevel < level && app.thread != null) { 17547 try { 17548 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17549 "Trimming memory of bg-ui " + app.processName 17550 + " to " + level); 17551 app.thread.scheduleTrimMemory(level); 17552 } catch (RemoteException e) { 17553 } 17554 } 17555 app.pendingUiClean = false; 17556 } 17557 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17558 try { 17559 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17560 "Trimming memory of fg " + app.processName 17561 + " to " + fgTrimLevel); 17562 app.thread.scheduleTrimMemory(fgTrimLevel); 17563 } catch (RemoteException e) { 17564 } 17565 } 17566 app.trimMemoryLevel = fgTrimLevel; 17567 } 17568 } 17569 } else { 17570 if (mLowRamStartTime != 0) { 17571 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17572 mLowRamStartTime = 0; 17573 } 17574 for (int i=N-1; i>=0; i--) { 17575 ProcessRecord app = mLruProcesses.get(i); 17576 if (allChanged || app.procStateChanged) { 17577 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17578 app.procStateChanged = false; 17579 } 17580 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17581 || app.systemNoUi) && app.pendingUiClean) { 17582 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17583 && app.thread != null) { 17584 try { 17585 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17586 "Trimming memory of ui hidden " + app.processName 17587 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17588 app.thread.scheduleTrimMemory( 17589 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17590 } catch (RemoteException e) { 17591 } 17592 } 17593 app.pendingUiClean = false; 17594 } 17595 app.trimMemoryLevel = 0; 17596 } 17597 } 17598 17599 if (mAlwaysFinishActivities) { 17600 // Need to do this on its own message because the stack may not 17601 // be in a consistent state at this point. 17602 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17603 } 17604 17605 if (allChanged) { 17606 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17607 } 17608 17609 if (mProcessStats.shouldWriteNowLocked(now)) { 17610 mHandler.post(new Runnable() { 17611 @Override public void run() { 17612 synchronized (ActivityManagerService.this) { 17613 mProcessStats.writeStateAsyncLocked(); 17614 } 17615 } 17616 }); 17617 } 17618 17619 if (DEBUG_OOM_ADJ) { 17620 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17621 } 17622 } 17623 17624 final void trimApplications() { 17625 synchronized (this) { 17626 int i; 17627 17628 // First remove any unused application processes whose package 17629 // has been removed. 17630 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17631 final ProcessRecord app = mRemovedProcesses.get(i); 17632 if (app.activities.size() == 0 17633 && app.curReceiver == null && app.services.size() == 0) { 17634 Slog.i( 17635 TAG, "Exiting empty application process " 17636 + app.processName + " (" 17637 + (app.thread != null ? app.thread.asBinder() : null) 17638 + ")\n"); 17639 if (app.pid > 0 && app.pid != MY_PID) { 17640 app.kill("empty", false); 17641 } else { 17642 try { 17643 app.thread.scheduleExit(); 17644 } catch (Exception e) { 17645 // Ignore exceptions. 17646 } 17647 } 17648 cleanUpApplicationRecordLocked(app, false, true, -1); 17649 mRemovedProcesses.remove(i); 17650 17651 if (app.persistent) { 17652 addAppLocked(app.info, false, null /* ABI override */); 17653 } 17654 } 17655 } 17656 17657 // Now update the oom adj for all processes. 17658 updateOomAdjLocked(); 17659 } 17660 } 17661 17662 /** This method sends the specified signal to each of the persistent apps */ 17663 public void signalPersistentProcesses(int sig) throws RemoteException { 17664 if (sig != Process.SIGNAL_USR1) { 17665 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17666 } 17667 17668 synchronized (this) { 17669 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17670 != PackageManager.PERMISSION_GRANTED) { 17671 throw new SecurityException("Requires permission " 17672 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17673 } 17674 17675 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17676 ProcessRecord r = mLruProcesses.get(i); 17677 if (r.thread != null && r.persistent) { 17678 Process.sendSignal(r.pid, sig); 17679 } 17680 } 17681 } 17682 } 17683 17684 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17685 if (proc == null || proc == mProfileProc) { 17686 proc = mProfileProc; 17687 profileType = mProfileType; 17688 clearProfilerLocked(); 17689 } 17690 if (proc == null) { 17691 return; 17692 } 17693 try { 17694 proc.thread.profilerControl(false, null, profileType); 17695 } catch (RemoteException e) { 17696 throw new IllegalStateException("Process disappeared"); 17697 } 17698 } 17699 17700 private void clearProfilerLocked() { 17701 if (mProfileFd != null) { 17702 try { 17703 mProfileFd.close(); 17704 } catch (IOException e) { 17705 } 17706 } 17707 mProfileApp = null; 17708 mProfileProc = null; 17709 mProfileFile = null; 17710 mProfileType = 0; 17711 mAutoStopProfiler = false; 17712 mSamplingInterval = 0; 17713 } 17714 17715 public boolean profileControl(String process, int userId, boolean start, 17716 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17717 17718 try { 17719 synchronized (this) { 17720 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17721 // its own permission. 17722 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17723 != PackageManager.PERMISSION_GRANTED) { 17724 throw new SecurityException("Requires permission " 17725 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17726 } 17727 17728 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17729 throw new IllegalArgumentException("null profile info or fd"); 17730 } 17731 17732 ProcessRecord proc = null; 17733 if (process != null) { 17734 proc = findProcessLocked(process, userId, "profileControl"); 17735 } 17736 17737 if (start && (proc == null || proc.thread == null)) { 17738 throw new IllegalArgumentException("Unknown process: " + process); 17739 } 17740 17741 if (start) { 17742 stopProfilerLocked(null, 0); 17743 setProfileApp(proc.info, proc.processName, profilerInfo); 17744 mProfileProc = proc; 17745 mProfileType = profileType; 17746 ParcelFileDescriptor fd = profilerInfo.profileFd; 17747 try { 17748 fd = fd.dup(); 17749 } catch (IOException e) { 17750 fd = null; 17751 } 17752 profilerInfo.profileFd = fd; 17753 proc.thread.profilerControl(start, profilerInfo, profileType); 17754 fd = null; 17755 mProfileFd = null; 17756 } else { 17757 stopProfilerLocked(proc, profileType); 17758 if (profilerInfo != null && profilerInfo.profileFd != null) { 17759 try { 17760 profilerInfo.profileFd.close(); 17761 } catch (IOException e) { 17762 } 17763 } 17764 } 17765 17766 return true; 17767 } 17768 } catch (RemoteException e) { 17769 throw new IllegalStateException("Process disappeared"); 17770 } finally { 17771 if (profilerInfo != null && profilerInfo.profileFd != null) { 17772 try { 17773 profilerInfo.profileFd.close(); 17774 } catch (IOException e) { 17775 } 17776 } 17777 } 17778 } 17779 17780 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17781 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17782 userId, true, ALLOW_FULL_ONLY, callName, null); 17783 ProcessRecord proc = null; 17784 try { 17785 int pid = Integer.parseInt(process); 17786 synchronized (mPidsSelfLocked) { 17787 proc = mPidsSelfLocked.get(pid); 17788 } 17789 } catch (NumberFormatException e) { 17790 } 17791 17792 if (proc == null) { 17793 ArrayMap<String, SparseArray<ProcessRecord>> all 17794 = mProcessNames.getMap(); 17795 SparseArray<ProcessRecord> procs = all.get(process); 17796 if (procs != null && procs.size() > 0) { 17797 proc = procs.valueAt(0); 17798 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17799 for (int i=1; i<procs.size(); i++) { 17800 ProcessRecord thisProc = procs.valueAt(i); 17801 if (thisProc.userId == userId) { 17802 proc = thisProc; 17803 break; 17804 } 17805 } 17806 } 17807 } 17808 } 17809 17810 return proc; 17811 } 17812 17813 public boolean dumpHeap(String process, int userId, boolean managed, 17814 String path, ParcelFileDescriptor fd) throws RemoteException { 17815 17816 try { 17817 synchronized (this) { 17818 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17819 // its own permission (same as profileControl). 17820 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17821 != PackageManager.PERMISSION_GRANTED) { 17822 throw new SecurityException("Requires permission " 17823 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17824 } 17825 17826 if (fd == null) { 17827 throw new IllegalArgumentException("null fd"); 17828 } 17829 17830 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17831 if (proc == null || proc.thread == null) { 17832 throw new IllegalArgumentException("Unknown process: " + process); 17833 } 17834 17835 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17836 if (!isDebuggable) { 17837 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17838 throw new SecurityException("Process not debuggable: " + proc); 17839 } 17840 } 17841 17842 proc.thread.dumpHeap(managed, path, fd); 17843 fd = null; 17844 return true; 17845 } 17846 } catch (RemoteException e) { 17847 throw new IllegalStateException("Process disappeared"); 17848 } finally { 17849 if (fd != null) { 17850 try { 17851 fd.close(); 17852 } catch (IOException e) { 17853 } 17854 } 17855 } 17856 } 17857 17858 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17859 public void monitor() { 17860 synchronized (this) { } 17861 } 17862 17863 void onCoreSettingsChange(Bundle settings) { 17864 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17865 ProcessRecord processRecord = mLruProcesses.get(i); 17866 try { 17867 if (processRecord.thread != null) { 17868 processRecord.thread.setCoreSettings(settings); 17869 } 17870 } catch (RemoteException re) { 17871 /* ignore */ 17872 } 17873 } 17874 } 17875 17876 // Multi-user methods 17877 17878 /** 17879 * Start user, if its not already running, but don't bring it to foreground. 17880 */ 17881 @Override 17882 public boolean startUserInBackground(final int userId) { 17883 return startUser(userId, /* foreground */ false); 17884 } 17885 17886 /** 17887 * Start user, if its not already running, and bring it to foreground. 17888 */ 17889 boolean startUserInForeground(final int userId, Dialog dlg) { 17890 boolean result = startUser(userId, /* foreground */ true); 17891 dlg.dismiss(); 17892 return result; 17893 } 17894 17895 /** 17896 * Refreshes the list of users related to the current user when either a 17897 * user switch happens or when a new related user is started in the 17898 * background. 17899 */ 17900 private void updateCurrentProfileIdsLocked() { 17901 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17902 mCurrentUserId, false /* enabledOnly */); 17903 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17904 for (int i = 0; i < currentProfileIds.length; i++) { 17905 currentProfileIds[i] = profiles.get(i).id; 17906 } 17907 mCurrentProfileIds = currentProfileIds; 17908 17909 synchronized (mUserProfileGroupIdsSelfLocked) { 17910 mUserProfileGroupIdsSelfLocked.clear(); 17911 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17912 for (int i = 0; i < users.size(); i++) { 17913 UserInfo user = users.get(i); 17914 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17915 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17916 } 17917 } 17918 } 17919 } 17920 17921 private Set getProfileIdsLocked(int userId) { 17922 Set userIds = new HashSet<Integer>(); 17923 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17924 userId, false /* enabledOnly */); 17925 for (UserInfo user : profiles) { 17926 userIds.add(Integer.valueOf(user.id)); 17927 } 17928 return userIds; 17929 } 17930 17931 @Override 17932 public boolean switchUser(final int userId) { 17933 String userName; 17934 synchronized (this) { 17935 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17936 if (userInfo == null) { 17937 Slog.w(TAG, "No user info for user #" + userId); 17938 return false; 17939 } 17940 if (userInfo.isManagedProfile()) { 17941 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17942 return false; 17943 } 17944 userName = userInfo.name; 17945 mTargetUserId = userId; 17946 } 17947 mHandler.removeMessages(START_USER_SWITCH_MSG); 17948 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17949 return true; 17950 } 17951 17952 private void showUserSwitchDialog(int userId, String userName) { 17953 // The dialog will show and then initiate the user switch by calling startUserInForeground 17954 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17955 true /* above system */); 17956 d.show(); 17957 } 17958 17959 private boolean startUser(final int userId, final boolean foreground) { 17960 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17961 != PackageManager.PERMISSION_GRANTED) { 17962 String msg = "Permission Denial: switchUser() from pid=" 17963 + Binder.getCallingPid() 17964 + ", uid=" + Binder.getCallingUid() 17965 + " requires " + INTERACT_ACROSS_USERS_FULL; 17966 Slog.w(TAG, msg); 17967 throw new SecurityException(msg); 17968 } 17969 17970 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17971 17972 final long ident = Binder.clearCallingIdentity(); 17973 try { 17974 synchronized (this) { 17975 final int oldUserId = mCurrentUserId; 17976 if (oldUserId == userId) { 17977 return true; 17978 } 17979 17980 mStackSupervisor.setLockTaskModeLocked(null, false); 17981 17982 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17983 if (userInfo == null) { 17984 Slog.w(TAG, "No user info for user #" + userId); 17985 return false; 17986 } 17987 if (foreground && userInfo.isManagedProfile()) { 17988 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17989 return false; 17990 } 17991 17992 if (foreground) { 17993 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17994 R.anim.screen_user_enter); 17995 } 17996 17997 boolean needStart = false; 17998 17999 // If the user we are switching to is not currently started, then 18000 // we need to start it now. 18001 if (mStartedUsers.get(userId) == null) { 18002 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18003 updateStartedUserArrayLocked(); 18004 needStart = true; 18005 } 18006 18007 final Integer userIdInt = Integer.valueOf(userId); 18008 mUserLru.remove(userIdInt); 18009 mUserLru.add(userIdInt); 18010 18011 if (foreground) { 18012 mCurrentUserId = userId; 18013 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18014 updateCurrentProfileIdsLocked(); 18015 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18016 // Once the internal notion of the active user has switched, we lock the device 18017 // with the option to show the user switcher on the keyguard. 18018 mWindowManager.lockNow(null); 18019 } else { 18020 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18021 updateCurrentProfileIdsLocked(); 18022 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18023 mUserLru.remove(currentUserIdInt); 18024 mUserLru.add(currentUserIdInt); 18025 } 18026 18027 final UserStartedState uss = mStartedUsers.get(userId); 18028 18029 // Make sure user is in the started state. If it is currently 18030 // stopping, we need to knock that off. 18031 if (uss.mState == UserStartedState.STATE_STOPPING) { 18032 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18033 // so we can just fairly silently bring the user back from 18034 // the almost-dead. 18035 uss.mState = UserStartedState.STATE_RUNNING; 18036 updateStartedUserArrayLocked(); 18037 needStart = true; 18038 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18039 // This means ACTION_SHUTDOWN has been sent, so we will 18040 // need to treat this as a new boot of the user. 18041 uss.mState = UserStartedState.STATE_BOOTING; 18042 updateStartedUserArrayLocked(); 18043 needStart = true; 18044 } 18045 18046 if (uss.mState == UserStartedState.STATE_BOOTING) { 18047 // Booting up a new user, need to tell system services about it. 18048 // Note that this is on the same handler as scheduling of broadcasts, 18049 // which is important because it needs to go first. 18050 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18051 } 18052 18053 if (foreground) { 18054 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18055 oldUserId)); 18056 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18057 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18058 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18059 oldUserId, userId, uss)); 18060 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18061 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18062 } 18063 18064 if (needStart) { 18065 // Send USER_STARTED broadcast 18066 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18068 | Intent.FLAG_RECEIVER_FOREGROUND); 18069 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18070 broadcastIntentLocked(null, null, intent, 18071 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18072 false, false, MY_PID, Process.SYSTEM_UID, userId); 18073 } 18074 18075 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18076 if (userId != UserHandle.USER_OWNER) { 18077 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18078 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18079 broadcastIntentLocked(null, null, intent, null, 18080 new IIntentReceiver.Stub() { 18081 public void performReceive(Intent intent, int resultCode, 18082 String data, Bundle extras, boolean ordered, 18083 boolean sticky, int sendingUser) { 18084 onUserInitialized(uss, foreground, oldUserId, userId); 18085 } 18086 }, 0, null, null, null, AppOpsManager.OP_NONE, 18087 true, false, MY_PID, Process.SYSTEM_UID, 18088 userId); 18089 uss.initializing = true; 18090 } else { 18091 getUserManagerLocked().makeInitialized(userInfo.id); 18092 } 18093 } 18094 18095 if (foreground) { 18096 if (!uss.initializing) { 18097 moveUserToForeground(uss, oldUserId, userId); 18098 } 18099 } else { 18100 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18101 } 18102 18103 if (needStart) { 18104 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18105 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18106 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18107 broadcastIntentLocked(null, null, intent, 18108 null, new IIntentReceiver.Stub() { 18109 @Override 18110 public void performReceive(Intent intent, int resultCode, String data, 18111 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18112 throws RemoteException { 18113 } 18114 }, 0, null, null, 18115 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18116 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18117 } 18118 } 18119 } finally { 18120 Binder.restoreCallingIdentity(ident); 18121 } 18122 18123 return true; 18124 } 18125 18126 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18127 long ident = Binder.clearCallingIdentity(); 18128 try { 18129 Intent intent; 18130 if (oldUserId >= 0) { 18131 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18132 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18133 int count = profiles.size(); 18134 for (int i = 0; i < count; i++) { 18135 int profileUserId = profiles.get(i).id; 18136 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18137 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18138 | Intent.FLAG_RECEIVER_FOREGROUND); 18139 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18140 broadcastIntentLocked(null, null, intent, 18141 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18142 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18143 } 18144 } 18145 if (newUserId >= 0) { 18146 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18147 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18148 int count = profiles.size(); 18149 for (int i = 0; i < count; i++) { 18150 int profileUserId = profiles.get(i).id; 18151 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18152 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18153 | Intent.FLAG_RECEIVER_FOREGROUND); 18154 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18155 broadcastIntentLocked(null, null, intent, 18156 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18157 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18158 } 18159 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18161 | Intent.FLAG_RECEIVER_FOREGROUND); 18162 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18163 broadcastIntentLocked(null, null, intent, 18164 null, null, 0, null, null, 18165 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18166 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18167 } 18168 } finally { 18169 Binder.restoreCallingIdentity(ident); 18170 } 18171 } 18172 18173 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18174 final int newUserId) { 18175 final int N = mUserSwitchObservers.beginBroadcast(); 18176 if (N > 0) { 18177 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18178 int mCount = 0; 18179 @Override 18180 public void sendResult(Bundle data) throws RemoteException { 18181 synchronized (ActivityManagerService.this) { 18182 if (mCurUserSwitchCallback == this) { 18183 mCount++; 18184 if (mCount == N) { 18185 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18186 } 18187 } 18188 } 18189 } 18190 }; 18191 synchronized (this) { 18192 uss.switching = true; 18193 mCurUserSwitchCallback = callback; 18194 } 18195 for (int i=0; i<N; i++) { 18196 try { 18197 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18198 newUserId, callback); 18199 } catch (RemoteException e) { 18200 } 18201 } 18202 } else { 18203 synchronized (this) { 18204 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18205 } 18206 } 18207 mUserSwitchObservers.finishBroadcast(); 18208 } 18209 18210 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18211 synchronized (this) { 18212 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18213 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18214 } 18215 } 18216 18217 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18218 mCurUserSwitchCallback = null; 18219 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18220 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18221 oldUserId, newUserId, uss)); 18222 } 18223 18224 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18225 synchronized (this) { 18226 if (foreground) { 18227 moveUserToForeground(uss, oldUserId, newUserId); 18228 } 18229 } 18230 18231 completeSwitchAndInitalize(uss, newUserId, true, false); 18232 } 18233 18234 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18235 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18236 if (homeInFront) { 18237 startHomeActivityLocked(newUserId); 18238 } else { 18239 mStackSupervisor.resumeTopActivitiesLocked(); 18240 } 18241 EventLogTags.writeAmSwitchUser(newUserId); 18242 getUserManagerLocked().userForeground(newUserId); 18243 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18244 } 18245 18246 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18247 completeSwitchAndInitalize(uss, newUserId, false, true); 18248 } 18249 18250 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18251 boolean clearInitializing, boolean clearSwitching) { 18252 boolean unfrozen = false; 18253 synchronized (this) { 18254 if (clearInitializing) { 18255 uss.initializing = false; 18256 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18257 } 18258 if (clearSwitching) { 18259 uss.switching = false; 18260 } 18261 if (!uss.switching && !uss.initializing) { 18262 mWindowManager.stopFreezingScreen(); 18263 unfrozen = true; 18264 } 18265 } 18266 if (unfrozen) { 18267 final int N = mUserSwitchObservers.beginBroadcast(); 18268 for (int i=0; i<N; i++) { 18269 try { 18270 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18271 } catch (RemoteException e) { 18272 } 18273 } 18274 mUserSwitchObservers.finishBroadcast(); 18275 } 18276 } 18277 18278 void scheduleStartProfilesLocked() { 18279 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18280 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18281 DateUtils.SECOND_IN_MILLIS); 18282 } 18283 } 18284 18285 void startProfilesLocked() { 18286 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18287 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18288 mCurrentUserId, false /* enabledOnly */); 18289 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18290 for (UserInfo user : profiles) { 18291 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18292 && user.id != mCurrentUserId) { 18293 toStart.add(user); 18294 } 18295 } 18296 final int n = toStart.size(); 18297 int i = 0; 18298 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18299 startUserInBackground(toStart.get(i).id); 18300 } 18301 if (i < n) { 18302 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18303 } 18304 } 18305 18306 void finishUserBoot(UserStartedState uss) { 18307 synchronized (this) { 18308 if (uss.mState == UserStartedState.STATE_BOOTING 18309 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18310 uss.mState = UserStartedState.STATE_RUNNING; 18311 final int userId = uss.mHandle.getIdentifier(); 18312 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18313 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18314 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18315 broadcastIntentLocked(null, null, intent, 18316 null, null, 0, null, null, 18317 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18318 true, false, MY_PID, Process.SYSTEM_UID, userId); 18319 } 18320 } 18321 } 18322 18323 void finishUserSwitch(UserStartedState uss) { 18324 synchronized (this) { 18325 finishUserBoot(uss); 18326 18327 startProfilesLocked(); 18328 18329 int num = mUserLru.size(); 18330 int i = 0; 18331 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18332 Integer oldUserId = mUserLru.get(i); 18333 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18334 if (oldUss == null) { 18335 // Shouldn't happen, but be sane if it does. 18336 mUserLru.remove(i); 18337 num--; 18338 continue; 18339 } 18340 if (oldUss.mState == UserStartedState.STATE_STOPPING 18341 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18342 // This user is already stopping, doesn't count. 18343 num--; 18344 i++; 18345 continue; 18346 } 18347 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18348 // Owner and current can't be stopped, but count as running. 18349 i++; 18350 continue; 18351 } 18352 // This is a user to be stopped. 18353 stopUserLocked(oldUserId, null); 18354 num--; 18355 i++; 18356 } 18357 } 18358 } 18359 18360 @Override 18361 public int stopUser(final int userId, final IStopUserCallback callback) { 18362 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18363 != PackageManager.PERMISSION_GRANTED) { 18364 String msg = "Permission Denial: switchUser() from pid=" 18365 + Binder.getCallingPid() 18366 + ", uid=" + Binder.getCallingUid() 18367 + " requires " + INTERACT_ACROSS_USERS_FULL; 18368 Slog.w(TAG, msg); 18369 throw new SecurityException(msg); 18370 } 18371 if (userId <= 0) { 18372 throw new IllegalArgumentException("Can't stop primary user " + userId); 18373 } 18374 synchronized (this) { 18375 return stopUserLocked(userId, callback); 18376 } 18377 } 18378 18379 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18380 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18381 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18382 return ActivityManager.USER_OP_IS_CURRENT; 18383 } 18384 18385 final UserStartedState uss = mStartedUsers.get(userId); 18386 if (uss == null) { 18387 // User is not started, nothing to do... but we do need to 18388 // callback if requested. 18389 if (callback != null) { 18390 mHandler.post(new Runnable() { 18391 @Override 18392 public void run() { 18393 try { 18394 callback.userStopped(userId); 18395 } catch (RemoteException e) { 18396 } 18397 } 18398 }); 18399 } 18400 return ActivityManager.USER_OP_SUCCESS; 18401 } 18402 18403 if (callback != null) { 18404 uss.mStopCallbacks.add(callback); 18405 } 18406 18407 if (uss.mState != UserStartedState.STATE_STOPPING 18408 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18409 uss.mState = UserStartedState.STATE_STOPPING; 18410 updateStartedUserArrayLocked(); 18411 18412 long ident = Binder.clearCallingIdentity(); 18413 try { 18414 // We are going to broadcast ACTION_USER_STOPPING and then 18415 // once that is done send a final ACTION_SHUTDOWN and then 18416 // stop the user. 18417 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18418 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18419 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18420 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18421 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18422 // This is the result receiver for the final shutdown broadcast. 18423 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18424 @Override 18425 public void performReceive(Intent intent, int resultCode, String data, 18426 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18427 finishUserStop(uss); 18428 } 18429 }; 18430 // This is the result receiver for the initial stopping broadcast. 18431 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18432 @Override 18433 public void performReceive(Intent intent, int resultCode, String data, 18434 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18435 // On to the next. 18436 synchronized (ActivityManagerService.this) { 18437 if (uss.mState != UserStartedState.STATE_STOPPING) { 18438 // Whoops, we are being started back up. Abort, abort! 18439 return; 18440 } 18441 uss.mState = UserStartedState.STATE_SHUTDOWN; 18442 } 18443 mBatteryStatsService.noteEvent( 18444 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18445 Integer.toString(userId), userId); 18446 mSystemServiceManager.stopUser(userId); 18447 broadcastIntentLocked(null, null, shutdownIntent, 18448 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18449 true, false, MY_PID, Process.SYSTEM_UID, userId); 18450 } 18451 }; 18452 // Kick things off. 18453 broadcastIntentLocked(null, null, stoppingIntent, 18454 null, stoppingReceiver, 0, null, null, 18455 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18456 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18457 } finally { 18458 Binder.restoreCallingIdentity(ident); 18459 } 18460 } 18461 18462 return ActivityManager.USER_OP_SUCCESS; 18463 } 18464 18465 void finishUserStop(UserStartedState uss) { 18466 final int userId = uss.mHandle.getIdentifier(); 18467 boolean stopped; 18468 ArrayList<IStopUserCallback> callbacks; 18469 synchronized (this) { 18470 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18471 if (mStartedUsers.get(userId) != uss) { 18472 stopped = false; 18473 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18474 stopped = false; 18475 } else { 18476 stopped = true; 18477 // User can no longer run. 18478 mStartedUsers.remove(userId); 18479 mUserLru.remove(Integer.valueOf(userId)); 18480 updateStartedUserArrayLocked(); 18481 18482 // Clean up all state and processes associated with the user. 18483 // Kill all the processes for the user. 18484 forceStopUserLocked(userId, "finish user"); 18485 } 18486 18487 // Explicitly remove the old information in mRecentTasks. 18488 removeRecentTasksForUserLocked(userId); 18489 } 18490 18491 for (int i=0; i<callbacks.size(); i++) { 18492 try { 18493 if (stopped) callbacks.get(i).userStopped(userId); 18494 else callbacks.get(i).userStopAborted(userId); 18495 } catch (RemoteException e) { 18496 } 18497 } 18498 18499 if (stopped) { 18500 mSystemServiceManager.cleanupUser(userId); 18501 synchronized (this) { 18502 mStackSupervisor.removeUserLocked(userId); 18503 } 18504 } 18505 } 18506 18507 @Override 18508 public UserInfo getCurrentUser() { 18509 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18510 != PackageManager.PERMISSION_GRANTED) && ( 18511 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18512 != PackageManager.PERMISSION_GRANTED)) { 18513 String msg = "Permission Denial: getCurrentUser() from pid=" 18514 + Binder.getCallingPid() 18515 + ", uid=" + Binder.getCallingUid() 18516 + " requires " + INTERACT_ACROSS_USERS; 18517 Slog.w(TAG, msg); 18518 throw new SecurityException(msg); 18519 } 18520 synchronized (this) { 18521 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18522 return getUserManagerLocked().getUserInfo(userId); 18523 } 18524 } 18525 18526 int getCurrentUserIdLocked() { 18527 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18528 } 18529 18530 @Override 18531 public boolean isUserRunning(int userId, boolean orStopped) { 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 isUserRunningLocked(userId, orStopped); 18543 } 18544 } 18545 18546 boolean isUserRunningLocked(int userId, boolean orStopped) { 18547 UserStartedState state = mStartedUsers.get(userId); 18548 if (state == null) { 18549 return false; 18550 } 18551 if (orStopped) { 18552 return true; 18553 } 18554 return state.mState != UserStartedState.STATE_STOPPING 18555 && state.mState != UserStartedState.STATE_SHUTDOWN; 18556 } 18557 18558 @Override 18559 public int[] getRunningUserIds() { 18560 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18561 != PackageManager.PERMISSION_GRANTED) { 18562 String msg = "Permission Denial: isUserRunning() from pid=" 18563 + Binder.getCallingPid() 18564 + ", uid=" + Binder.getCallingUid() 18565 + " requires " + INTERACT_ACROSS_USERS; 18566 Slog.w(TAG, msg); 18567 throw new SecurityException(msg); 18568 } 18569 synchronized (this) { 18570 return mStartedUserArray; 18571 } 18572 } 18573 18574 private void updateStartedUserArrayLocked() { 18575 int num = 0; 18576 for (int i=0; i<mStartedUsers.size(); i++) { 18577 UserStartedState uss = mStartedUsers.valueAt(i); 18578 // This list does not include stopping users. 18579 if (uss.mState != UserStartedState.STATE_STOPPING 18580 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18581 num++; 18582 } 18583 } 18584 mStartedUserArray = new int[num]; 18585 num = 0; 18586 for (int i=0; i<mStartedUsers.size(); i++) { 18587 UserStartedState uss = mStartedUsers.valueAt(i); 18588 if (uss.mState != UserStartedState.STATE_STOPPING 18589 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18590 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18591 num++; 18592 } 18593 } 18594 } 18595 18596 @Override 18597 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18598 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18599 != PackageManager.PERMISSION_GRANTED) { 18600 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18601 + Binder.getCallingPid() 18602 + ", uid=" + Binder.getCallingUid() 18603 + " requires " + INTERACT_ACROSS_USERS_FULL; 18604 Slog.w(TAG, msg); 18605 throw new SecurityException(msg); 18606 } 18607 18608 mUserSwitchObservers.register(observer); 18609 } 18610 18611 @Override 18612 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18613 mUserSwitchObservers.unregister(observer); 18614 } 18615 18616 private boolean userExists(int userId) { 18617 if (userId == 0) { 18618 return true; 18619 } 18620 UserManagerService ums = getUserManagerLocked(); 18621 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18622 } 18623 18624 int[] getUsersLocked() { 18625 UserManagerService ums = getUserManagerLocked(); 18626 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18627 } 18628 18629 UserManagerService getUserManagerLocked() { 18630 if (mUserManager == null) { 18631 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18632 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18633 } 18634 return mUserManager; 18635 } 18636 18637 private int applyUserId(int uid, int userId) { 18638 return UserHandle.getUid(userId, uid); 18639 } 18640 18641 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18642 if (info == null) return null; 18643 ApplicationInfo newInfo = new ApplicationInfo(info); 18644 newInfo.uid = applyUserId(info.uid, userId); 18645 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18646 + info.packageName; 18647 return newInfo; 18648 } 18649 18650 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18651 if (aInfo == null 18652 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18653 return aInfo; 18654 } 18655 18656 ActivityInfo info = new ActivityInfo(aInfo); 18657 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18658 return info; 18659 } 18660 18661 private final class LocalService extends ActivityManagerInternal { 18662 @Override 18663 public void goingToSleep() { 18664 ActivityManagerService.this.goingToSleep(); 18665 } 18666 18667 @Override 18668 public void wakingUp() { 18669 ActivityManagerService.this.wakingUp(); 18670 } 18671 18672 @Override 18673 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18674 String processName, String abiOverride, int uid, Runnable crashHandler) { 18675 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18676 processName, abiOverride, uid, crashHandler); 18677 } 18678 } 18679 18680 /** 18681 * An implementation of IAppTask, that allows an app to manage its own tasks via 18682 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18683 * only the process that calls getAppTasks() can call the AppTask methods. 18684 */ 18685 class AppTaskImpl extends IAppTask.Stub { 18686 private int mTaskId; 18687 private int mCallingUid; 18688 18689 public AppTaskImpl(int taskId, int callingUid) { 18690 mTaskId = taskId; 18691 mCallingUid = callingUid; 18692 } 18693 18694 private void checkCaller() { 18695 if (mCallingUid != Binder.getCallingUid()) { 18696 throw new SecurityException("Caller " + mCallingUid 18697 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18698 } 18699 } 18700 18701 @Override 18702 public void finishAndRemoveTask() { 18703 checkCaller(); 18704 18705 synchronized (ActivityManagerService.this) { 18706 long origId = Binder.clearCallingIdentity(); 18707 try { 18708 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18709 if (tr == null) { 18710 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18711 } 18712 // Only kill the process if we are not a new document 18713 int flags = tr.getBaseIntent().getFlags(); 18714 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18715 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18716 removeTaskByIdLocked(mTaskId, 18717 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18718 } finally { 18719 Binder.restoreCallingIdentity(origId); 18720 } 18721 } 18722 } 18723 18724 @Override 18725 public ActivityManager.RecentTaskInfo getTaskInfo() { 18726 checkCaller(); 18727 18728 synchronized (ActivityManagerService.this) { 18729 long origId = Binder.clearCallingIdentity(); 18730 try { 18731 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18732 if (tr == null) { 18733 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18734 } 18735 return createRecentTaskInfoFromTaskRecord(tr); 18736 } finally { 18737 Binder.restoreCallingIdentity(origId); 18738 } 18739 } 18740 } 18741 18742 @Override 18743 public void moveToFront() { 18744 checkCaller(); 18745 18746 final TaskRecord tr; 18747 synchronized (ActivityManagerService.this) { 18748 tr = recentTaskForIdLocked(mTaskId); 18749 if (tr == null) { 18750 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18751 } 18752 if (tr.getRootActivity() != null) { 18753 long origId = Binder.clearCallingIdentity(); 18754 try { 18755 moveTaskToFrontLocked(tr.taskId, 0, null); 18756 return; 18757 } finally { 18758 Binder.restoreCallingIdentity(origId); 18759 } 18760 } 18761 } 18762 18763 startActivityFromRecentsInner(tr.taskId, null); 18764 } 18765 18766 @Override 18767 public int startActivity(IBinder whoThread, String callingPackage, 18768 Intent intent, String resolvedType, Bundle options) { 18769 checkCaller(); 18770 18771 int callingUser = UserHandle.getCallingUserId(); 18772 TaskRecord tr; 18773 IApplicationThread appThread; 18774 synchronized (ActivityManagerService.this) { 18775 tr = recentTaskForIdLocked(mTaskId); 18776 if (tr == null) { 18777 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18778 } 18779 appThread = ApplicationThreadNative.asInterface(whoThread); 18780 if (appThread == null) { 18781 throw new IllegalArgumentException("Bad app thread " + appThread); 18782 } 18783 } 18784 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18785 resolvedType, null, null, null, null, 0, 0, null, null, 18786 null, options, callingUser, null, tr); 18787 } 18788 18789 @Override 18790 public void setExcludeFromRecents(boolean exclude) { 18791 checkCaller(); 18792 18793 synchronized (ActivityManagerService.this) { 18794 long origId = Binder.clearCallingIdentity(); 18795 try { 18796 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18797 if (tr == null) { 18798 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18799 } 18800 Intent intent = tr.getBaseIntent(); 18801 if (exclude) { 18802 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18803 } else { 18804 intent.setFlags(intent.getFlags() 18805 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18806 } 18807 } finally { 18808 Binder.restoreCallingIdentity(origId); 18809 } 18810 } 18811 } 18812 } 18813} 18814